Files
m241Neelima/components/ip_net2-6.9/ipipsec2/src/ipipsec_crypt.c
T
2026-07-30 11:19:44 +05:30

1357 lines
44 KiB
C

/*
******************************************************************************
* INTERPEAK SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipipsec_crypt.c,v $ $Revision: 1.36.10.7 $
* $Source: /home/interpeak/CVSRoot/ipipsec2/src/ipipsec_crypt.c,v $
* $Author: jwang9 $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Lennart Bang <lob@interpeak.se>
******************************************************************************
*/
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
#ifndef IPCOM_KERNEL
#define IPCOM_KERNEL
#endif
#include "ipipsec_config.h"
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#define IPCOM_USE_CLIB_PROTO
#include <ipcom_type.h>
#include <ipcom_cstyle.h>
#include <ipcom_syslog.h>
#include <ipcom_clib.h>
#include "ipipsec_h.h"
#include "ipipsec_pfkeyv2.h"
#ifdef OPENSSL_FIPS
#include <openssl/fips.h>
#endif
/*
****************************************************************************
* 4 EXTERN PROTOTYPES
****************************************************************************
*/
IP_EXTERN Ipipsec_data ipipsec;
/*
****************************************************************************
* 5 DEFINES
****************************************************************************
*/
#define IPCOM_SYSLOG_PRIORITY IPIPSEC_SYSTEM_PRIORITY
#define IPCOM_SYSLOG_FACILITY IPCOM_LOG_IPIPSEC
/*
****************************************************************************
* 6 TYPES
****************************************************************************
*/
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
#ifdef IPIPSEC_USE_AESMAC
IP_STATIC int AESMAC_Init(Ipipsec_auth_ctx *ctx);
IP_STATIC void AESMAC_Update(Ipipsec_auth_ctx *ctx, IP_CONST Ip_u8 *data, Ip_u32 length);
IP_STATIC void AESMAC_Final(Ip_u8 *digest, Ipipsec_auth_ctx *ctx);
#endif
#if defined(IPIPSEC_USE_AES) || defined(IPIPSEC_USE_AESMAC)
IP_STATIC Ip_s32 ipipsec_aes_setkey(Ip_u8 *secret, Ip_u32 length, Ipipsec_encrypt_key *ekey);
IP_STATIC void ipipsec_aes_encrypt(Ip_u8 *data, Ip_u32 length, Ipipsec_encrypt_key *key, Ip_u8 *iv);
#endif
#ifdef IPIPSEC_USE_AES
IP_STATIC void ipipsec_aes_decrypt(Ip_u8 *data, Ip_u32 length, Ipipsec_encrypt_key *key, Ip_u8 *iv);
#endif
#ifdef IPIPSEC_USE_AESCTR
IP_STATIC Ip_s32 ipipsec_aesctr_setkey(Ip_u8 *secret, Ip_u32 length, Ipipsec_encrypt_key *ekey);
IP_STATIC void ipipsec_aesctr_encrypt(Ip_u8 *data, Ip_u32 length, Ipipsec_encrypt_key *key, Ip_u8 *iv);
#endif
#ifdef IPIPSEC_USE_DES
IP_STATIC void ipipsec_descbc_encrypt(Ip_u8 *data, Ip_u32 length, Ipipsec_encrypt_key *key, Ip_u8 *iv);
IP_STATIC void ipipsec_descbc_decrypt(Ip_u8 *data, Ip_u32 length, Ipipsec_encrypt_key *key, Ip_u8 *iv);
IP_STATIC Ip_s32 ipipsec_descbc_setkey(Ip_u8 *secret, Ip_u32 length, Ipipsec_encrypt_key *ekey);
#endif
#ifdef IPIPSEC_USE_3DES
IP_STATIC void ipipsec_3descbc_encrypt(Ip_u8 *data, Ip_u32 length, Ipipsec_encrypt_key *key, Ip_u8 *iv);
IP_STATIC void ipipsec_3descbc_decrypt(Ip_u8 *data, Ip_u32 length, Ipipsec_encrypt_key *key, Ip_u8 *iv);
IP_STATIC Ip_s32 ipipsec_3descbc_setkey(Ip_u8 *secret, Ip_u32 length, Ipipsec_encrypt_key *ekey);
#endif
#ifdef IPIPSEC_USE_CAST
IP_STATIC void ipipsec_cast_encrypt(Ip_u8 *data, Ip_u32 length, Ipipsec_encrypt_key *key, Ip_u8 *iv);
IP_STATIC void ipipsec_cast_decrypt(Ip_u8 *data, Ip_u32 length, Ipipsec_encrypt_key *key, Ip_u8 *iv);
IP_STATIC Ip_s32 ipipsec_cast_setkey(Ip_u8 *secret, Ip_u32 length, Ipipsec_encrypt_key *ekey);
#endif
#ifdef IPIPSEC_USE_BLOWFISH
IP_STATIC void ipipsec_blowfish_encrypt(Ip_u8 *data, Ip_u32 length, Ipipsec_encrypt_key *key, Ip_u8 *iv);
IP_STATIC void ipipsec_blowfish_decrypt(Ip_u8 *data, Ip_u32 length, Ipipsec_encrypt_key *key, Ip_u8 *iv);
IP_STATIC Ip_s32 ipipsec_blowfish_setkey(Ip_u8 *secret, Ip_u32 length, Ipipsec_encrypt_key *ekey);
#endif
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
/*
*===========================================================================
* ipipsec_auth_method
*===========================================================================
*/
IP_GLOBAL IP_CONST Ipipsec_auth_method ipipsec_auth_method[SADB_AALG_NUM] =
{
/*********** MD5HMAC96 ***********/
{
SADB_AALG_MD5HMAC,
#ifdef IPIPSEC_USE_MD5
MD5_CBLOCK,
MD5_DIGEST_LENGTH /* 16 */ , MD5_DIGEST_LENGTH /* 16 */ ,
MD5_DIGEST_LENGTH /* 16 */ , IPIPSEC_HMAC_AUTHLEN /* 12 */,
(Hash_init)MD5_Init,
(Hash_update)MD5_Update,
(Hash_final)MD5_Final
#else
0, 0, 0, 0, 0, IP_NULL, IP_NULL, IP_NULL
#endif
},
/*********** SHA1HMAC96 ***********/
{
SADB_AALG_SHA1HMAC,
#ifdef IPIPSEC_USE_SHA
SHA_CBLOCK,
SHA_DIGEST_LENGTH /* 20 */, SHA_DIGEST_LENGTH /* 20 */,
SHA_DIGEST_LENGTH /* 20 */, IPIPSEC_HMAC_AUTHLEN /* 12 */,
(Hash_init)SHA1_Init,
(Hash_update)SHA1_Update,
(Hash_final)SHA1_Final
#else
0, 0, 0, 0, 0, IP_NULL, IP_NULL, IP_NULL
#endif
},
/*********** SHA2_256_HMAC ***********/
{
SADB_X_AALG_SHA2_256_HMAC,
#ifdef IPIPSEC_USE_SHA256
SHA256_CBLOCK,
SHA256_DIGEST_LENGTH /* 32 */, SHA256_DIGEST_LENGTH /* 32 */,
SHA256_DIGEST_LENGTH /* 32 */, SHA256_DIGEST_LENGTH / 2 /* 16 */,
(Hash_init)SHA256_Init,
(Hash_update)SHA256_Update,
(Hash_final)SHA256_Final
#else
0, 0, 0, 0, 0, IP_NULL, IP_NULL, IP_NULL
#endif
},
/*********** SHA2_384_HMAC ***********/
{
SADB_X_AALG_SHA2_384_HMAC,
#ifdef IPIPSEC_USE_SHA384
SHA512_CBLOCK,
SHA384_DIGEST_LENGTH /* 48 */, SHA384_DIGEST_LENGTH /* 48 */,
SHA384_DIGEST_LENGTH /* 48 */, SHA384_DIGEST_LENGTH / 2 /* 24*/,
(Hash_init)SHA384_Init,
(Hash_update)SHA384_Update,
(Hash_final)SHA384_Final
#else
0, 0, 0, 0, 0, IP_NULL, IP_NULL, IP_NULL
#endif
},
/*********** SHA2_512_HMAC ***********/
{
SADB_X_AALG_SHA2_512_HMAC,
#ifdef IPIPSEC_USE_SHA512
SHA512_CBLOCK,
SHA512_DIGEST_LENGTH /* 64 */, SHA512_DIGEST_LENGTH /* 64 */,
SHA512_DIGEST_LENGTH /* 64 */, SHA512_DIGEST_LENGTH / 2 /* 32 */,
(Hash_init)SHA512_Init,
(Hash_update)SHA512_Update,
(Hash_final)SHA512_Final
#else
0, 0, 0, 0, 0, IP_NULL, IP_NULL, IP_NULL
#endif
},
/*********** RIPEMD160HMAC96 ***********/
{
SADB_X_AALG_RIPEMD160HMAC,
#ifdef IPIPSEC_USE_RIPEMD
RIPEMD160_CBLOCK,
RIPEMD160_DIGEST_LENGTH /* 20 */, RIPEMD160_DIGEST_LENGTH /* 20 */,
RIPEMD160_DIGEST_LENGTH /* 20 */, IPIPSEC_HMAC_AUTHLEN /* 12 */,
(Hash_init)RIPEMD160_Init,
(Hash_update)RIPEMD160_Update,
(Hash_final)RIPEMD160_Final
#else
0, 0, 0, 0, 0, IP_NULL, IP_NULL, IP_NULL
#endif
},
/*********** SADB_X_AALG_AESXCBCMAC96 ***********/
{
SADB_X_AALG_AES_XCBC_MAC,
#ifdef IPIPSEC_USE_AESMAC
AES_BLOCK_SIZE,
AES_BLOCK_SIZE /* 16 */, AES_BLOCK_SIZE /* 16 */,
AES_BLOCK_SIZE /* 16 */, IPIPSEC_HMAC_AUTHLEN /* 12 */,
(Hash_init)AESMAC_Init,
(Hash_update)AESMAC_Update,
(Hash_final)AESMAC_Final
#else
0, 0, 0, 0, 0, IP_NULL, IP_NULL, IP_NULL
#endif
},
};
/*
*===========================================================================
* ipipsec_encrypt_method
*===========================================================================
* Crypt entry:
* {
* id,
* key_size,
* minkey_bytes, maxkey_bytes, block_bytes, iv_bytes,
* encrypt function,
* decrypt function,
* setkey function
* }
*
*/
IP_GLOBAL IP_CONST Ipipsec_encrypt_method ipipsec_encrypt_method[SADB_EALG_NUM] =
{
/*********** DESCBC (64 bits -acctually 56 bits key) ***********/
{
SADB_EALG_DESCBC,
#ifdef IPIPSEC_USE_DES
sizeof(des_key_schedule) + sizeof(Ipipsec_sa_encrypt) - sizeof(Ipipsec_encrypt_key),
8, 8, 8, 8,
ipipsec_descbc_encrypt,
ipipsec_descbc_decrypt,
ipipsec_descbc_setkey
#else
sizeof(Ipipsec_sa_encrypt) - sizeof(Ipipsec_encrypt_key),
8, 8, 8, 8,
IP_NULL, IP_NULL, IP_NULL
#endif
},
/*********** 3DESCBC ***********/
{
SADB_EALG_3DESCBC,
#ifdef IPIPSEC_USE_3DES
3 * sizeof(des_key_schedule) + sizeof(Ipipsec_sa_encrypt) - sizeof(Ipipsec_encrypt_key),
24, 24, 8, 8,
ipipsec_3descbc_encrypt,
ipipsec_3descbc_decrypt,
ipipsec_3descbc_setkey
#else
sizeof(Ipipsec_sa_encrypt) - sizeof(Ipipsec_encrypt_key),
24, 24, 8, 8,
IP_NULL, IP_NULL, IP_NULL
#endif
},
/*********** BLOWFISH ***********/
{
SADB_X_EALG_BLOWFISHCBC,
#ifdef IPIPSEC_USE_BLOWFISH
sizeof(BF_KEY) + sizeof(Ipipsec_sa_encrypt) - sizeof(Ipipsec_encrypt_key),
5, IPIPSEC_BLF_MAXKEYLEN, 8, 8,
ipipsec_blowfish_encrypt,
ipipsec_blowfish_decrypt,
ipipsec_blowfish_setkey
#else
sizeof(Ipipsec_sa_encrypt) - sizeof(Ipipsec_encrypt_key),
5, IPIPSEC_BLF_MAXKEYLEN, 8, 8,
IP_NULL, IP_NULL, IP_NULL
#endif
},
/*********** CAST ***********/
{
SADB_X_EALG_CASTCBC,
#ifdef IPIPSEC_USE_CAST
sizeof(CAST_KEY) + sizeof(Ipipsec_sa_encrypt) - sizeof(Ipipsec_encrypt_key),
5, 16, 8, 8,
ipipsec_cast_encrypt,
ipipsec_cast_decrypt,
ipipsec_cast_setkey
#else
sizeof(Ipipsec_sa_encrypt) - sizeof(Ipipsec_encrypt_key),
5, 16, 8, 8,
IP_NULL, IP_NULL, IP_NULL
#endif
},
/*********** AESCBC (128,192,256 bits only) ***********/
{
SADB_X_EALG_AESCBC,
#ifdef IPIPSEC_USE_AES
2 * sizeof(AES_KEY) + sizeof(Ipipsec_sa_encrypt) - sizeof(Ipipsec_encrypt_key),
16, 32, 16, 16,
ipipsec_aes_encrypt,
ipipsec_aes_decrypt,
ipipsec_aes_setkey
#else
sizeof(Ipipsec_sa_encrypt) - sizeof(Ipipsec_encrypt_key),
16, 32, 16, 16,
IP_NULL, IP_NULL, IP_NULL
#endif
},
/*********** AESCTR (128,192,256 bits + 32 bits nonce) ***********/
{
SADB_X_EALG_AESCTR,
#ifdef IPIPSEC_USE_AESCTR
sizeof(struct aesctr_struct) + sizeof(Ipipsec_sa_encrypt) - sizeof(Ipipsec_encrypt_key),
20, 36, 16, 8,
ipipsec_aesctr_encrypt,
ipipsec_aesctr_encrypt,
ipipsec_aesctr_setkey
#else
sizeof(Ipipsec_sa_encrypt) - sizeof(Ipipsec_encrypt_key),
16, 16, 16, 8,
IP_NULL, IP_NULL, IP_NULL
#endif
}
};
/*
****************************************************************************
* 9 ENCRYPTION FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipipsec_descbc_encrypt
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
#ifdef IPIPSEC_USE_DES
IP_STATIC void
ipipsec_descbc_encrypt(Ip_u8 *data, Ip_u32 length, Ipipsec_encrypt_key *key, Ip_u8 *iv)
{
des_cbc_encrypt(data, data, length, key->des, (des_cblock *)iv, DES_ENCRYPT);
}
/*
*===========================================================================
* ipipsec_descbc_decrypt
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC void
ipipsec_descbc_decrypt(Ip_u8 *data, Ip_u32 length, Ipipsec_encrypt_key *key, Ip_u8 *iv)
{
des_cbc_encrypt(data, data, length, key->des, (des_cblock *)iv, DES_DECRYPT);
}
/*
*===========================================================================
* ipipsec_descbc_setkey
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC Ip_s32
ipipsec_descbc_setkey(Ip_u8 *secret, Ip_u32 length, Ipipsec_encrypt_key *key)
{
if (length != DES_KEY_SZ)
return -1;
if (des_set_key((const_des_cblock *)secret, key->des) != 0)
return -1;
return 0;
}
#endif /* #ifdef IPIPSEC_USE_DES */
/*
*===========================================================================
* ipipsec_3descbc_encrypt
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
#ifdef IPIPSEC_USE_3DES
IP_STATIC void
ipipsec_3descbc_encrypt(Ip_u8 *data, Ip_u32 length, Ipipsec_encrypt_key *key, Ip_u8 *iv)
{
des_ede3_cbc_encrypt(data, data, length,
key->des3.key1, key->des3.key2, key->des3.key3,
(des_cblock *)iv, DES_ENCRYPT);
}
/*
*===========================================================================
* ipipsec_3descbc_decrypt
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC void
ipipsec_3descbc_decrypt(Ip_u8 *data, Ip_u32 length, Ipipsec_encrypt_key *key, Ip_u8 *iv)
{
des_ede3_cbc_encrypt(data, data, length,
key->des3.key1, key->des3.key2, key->des3.key3,
(des_cblock *)iv, DES_DECRYPT);
}
/*
*===========================================================================
* ipipsec_3descbc_setkey
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC Ip_s32
ipipsec_3descbc_setkey(Ip_u8 *secret, Ip_u32 length, Ipipsec_encrypt_key *key)
{
/* 3 keys a 8 bytes */
if (length != 24)
return -1;
/* Check that the 3 des keys differ */
if (ipcom_memcmp(secret, secret + DES_KEY_SZ, DES_KEY_SZ) == 0
|| ipcom_memcmp(secret, secret + 2*DES_KEY_SZ, DES_KEY_SZ) == 0
|| ipcom_memcmp(secret + DES_KEY_SZ, secret + 2*DES_KEY_SZ, DES_KEY_SZ) == 0)
return -1;
/* Set the 3 keys */
if (des_set_key((const_des_cblock *)secret, key->des3.key1) != 0
|| des_set_key((const_des_cblock *)(secret + 8), key->des3.key2) != 0
|| des_set_key((const_des_cblock *)(secret + 16), key->des3.key3) != 0)
return -1;
return 0;
}
#endif /* #ifdef IPIPSEC_USE_3DES */
/*
*===========================================================================
* ipipsec_cast_encrypt
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
#ifdef IPIPSEC_USE_CAST
IP_STATIC void
ipipsec_cast_encrypt(Ip_u8 *data, Ip_u32 length, Ipipsec_encrypt_key *key, Ip_u8 *iv)
{
CAST_cbc_encrypt(data, data, length, &key->cast, iv, CAST_ENCRYPT);
}
/*
*===========================================================================
* ipipsec_cast_decrypt
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC void
ipipsec_cast_decrypt(Ip_u8 *data, Ip_u32 length, Ipipsec_encrypt_key *key, Ip_u8 *iv)
{
CAST_cbc_encrypt(data, data, length, &key->cast, iv, CAST_DECRYPT);
}
/*
*===========================================================================
* ipipsec_cast_setkey
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC Ip_s32
ipipsec_cast_setkey(Ip_u8 *secret, Ip_u32 length, Ipipsec_encrypt_key *key)
{
CAST_set_key(&key->cast, length, secret);
return 0;
}
#endif /* #ifdef IPIPSEC_USE_CAST */
/*
*===========================================================================
* ipipsec_blowfish_encrypt
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
#ifdef IPIPSEC_USE_BLOWFISH
IP_STATIC void
ipipsec_blowfish_encrypt(Ip_u8 *data, Ip_u32 length, Ipipsec_encrypt_key *key, Ip_u8 *iv)
{
BF_cbc_encrypt(data, data, length, &key->bf, iv, BF_ENCRYPT);
}
/*
*===========================================================================
* ipipsec_blowfish_decrypt
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC void
ipipsec_blowfish_decrypt(Ip_u8 *data, Ip_u32 length, Ipipsec_encrypt_key *key, Ip_u8 *iv)
{
BF_cbc_encrypt(data, data, length, &key->bf, iv, BF_DECRYPT);
}
/*
*===========================================================================
* ipipsec_blowfish_setkey
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC Ip_s32
ipipsec_blowfish_setkey(Ip_u8 *secret, Ip_u32 length, Ipipsec_encrypt_key *key)
{
BF_set_key(&key->bf, length, secret);
return 0;
}
#endif /* #ifdef IPIPSEC_USE_BLOWFISH */
/*
*===========================================================================
* ipipsec_crypt_random_fill
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_GLOBAL void
ipipsec_crypt_random_fill(Ip_u8 *buf, int length)
{
int i;
/*!!FIXME: too expensive! */
for (i = 0; i < length; i++)
buf[i] = (Ip_u8)ipcom_random();
}
/*
*===========================================================================
* ipipsec_aes_decrypt
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
#ifdef IPIPSEC_USE_AES
IP_STATIC void
ipipsec_aes_decrypt(Ip_u8 *data, Ip_u32 length, Ipipsec_encrypt_key *key, Ip_u8 *iv)
{
AES_cbc_encrypt(data, data, (unsigned long)length, (AES_KEY *)&key->aes[1],
(unsigned char *)iv, AES_DECRYPT);
}
#endif
#if defined(IPIPSEC_USE_AES) || defined(IPIPSEC_USE_AESMAC)
/*
*===========================================================================
* ipipsec_aes_encrypt
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC void
ipipsec_aes_encrypt(Ip_u8 *data, Ip_u32 length, Ipipsec_encrypt_key *key, Ip_u8 *iv)
{
AES_cbc_encrypt(data, data, (unsigned long)length, (AES_KEY *)&key->aes[0],
(unsigned char *)iv, AES_ENCRYPT);
}
/*
*===========================================================================
* ipipsec_aes_setkey
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC Ip_s32
ipipsec_aes_setkey(Ip_u8 *secret, Ip_u32 length, Ipipsec_encrypt_key *key)
{
if (length != 16 && length != 24 && length != 32)
return -1;
(void)AES_set_encrypt_key(secret, length * 8, &key->aes[0]);
(void)AES_set_decrypt_key(secret, length * 8, &key->aes[1]);
return 0;
}
#endif /* defined(IPIPSEC_USE_AES) || defined(IPIPSEC_USE_AESMAC) */
#ifdef IPIPSEC_USE_AESCTR
/*
*===========================================================================
* ipipsec_incr_64bit
*===========================================================================
* Description: increace iv
* Parameters: iv
* Returns:
*
*/
IP_STATIC void
ipipsec_incr_64bit(Ip_u8* ptr)
{
int i = 8;
Ip_u8 c;
do
{
i--;
c = ptr[i];
++c;
ptr[i] = c;
if (c)
return;
} while (i);
return;
}
/*
*===========================================================================
* ipipsec_aesctr_encrypt
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC void
ipipsec_aesctr_encrypt(Ip_u8 *data, Ip_u32 length, Ipipsec_encrypt_key *key, Ip_u8 *iv)
{
unsigned char ivec[AES_BLOCK_SIZE];
unsigned char ecount_buf[AES_BLOCK_SIZE]={0};
unsigned int num = 0;
ivec[0] = key->aesctr.nonce[0];
ivec[1] = key->aesctr.nonce[1];
ivec[2] = key->aesctr.nonce[2];
ivec[3] = key->aesctr.nonce[3];
ipcom_memcpy(ivec + 4, iv, 8);
ivec[12] = 0; ivec[13] = 0; ivec[14] = 0; ivec[15] = 1;
/* Must use data lock because AESCTR encrypt is non-reentrant */
IPIPSEC_DATA_LOCK();
AES_ctr128_encrypt(data, data, (unsigned long)length, (AES_KEY *)&key->aesctr.key,
ivec,
ecount_buf,
&num);
ipipsec_incr_64bit(iv);
IPIPSEC_DATA_UNLOCK();
}
/*
*===========================================================================
* ipipsec_aesctr_setkey
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC Ip_s32
ipipsec_aesctr_setkey(Ip_u8 *secret, Ip_u32 length, Ipipsec_encrypt_key *key)
{
length -= 4; /* remove nonce 32-bits */
if (length != 16 && length != 24 && length != 32)
return -1;
/* Clear aesctr structure (important for ecount_buf and num) */
ipcom_memset(&key->aesctr, 0, sizeof(key->aesctr));
/* Save nonce */
ipcom_memcpy(key->aesctr.nonce, secret + length, 4);
/* Store key */
if (AES_set_encrypt_key(secret, length * 8, &key->aesctr.key) != 0)
return -1;
return 0;
}
#endif /* IPIPSEC_USE_AESCTR */
/*
****************************************************************************
* 10 PUBLIC FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipipsec_auth_setkey
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_GLOBAL Ip_s32
ipipsec_auth_setkey(Ipipsec_sa_auth ** auth, Ip_u8 id, Ip_u8 *key, Ip_u32 bytes)
{
Ipipsec_sa_auth * a;
Ip_u32 i;
int aalg;
*auth = IP_NULL;
/* Check if the authentication algorithm is supported/implemented. */
for (aalg = 0; aalg < SADB_AALG_NUM; aalg++)
if (ipipsec_auth_method[aalg].id == id
&& ipipsec_auth_method[aalg].init != IP_NULL)
{
#ifdef OPENSSL_FIPS
if (ipipsec_auth_method[aalg].init == (Hash_init)MD5_Init && FIPS_mode())
return -IP_ERRNO_EINVAL;
#endif
goto found;
}
return -IP_ERRNO_EINVAL;
found:
/* Check the authentication key length. */
if (bytes < ipipsec_auth_method[aalg].minkey_bytes ||
bytes > ipipsec_auth_method[aalg].maxkey_bytes ||
(bytes & 0x3L)) /* key-length must be multiple of 32 bits. */
return -IP_ERRNO_EINVAL;
ip_assert(bytes <= IPIPSEC_AUTH_MAXKEYLEN);
/* Get memory to store the key. */
a = (Ipipsec_sa_auth *)ipipsec_shm_calloc(1, sizeof(Ipipsec_sa_auth));
if (a == IP_NULL)
return -IP_ERRNO_ENOMEM;
/* Save key length but not the raw key. */
a->keyLen = bytes;
a->aindex = aalg;
#ifdef IPIPSEC_USE_AESMAC
/*** AES MAC ***/
if (id == SADB_X_AALG_AES_XCBC_MAC)
{
ipcom_memcpy(a->i_ctx.aes.key, key, a->keyLen);
if (!ipipsec_auth_method[aalg].init(&a->i_ctx))
{
ipipsec_shm_free(a);
return -IP_ERRNO_EINVAL;
}
}
else
#endif /* IPIPSEC_USE_AESMAC */
/*** HMAC ***/
{
Ip_u8 keybuf[IPIPSEC_AUTH_MAXKEYLEN];
ipcom_memcpy(keybuf, key, bytes); /* No need to save key for HMAC */
/* HMAC - precompute the I pad. */
for (i = 0; i < bytes; i++)
keybuf[i] ^= HMAC_IPAD;
if (!ipipsec_auth_method[aalg].init(&a->i_ctx))
{
ipipsec_shm_free(a);
return -IP_ERRNO_EINVAL;
}
ipipsec_auth_method[aalg].update(&a->i_ctx, keybuf, bytes);
ipipsec_auth_method[aalg].update(&a->i_ctx, ipipsec.i_buffer,
ipipsec_auth_method[aalg].block_size - bytes);
/* HMAC - precompute the O pad. */
for (i = 0; i < bytes; i++)
keybuf[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
if (!ipipsec_auth_method[aalg].init(&a->o_ctx))
{
ipipsec_shm_free(a);
return -IP_ERRNO_EINVAL;
}
ipipsec_auth_method[aalg].update(&a->o_ctx, keybuf, bytes);
ipipsec_auth_method[aalg].update(&a->o_ctx, ipipsec.o_buffer,
ipipsec_auth_method[aalg].block_size - bytes);
ipcom_memset(keybuf, 0, sizeof(keybuf)); /* paranoia */
}
*auth = a;
return 0;
}
/*
*===========================================================================
* ipipsec_auth_digest_len
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_GLOBAL Ip_u16
ipipsec_auth_digest_len(Ip_u8 id)
{
int aalg;
/* Check if the authentication algorithm is supported/implemented. */
for (aalg = 0; aalg < SADB_AALG_NUM; aalg++)
if (ipipsec_auth_method[aalg].id == id
&& ipipsec_auth_method[aalg].init != IP_NULL)
{
#ifdef OPENSSL_FIPS
if (ipipsec_auth_method[aalg].init == (Hash_init)MD5_Init && FIPS_mode())
return 0;
#endif
return ipipsec_auth_method[aalg].hash_bytes;
}
return 0;
}
/*
*===========================================================================
* ipipsec_encrypt_setkey
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_GLOBAL Ip_s32
ipipsec_encrypt_setkey(Ipipsec_sa *sa, Ip_u8 id, Ip_u8 *key, Ip_u32 bytes)
{
int ealg;
/* Check if the encryption algorithm is supported/implemented. */
for (ealg = 0; ealg < SADB_EALG_NUM; ealg++)
if (ipipsec_encrypt_method[ealg].id == id
&& ipipsec_encrypt_method[ealg].setkey != IP_NULL)
goto found;
return -IP_ERRNO_EINVAL;
found:
/* Check the encryption key length. */
if (bytes < ipipsec_encrypt_method[ealg].minkey_bytes
|| bytes > ipipsec_encrypt_method[ealg].maxkey_bytes)
return -IP_ERRNO_EINVAL;
/* Get memory to store the key. */
sa->encrypt = (Ipipsec_sa_encrypt *)ipipsec_shm_calloc(1, ipipsec_encrypt_method[ealg].key_size);
if (sa->encrypt == IP_NULL)
return -IP_ERRNO_ENOMEM;
/* IV */
ip_assert(ipipsec_encrypt_method[ealg].iv_bytes <= IPIPSEC_MAX_IV_SIZE);
sa->encrypt->iv_length = ipipsec_encrypt_method[ealg].iv_bytes;
sa->header_space += ipipsec_encrypt_method[ealg].iv_bytes;
/* Initialize IV with random bytes. */
ipipsec_crypt_random_fill(sa->encrypt->iv, sa->encrypt->iv_length);
/* Save encryption method pointer. */
sa->encrypt->eindex = ealg;
/* ESP trailer space. */
sa->trailer_space += ipipsec_encrypt_method[ealg].block_bytes;
if (ipipsec_encrypt_method[ealg].block_bytes >= 2)
{
/* Reduce trailer space since length+protocol fits within the block size. */
sa->trailer_space -= 2;
}
/* Store encryption key SA. */
sa->encrypt->keyLen = bytes;
if (ipipsec_encrypt_method[ealg].setkey != IP_NULL)
{
if (ipipsec_encrypt_method[ealg].setkey(key, bytes, &sa->encrypt->key) != 0)
{
IPCOM_LOG1(ERR, "ipipsec_encrypt_setkey() :: failed to set encryption key for EALG=%d", ealg);
ipcom_memset(sa->encrypt, 0, ipipsec_encrypt_method[ealg].key_size); /* clear enc key. */
ipcom_free(sa->encrypt);
sa->encrypt = IP_NULL;
return -IP_ERRNO_EINVAL;
}
}
return 0;
}
/*
*===========================================================================
* ipipsec_crypt_get_algs
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_GLOBAL void
ipipsec_crypt_get_algs(struct sadb_supported *supported)
{
struct sadb_alg *alg;
Ip_s32 i, tot;
tot = 0;
alg = (struct sadb_alg *)((Ip_u8 *)supported + sizeof(struct sadb_supported));
/* Fill in encryption algorithms */
for (i = 0; i < SADB_EALG_NUM; i++)
if (ipipsec_encrypt_method[i].setkey)
{
alg->sadb_alg_id = ipipsec_encrypt_method[i].id;
alg->sadb_alg_ivlen = (uint8_t)(ipipsec_encrypt_method[i].iv_bytes << 3);
alg->sadb_alg_minbits = (uint16_t)(ipipsec_encrypt_method[i].minkey_bytes << 3);
alg->sadb_alg_maxbits = (uint16_t)(ipipsec_encrypt_method[i].maxkey_bytes << 3);
alg->sadb_alg_reserved = 0;
tot++;
alg++;
}
supported->sadb_supported_nencrypt = (uint8_t)tot;
/* Fill in authentication algorithms */
for (i = 0; i < SADB_AALG_NUM; i++)
if (ipipsec_auth_method[i].init)
{
#if defined(OPENSSL_FIPS) && defined(IPIPSEC_USE_MD5)
/* MD5 not possible/allowed to use when the system is in FIPS 140-2 mode */
if (ipipsec_auth_method[i].init == (Hash_init)MD5_Init && FIPS_mode())
continue;
#endif
alg->sadb_alg_id = ipipsec_auth_method[i].id;
alg->sadb_alg_ivlen = 0;
alg->sadb_alg_minbits = (uint16_t)(ipipsec_auth_method[i].minkey_bytes << 3);
alg->sadb_alg_maxbits = (uint16_t)(ipipsec_auth_method[i].maxkey_bytes << 3);
alg->sadb_alg_reserved = 0;
tot++;
alg++;
}
supported->sadb_supported_nauth = (uint8_t)tot;
supported->sadb_supported_len = (uint16_t)(1 + tot);
supported->sadb_supported_exttype = SADB_EXT_SUPPORTED;
supported->sadb_supported_reserved = 0;
}
#ifdef IPIPSEC_USE_AESMAC
/*
*===========================================================================
* AESMAC_Init
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC int
AESMAC_Init(Ipipsec_auth_ctx *ctx)
{
AES_KEY aes[2];
Ip_u8 iv[AES_BLOCK_SIZE];
ipcom_memset(ctx->aes.e, 0, sizeof(ctx->aes.e));
ipcom_memset(ctx->aes.msg, 0, sizeof(ctx->aes.msg));
ctx->aes.msgLen = 0;
ipcom_memset(ctx->aes.k1, 0x01, sizeof(ctx->aes.k1));
ipcom_memset(ctx->aes.k2, 0x02, sizeof(ctx->aes.k2));
ipcom_memset(ctx->aes.k3, 0x03, sizeof(ctx->aes.k3));
(void)ipipsec_aes_setkey(ctx->aes.key, sizeof(ctx->aes.key), (Ipipsec_encrypt_key *)&aes[0]);
ipcom_memset(iv, 0, sizeof(iv));
(void)ipipsec_aes_encrypt(ctx->aes.k1, sizeof(ctx->aes.k1), (Ipipsec_encrypt_key *)&aes[0], iv);
ipcom_memset(iv, 0, sizeof(iv));
(void)ipipsec_aes_encrypt(ctx->aes.k2, sizeof(ctx->aes.k2), (Ipipsec_encrypt_key *)&aes[0], iv);
ipcom_memset(iv, 0, sizeof(iv));
(void)ipipsec_aes_encrypt(ctx->aes.k3, sizeof(ctx->aes.k3), (Ipipsec_encrypt_key *)&aes[0], iv);
return 1;
}
/*
*===========================================================================
* AESMAC_Update
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC void
AESMAC_Update(Ipipsec_auth_ctx *ctx, IP_CONST Ip_u8 *data, Ip_u32 length)
{
Ip_u8 *e;
Ip_u8 iv[AES_BLOCK_SIZE];
int i;
AES_KEY aes[2];
/* This algoritm is specified in RFC3566 */
e = ctx->aes.e;
(void)ipipsec_aes_setkey(ctx->aes.k1, sizeof(ctx->aes.k1), (Ipipsec_encrypt_key *)&aes[0]);
/* Append data to context data buffer, digest data when buffer is full */
while ((ctx->aes.msgLen + length) > sizeof(ctx->aes.msg))
{
/* append so we have full buffer */
i = sizeof(ctx->aes.msg) - ctx->aes.msgLen;
ipcom_memcpy(&ctx->aes.msg[ctx->aes.msgLen], data, i);
/* jump handled data */
data += i;
length -= i;
ctx->aes.msgLen = 0;
/* Encrypt e buffer with k1 */
for (i = 0; i<(int)sizeof(ctx->aes.msg); i++)
e[i] = e[i] ^ (ctx->aes.msg[i]);
ipcom_memset(iv, 0, sizeof(iv));
ipipsec_aes_encrypt(e, sizeof(ctx->aes.msg), (Ipipsec_encrypt_key *)&aes[0], iv);
}
/* Append unhandled data to context data */
ipcom_memcpy(&ctx->aes.msg[ctx->aes.msgLen], data, length);
ctx->aes.msgLen += length;
}
/*
*===========================================================================
* AESMAC_Final
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC void
AESMAC_Final(Ip_u8 *digest, Ipipsec_auth_ctx *ctx)
{
int i;
Ip_u8 iv[AES_BLOCK_SIZE];
AES_KEY aes[2];
ipcom_memset(iv, 0, sizeof(iv));
(void)ipipsec_aes_setkey(ctx->aes.k1, sizeof(ctx->aes.k1), (Ipipsec_encrypt_key *)&aes[0]);
if (sizeof(ctx->aes.msg) > ctx->aes.msgLen)
{
ctx->aes.msg[ctx->aes.msgLen] = 0x80;
i = sizeof(ctx->aes.msg) - ctx->aes.msgLen - 1;
if (i > 0)
ipcom_memset(&ctx->aes.msg[ctx->aes.msgLen+1], 0, i);
for (i = 0; i < (int)sizeof(ctx->aes.e); i++)
ctx->aes.e[i] = ctx->aes.e[i] ^ ctx->aes.msg[i] ^ ctx->aes.k3[i];
ipipsec_aes_encrypt(ctx->aes.e, sizeof(ctx->aes.msg), (Ipipsec_encrypt_key *)&aes[0], iv);
}
else
{
for (i = 0; i < (int)sizeof(ctx->aes.e); i++)
ctx->aes.e[i] = ctx->aes.e[i] ^ ctx->aes.msg[i] ^ ctx->aes.k2[i];
ipipsec_aes_encrypt(ctx->aes.e, sizeof(ctx->aes.msg), (Ipipsec_encrypt_key *)&aes[0], iv);
}
ipcom_memcpy(digest, ctx->aes.e, sizeof(ctx->aes.e));
}
#endif /* IPIPSEC_USE_AESMAC */
#ifdef IPIPSEC_USE_CRYPTO_SELF_TEST
/*
*===========================================================================
* ipipsec_crypt_self_test
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_GLOBAL void
ipipsec_crypt_self_test(void)
{
/* RFC 4868: Test Case 1: */
static IP_CONST Ip_u8 SHA_512_KEY_1[64] = {0x0b, 0x0b, 0x0b, 0x0b ,0x0b ,0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b ,0x0b ,0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b ,0x0b ,0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b ,0x0b ,0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b ,0x0b ,0x0b, 0x0b, 0x0b};
static IP_CONST Ip_u8 SHA_X_DATA_1[8] = {'H', 'i', ' ', 'T', 'h', 'e', 'r', 'e'};
static IP_CONST Ip_u8 SHA_256_MAC_1[16] = {0x19, 0x8a, 0x60, 0x7e, 0xb4, 0x4b, 0xfb, 0xc6,
0x99, 0x03, 0xa0, 0xf1, 0xcf, 0x2b, 0xbd, 0xc5};
static IP_CONST Ip_u8 SHA_384_MAC_1[24] = {0xb6, 0xa8, 0xd5, 0x63, 0x6f, 0x5c, 0x6a, 0x72,
0x24, 0xf9, 0x97, 0x7d, 0xcf, 0x7e, 0xe6, 0xc7,
0xfb, 0x6d, 0x0c, 0x48, 0xcb, 0xde, 0xe9, 0x73};
static IP_CONST Ip_u8 SHA_512_MAC_1[32] = {0x63, 0x7e, 0xdc, 0x6e, 0x01, 0xdc, 0xe7, 0xe6,
0x74, 0x2a, 0x99, 0x45, 0x1a, 0xae, 0x82, 0xdf,
0x23, 0xda, 0x3e, 0x92, 0x43, 0x9e, 0x59, 0x0e,
0x43, 0xe7, 0x61, 0xb3, 0x3e, 0x91, 0x0f, 0xb8};
/* RFC 4868: Test Case 3: */
static IP_CONST Ip_u8 SHA_512_KEY_3[64] = {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa};
static IP_CONST Ip_u8 SHA_X_DATA_3[50] = {0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
0xdd, 0xdd};
static IP_CONST Ip_u8 SHA_256_MAC_3[16] = {0xcd, 0xcb, 0x12, 0x20, 0xd1, 0xec, 0xcc, 0xea,
0x91, 0xe5, 0x3a, 0xba, 0x30, 0x92, 0xf9, 0x62};
static IP_CONST Ip_u8 SHA_384_MAC_3[24] = {0x80, 0x9f, 0x43, 0x9b, 0xe0, 0x02, 0x74, 0x32,
0x1d, 0x4a, 0x53, 0x86, 0x52, 0x16, 0x4b, 0x53,
0x55, 0x4a, 0x50, 0x81, 0x84, 0xa0, 0xc3, 0x16};
static IP_CONST Ip_u8 SHA_512_MAC_3[32] = {0x2e, 0xe7, 0xac, 0xd7, 0x83, 0x62, 0x4c, 0xa9,
0x39, 0x87, 0x10, 0xf3, 0xee, 0x05, 0xae, 0x41,
0xb9, 0xf9, 0xb0, 0x51, 0x0c, 0x87, 0xe4, 0x9e,
0x58, 0x6c, 0xc9, 0xbf, 0x96, 0x17, 0x33, 0xd8};
struct ipipsec_crypt_self_test_auth_alg_struct
{
Ip_u8 alg;
IP_CONST char * name;
IP_CONST Ip_u8 * key;
Ip_size_t key_len;
IP_CONST Ip_u8 * data;
Ip_size_t data_len;
IP_CONST Ip_u8 * mac;
Ip_size_t mac_len;
} self_test_auth_algs[] =
{
#ifdef IPIPSEC_USE_SHA256
{
.alg = SADB_X_AALG_SHA2_256_HMAC,
.name = "hmac(sha2-256-128) RFC-4858 AUTH256-1",
.key = SHA_512_KEY_1,
.key_len = 32, /* Only use 256 of the key */
.data = SHA_X_DATA_1,
.data_len = sizeof(SHA_X_DATA_1),
.mac = SHA_256_MAC_1,
.mac_len = sizeof(SHA_256_MAC_1),
},
{
.alg = SADB_X_AALG_SHA2_256_HMAC,
.name = "hmac(sha2-256-128) RFC-4858 AUTH256-3",
.key = SHA_512_KEY_3,
.key_len = 32, /* Only use 256 of the key */
.data = SHA_X_DATA_3,
.data_len = sizeof(SHA_X_DATA_3),
.mac = SHA_256_MAC_3,
.mac_len = sizeof(SHA_256_MAC_3),
},
#endif
#ifdef IPIPSEC_USE_SHA384
{
.alg = SADB_X_AALG_SHA2_384_HMAC,
.name = "hmac(sha2-384-192) RFC-4858 AUTH384-1",
.key = SHA_512_KEY_1,
.key_len = 48,
.data = SHA_X_DATA_1,
.data_len = sizeof(SHA_X_DATA_1),
.mac = SHA_384_MAC_1,
.mac_len = sizeof(SHA_384_MAC_1),
},
{
.alg = SADB_X_AALG_SHA2_384_HMAC,
.name = "hmac(sha2-384-192) RFC-4858 AUTH384-3",
.key = SHA_512_KEY_3,
.key_len = 48,
.data = SHA_X_DATA_3,
.data_len = sizeof(SHA_X_DATA_3),
.mac = SHA_384_MAC_3,
.mac_len = sizeof(SHA_384_MAC_3),
},
#endif
#ifdef IPIPSEC_USE_SHA512
{
.alg = SADB_X_AALG_SHA2_512_HMAC,
.name = "hmac(sha2-512-256) RFC-4858 AUTH512-1",
.key = SHA_512_KEY_1,
.key_len = sizeof(SHA_512_KEY_1),
.data = SHA_X_DATA_1,
.data_len = sizeof(SHA_X_DATA_1),
.mac = SHA_512_MAC_1,
.mac_len = sizeof(SHA_512_MAC_1),
},
{
.alg = SADB_X_AALG_SHA2_512_HMAC,
.name = "hmac(sha2-512-256) RFC-4858 AUTH512-3",
.key = SHA_512_KEY_3,
.key_len = sizeof(SHA_512_KEY_3),
.data = SHA_X_DATA_3,
.data_len = sizeof(SHA_X_DATA_3),
.mac = SHA_512_MAC_3,
.mac_len = sizeof(SHA_512_MAC_3),
},
#endif
};
IP_CONST Ipipsec_auth_method * aalg;
Ipcom_pkt dummy_pkt;
Ipipsec_sa dummy_sa;
Ip_u8 calc_digest[IPIPSEC_AUTH_MAXKEYLEN];
Ip_size_t i = 0;
ipcom_memset(&dummy_sa, 0, sizeof(Ipipsec_sa));
for (i = 0;
i < (sizeof(self_test_auth_algs)/sizeof(self_test_auth_algs[0]));
i++)
{
/* Prepare dummy packet */
dummy_pkt.data = (Ip_u8 *)self_test_auth_algs[i].data;
dummy_pkt.start = 0;
dummy_pkt.end = (int) self_test_auth_algs[i].data_len;
/* Prepare dummy SA */
dummy_sa.sadb_sa_auth = self_test_auth_algs[i].alg;
/* Set the key */
if ( 0 == ipipsec_auth_setkey(&dummy_sa.auth,
self_test_auth_algs[i].alg,
(Ip_u8 *) self_test_auth_algs[i].key,
(Ip_u32) self_test_auth_algs[i].key_len))
{
/* Get auth method */
aalg = &ipipsec_auth_method[dummy_sa.auth->aindex];
/* Calculate digest */
ipipsec_calc_digest(&dummy_sa, &dummy_pkt, 0, calc_digest);
if ( ipcom_memcmp(self_test_auth_algs[i].mac, calc_digest, aalg->auth_bytes) != 0 )
{
IPCOM_LOG1(ERR, "ipipsec_crypt_self_test() :: %s FAILED",
self_test_auth_algs[i].name);
}
else
{
IPCOM_LOG1(ERR, "ipipsec_crypt_self_test() :: %s PASSED",
self_test_auth_algs[i].name);
}
}
/* Free auth object allocated by ipipsec_auth_setkey */
if ( dummy_sa.auth != IP_NULL )
{
ipipsec_shm_free(dummy_sa.auth);
dummy_sa.auth = IP_NULL;
}
}
}
#endif /* IPIPSEC_USE_CRYPTO_SELF_TEST */
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/