2008-08-31 09:47:27 +04:00
/*
* Synchronous Cryptographic Hash operations .
*
* Copyright ( c ) 2008 Herbert Xu < herbert @ gondor . apana . org . au >
*
* This program is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation ; either version 2 of the License , or ( at your option )
* any later version .
*
*/
2008-08-31 12:52:18 +04:00
# include <crypto/scatterwalk.h>
2008-08-31 09:47:27 +04:00
# include <crypto/internal/hash.h>
# include <linux/err.h>
# include <linux/kernel.h>
# include <linux/module.h>
# include <linux/slab.h>
# include <linux/seq_file.h>
2011-09-27 09:26:10 +04:00
# include <linux/cryptouser.h>
# include <net/netlink.h>
2016-12-31 18:56:23 +03:00
# include <linux/compiler.h>
2008-08-31 09:47:27 +04:00
2008-08-31 12:52:18 +04:00
# include "internal.h"
2009-02-18 11:56:59 +03:00
static const struct crypto_type crypto_shash_type ;
2009-07-11 18:17:39 +04:00
static int shash_no_setkey ( struct crypto_shash * tfm , const u8 * key ,
unsigned int keylen )
{
return - ENOSYS ;
}
2008-08-31 09:47:27 +04:00
static int shash_setkey_unaligned ( struct crypto_shash * tfm , const u8 * key ,
unsigned int keylen )
{
struct shash_alg * shash = crypto_shash_alg ( tfm ) ;
unsigned long alignmask = crypto_shash_alignmask ( tfm ) ;
unsigned long absize ;
u8 * buffer , * alignbuffer ;
int err ;
2010-05-19 05:50:58 +04:00
absize = keylen + ( alignmask & ~ ( crypto_tfm_ctx_alignment ( ) - 1 ) ) ;
2017-10-03 05:25:22 +03:00
buffer = kmalloc ( absize , GFP_ATOMIC ) ;
2008-08-31 09:47:27 +04:00
if ( ! buffer )
return - ENOMEM ;
alignbuffer = ( u8 * ) ALIGN ( ( unsigned long ) buffer , alignmask + 1 ) ;
memcpy ( alignbuffer , key , keylen ) ;
err = shash - > setkey ( tfm , alignbuffer , keylen ) ;
2009-07-14 17:35:36 +04:00
kzfree ( buffer ) ;
2008-08-31 09:47:27 +04:00
return err ;
}
int crypto_shash_setkey ( struct crypto_shash * tfm , const u8 * key ,
unsigned int keylen )
{
struct shash_alg * shash = crypto_shash_alg ( tfm ) ;
unsigned long alignmask = crypto_shash_alignmask ( tfm ) ;
if ( ( unsigned long ) key & alignmask )
return shash_setkey_unaligned ( tfm , key , keylen ) ;
return shash - > setkey ( tfm , key , keylen ) ;
}
EXPORT_SYMBOL_GPL ( crypto_shash_setkey ) ;
static inline unsigned int shash_align_buffer_size ( unsigned len ,
unsigned long mask )
{
2016-12-31 18:56:23 +03:00
typedef u8 __aligned_largest u8_aligned ;
2012-11-21 00:18:16 +04:00
return len + ( mask & ~ ( __alignof__ ( u8_aligned ) - 1 ) ) ;
2008-08-31 09:47:27 +04:00
}
static int shash_update_unaligned ( struct shash_desc * desc , const u8 * data ,
unsigned int len )
{
struct crypto_shash * tfm = desc - > tfm ;
struct shash_alg * shash = crypto_shash_alg ( tfm ) ;
unsigned long alignmask = crypto_shash_alignmask ( tfm ) ;
unsigned int unaligned_len = alignmask + 1 -
( ( unsigned long ) data & alignmask ) ;
2009-07-14 17:43:56 +04:00
u8 ubuf [ shash_align_buffer_size ( unaligned_len , alignmask ) ]
2016-12-31 18:56:23 +03:00
__aligned_largest ;
2009-07-14 17:43:56 +04:00
u8 * buf = PTR_ALIGN ( & ubuf [ 0 ] , alignmask + 1 ) ;
2009-07-14 17:35:36 +04:00
int err ;
2008-08-31 09:47:27 +04:00
2009-03-27 08:03:51 +03:00
if ( unaligned_len > len )
unaligned_len = len ;
2008-08-31 09:47:27 +04:00
memcpy ( buf , data , unaligned_len ) ;
2009-07-14 17:35:36 +04:00
err = shash - > update ( desc , buf , unaligned_len ) ;
memset ( buf , 0 , unaligned_len ) ;
2008-08-31 09:47:27 +04:00
2009-07-14 17:35:36 +04:00
return err ? :
2008-08-31 09:47:27 +04:00
shash - > update ( desc , data + unaligned_len , len - unaligned_len ) ;
}
int crypto_shash_update ( struct shash_desc * desc , const u8 * data ,
unsigned int len )
{
struct crypto_shash * tfm = desc - > tfm ;
struct shash_alg * shash = crypto_shash_alg ( tfm ) ;
unsigned long alignmask = crypto_shash_alignmask ( tfm ) ;
if ( ( unsigned long ) data & alignmask )
return shash_update_unaligned ( desc , data , len ) ;
return shash - > update ( desc , data , len ) ;
}
EXPORT_SYMBOL_GPL ( crypto_shash_update ) ;
static int shash_final_unaligned ( struct shash_desc * desc , u8 * out )
{
struct crypto_shash * tfm = desc - > tfm ;
unsigned long alignmask = crypto_shash_alignmask ( tfm ) ;
struct shash_alg * shash = crypto_shash_alg ( tfm ) ;
unsigned int ds = crypto_shash_digestsize ( tfm ) ;
2009-07-14 17:43:56 +04:00
u8 ubuf [ shash_align_buffer_size ( ds , alignmask ) ]
2016-12-31 18:56:23 +03:00
__aligned_largest ;
2009-07-14 17:43:56 +04:00
u8 * buf = PTR_ALIGN ( & ubuf [ 0 ] , alignmask + 1 ) ;
2008-08-31 09:47:27 +04:00
int err ;
err = shash - > final ( desc , buf ) ;
2009-07-14 17:35:36 +04:00
if ( err )
goto out ;
2008-08-31 09:47:27 +04:00
memcpy ( out , buf , ds ) ;
2009-07-14 17:35:36 +04:00
out :
memset ( buf , 0 , ds ) ;
2008-08-31 09:47:27 +04:00
return err ;
}
int crypto_shash_final ( struct shash_desc * desc , u8 * out )
{
struct crypto_shash * tfm = desc - > tfm ;
struct shash_alg * shash = crypto_shash_alg ( tfm ) ;
unsigned long alignmask = crypto_shash_alignmask ( tfm ) ;
if ( ( unsigned long ) out & alignmask )
return shash_final_unaligned ( desc , out ) ;
return shash - > final ( desc , out ) ;
}
EXPORT_SYMBOL_GPL ( crypto_shash_final ) ;
static int shash_finup_unaligned ( struct shash_desc * desc , const u8 * data ,
unsigned int len , u8 * out )
{
return crypto_shash_update ( desc , data , len ) ? :
crypto_shash_final ( desc , out ) ;
}
int crypto_shash_finup ( struct shash_desc * desc , const u8 * data ,
unsigned int len , u8 * out )
{
struct crypto_shash * tfm = desc - > tfm ;
struct shash_alg * shash = crypto_shash_alg ( tfm ) ;
unsigned long alignmask = crypto_shash_alignmask ( tfm ) ;
2009-07-09 16:36:44 +04:00
if ( ( ( unsigned long ) data | ( unsigned long ) out ) & alignmask )
2008-08-31 09:47:27 +04:00
return shash_finup_unaligned ( desc , data , len , out ) ;
return shash - > finup ( desc , data , len , out ) ;
}
EXPORT_SYMBOL_GPL ( crypto_shash_finup ) ;
static int shash_digest_unaligned ( struct shash_desc * desc , const u8 * data ,
unsigned int len , u8 * out )
{
return crypto_shash_init ( desc ) ? :
2009-07-08 19:32:08 +04:00
crypto_shash_finup ( desc , data , len , out ) ;
2008-08-31 09:47:27 +04:00
}
int crypto_shash_digest ( struct shash_desc * desc , const u8 * data ,
unsigned int len , u8 * out )
{
struct crypto_shash * tfm = desc - > tfm ;
struct shash_alg * shash = crypto_shash_alg ( tfm ) ;
unsigned long alignmask = crypto_shash_alignmask ( tfm ) ;
2009-07-09 16:36:44 +04:00
if ( ( ( unsigned long ) data | ( unsigned long ) out ) & alignmask )
2008-08-31 09:47:27 +04:00
return shash_digest_unaligned ( desc , data , len , out ) ;
return shash - > digest ( desc , data , len , out ) ;
}
EXPORT_SYMBOL_GPL ( crypto_shash_digest ) ;
2009-07-22 08:37:06 +04:00
static int shash_default_export ( struct shash_desc * desc , void * out )
2008-11-02 16:38:11 +03:00
{
2009-07-22 08:37:06 +04:00
memcpy ( out , shash_desc_ctx ( desc ) , crypto_shash_descsize ( desc - > tfm ) ) ;
return 0 ;
2009-07-09 16:30:57 +04:00
}
2008-11-02 16:38:11 +03:00
2009-07-22 08:37:06 +04:00
static int shash_default_import ( struct shash_desc * desc , const void * in )
2009-07-09 16:30:57 +04:00
{
2009-07-22 08:37:06 +04:00
memcpy ( shash_desc_ctx ( desc ) , in , crypto_shash_descsize ( desc - > tfm ) ) ;
return 0 ;
2008-11-02 16:38:11 +03:00
}
2008-08-31 12:52:18 +04:00
static int shash_async_setkey ( struct crypto_ahash * tfm , const u8 * key ,
unsigned int keylen )
{
struct crypto_shash * * ctx = crypto_ahash_ctx ( tfm ) ;
return crypto_shash_setkey ( * ctx , key , keylen ) ;
}
static int shash_async_init ( struct ahash_request * req )
{
struct crypto_shash * * ctx = crypto_ahash_ctx ( crypto_ahash_reqtfm ( req ) ) ;
struct shash_desc * desc = ahash_request_ctx ( req ) ;
desc - > tfm = * ctx ;
desc - > flags = req - > base . flags ;
return crypto_shash_init ( desc ) ;
}
2009-07-12 17:25:20 +04:00
int shash_ahash_update ( struct ahash_request * req , struct shash_desc * desc )
2008-08-31 12:52:18 +04:00
{
struct crypto_hash_walk walk ;
int nbytes ;
for ( nbytes = crypto_hash_walk_first ( req , & walk ) ; nbytes > 0 ;
nbytes = crypto_hash_walk_done ( & walk , nbytes ) )
nbytes = crypto_shash_update ( desc , walk . data , nbytes ) ;
return nbytes ;
}
2009-07-12 17:25:20 +04:00
EXPORT_SYMBOL_GPL ( shash_ahash_update ) ;
static int shash_async_update ( struct ahash_request * req )
{
return shash_ahash_update ( req , ahash_request_ctx ( req ) ) ;
}
2008-08-31 12:52:18 +04:00
static int shash_async_final ( struct ahash_request * req )
{
return crypto_shash_final ( ahash_request_ctx ( req ) , req - > result ) ;
}
2009-07-15 08:40:40 +04:00
int shash_ahash_finup ( struct ahash_request * req , struct shash_desc * desc )
{
struct crypto_hash_walk walk ;
int nbytes ;
2009-07-15 17:26:41 +04:00
nbytes = crypto_hash_walk_first ( req , & walk ) ;
if ( ! nbytes )
return crypto_shash_final ( desc , req - > result ) ;
do {
2009-07-15 08:40:40 +04:00
nbytes = crypto_hash_walk_last ( & walk ) ?
crypto_shash_finup ( desc , walk . data , nbytes ,
req - > result ) :
crypto_shash_update ( desc , walk . data , nbytes ) ;
2009-07-15 17:26:41 +04:00
nbytes = crypto_hash_walk_done ( & walk , nbytes ) ;
} while ( nbytes > 0 ) ;
2009-07-15 08:40:40 +04:00
return nbytes ;
}
EXPORT_SYMBOL_GPL ( shash_ahash_finup ) ;
static int shash_async_finup ( struct ahash_request * req )
{
struct crypto_shash * * ctx = crypto_ahash_ctx ( crypto_ahash_reqtfm ( req ) ) ;
struct shash_desc * desc = ahash_request_ctx ( req ) ;
desc - > tfm = * ctx ;
desc - > flags = req - > base . flags ;
return shash_ahash_finup ( req , desc ) ;
}
2009-07-12 17:25:20 +04:00
int shash_ahash_digest ( struct ahash_request * req , struct shash_desc * desc )
2008-08-31 12:52:18 +04:00
{
unsigned int nbytes = req - > nbytes ;
2017-10-09 18:30:02 +03:00
struct scatterlist * sg ;
unsigned int offset ;
2008-08-31 12:52:18 +04:00
int err ;
2017-10-09 18:30:02 +03:00
if ( nbytes & &
( sg = req - > src , offset = sg - > offset ,
nbytes < min ( sg - > length , ( ( unsigned int ) ( PAGE_SIZE ) ) - offset ) ) ) {
2008-08-31 12:52:18 +04:00
void * data ;
2011-11-25 19:14:17 +04:00
data = kmap_atomic ( sg_page ( sg ) ) ;
2008-08-31 12:52:18 +04:00
err = crypto_shash_digest ( desc , data + offset , nbytes ,
req - > result ) ;
2011-11-25 19:14:17 +04:00
kunmap_atomic ( data ) ;
2008-08-31 12:52:18 +04:00
crypto_yield ( desc - > flags ) ;
2009-07-12 17:25:20 +04:00
} else
err = crypto_shash_init ( desc ) ? :
2009-07-15 08:40:40 +04:00
shash_ahash_finup ( req , desc ) ;
2008-08-31 12:52:18 +04:00
2009-07-12 17:25:20 +04:00
return err ;
}
EXPORT_SYMBOL_GPL ( shash_ahash_digest ) ;
2008-08-31 12:52:18 +04:00
2009-07-12 17:25:20 +04:00
static int shash_async_digest ( struct ahash_request * req )
{
struct crypto_shash * * ctx = crypto_ahash_ctx ( crypto_ahash_reqtfm ( req ) ) ;
struct shash_desc * desc = ahash_request_ctx ( req ) ;
2008-08-31 12:52:18 +04:00
2009-07-12 17:25:20 +04:00
desc - > tfm = * ctx ;
desc - > flags = req - > base . flags ;
2008-08-31 12:52:18 +04:00
2009-07-12 17:25:20 +04:00
return shash_ahash_digest ( req , desc ) ;
2008-08-31 12:52:18 +04:00
}
2009-07-15 08:40:40 +04:00
static int shash_async_export ( struct ahash_request * req , void * out )
{
return crypto_shash_export ( ahash_request_ctx ( req ) , out ) ;
}
static int shash_async_import ( struct ahash_request * req , const void * in )
{
2010-11-04 21:00:22 +03:00
struct crypto_shash * * ctx = crypto_ahash_ctx ( crypto_ahash_reqtfm ( req ) ) ;
struct shash_desc * desc = ahash_request_ctx ( req ) ;
desc - > tfm = * ctx ;
desc - > flags = req - > base . flags ;
return crypto_shash_import ( desc , in ) ;
2009-07-15 08:40:40 +04:00
}
2008-08-31 12:52:18 +04:00
static void crypto_exit_shash_ops_async ( struct crypto_tfm * tfm )
{
struct crypto_shash * * ctx = crypto_tfm_ctx ( tfm ) ;
crypto_free_shash ( * ctx ) ;
}
2009-07-14 08:28:26 +04:00
int crypto_init_shash_ops_async ( struct crypto_tfm * tfm )
2008-08-31 12:52:18 +04:00
{
struct crypto_alg * calg = tfm - > __crt_alg ;
2009-07-15 08:40:40 +04:00
struct shash_alg * alg = __crypto_shash_alg ( calg ) ;
2009-07-14 08:28:26 +04:00
struct crypto_ahash * crt = __crypto_ahash_cast ( tfm ) ;
2008-08-31 12:52:18 +04:00
struct crypto_shash * * ctx = crypto_tfm_ctx ( tfm ) ;
struct crypto_shash * shash ;
if ( ! crypto_mod_get ( calg ) )
return - EAGAIN ;
2009-02-18 11:56:59 +03:00
shash = crypto_create_tfm ( calg , & crypto_shash_type ) ;
2008-08-31 12:52:18 +04:00
if ( IS_ERR ( shash ) ) {
crypto_mod_put ( calg ) ;
return PTR_ERR ( shash ) ;
}
* ctx = shash ;
tfm - > exit = crypto_exit_shash_ops_async ;
crt - > init = shash_async_init ;
crt - > update = shash_async_update ;
2009-07-15 08:40:40 +04:00
crt - > final = shash_async_final ;
crt - > finup = shash_async_finup ;
2008-08-31 12:52:18 +04:00
crt - > digest = shash_async_digest ;
2016-01-26 19:16:37 +03:00
crt - > setkey = shash_async_setkey ;
crt - > has_setkey = alg - > setkey ! = shash_no_setkey ;
2009-07-15 08:40:40 +04:00
if ( alg - > export )
crt - > export = shash_async_export ;
2009-07-24 09:57:13 +04:00
if ( alg - > import )
2009-07-15 08:40:40 +04:00
crt - > import = shash_async_import ;
2008-08-31 12:52:18 +04:00
crt - > reqsize = sizeof ( struct shash_desc ) + crypto_shash_descsize ( shash ) ;
return 0 ;
}
2009-07-13 16:46:25 +04:00
static int crypto_shash_init_tfm ( struct crypto_tfm * tfm )
2008-08-31 09:47:27 +04:00
{
2009-07-14 08:50:12 +04:00
struct crypto_shash * hash = __crypto_shash_cast ( tfm ) ;
hash - > descsize = crypto_shash_alg ( hash ) - > descsize ;
2008-08-31 09:47:27 +04:00
return 0 ;
}
2011-11-03 16:46:07 +04:00
# ifdef CONFIG_NET
2011-09-27 09:26:10 +04:00
static int crypto_shash_report ( struct sk_buff * skb , struct crypto_alg * alg )
{
struct crypto_report_hash rhash ;
struct shash_alg * salg = __crypto_shash_alg ( alg ) ;
2013-02-05 21:19:13 +04:00
strncpy ( rhash . type , " shash " , sizeof ( rhash . type ) ) ;
2011-09-27 09:26:10 +04:00
rhash . blocksize = alg - > cra_blocksize ;
rhash . digestsize = salg - > digestsize ;
2012-04-02 04:19:05 +04:00
if ( nla_put ( skb , CRYPTOCFGA_REPORT_HASH ,
sizeof ( struct crypto_report_hash ) , & rhash ) )
goto nla_put_failure ;
2011-09-27 09:26:10 +04:00
return 0 ;
nla_put_failure :
return - EMSGSIZE ;
}
2011-11-03 16:46:07 +04:00
# else
static int crypto_shash_report ( struct sk_buff * skb , struct crypto_alg * alg )
{
return - ENOSYS ;
}
# endif
2011-09-27 09:26:10 +04:00
2008-08-31 09:47:27 +04:00
static void crypto_shash_show ( struct seq_file * m , struct crypto_alg * alg )
2016-12-31 18:56:23 +03:00
__maybe_unused ;
2008-08-31 09:47:27 +04:00
static void crypto_shash_show ( struct seq_file * m , struct crypto_alg * alg )
{
struct shash_alg * salg = __crypto_shash_alg ( alg ) ;
seq_printf ( m , " type : shash \n " ) ;
seq_printf ( m , " blocksize : %u \n " , alg - > cra_blocksize ) ;
seq_printf ( m , " digestsize : %u \n " , salg - > digestsize ) ;
}
static const struct crypto_type crypto_shash_type = {
2015-04-20 08:39:01 +03:00
. extsize = crypto_alg_extsize ,
2008-08-31 09:47:27 +04:00
. init_tfm = crypto_shash_init_tfm ,
# ifdef CONFIG_PROC_FS
. show = crypto_shash_show ,
# endif
2011-09-27 09:26:10 +04:00
. report = crypto_shash_report ,
2008-08-31 09:47:27 +04:00
. maskclear = ~ CRYPTO_ALG_TYPE_MASK ,
. maskset = CRYPTO_ALG_TYPE_MASK ,
. type = CRYPTO_ALG_TYPE_SHASH ,
. tfmsize = offsetof ( struct crypto_shash , base ) ,
} ;
struct crypto_shash * crypto_alloc_shash ( const char * alg_name , u32 type ,
u32 mask )
{
2009-02-18 11:56:59 +03:00
return crypto_alloc_tfm ( alg_name , & crypto_shash_type , type , mask ) ;
2008-08-31 09:47:27 +04:00
}
EXPORT_SYMBOL_GPL ( crypto_alloc_shash ) ;
2009-07-08 14:46:23 +04:00
static int shash_prepare_alg ( struct shash_alg * alg )
2008-08-31 09:47:27 +04:00
{
struct crypto_alg * base = & alg - > base ;
if ( alg - > digestsize > PAGE_SIZE / 8 | |
2009-07-09 16:30:57 +04:00
alg - > descsize > PAGE_SIZE / 8 | |
alg - > statesize > PAGE_SIZE / 8 )
2008-08-31 09:47:27 +04:00
return - EINVAL ;
base - > cra_type = & crypto_shash_type ;
base - > cra_flags & = ~ CRYPTO_ALG_TYPE_MASK ;
base - > cra_flags | = CRYPTO_ALG_TYPE_SHASH ;
2009-07-09 16:30:57 +04:00
2009-07-09 16:36:44 +04:00
if ( ! alg - > finup )
alg - > finup = shash_finup_unaligned ;
if ( ! alg - > digest )
alg - > digest = shash_digest_unaligned ;
2009-07-22 08:37:06 +04:00
if ( ! alg - > export ) {
alg - > export = shash_default_export ;
alg - > import = shash_default_import ;
alg - > statesize = alg - > descsize ;
}
2009-07-11 18:17:39 +04:00
if ( ! alg - > setkey )
alg - > setkey = shash_no_setkey ;
2009-07-09 16:30:57 +04:00
2009-07-08 14:46:23 +04:00
return 0 ;
}
int crypto_register_shash ( struct shash_alg * alg )
{
struct crypto_alg * base = & alg - > base ;
int err ;
err = shash_prepare_alg ( alg ) ;
if ( err )
return err ;
2008-08-31 09:47:27 +04:00
return crypto_register_alg ( base ) ;
}
EXPORT_SYMBOL_GPL ( crypto_register_shash ) ;
int crypto_unregister_shash ( struct shash_alg * alg )
{
return crypto_unregister_alg ( & alg - > base ) ;
}
EXPORT_SYMBOL_GPL ( crypto_unregister_shash ) ;
2012-07-11 15:20:20 +04:00
int crypto_register_shashes ( struct shash_alg * algs , int count )
{
int i , ret ;
for ( i = 0 ; i < count ; i + + ) {
ret = crypto_register_shash ( & algs [ i ] ) ;
if ( ret )
goto err ;
}
return 0 ;
err :
for ( - - i ; i > = 0 ; - - i )
crypto_unregister_shash ( & algs [ i ] ) ;
return ret ;
}
EXPORT_SYMBOL_GPL ( crypto_register_shashes ) ;
int crypto_unregister_shashes ( struct shash_alg * algs , int count )
{
int i , ret ;
for ( i = count - 1 ; i > = 0 ; - - i ) {
ret = crypto_unregister_shash ( & algs [ i ] ) ;
if ( ret )
pr_err ( " Failed to unregister %s %s: %d \n " ,
algs [ i ] . base . cra_driver_name ,
algs [ i ] . base . cra_name , ret ) ;
}
return 0 ;
}
EXPORT_SYMBOL_GPL ( crypto_unregister_shashes ) ;
2009-07-08 14:46:23 +04:00
int shash_register_instance ( struct crypto_template * tmpl ,
struct shash_instance * inst )
{
int err ;
err = shash_prepare_alg ( & inst - > alg ) ;
if ( err )
return err ;
return crypto_register_instance ( tmpl , shash_crypto_instance ( inst ) ) ;
}
EXPORT_SYMBOL_GPL ( shash_register_instance ) ;
2009-07-07 11:17:12 +04:00
void shash_free_instance ( struct crypto_instance * inst )
{
crypto_drop_spawn ( crypto_instance_ctx ( inst ) ) ;
kfree ( shash_instance ( inst ) ) ;
}
EXPORT_SYMBOL_GPL ( shash_free_instance ) ;
2009-07-08 13:21:37 +04:00
int crypto_init_shash_spawn ( struct crypto_shash_spawn * spawn ,
struct shash_alg * alg ,
struct crypto_instance * inst )
{
return crypto_init_spawn2 ( & spawn - > base , & alg - > base , inst ,
& crypto_shash_type ) ;
}
EXPORT_SYMBOL_GPL ( crypto_init_shash_spawn ) ;
2009-07-08 13:56:28 +04:00
struct shash_alg * shash_attr_alg ( struct rtattr * rta , u32 type , u32 mask )
{
struct crypto_alg * alg ;
alg = crypto_attr_alg2 ( rta , & crypto_shash_type , type , mask ) ;
return IS_ERR ( alg ) ? ERR_CAST ( alg ) :
container_of ( alg , struct shash_alg , base ) ;
}
EXPORT_SYMBOL_GPL ( shash_attr_alg ) ;
2008-08-31 09:47:27 +04:00
MODULE_LICENSE ( " GPL " ) ;
MODULE_DESCRIPTION ( " Synchronous cryptographic hash type " ) ;