2019-05-27 09:55:01 +03:00
// SPDX-License-Identifier: GPL-2.0-or-later
2007-02-09 17:25:29 +03:00
/*
2005-04-17 02:20:36 +04:00
* xfrm algorithm interface
*
* Copyright ( c ) 2002 James Morris < jmorris @ intercode . com . au >
*/
2016-01-24 16:19:11 +03:00
# include <crypto/hash.h>
# include <crypto/skcipher.h>
2005-04-17 02:20:36 +04:00
# include <linux/module.h>
# include <linux/kernel.h>
# include <linux/pfkeyv2.h>
# include <linux/crypto.h>
2007-10-23 11:28:34 +04:00
# include <linux/scatterlist.h>
2005-04-17 02:20:36 +04:00
# include <net/xfrm.h>
2016-09-09 15:43:20 +03:00
# if IS_ENABLED(CONFIG_INET_ESP) || IS_ENABLED(CONFIG_INET6_ESP)
2005-04-17 02:20:36 +04:00
# include <net/esp.h>
# endif
/*
* Algorithms supported by IPsec . These entries contain properties which
* are used in key negotiation and xfrm processing , and are used to verify
* that instantiated crypto transforms have correct parameters for IPsec
* purposes .
*/
2008-01-29 06:37:29 +03:00
static struct xfrm_algo_desc aead_list [ ] = {
{
. name = " rfc4106(gcm(aes)) " ,
. uinfo = {
. aead = {
2015-08-13 12:28:52 +03:00
. geniv = " seqiv " ,
2008-01-29 06:37:29 +03:00
. icv_truncbits = 64 ,
}
} ,
2013-01-31 14:40:38 +04:00
. pfkey_supported = 1 ,
2008-01-29 06:37:29 +03:00
. desc = {
. sadb_alg_id = SADB_X_EALG_AES_GCM_ICV8 ,
. sadb_alg_ivlen = 8 ,
. sadb_alg_minbits = 128 ,
. sadb_alg_maxbits = 256
}
} ,
{
. name = " rfc4106(gcm(aes)) " ,
. uinfo = {
. aead = {
2015-08-13 12:28:52 +03:00
. geniv = " seqiv " ,
2008-01-29 06:37:29 +03:00
. icv_truncbits = 96 ,
}
} ,
2013-01-31 14:40:38 +04:00
. pfkey_supported = 1 ,
2008-01-29 06:37:29 +03:00
. desc = {
. sadb_alg_id = SADB_X_EALG_AES_GCM_ICV12 ,
. sadb_alg_ivlen = 8 ,
. sadb_alg_minbits = 128 ,
. sadb_alg_maxbits = 256
}
} ,
{
. name = " rfc4106(gcm(aes)) " ,
. uinfo = {
. aead = {
2015-08-13 12:28:52 +03:00
. geniv = " seqiv " ,
2008-01-29 06:37:29 +03:00
. icv_truncbits = 128 ,
}
} ,
2013-01-31 14:40:38 +04:00
. pfkey_supported = 1 ,
2008-01-29 06:37:29 +03:00
. desc = {
. sadb_alg_id = SADB_X_EALG_AES_GCM_ICV16 ,
. sadb_alg_ivlen = 8 ,
. sadb_alg_minbits = 128 ,
. sadb_alg_maxbits = 256
}
} ,
{
. name = " rfc4309(ccm(aes)) " ,
. uinfo = {
. aead = {
2015-08-13 12:28:52 +03:00
. geniv = " seqiv " ,
2008-01-29 06:37:29 +03:00
. icv_truncbits = 64 ,
}
} ,
2013-01-31 14:40:38 +04:00
. pfkey_supported = 1 ,
2008-01-29 06:37:29 +03:00
. desc = {
. sadb_alg_id = SADB_X_EALG_AES_CCM_ICV8 ,
. sadb_alg_ivlen = 8 ,
. sadb_alg_minbits = 128 ,
. sadb_alg_maxbits = 256
}
} ,
{
. name = " rfc4309(ccm(aes)) " ,
. uinfo = {
. aead = {
2015-08-13 12:28:52 +03:00
. geniv = " seqiv " ,
2008-01-29 06:37:29 +03:00
. icv_truncbits = 96 ,
}
} ,
2013-01-31 14:40:38 +04:00
. pfkey_supported = 1 ,
2008-01-29 06:37:29 +03:00
. desc = {
. sadb_alg_id = SADB_X_EALG_AES_CCM_ICV12 ,
. sadb_alg_ivlen = 8 ,
. sadb_alg_minbits = 128 ,
. sadb_alg_maxbits = 256
}
} ,
{
. name = " rfc4309(ccm(aes)) " ,
. uinfo = {
. aead = {
2015-08-13 12:28:52 +03:00
. geniv = " seqiv " ,
2008-01-29 06:37:29 +03:00
. icv_truncbits = 128 ,
}
} ,
2013-01-31 14:40:38 +04:00
. pfkey_supported = 1 ,
2008-01-29 06:37:29 +03:00
. desc = {
. sadb_alg_id = SADB_X_EALG_AES_CCM_ICV16 ,
. sadb_alg_ivlen = 8 ,
. sadb_alg_minbits = 128 ,
. sadb_alg_maxbits = 256
}
} ,
2010-01-17 13:52:11 +03:00
{
. name = " rfc4543(gcm(aes)) " ,
. uinfo = {
. aead = {
2015-05-27 11:03:44 +03:00
. geniv = " seqiv " ,
2010-01-17 13:52:11 +03:00
. icv_truncbits = 128 ,
}
} ,
2013-01-31 14:40:38 +04:00
. pfkey_supported = 1 ,
2010-01-17 13:52:11 +03:00
. desc = {
. sadb_alg_id = SADB_X_EALG_NULL_AES_GMAC ,
. sadb_alg_ivlen = 8 ,
. sadb_alg_minbits = 128 ,
. sadb_alg_maxbits = 256
}
} ,
2015-06-01 14:44:04 +03:00
{
. name = " rfc7539esp(chacha20,poly1305) " ,
. uinfo = {
. aead = {
2015-08-13 12:28:52 +03:00
. geniv = " seqiv " ,
2015-06-01 14:44:04 +03:00
. icv_truncbits = 128 ,
}
} ,
. pfkey_supported = 0 ,
} ,
2008-01-29 06:37:29 +03:00
} ;
2005-04-17 02:20:36 +04:00
static struct xfrm_algo_desc aalg_list [ ] = {
{
2008-04-27 11:59:59 +04:00
. name = " digest_null " ,
2007-02-09 17:25:29 +03:00
2005-04-17 02:20:36 +04:00
. uinfo = {
. auth = {
. icv_truncbits = 0 ,
. icv_fullbits = 0 ,
}
} ,
2007-02-09 17:25:29 +03:00
2013-01-31 14:40:38 +04:00
. pfkey_supported = 1 ,
2005-04-17 02:20:36 +04:00
. desc = {
. sadb_alg_id = SADB_X_AALG_NULL ,
. sadb_alg_ivlen = 0 ,
. sadb_alg_minbits = 0 ,
. sadb_alg_maxbits = 0
}
} ,
{
2006-08-20 08:24:50 +04:00
. name = " hmac(md5) " ,
. compat = " md5 " ,
2005-04-17 02:20:36 +04:00
. uinfo = {
. auth = {
. icv_truncbits = 96 ,
. icv_fullbits = 128 ,
}
} ,
2007-02-09 17:25:29 +03:00
2013-01-31 14:40:38 +04:00
. pfkey_supported = 1 ,
2005-04-17 02:20:36 +04:00
. desc = {
. sadb_alg_id = SADB_AALG_MD5HMAC ,
. sadb_alg_ivlen = 0 ,
. sadb_alg_minbits = 128 ,
. sadb_alg_maxbits = 128
}
} ,
{
2006-08-20 08:24:50 +04:00
. name = " hmac(sha1) " ,
. compat = " sha1 " ,
2005-04-17 02:20:36 +04:00
. uinfo = {
. auth = {
. icv_truncbits = 96 ,
. icv_fullbits = 160 ,
}
} ,
2013-01-31 14:40:38 +04:00
. pfkey_supported = 1 ,
2005-04-17 02:20:36 +04:00
. desc = {
. sadb_alg_id = SADB_AALG_SHA1HMAC ,
. sadb_alg_ivlen = 0 ,
. sadb_alg_minbits = 160 ,
. sadb_alg_maxbits = 160
}
} ,
{
2006-08-20 08:24:50 +04:00
. name = " hmac(sha256) " ,
. compat = " sha256 " ,
2005-04-17 02:20:36 +04:00
. uinfo = {
. auth = {
. icv_truncbits = 96 ,
. icv_fullbits = 256 ,
}
} ,
2013-01-31 14:40:38 +04:00
. pfkey_supported = 1 ,
2005-04-17 02:20:36 +04:00
. desc = {
. sadb_alg_id = SADB_X_AALG_SHA2_256HMAC ,
. sadb_alg_ivlen = 0 ,
. sadb_alg_minbits = 256 ,
. sadb_alg_maxbits = 256
}
} ,
2009-11-25 03:58:39 +03:00
{
. name = " hmac(sha384) " ,
. uinfo = {
. auth = {
. icv_truncbits = 192 ,
. icv_fullbits = 384 ,
}
} ,
2013-01-31 14:40:38 +04:00
. pfkey_supported = 1 ,
2009-11-25 03:58:39 +03:00
. desc = {
. sadb_alg_id = SADB_X_AALG_SHA2_384HMAC ,
. sadb_alg_ivlen = 0 ,
. sadb_alg_minbits = 384 ,
. sadb_alg_maxbits = 384
}
} ,
{
. name = " hmac(sha512) " ,
. uinfo = {
. auth = {
. icv_truncbits = 256 ,
. icv_fullbits = 512 ,
}
} ,
2013-01-31 14:40:38 +04:00
. pfkey_supported = 1 ,
2009-11-25 03:58:39 +03:00
. desc = {
. sadb_alg_id = SADB_X_AALG_SHA2_512HMAC ,
. sadb_alg_ivlen = 0 ,
. sadb_alg_minbits = 512 ,
. sadb_alg_maxbits = 512
}
} ,
2005-04-17 02:20:36 +04:00
{
2008-06-04 23:04:55 +04:00
. name = " hmac(rmd160) " ,
. compat = " rmd160 " ,
2005-04-17 02:20:36 +04:00
. uinfo = {
. auth = {
. icv_truncbits = 96 ,
. icv_fullbits = 160 ,
}
} ,
2013-01-31 14:40:38 +04:00
. pfkey_supported = 1 ,
2005-04-17 02:20:36 +04:00
. desc = {
. sadb_alg_id = SADB_X_AALG_RIPEMD160HMAC ,
. sadb_alg_ivlen = 0 ,
. sadb_alg_minbits = 160 ,
. sadb_alg_maxbits = 160
}
} ,
2006-10-28 07:21:22 +04:00
{
. name = " xcbc(aes) " ,
. uinfo = {
. auth = {
. icv_truncbits = 96 ,
. icv_fullbits = 128 ,
}
} ,
2013-01-31 14:40:38 +04:00
. pfkey_supported = 1 ,
2006-10-28 07:21:22 +04:00
. desc = {
. sadb_alg_id = SADB_X_AALG_AES_XCBC_MAC ,
. sadb_alg_ivlen = 0 ,
. sadb_alg_minbits = 128 ,
. sadb_alg_maxbits = 128
}
} ,
2013-04-08 11:48:49 +04:00
{
/* rfc4494 */
. name = " cmac(aes) " ,
. uinfo = {
. auth = {
. icv_truncbits = 96 ,
. icv_fullbits = 128 ,
}
} ,
. pfkey_supported = 0 ,
} ,
2005-04-17 02:20:36 +04:00
} ;
static struct xfrm_algo_desc ealg_list [ ] = {
{
2006-07-30 09:41:01 +04:00
. name = " ecb(cipher_null) " ,
. compat = " cipher_null " ,
2007-02-09 17:25:29 +03:00
2005-04-17 02:20:36 +04:00
. uinfo = {
. encr = {
. blockbits = 8 ,
. defkeybits = 0 ,
}
} ,
2007-02-09 17:25:29 +03:00
2013-01-31 14:40:38 +04:00
. pfkey_supported = 1 ,
2005-04-17 02:20:36 +04:00
. desc = {
. sadb_alg_id = SADB_EALG_NULL ,
. sadb_alg_ivlen = 0 ,
. sadb_alg_minbits = 0 ,
. sadb_alg_maxbits = 0
}
} ,
{
2006-07-30 09:41:01 +04:00
. name = " cbc(des) " ,
. compat = " des " ,
2005-04-17 02:20:36 +04:00
. uinfo = {
. encr = {
2015-05-27 11:03:44 +03:00
. geniv = " echainiv " ,
2005-04-17 02:20:36 +04:00
. blockbits = 64 ,
. defkeybits = 64 ,
}
} ,
2013-01-31 14:40:38 +04:00
. pfkey_supported = 1 ,
2005-04-17 02:20:36 +04:00
. desc = {
. sadb_alg_id = SADB_EALG_DESCBC ,
. sadb_alg_ivlen = 8 ,
. sadb_alg_minbits = 64 ,
. sadb_alg_maxbits = 64
}
} ,
{
2006-07-30 09:41:01 +04:00
. name = " cbc(des3_ede) " ,
. compat = " des3_ede " ,
2005-04-17 02:20:36 +04:00
. uinfo = {
. encr = {
2015-05-27 11:03:44 +03:00
. geniv = " echainiv " ,
2005-04-17 02:20:36 +04:00
. blockbits = 64 ,
. defkeybits = 192 ,
}
} ,
2013-01-31 14:40:38 +04:00
. pfkey_supported = 1 ,
2005-04-17 02:20:36 +04:00
. desc = {
. sadb_alg_id = SADB_EALG_3DESCBC ,
. sadb_alg_ivlen = 8 ,
. sadb_alg_minbits = 192 ,
. sadb_alg_maxbits = 192
}
} ,
{
2009-06-24 14:55:41 +04:00
. name = " cbc(cast5) " ,
. compat = " cast5 " ,
2005-04-17 02:20:36 +04:00
. uinfo = {
. encr = {
2015-05-27 11:03:44 +03:00
. geniv = " echainiv " ,
2005-04-17 02:20:36 +04:00
. blockbits = 64 ,
. defkeybits = 128 ,
}
} ,
2013-01-31 14:40:38 +04:00
. pfkey_supported = 1 ,
2005-04-17 02:20:36 +04:00
. desc = {
. sadb_alg_id = SADB_X_EALG_CASTCBC ,
. sadb_alg_ivlen = 8 ,
. sadb_alg_minbits = 40 ,
. sadb_alg_maxbits = 128
}
} ,
{
2006-07-30 09:41:01 +04:00
. name = " cbc(blowfish) " ,
. compat = " blowfish " ,
2005-04-17 02:20:36 +04:00
. uinfo = {
. encr = {
2015-05-27 11:03:44 +03:00
. geniv = " echainiv " ,
2005-04-17 02:20:36 +04:00
. blockbits = 64 ,
. defkeybits = 128 ,
}
} ,
2013-01-31 14:40:38 +04:00
. pfkey_supported = 1 ,
2005-04-17 02:20:36 +04:00
. desc = {
. sadb_alg_id = SADB_X_EALG_BLOWFISHCBC ,
. sadb_alg_ivlen = 8 ,
. sadb_alg_minbits = 40 ,
. sadb_alg_maxbits = 448
}
} ,
{
2006-07-30 09:41:01 +04:00
. name = " cbc(aes) " ,
. compat = " aes " ,
2005-04-17 02:20:36 +04:00
. uinfo = {
. encr = {
2015-05-27 11:03:44 +03:00
. geniv = " echainiv " ,
2005-04-17 02:20:36 +04:00
. blockbits = 128 ,
. defkeybits = 128 ,
}
} ,
2013-01-31 14:40:38 +04:00
. pfkey_supported = 1 ,
2005-04-17 02:20:36 +04:00
. desc = {
. sadb_alg_id = SADB_X_EALG_AESCBC ,
. sadb_alg_ivlen = 8 ,
. sadb_alg_minbits = 128 ,
. sadb_alg_maxbits = 256
}
} ,
{
2007-02-09 17:25:29 +03:00
. name = " cbc(serpent) " ,
. compat = " serpent " ,
. uinfo = {
. encr = {
2015-05-27 11:03:44 +03:00
. geniv = " echainiv " ,
2007-02-09 17:25:29 +03:00
. blockbits = 128 ,
. defkeybits = 128 ,
}
} ,
2013-01-31 14:40:38 +04:00
. pfkey_supported = 1 ,
2007-02-09 17:25:29 +03:00
. desc = {
. sadb_alg_id = SADB_X_EALG_SERPENTCBC ,
. sadb_alg_ivlen = 8 ,
. sadb_alg_minbits = 128 ,
. sadb_alg_maxbits = 256 ,
}
2005-04-17 02:20:36 +04:00
} ,
2006-10-22 09:05:57 +04:00
{
. name = " cbc(camellia) " ,
2009-12-02 02:35:05 +03:00
. compat = " camellia " ,
2006-10-22 09:05:57 +04:00
. uinfo = {
. encr = {
2015-05-27 11:03:44 +03:00
. geniv = " echainiv " ,
2006-10-22 09:05:57 +04:00
. blockbits = 128 ,
. defkeybits = 128 ,
}
} ,
2013-01-31 14:40:38 +04:00
. pfkey_supported = 1 ,
2006-10-22 09:05:57 +04:00
. desc = {
. sadb_alg_id = SADB_X_EALG_CAMELLIACBC ,
. sadb_alg_ivlen = 8 ,
. sadb_alg_minbits = 128 ,
. sadb_alg_maxbits = 256
}
} ,
2005-04-17 02:20:36 +04:00
{
2007-02-09 17:25:29 +03:00
. name = " cbc(twofish) " ,
. compat = " twofish " ,
. uinfo = {
. encr = {
2015-05-27 11:03:44 +03:00
. geniv = " echainiv " ,
2007-02-09 17:25:29 +03:00
. blockbits = 128 ,
. defkeybits = 128 ,
}
} ,
2013-01-31 14:40:38 +04:00
. pfkey_supported = 1 ,
2007-02-09 17:25:29 +03:00
. desc = {
. sadb_alg_id = SADB_X_EALG_TWOFISHCBC ,
. sadb_alg_ivlen = 8 ,
. sadb_alg_minbits = 128 ,
. sadb_alg_maxbits = 256
}
2005-04-17 02:20:36 +04:00
} ,
2008-02-08 10:11:56 +03:00
{
. name = " rfc3686(ctr(aes)) " ,
. uinfo = {
. encr = {
2015-05-27 11:03:44 +03:00
. geniv = " seqiv " ,
2008-02-08 10:11:56 +03:00
. blockbits = 128 ,
. defkeybits = 160 , /* 128-bit key + 32-bit nonce */
}
} ,
2013-01-31 14:40:38 +04:00
. pfkey_supported = 1 ,
2008-02-08 10:11:56 +03:00
. desc = {
. sadb_alg_id = SADB_X_EALG_AESCTR ,
. sadb_alg_ivlen = 8 ,
2011-07-28 14:36:20 +04:00
. sadb_alg_minbits = 160 ,
. sadb_alg_maxbits = 288
2008-02-08 10:11:56 +03:00
}
} ,
2005-04-17 02:20:36 +04:00
} ;
static struct xfrm_algo_desc calg_list [ ] = {
{
. name = " deflate " ,
. uinfo = {
. comp = {
. threshold = 90 ,
}
} ,
2013-01-31 14:40:38 +04:00
. pfkey_supported = 1 ,
2005-04-17 02:20:36 +04:00
. desc = { . sadb_alg_id = SADB_X_CALG_DEFLATE }
} ,
{
. name = " lzs " ,
. uinfo = {
. comp = {
. threshold = 90 ,
}
} ,
2013-01-31 14:40:38 +04:00
. pfkey_supported = 1 ,
2005-04-17 02:20:36 +04:00
. desc = { . sadb_alg_id = SADB_X_CALG_LZS }
} ,
{
. name = " lzjh " ,
. uinfo = {
. comp = {
. threshold = 50 ,
}
} ,
2013-01-31 14:40:38 +04:00
. pfkey_supported = 1 ,
2005-04-17 02:20:36 +04:00
. desc = { . sadb_alg_id = SADB_X_CALG_LZJH }
} ,
} ;
static inline int aalg_entries ( void )
{
return ARRAY_SIZE ( aalg_list ) ;
}
static inline int ealg_entries ( void )
{
return ARRAY_SIZE ( ealg_list ) ;
}
static inline int calg_entries ( void )
{
return ARRAY_SIZE ( calg_list ) ;
}
2007-05-20 01:21:18 +04:00
struct xfrm_algo_list {
struct xfrm_algo_desc * algs ;
int entries ;
u32 type ;
u32 mask ;
} ;
2005-04-17 02:20:36 +04:00
2008-01-29 06:37:29 +03:00
static const struct xfrm_algo_list xfrm_aead_list = {
. algs = aead_list ,
. entries = ARRAY_SIZE ( aead_list ) ,
. type = CRYPTO_ALG_TYPE_AEAD ,
. mask = CRYPTO_ALG_TYPE_MASK ,
} ;
2007-05-20 01:21:18 +04:00
static const struct xfrm_algo_list xfrm_aalg_list = {
. algs = aalg_list ,
. entries = ARRAY_SIZE ( aalg_list ) ,
. type = CRYPTO_ALG_TYPE_HASH ,
2008-01-29 06:35:49 +03:00
. mask = CRYPTO_ALG_TYPE_HASH_MASK ,
2007-05-20 01:21:18 +04:00
} ;
2005-04-17 02:20:36 +04:00
2007-05-20 01:21:18 +04:00
static const struct xfrm_algo_list xfrm_ealg_list = {
. algs = ealg_list ,
. entries = ARRAY_SIZE ( ealg_list ) ,
crypto: skcipher - remove the "blkcipher" algorithm type
Now that all "blkcipher" algorithms have been converted to "skcipher",
remove the blkcipher algorithm type.
The skcipher (symmetric key cipher) algorithm type was introduced a few
years ago to replace both blkcipher and ablkcipher (synchronous and
asynchronous block cipher). The advantages of skcipher include:
- A much less confusing name, since none of these algorithm types have
ever actually been for raw block ciphers, but rather for all
length-preserving encryption modes including block cipher modes of
operation, stream ciphers, and other length-preserving modes.
- It unified blkcipher and ablkcipher into a single algorithm type
which supports both synchronous and asynchronous implementations.
Note, blkcipher already operated only on scatterlists, so the fact
that skcipher does too isn't a regression in functionality.
- Better type safety by using struct skcipher_alg, struct
crypto_skcipher, etc. instead of crypto_alg, crypto_tfm, etc.
- It sometimes simplifies the implementations of algorithms.
Also, the blkcipher API was no longer being tested.
Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2019-10-25 22:41:12 +03:00
. type = CRYPTO_ALG_TYPE_SKCIPHER ,
. mask = CRYPTO_ALG_TYPE_MASK ,
2007-05-20 01:21:18 +04:00
} ;
2005-04-17 02:20:36 +04:00
2007-05-20 01:21:18 +04:00
static const struct xfrm_algo_list xfrm_calg_list = {
. algs = calg_list ,
. entries = ARRAY_SIZE ( calg_list ) ,
. type = CRYPTO_ALG_TYPE_COMPRESS ,
2008-01-29 06:35:49 +03:00
. mask = CRYPTO_ALG_TYPE_MASK ,
2007-05-20 01:21:18 +04:00
} ;
2005-04-17 02:20:36 +04:00
2007-05-20 01:21:18 +04:00
static struct xfrm_algo_desc * xfrm_find_algo (
const struct xfrm_algo_list * algo_list ,
int match ( const struct xfrm_algo_desc * entry , const void * data ) ,
const void * data , int probe )
2005-04-17 02:20:36 +04:00
{
2007-05-20 01:21:18 +04:00
struct xfrm_algo_desc * list = algo_list - > algs ;
2005-04-17 02:20:36 +04:00
int i , status ;
2007-05-20 01:21:18 +04:00
for ( i = 0 ; i < algo_list - > entries ; i + + ) {
if ( ! match ( list + i , data ) )
2005-04-17 02:20:36 +04:00
continue ;
if ( list [ i ] . available )
return & list [ i ] ;
if ( ! probe )
break ;
2007-05-20 01:21:18 +04:00
status = crypto_has_alg ( list [ i ] . name , algo_list - > type ,
algo_list - > mask ) ;
2005-04-17 02:20:36 +04:00
if ( ! status )
break ;
list [ i ] . available = status ;
return & list [ i ] ;
}
return NULL ;
}
2007-05-20 01:21:18 +04:00
static int xfrm_alg_id_match ( const struct xfrm_algo_desc * entry ,
const void * data )
{
2007-05-23 03:12:26 +04:00
return entry - > desc . sadb_alg_id = = ( unsigned long ) data ;
2007-05-20 01:21:18 +04:00
}
struct xfrm_algo_desc * xfrm_aalg_get_byid ( int alg_id )
{
return xfrm_find_algo ( & xfrm_aalg_list , xfrm_alg_id_match ,
2007-05-23 03:12:26 +04:00
( void * ) ( unsigned long ) alg_id , 1 ) ;
2007-05-20 01:21:18 +04:00
}
EXPORT_SYMBOL_GPL ( xfrm_aalg_get_byid ) ;
struct xfrm_algo_desc * xfrm_ealg_get_byid ( int alg_id )
{
return xfrm_find_algo ( & xfrm_ealg_list , xfrm_alg_id_match ,
2007-05-23 03:12:26 +04:00
( void * ) ( unsigned long ) alg_id , 1 ) ;
2007-05-20 01:21:18 +04:00
}
EXPORT_SYMBOL_GPL ( xfrm_ealg_get_byid ) ;
struct xfrm_algo_desc * xfrm_calg_get_byid ( int alg_id )
{
return xfrm_find_algo ( & xfrm_calg_list , xfrm_alg_id_match ,
2007-05-23 03:12:26 +04:00
( void * ) ( unsigned long ) alg_id , 1 ) ;
2007-05-20 01:21:18 +04:00
}
EXPORT_SYMBOL_GPL ( xfrm_calg_get_byid ) ;
static int xfrm_alg_name_match ( const struct xfrm_algo_desc * entry ,
const void * data )
{
const char * name = data ;
return name & & ( ! strcmp ( name , entry - > name ) | |
( entry - > compat & & ! strcmp ( name , entry - > compat ) ) ) ;
}
2011-02-28 10:04:45 +03:00
struct xfrm_algo_desc * xfrm_aalg_get_byname ( const char * name , int probe )
2005-04-17 02:20:36 +04:00
{
2007-05-20 01:21:18 +04:00
return xfrm_find_algo ( & xfrm_aalg_list , xfrm_alg_name_match , name ,
probe ) ;
2005-04-17 02:20:36 +04:00
}
EXPORT_SYMBOL_GPL ( xfrm_aalg_get_byname ) ;
2011-02-28 10:04:45 +03:00
struct xfrm_algo_desc * xfrm_ealg_get_byname ( const char * name , int probe )
2005-04-17 02:20:36 +04:00
{
2007-05-20 01:21:18 +04:00
return xfrm_find_algo ( & xfrm_ealg_list , xfrm_alg_name_match , name ,
probe ) ;
2005-04-17 02:20:36 +04:00
}
EXPORT_SYMBOL_GPL ( xfrm_ealg_get_byname ) ;
2011-02-28 10:04:45 +03:00
struct xfrm_algo_desc * xfrm_calg_get_byname ( const char * name , int probe )
2005-04-17 02:20:36 +04:00
{
2007-05-20 01:21:18 +04:00
return xfrm_find_algo ( & xfrm_calg_list , xfrm_alg_name_match , name ,
probe ) ;
2005-04-17 02:20:36 +04:00
}
EXPORT_SYMBOL_GPL ( xfrm_calg_get_byname ) ;
2008-01-29 06:37:29 +03:00
struct xfrm_aead_name {
const char * name ;
int icvbits ;
} ;
static int xfrm_aead_name_match ( const struct xfrm_algo_desc * entry ,
const void * data )
{
const struct xfrm_aead_name * aead = data ;
const char * name = aead - > name ;
return aead - > icvbits = = entry - > uinfo . aead . icv_truncbits & & name & &
! strcmp ( name , entry - > name ) ;
}
2011-02-28 10:04:45 +03:00
struct xfrm_algo_desc * xfrm_aead_get_byname ( const char * name , int icv_len , int probe )
2008-01-29 06:37:29 +03:00
{
struct xfrm_aead_name data = {
. name = name ,
. icvbits = icv_len ,
} ;
return xfrm_find_algo ( & xfrm_aead_list , xfrm_aead_name_match , & data ,
probe ) ;
}
EXPORT_SYMBOL_GPL ( xfrm_aead_get_byname ) ;
2005-04-17 02:20:36 +04:00
struct xfrm_algo_desc * xfrm_aalg_get_byidx ( unsigned int idx )
{
if ( idx > = aalg_entries ( ) )
return NULL ;
return & aalg_list [ idx ] ;
}
EXPORT_SYMBOL_GPL ( xfrm_aalg_get_byidx ) ;
struct xfrm_algo_desc * xfrm_ealg_get_byidx ( unsigned int idx )
{
if ( idx > = ealg_entries ( ) )
return NULL ;
return & ealg_list [ idx ] ;
}
EXPORT_SYMBOL_GPL ( xfrm_ealg_get_byidx ) ;
/*
* Probe for the availability of crypto algorithms , and set the available
* flag for any algorithms found on the system . This is typically called by
* pfkey during userspace SA add , update or register .
*/
void xfrm_probe_algs ( void )
{
int i , status ;
2007-02-09 17:25:29 +03:00
2005-04-17 02:20:36 +04:00
BUG_ON ( in_softirq ( ) ) ;
for ( i = 0 ; i < aalg_entries ( ) ; i + + ) {
2016-01-24 16:19:11 +03:00
status = crypto_has_ahash ( aalg_list [ i ] . name , 0 , 0 ) ;
2005-04-17 02:20:36 +04:00
if ( aalg_list [ i ] . available ! = status )
aalg_list [ i ] . available = status ;
}
2007-02-09 17:25:29 +03:00
2005-04-17 02:20:36 +04:00
for ( i = 0 ; i < ealg_entries ( ) ; i + + ) {
2016-01-24 16:19:11 +03:00
status = crypto_has_skcipher ( ealg_list [ i ] . name , 0 , 0 ) ;
2005-04-17 02:20:36 +04:00
if ( ealg_list [ i ] . available ! = status )
ealg_list [ i ] . available = status ;
}
2007-02-09 17:25:29 +03:00
2005-04-17 02:20:36 +04:00
for ( i = 0 ; i < calg_entries ( ) ; i + + ) {
2006-08-26 12:12:40 +04:00
status = crypto_has_comp ( calg_list [ i ] . name , 0 ,
CRYPTO_ALG_ASYNC ) ;
2005-04-17 02:20:36 +04:00
if ( calg_list [ i ] . available ! = status )
calg_list [ i ] . available = status ;
}
}
EXPORT_SYMBOL_GPL ( xfrm_probe_algs ) ;
2013-01-31 14:40:38 +04:00
int xfrm_count_pfkey_auth_supported ( void )
2005-04-17 02:20:36 +04:00
{
int i , n ;
for ( i = 0 , n = 0 ; i < aalg_entries ( ) ; i + + )
2013-01-31 14:40:38 +04:00
if ( aalg_list [ i ] . available & & aalg_list [ i ] . pfkey_supported )
2005-04-17 02:20:36 +04:00
n + + ;
return n ;
}
2013-01-31 14:40:38 +04:00
EXPORT_SYMBOL_GPL ( xfrm_count_pfkey_auth_supported ) ;
2005-04-17 02:20:36 +04:00
2013-01-31 14:40:38 +04:00
int xfrm_count_pfkey_enc_supported ( void )
2005-04-17 02:20:36 +04:00
{
int i , n ;
for ( i = 0 , n = 0 ; i < ealg_entries ( ) ; i + + )
2013-01-31 14:40:38 +04:00
if ( ealg_list [ i ] . available & & ealg_list [ i ] . pfkey_supported )
2005-04-17 02:20:36 +04:00
n + + ;
return n ;
}
2013-01-31 14:40:38 +04:00
EXPORT_SYMBOL_GPL ( xfrm_count_pfkey_enc_supported ) ;
2005-04-17 02:20:36 +04:00
2012-05-15 05:57:44 +04:00
MODULE_LICENSE ( " GPL " ) ;