2019-05-29 16:57:50 -07:00
// SPDX-License-Identifier: GPL-2.0-only
2007-12-07 16:53:23 +08:00
/*
* Cryptographic API .
*/
# include <linux/init.h>
# include <linux/module.h>
# include <linux/crypto.h>
# include <linux/vmalloc.h>
2014-05-27 10:28:55 -07:00
# include <linux/mm.h>
2007-12-07 16:53:23 +08:00
# include <linux/lzo.h>
2016-10-21 13:19:49 +01:00
# include <crypto/internal/scompress.h>
2007-12-07 16:53:23 +08:00
struct lzo_ctx {
void * lzo_comp_mem ;
} ;
2016-10-21 13:19:49 +01:00
static void * lzo_alloc_ctx ( struct crypto_scomp * tfm )
{
void * ctx ;
2017-05-08 15:57:27 -07:00
ctx = kvmalloc ( LZO1X_MEM_COMPRESS , GFP_KERNEL ) ;
2016-10-21 13:19:49 +01:00
if ( ! ctx )
return ERR_PTR ( - ENOMEM ) ;
return ctx ;
}
2007-12-07 16:53:23 +08:00
static int lzo_init ( struct crypto_tfm * tfm )
{
struct lzo_ctx * ctx = crypto_tfm_ctx ( tfm ) ;
2016-10-21 13:19:49 +01:00
ctx - > lzo_comp_mem = lzo_alloc_ctx ( NULL ) ;
if ( IS_ERR ( ctx - > lzo_comp_mem ) )
2007-12-07 16:53:23 +08:00
return - ENOMEM ;
return 0 ;
}
2016-10-21 13:19:49 +01:00
static void lzo_free_ctx ( struct crypto_scomp * tfm , void * ctx )
{
kvfree ( ctx ) ;
}
2007-12-07 16:53:23 +08:00
static void lzo_exit ( struct crypto_tfm * tfm )
{
struct lzo_ctx * ctx = crypto_tfm_ctx ( tfm ) ;
2016-10-21 13:19:49 +01:00
lzo_free_ctx ( NULL , ctx - > lzo_comp_mem ) ;
2007-12-07 16:53:23 +08:00
}
2016-10-21 13:19:49 +01:00
static int __lzo_compress ( const u8 * src , unsigned int slen ,
u8 * dst , unsigned int * dlen , void * ctx )
2007-12-07 16:53:23 +08:00
{
size_t tmp_len = * dlen ; /* size_t(ulong) <-> uint on 64 bit */
int err ;
2016-10-21 13:19:49 +01:00
err = lzo1x_1_compress ( src , slen , dst , & tmp_len , ctx ) ;
2007-12-07 16:53:23 +08:00
if ( err ! = LZO_E_OK )
return - EINVAL ;
* dlen = tmp_len ;
return 0 ;
}
2016-10-21 13:19:49 +01:00
static int lzo_compress ( struct crypto_tfm * tfm , const u8 * src ,
unsigned int slen , u8 * dst , unsigned int * dlen )
{
struct lzo_ctx * ctx = crypto_tfm_ctx ( tfm ) ;
return __lzo_compress ( src , slen , dst , dlen , ctx - > lzo_comp_mem ) ;
}
static int lzo_scompress ( struct crypto_scomp * tfm , const u8 * src ,
unsigned int slen , u8 * dst , unsigned int * dlen ,
void * ctx )
{
return __lzo_compress ( src , slen , dst , dlen , ctx ) ;
}
static int __lzo_decompress ( const u8 * src , unsigned int slen ,
u8 * dst , unsigned int * dlen )
2007-12-07 16:53:23 +08:00
{
int err ;
size_t tmp_len = * dlen ; /* size_t(ulong) <-> uint on 64 bit */
err = lzo1x_decompress_safe ( src , slen , dst , & tmp_len ) ;
if ( err ! = LZO_E_OK )
return - EINVAL ;
* dlen = tmp_len ;
return 0 ;
2016-10-21 13:19:49 +01:00
}
2007-12-07 16:53:23 +08:00
2016-10-21 13:19:49 +01:00
static int lzo_decompress ( struct crypto_tfm * tfm , const u8 * src ,
unsigned int slen , u8 * dst , unsigned int * dlen )
{
return __lzo_decompress ( src , slen , dst , dlen ) ;
}
static int lzo_sdecompress ( struct crypto_scomp * tfm , const u8 * src ,
unsigned int slen , u8 * dst , unsigned int * dlen ,
void * ctx )
{
return __lzo_decompress ( src , slen , dst , dlen ) ;
2007-12-07 16:53:23 +08:00
}
static struct crypto_alg alg = {
. cra_name = " lzo " ,
2019-06-02 22:40:57 -07:00
. cra_driver_name = " lzo-generic " ,
2007-12-07 16:53:23 +08:00
. cra_flags = CRYPTO_ALG_TYPE_COMPRESS ,
. cra_ctxsize = sizeof ( struct lzo_ctx ) ,
. cra_module = THIS_MODULE ,
. cra_init = lzo_init ,
. cra_exit = lzo_exit ,
. cra_u = { . compress = {
2016-10-21 13:19:49 +01:00
. coa_compress = lzo_compress ,
. coa_decompress = lzo_decompress } }
} ;
static struct scomp_alg scomp = {
. alloc_ctx = lzo_alloc_ctx ,
. free_ctx = lzo_free_ctx ,
. compress = lzo_scompress ,
. decompress = lzo_sdecompress ,
. base = {
. cra_name = " lzo " ,
. cra_driver_name = " lzo-scomp " ,
. cra_module = THIS_MODULE ,
}
2007-12-07 16:53:23 +08:00
} ;
2008-04-05 21:00:57 +08:00
static int __init lzo_mod_init ( void )
2007-12-07 16:53:23 +08:00
{
2016-10-21 13:19:49 +01:00
int ret ;
ret = crypto_register_alg ( & alg ) ;
if ( ret )
return ret ;
ret = crypto_register_scomp ( & scomp ) ;
if ( ret ) {
crypto_unregister_alg ( & alg ) ;
return ret ;
}
return ret ;
2007-12-07 16:53:23 +08:00
}
2008-04-05 21:00:57 +08:00
static void __exit lzo_mod_fini ( void )
2007-12-07 16:53:23 +08:00
{
crypto_unregister_alg ( & alg ) ;
2016-10-21 13:19:49 +01:00
crypto_unregister_scomp ( & scomp ) ;
2007-12-07 16:53:23 +08:00
}
2019-04-11 21:57:42 -07:00
subsys_initcall ( lzo_mod_init ) ;
2008-04-05 21:00:57 +08:00
module_exit ( lzo_mod_fini ) ;
2007-12-07 16:53:23 +08:00
MODULE_LICENSE ( " GPL " ) ;
MODULE_DESCRIPTION ( " LZO Compression Algorithm " ) ;
2014-11-20 17:05:53 -08:00
MODULE_ALIAS_CRYPTO ( " lzo " ) ;