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

1599 lines
60 KiB
C

/*
******************************************************************************
* INTERPEAK SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipfreescale.c,v $ $Revision: 1.71.28.1 $
* $Source: /home/interpeak/CVSRoot/ipfreescale/src/ipfreescale.c,v $
* $Author: svc-cmnet $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Markus Carlstedt <markus@interpeak.se>
******************************************************************************
*/
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
* IPFREESCALE - Hardware crypto support product - core file.
*
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
#include "ipfreescale_config.h"
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#define IPCOM_USE_CLIB_PROTO
#include <ipcom_type.h>
#include <ipcom_cstyle.h>
#include <ipcom_clib.h>
#include <ipcom_syslog.h>
#include <ipcom_err.h>
#include <ipcom_os.h>
#include <ipcom_shell.h>
/* TODO: Not pretty! Nasty dependencies between files */
/* Include ipfreescale_sec4.h before iphwcrypto.h to avoid type collition for uint32_t between stdint.h and ipipsec_pfkeyv2.h */
#ifdef IPFREESCALE_SEC4
#define IPIPSEC_HAVE_UINT_TYPE
#endif
#if defined(IPFREESCALE_SEC2) || defined(IPFREESCALE_SEC4)
#include "ipfreescale_sec.h"
#endif
#include <iphwcrypto.h>
#include "ipfreescale.h"
#include "ipfreescale_h.h"
#ifdef IPFREESCALE_COLDFIRE
#include "ipfreescale_coldfire.h"
#endif
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/*
****************************************************************************
* 6 EXTERN PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
IP_PUBLIC Ip_err ipfreescale_create(void);
IP_PUBLIC Ip_err ipfreescale_start(void);
IP_PUBLIC const char *ipfreescale_version(void);
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
/*
****************************************************************************
* 9 STATIC FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* 10 GLOBAL FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* 11 PUBLIC FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipfreescale_random_gen
*===========================================================================
* Description: Generate sequence of random data.
* Parameters: data - pointer to buffer for random data.
* length - number of bytes in sequence.
* Returns: -1 = error
* 0 = timeout
* 1 = ok
*/
IP_PUBLIC int
ipfreescale_random_gen(Ip_u8 *data, Ip_u32 length)
{
ip_assert(data != IP_NULL);
if(length > IPFREESCALE_CRYPTO_BUFSIZE)
{
IPCOM_LOG1(ERR, "ipfreescale_random_gen() :: Too large buffer %d", length);
return -1;
}
#if defined(IPFREESCALE_SEC2) || defined(IPFREESCALE_SEC4)
return ipfreescale_sec_random_gen(data, length);
#endif
#ifdef IPFREESCALE_COLDFIRE
return ipfreescale_coldfire_random_gen(data, length);
#endif
}
/*
*===========================================================================
* ipfreescale_md5_hmac
*===========================================================================
* Description: Calculate HMAC using the MD5 algorithm.
* Parameters: data - pointer to buffer with the data to hash.
* length - length of data in bytes.
* key - pointer to buffer with the key.
* keylength - length of key in bytes.
* hmac - pointer to buffer for the hmac (16 bytes).
* Returns: -1 = error
* 0 = timeout
* 1 = ok
*/
IP_PUBLIC int
ipfreescale_md5_hmac(Ip_u8 *data, Ip_u32 length, Ip_u8 *key, Ip_u32 keylength, Ip_u8 *hmac)
{
ip_assert(hmac != IP_NULL);
ip_assert(data != IP_NULL || length == 0);
if(length > IPFREESCALE_CRYPTO_BUFSIZE)
{
IPCOM_LOG1(ERR, "ipfreescale_md5_hmac() :: Too large buffer %d", length);
return -1;
}
#if defined(IPFREESCALE_SEC2) || defined(IPFREESCALE_SEC4)
return ipfreescale_sec_md5_hmac(data, length, key, keylength, hmac);
#endif
#ifdef IPFREESCALE_COLDFIRE
return -1;
#endif
}
/*
*===========================================================================
* ipfreescale_md5_digest
*===========================================================================
* Description: Calculate message digest using the MD5 algorithm.
* Parameters: data - pointer to buffer with the data to hash.
* length - length of data in bytes.
* digest - pointer to buffer for the digest (16 bytes).
* Returns: -1 = error
* 0 = timeout
* 1 = ok
*/
IP_PUBLIC int
ipfreescale_md5_digest(Ip_u8 *data, Ip_u32 length, Ip_u8 *digest)
{
ip_assert(digest != IP_NULL);
ip_assert(data != IP_NULL || length == 0);
if(length > IPFREESCALE_CRYPTO_BUFSIZE)
{
IPCOM_LOG1(ERR, "ipfreescale_md5_digest() :: Too large buffer %d", length);
return -1;
}
#ifdef IPFREESCALE_SEC2
return ipfreescale_sec_md5_digest(data, length, digest);
#endif
#ifdef IPFREESCALE_COLDFIRE
if (data == IP_NULL || length == 0)
{
/* Coldfire SEC does not allow zero length digests */
ipcom_memcpy(digest, "\xd4\x1d\x8c\xd9\x8f\x00\xb2\x04\xe9\x80\x09\x98\xec\xf8\x42\x7e", 16);
IPFREESCALE_STATS(op_md5++);
return 1;
}
return ipfreescale_coldfire_md5_digest(data, length, digest);
#endif
#ifdef IPFREESCALE_SEC4
if (data == IP_NULL || length == 0)
{
/* SEC4 driver does not allow zero length digests */
ipcom_memcpy(digest, "\xd4\x1d\x8c\xd9\x8f\x00\xb2\x04\xe9\x80\x09\x98\xec\xf8\x42\x7e", 16);
IPFREESCALE_STATS(op_md5++);
return 1;
}
return ipfreescale_sec_md5_digest(data, length, digest);
#endif
}
/*
*===========================================================================
* ipfreescale_md5_digest_init
*===========================================================================
* Description: Initialize MD5 message digest context.
* Parameters: ctx - pointer to the context.
* Returns: 1 = ok
*/
IP_PUBLIC int
ipfreescale_md5_digest_init(void *ctx)
{
ip_assert(ctx != IP_NULL);
ipcom_memset(ctx, 0, sizeof(Ipfreescale_digest_context));
return 1;
}
/*
*===========================================================================
* ipfreescale_md5_digest_update
*===========================================================================
* Description: Update MD5 message digest context.
* Parameters: ctx - pointer to the context.
* data - pointer to buffer with the data to hash.
* length - length of data in bytes.
* Returns: -1 = error
* 1 = ok
*/
IP_PUBLIC int
ipfreescale_md5_digest_update(void *ctx, IP_CONST Ip_u8 *data, Ip_u32 length)
{
Ipfreescale_digest_context *dgst_ctx = ctx;
void *tmp;
ip_assert(ctx != IP_NULL && (data != IP_NULL || length == 0));
if(length > IPFREESCALE_CRYPTO_BUFSIZE)
{
IPCOM_LOG1(ERR, "ipfreescale_md5_digest_update() :: Too large buffer %d", length);
return -1;
}
if(length > 0)
{
tmp = ipcom_realloc(dgst_ctx->msg, dgst_ctx->length + length);
if (tmp == IP_NULL)
return -1;
dgst_ctx->msg = tmp;
ipcom_memcpy(&dgst_ctx->msg[dgst_ctx->length], data, length);
dgst_ctx->length += length;
}
return 1;
}
/*
*===========================================================================
* ipfreescale_md5_digest_final
*===========================================================================
* Description: Finalize MD5 message digest context.
* Parameters: ctx - pointer to the context.
* digest - pointer to buffer for the digest (16 bytes).
* Returns: -1 = error
* 0 = timeout
* 1 = ok
*/
IP_PUBLIC int
ipfreescale_md5_digest_final(void *ctx, Ip_u8 *digest)
{
Ipfreescale_digest_context *dgst_ctx = ctx;
int ret;
ip_assert(ctx != IP_NULL && digest != IP_NULL);
ret = ipfreescale_md5_digest(dgst_ctx->msg, dgst_ctx->length, digest);
return ret;
}
/*
*===========================================================================
* ipfreescale_sha1_hmac
*===========================================================================
* Description: Calculate HMAC using the SHA1 algorithm.
* Parameters: data - pointer to buffer with the data to hash.
* length - length of data in bytes.
* key - pointer to buffer with the key.
* keylength - length of key in bytes.
* hmac - pointer to buffer for the hmac (20 bytes).
* Returns: -1 = error
* 0 = timeout
* 1 = ok
*/
IP_PUBLIC int
ipfreescale_sha1_hmac(Ip_u8 *data, Ip_u32 length, Ip_u8 *key, Ip_u32 keylength, Ip_u8 *hmac)
{
ip_assert(hmac != IP_NULL);
ip_assert(data != IP_NULL || length == 0);
if(length > IPFREESCALE_CRYPTO_BUFSIZE)
{
IPCOM_LOG1(ERR, "ipfreescale_sha1_hmac() :: Too large buffer %d", length);
return -1;
}
#if defined(IPFREESCALE_SEC2) || defined(IPFREESCALE_SEC4)
return ipfreescale_sec_sha1_hmac(data, length, key, keylength, hmac);
#endif
#ifdef IPFREESCALE_COLDFIRE
return -1;
#endif
}
/*
*===========================================================================
* ipfreescale_sha1_digest
*===========================================================================
* Description: Calculate message digest using the SHA1 algorithm.
* Parameters: data - pointer to buffer with the data to hash.
* length - length of data in bytes.
* digest - pointer to buffer for the digest (20 bytes).
* Returns: -1 = error
* 0 = timeout
* 1 = ok
*/
IP_PUBLIC int
ipfreescale_sha1_digest(Ip_u8 *data, Ip_u32 length, Ip_u8 *digest)
{
ip_assert(data != IP_NULL || length == 0);
if(length > IPFREESCALE_CRYPTO_BUFSIZE)
{
IPCOM_LOG1(ERR, "ipfreescale_sha1_digest() :: Too large buffer %d", length);
return -1;
}
#ifdef IPFREESCALE_SEC2
return ipfreescale_sec_sha1_digest(data, length, digest);
#endif
#ifdef IPFREESCALE_COLDFIRE
if (data == IP_NULL || length == 0)
{
/* Coldfire SEC does not allow zero length digests */
IPFREESCALE_STATS(op_sha1++);
ipcom_memcpy(digest, "\xda\x39\xa3\xee\x5e\x6b\x4b\x0d\x32\x55\xbf\xef\x95\x60\x18\x90\xaf\xd8\x07\x09", 20);
return 1;
}
return ipfreescale_coldfire_sha1_digest(data, length, digest);
#endif
#ifdef IPFREESCALE_SEC4
if (data == IP_NULL || length == 0)
{
/* SEC4 driver does not allow zero length digests */
IPFREESCALE_STATS(op_sha1++);
ipcom_memcpy(digest, "\xda\x39\xa3\xee\x5e\x6b\x4b\x0d\x32\x55\xbf\xef\x95\x60\x18\x90\xaf\xd8\x07\x09", 20);
return 1;
}
return ipfreescale_sec_sha1_digest(data, length, digest);
#endif
}
/*
*===========================================================================
* ipfreescale_sha1_digest_init
*===========================================================================
* Description: Initialize SHA1 message digest context.
* Parameters: ctx - pointer to the context.
* Returns: 1 = ok
*/
IP_PUBLIC int
ipfreescale_sha1_digest_init(void *ctx)
{
ip_assert(ctx != IP_NULL);
ipcom_memset(ctx, 0, sizeof(Ipfreescale_digest_context));
return 1;
}
/*
*===========================================================================
* ipfreescale_sha1_digest_update
*===========================================================================
* Description: Update SHA1 message digest context.
* Parameters: ctx - pointer to the context.
* data - pointer to buffer with the data to hash.
* length - length of data in bytes.
* Returns: -1 = error
* 1 = ok
*/
IP_PUBLIC int
ipfreescale_sha1_digest_update(void *ctx, IP_CONST Ip_u8 *data, Ip_u32 length)
{
Ipfreescale_digest_context *dgst_ctx = ctx;
void *tmp;
ip_assert(ctx != IP_NULL && (data != IP_NULL || length == 0));
if(length > IPFREESCALE_CRYPTO_BUFSIZE)
{
IPCOM_LOG1(ERR, "ipfreescale_sha1_digest_update() :: Too large buffer %d", length);
return -1;
}
if(length > 0)
{
tmp = ipcom_realloc(dgst_ctx->msg, dgst_ctx->length + length);
if (tmp == IP_NULL)
return -1;
dgst_ctx->msg = tmp;
ipcom_memcpy(&dgst_ctx->msg[dgst_ctx->length], data, length);
dgst_ctx->length += length;
}
return 1;
}
/*
*===========================================================================
* ipfreescale_sha1_digest_final
*===========================================================================
* Description: Finalize SHA1 message digest context.
* Parameters: ctx - pointer to the context.
* digest - pointer to buffer for the digest (20 bytes).
* Returns: -1 = error
* 0 = timeout
* 1 = ok
*/
IP_PUBLIC int
ipfreescale_sha1_digest_final(void *ctx, Ip_u8 *digest)
{
Ipfreescale_digest_context *dgst_ctx = ctx;
int ret;
ip_assert(ctx != IP_NULL && digest != IP_NULL);
ret = ipfreescale_sha1_digest(dgst_ctx->msg, dgst_ctx->length, digest);
return ret;
}
/*
*===========================================================================
* ipfreescale_digest_copy
*===========================================================================
* Description: Copy message digest context.
* Parameters: ctx_to - pointer to the destination context.
* ctx_from - pointer to the source context.
* Returns: -1 = error
* 1 = ok
*/
IP_PUBLIC int
ipfreescale_digest_copy(void *ctx_to, IP_CONST void *ctx_from)
{
Ipfreescale_digest_context *dgst_ctx_to = ctx_to;
IP_CONST Ipfreescale_digest_context *dgst_ctx_from = ctx_from;
ip_assert(ctx_to != IP_NULL && ctx_from != IP_NULL);
if (dgst_ctx_from->length > 0)
{
dgst_ctx_to->msg = ipcom_malloc(dgst_ctx_from->length);
if (dgst_ctx_to->msg == IP_NULL)
return -1;
ipcom_memcpy(dgst_ctx_to->msg, dgst_ctx_from->msg, dgst_ctx_from->length);
dgst_ctx_to->length = dgst_ctx_from->length;
}
else
{
dgst_ctx_to->msg = IP_NULL;
dgst_ctx_to->length = 0;
}
return 1;
}
/*
*===========================================================================
* ipfreescale_digest_cleanup
*===========================================================================
* Description: Cleanup message digest context.
* Parameters: ctx - pointer to the context.
* Returns: 1 = ok.
*/
IP_PUBLIC int
ipfreescale_digest_cleanup(void *ctx)
{
Ipfreescale_digest_context *dgst_ctx = ctx;
ip_assert(ctx != IP_NULL);
if(dgst_ctx->msg)
ipcom_free(dgst_ctx->msg);
return 1;
}
/*
*===========================================================================
* ipfreescale_des_cbc_cipher
*===========================================================================
* Description: Encrypt or decrypt a data buffer using DES-CBC cipher.
* Parameters: out - pointer to buffer for the result.
* in - pointer to buffer with the data to encrypt/decrypt.
* length - length of data in bytes.
* key - pointer to buffer with the key (8 bytes).
* iv - Initialization vector (8 bytes). Updated by hardware.
* enc - 1 = encryption. 0 = decryption.
* Returns: -1 = error
* 0 = timeout
* 1 = ok
*/
IP_PUBLIC int
ipfreescale_des_cbc_cipher(Ip_u8 *out, IP_CONST Ip_u8 *in, Ip_u32 length, void *key, Ip_u8 *iv, int enc)
{
ip_assert(out != IP_NULL && in != IP_NULL && key != IP_NULL && iv != IP_NULL);
ip_assert(length % IPFREESCALE_DES_BLOCK_SIZE == 0);
if(length > IPFREESCALE_CRYPTO_BUFSIZE)
{
IPCOM_LOG1(ERR, "ipfreescale_des_cbc_cipher() :: Too large buffer %d", length);
return -1;
}
if(length % IPFREESCALE_DES_BLOCK_SIZE != 0)
return -1;
#if defined(IPFREESCALE_SEC2) || defined(IPFREESCALE_SEC4)
return ipfreescale_sec_des_cbc_cipher(out, in, length, key, iv, enc);
#endif
#ifdef IPFREESCALE_COLDFIRE
return ipfreescale_coldfire_des_cbc_cipher(out, in, length, key, iv, enc);
#endif
}
/*
*===========================================================================
* ipfreescale_des_ecb_cipher
*===========================================================================
* Description: Encrypt or decrypt a data buffer using DES-ECB cipher.
* Parameters: out - pointer to buffer for the result.
* in - pointer to buffer with the data to encrypt/decrypt.
* length - length of data in bytes.
* key - pointer to buffer with the key (8 bytes).
* enc - 1 = encryption. 0 = decryption.
* Returns: -1 = error
* 0 = timeout
* 1 = ok
*/
IP_PUBLIC int
ipfreescale_des_ecb_cipher(Ip_u8 *out, IP_CONST Ip_u8 *in, Ip_u32 length, void *key, int enc)
{
ip_assert(out != IP_NULL && in != IP_NULL && key != IP_NULL);
ip_assert(length % IPFREESCALE_DES_BLOCK_SIZE == 0);
if(length > IPFREESCALE_CRYPTO_BUFSIZE)
{
IPCOM_LOG1(ERR, "ipfreescale_des_ecb_cipher() :: Too large buffer %d", length);
return -1;
}
if(length % IPFREESCALE_DES_BLOCK_SIZE != 0)
return -1;
#if defined(IPFREESCALE_SEC2) || defined(IPFREESCALE_SEC4)
return ipfreescale_sec_des_ecb_cipher(out, in, length, key, enc);
#endif
#ifdef IPFREESCALE_COLDFIRE
return ipfreescale_coldfire_des_ecb_cipher(out, in, length, key, enc);
#endif
}
/*
*===========================================================================
* ipfreescale_3des_cbc_cipher
*===========================================================================
* Description: Encrypt or decrypt a data buffer using 3DES-CBC cipher.
* Parameters: out - pointer to buffer for the result.
* in - pointer to buffer with the data to encrypt/decrypt.
* length - length of data in bytes.
* key - pointer to buffer with the key (24 bytes).
* iv - Initialization vector (8 bytes). Updated by hardware.
* enc - 1 = encryption. 0 = decryption.
* Returns: -1 = error
* 0 = timeout
* 1 = ok
*/
IP_PUBLIC int
ipfreescale_3des_cbc_cipher(Ip_u8 *out, IP_CONST Ip_u8 *in, Ip_u32 length, void *key, Ip_u8 *iv, int enc)
{
ip_assert(out != IP_NULL && in != IP_NULL && key != IP_NULL && iv != IP_NULL);
ip_assert(length % IPFREESCALE_3DES_BLOCK_SIZE == 0);
if(length > IPFREESCALE_CRYPTO_BUFSIZE)
{
IPCOM_LOG1(ERR, "ipfreescale_3des_cbc_cipher() :: Too large buffer %d", length);
return -1;
}
if(length % IPFREESCALE_3DES_BLOCK_SIZE != 0)
return -1;
#if defined(IPFREESCALE_SEC2) || defined(IPFREESCALE_SEC4)
return ipfreescale_sec_3des_cbc_cipher(out, in, length, key, iv, enc);
#endif
#ifdef IPFREESCALE_COLDFIRE
return ipfreescale_coldfire_3des_cbc_cipher(out, in, length, key, iv, enc);
#endif
}
/*
*===========================================================================
* ipfreescale_3des_ecb_cipher
*===========================================================================
* Description: Encrypt or decrypt a data buffer using 3DES-ECB cipher.
* Parameters: out - pointer to buffer for the result.
* in - pointer to buffer with the data to encrypt/decrypt.
* length - length of data in bytes.
* key - pointer to buffer with the key (24 bytes).
* enc - 1 = encryption. 0 = decryption.
* Returns: -1 = error
* 0 = timeout
* 1 = ok
*/
IP_PUBLIC int
ipfreescale_3des_ecb_cipher(Ip_u8 *out, IP_CONST Ip_u8 *in, Ip_u32 length, void *key, int enc)
{
ip_assert(out != IP_NULL && in != IP_NULL && key != IP_NULL);
ip_assert(length % IPFREESCALE_3DES_BLOCK_SIZE == 0);
if(length > IPFREESCALE_CRYPTO_BUFSIZE)
{
IPCOM_LOG1(ERR, "ipfreescale_3des_ecb_cipher() :: Too large buffer %d", length);
return -1;
}
if(length % IPFREESCALE_3DES_BLOCK_SIZE != 0)
return -1;
#if defined(IPFREESCALE_SEC2) || defined(IPFREESCALE_SEC4)
return ipfreescale_sec_3des_ecb_cipher(out, in, length, key, enc);
#endif
#ifdef IPFREESCALE_COLDFIRE
return ipfreescale_coldfire_3des_ecb_cipher(out, in, length, key, enc);
#endif
}
/*
*===========================================================================
* ipfreescale_aes128_cbc_cipher
*===========================================================================
* Description: Encrypt or decrypt a data buffer using AES-CBC-128 cipher.
* Parameters: out - pointer to buffer for the result.
* in - pointer to buffer with the data to encrypt/decrypt.
* length - length of data in bytes.
* key - pointer to buffer with the key (16 bytes).
* iv - Initialization vector (16 bytes). Updated by hardware.
* enc - 1 = encryption. 0 = decryption.
* Returns: -1 = error
* 0 = timeout
* 1 = ok
*/
IP_PUBLIC int
ipfreescale_aes128_cbc_cipher(Ip_u8 *out, IP_CONST Ip_u8 *in, Ip_u32 length, void *key, Ip_u8 *iv, int enc)
{
ip_assert(out != IP_NULL && in != IP_NULL && key != IP_NULL && iv != IP_NULL);
ip_assert(length % IPFREESCALE_AES_BLOCK_SIZE == 0);
if(length > IPFREESCALE_CRYPTO_BUFSIZE)
{
IPCOM_LOG1(ERR, "ipfreescale_aes128_cbc_cipher() :: Too large buffer %d", length);
return -1;
}
if(length % IPFREESCALE_AES_BLOCK_SIZE != 0)
return -1;
#if defined(IPFREESCALE_SEC2) || defined(IPFREESCALE_SEC4)
return ipfreescale_sec_aes_cbc_cipher(out, in, length, key, 16, iv, enc);
#endif
#ifdef IPFREESCALE_COLDFIRE
return ipfreescale_coldfire_aes_cbc_cipher(out, in, length, key, 16, iv, enc);
#endif
}
/*
*===========================================================================
* ipfreescale_aes128_ecb_cipher
*===========================================================================
* Description: Encrypt or decrypt a data buffer using AES-ECB-128 cipher.
* Parameters: out - pointer to buffer for the result.
* in - pointer to buffer with the data to encrypt/decrypt.
* length - length of data in bytes.
* key - pointer to buffer with the key (16 bytes).
* enc - 1 = encryption. 0 = decryption.
* Returns: -1 = error
* 0 = timeout
* 1 = ok
*/
IP_PUBLIC int
ipfreescale_aes128_ecb_cipher(Ip_u8 *out, IP_CONST Ip_u8 *in, Ip_u32 length, void *key, int enc)
{
ip_assert(out != IP_NULL && in != IP_NULL && key != IP_NULL);
ip_assert(length % IPFREESCALE_AES_BLOCK_SIZE == 0);
if(length > IPFREESCALE_CRYPTO_BUFSIZE)
{
IPCOM_LOG1(ERR, "ipfreescale_aes128_ecb_cipher() :: Too large buffer %d", length);
return -1;
}
if(length % IPFREESCALE_AES_BLOCK_SIZE != 0)
return -1;
#if defined(IPFREESCALE_SEC2) || defined(IPFREESCALE_SEC4)
return ipfreescale_sec_aes_ecb_cipher(out, in, length, key, 16, enc);
#endif
#ifdef IPFREESCALE_COLDFIRE
return ipfreescale_coldfire_aes_ecb_cipher(out, in, length, key, 16, enc);
#endif
}
/*
*===========================================================================
* ipfreescale_aes192_cbc_cipher
*===========================================================================
* Description: Encrypt or decrypt a data buffer using AES-CBC-192 cipher.
* Parameters: out - pointer to buffer for the result.
* in - pointer to buffer with the data to encrypt/decrypt.
* length - length of data in bytes.
* key - pointer to buffer with the key (24 bytes).
* iv - Initialization vector (16 bytes). Updated by hardware.
* enc - 1 = encryption. 0 = decryption.
* Returns: -1 = error
* 0 = timeout
* 1 = ok
*/
IP_PUBLIC int
ipfreescale_aes192_cbc_cipher(Ip_u8 *out, IP_CONST Ip_u8 *in, Ip_u32 length, void *key, Ip_u8 *iv, int enc)
{
ip_assert(out != IP_NULL && in != IP_NULL && key != IP_NULL && iv != IP_NULL);
ip_assert(length % IPFREESCALE_AES_BLOCK_SIZE == 0);
if(length > IPFREESCALE_CRYPTO_BUFSIZE)
{
IPCOM_LOG1(ERR, "ipfreescale_aes192_cbc_cipher() :: Too large buffer %d", length);
return -1;
}
if(length % IPFREESCALE_AES_BLOCK_SIZE != 0)
return -1;
#if defined(IPFREESCALE_SEC2) || defined(IPFREESCALE_SEC4)
return ipfreescale_sec_aes_cbc_cipher(out, in, length, key, 24, iv, enc);
#endif
#ifdef IPFREESCALE_COLDFIRE
return ipfreescale_coldfire_aes_cbc_cipher(out, in, length, key, 24, iv, enc);
#endif
}
/*
*===========================================================================
* ipfreescale_aes192_ecb_cipher
*===========================================================================
* Description: Encrypt or decrypt a data buffer using AES-ECB-192 cipher.
* Parameters: out - pointer to buffer for the result.
* in - pointer to buffer with the data to encrypt/decrypt.
* length - length of data in bytes.
* key - pointer to buffer with the key (24 bytes).
* enc - 1 = encryption. 0 = decryption.
* Returns: -1 = error
* 0 = timeout
* 1 = ok
*/
IP_PUBLIC int
ipfreescale_aes192_ecb_cipher(Ip_u8 *out, IP_CONST Ip_u8 *in, Ip_u32 length, void *key, int enc)
{
ip_assert(out != IP_NULL && in != IP_NULL && key != IP_NULL);
ip_assert(length % IPFREESCALE_AES_BLOCK_SIZE == 0);
if(length > IPFREESCALE_CRYPTO_BUFSIZE)
{
IPCOM_LOG1(ERR, "ipfreescale_aes192_ecb_cipher() :: Too large buffer %d", length);
return -1;
}
if(length % IPFREESCALE_AES_BLOCK_SIZE != 0)
return -1;
#if defined(IPFREESCALE_SEC2) || defined(IPFREESCALE_SEC4)
return ipfreescale_sec_aes_ecb_cipher(out, in, length, key, 24, enc);
#endif
#ifdef IPFREESCALE_COLDFIRE
return ipfreescale_coldfire_aes_ecb_cipher(out, in, length, key, 24, enc);
#endif
}
/*
*===========================================================================
* ipfreescale_aes256_cbc_cipher
*===========================================================================
* Description: Encrypt or decrypt a data buffer using AES-CBC-256 cipher.
* Parameters: out - pointer to buffer for the result.
* in - pointer to buffer with the data to encrypt/decrypt.
* length - length of data in bytes.
* key - pointer to buffer with the key (32 bytes).
* iv - Initialization vector (16 bytes). Updated by hardware.
* enc - 1 = encryption. 0 = decryption.
* Returns: -1 = error
* 0 = timeout
* 1 = ok
*/
IP_PUBLIC int
ipfreescale_aes256_cbc_cipher(Ip_u8 *out, IP_CONST Ip_u8 *in, Ip_u32 length, void *key, Ip_u8 *iv, int enc)
{
ip_assert(out != IP_NULL && in != IP_NULL && key != IP_NULL && iv != IP_NULL);
ip_assert(length % IPFREESCALE_AES_BLOCK_SIZE == 0);
if(length > IPFREESCALE_CRYPTO_BUFSIZE)
{
IPCOM_LOG1(ERR, "ipfreescale_aes256_cbc_cipher() :: Too large buffer %d", length);
return -1;
}
if(length % IPFREESCALE_AES_BLOCK_SIZE != 0)
return -1;
#if defined(IPFREESCALE_SEC2) || defined(IPFREESCALE_SEC4)
return ipfreescale_sec_aes_cbc_cipher(out, in, length, key, 32, iv, enc);
#endif
#ifdef IPFREESCALE_COLDFIRE
return ipfreescale_coldfire_aes_cbc_cipher(out, in, length, key, 32, iv, enc);
#endif
}
/*
*===========================================================================
* ipfreescale_aes256_ecb_cipher
*===========================================================================
* Description: Encrypt or decrypt a data buffer using AES-ECB-256 cipher.
* Parameters: out - pointer to buffer for the result.
* in - pointer to buffer with the data to encrypt/decrypt.
* length - length of data in bytes.
* key - pointer to buffer with the key (32 bytes).
* enc - 1 = encryption. 0 = decryption.
* Returns: -1 = error
* 0 = timeout
* 1 = ok
*/
IP_PUBLIC int
ipfreescale_aes256_ecb_cipher(Ip_u8 *out, IP_CONST Ip_u8 *in, Ip_u32 length, void *key, int enc)
{
ip_assert(out != IP_NULL && in != IP_NULL && key != IP_NULL);
ip_assert(length % IPFREESCALE_AES_BLOCK_SIZE == 0);
if(length > IPFREESCALE_CRYPTO_BUFSIZE)
{
IPCOM_LOG1(ERR, "ipfreescale_aes256_ecb_cipher() :: Too large buffer %d", length);
return -1;
}
if(length % IPFREESCALE_AES_BLOCK_SIZE != 0)
return -1;
#if defined(IPFREESCALE_SEC2) || defined(IPFREESCALE_SEC4)
return ipfreescale_sec_aes_ecb_cipher(out, in, length, key, 32, enc);
#endif
#ifdef IPFREESCALE_COLDFIRE
return ipfreescale_coldfire_aes_ecb_cipher(out, in, length, key, 32, enc);
#endif
}
/*
*===========================================================================
* ipfreescale_rc4_cipher
*===========================================================================
* Description: RC4 stream cipher. Provide key and output context for operation
* with key load and context save. Provide input context and
* output context for operation with context load and context save.
* Parameters: out - pointer to buffer for the result.
* in - pointer to buffer with the data to encrypt/decrypt.
* length - length of data in bytes.
* key - pointer to buffer with the key.
* keylen - length of encryption key (1-16 bytes).
* ctxi - buffer with input context (259 bytes).
* ctxo - buffer with output context (259 bytes).
* Returns: -1 = error
* 0 = timeout
* 1 = ok
*/
IP_PUBLIC int
ipfreescale_rc4_cipher(Ip_u8 *out, IP_CONST Ip_u8 *in, Ip_u32 length, void *key, Ip_u32 keylen, Ip_u8 *ctxi, Ip_u8 *ctxo)
{
ip_assert(out != IP_NULL && in != IP_NULL && (key != IP_NULL || ctxi != IP_NULL) && ctxo != IP_NULL);
if(length > IPFREESCALE_CRYPTO_BUFSIZE)
{
IPCOM_LOG1(ERR, "ipfreescale_rc4_cipher() :: Too large buffer %d", length);
return -1;
}
#if defined(IPFREESCALE_SEC2) || defined(IPFREESCALE_SEC4)
return ipfreescale_sec_rc4_cipher(out, in, length, key, keylen, ctxi, ctxo);
#endif
#ifdef IPFREESCALE_COLDFIRE
return ipfreescale_coldfire_rc4_cipher(out, in, length, key, keylen, ctxi, ctxo);
#endif
}
/*
*===========================================================================
* ipfreescale_ccmp_encrypt
*===========================================================================
* Description: Encrypt a packet using AES-CCM
* Parameters: out - pointer to buffer for the result.
* in - pointer to buffer with the data to encrypt.
* length - length of data in bytes.
* mic - pointer to buffer with the MIC output (32 bytes).
* aad - pointer to buffer with additional authenticated data.
* aadlen - length of additional authenticated data
* key - pointer to buffer with the encryption key
* keylen - length of encryption key
* ctxi - pointer to buffer with the input context (56 bytes)
* Returns: -1 = error
* 0 = timeout
* 1 = ok
*/
IP_GLOBAL int
ipfreescale_ccmp_encrypt(Ip_u8 *out, IP_CONST Ip_u8 *in, Ip_u32 length,
Ip_u8 *mic, IP_CONST Ip_u8 *aad, Ip_u32 aadlen,
void *key, Ip_u32 keylen, Ip_u8 *ctxi)
{
ip_assert(out != IP_NULL && in != IP_NULL && (key != IP_NULL || ctxi != IP_NULL));
#if defined(IPFREESCALE_SEC2) || defined(IPFREESCALE_SEC4)
return ipfreescale_sec_ccmp_encrypt(out, in, length, mic, aad, aadlen, key, keylen, ctxi);
#endif
}
/*
*===========================================================================
* ipfreescale_aesccm
*===========================================================================
* Description: Encrypt a packet using AES-CCM
* Parameters: out - pointer to buffer for the result.
* in - pointer to buffer with the input data.
* length - length of data in bytes.
* micout - pointer to buffer with the MIC output
* micin - pointer to buffer with the MIC input (decrypt only)
* miclen - Length of MIC
* aad - pointer to buffer with additional authenticated data.
* aadlen - length of additional authenticated data
* key - pointer to buffer with the encryption key
* keylen - length of encryption key
* ctxi - pointer to buffer with the input context (56 bytes)
* enc - 1 = encryption. 0 = decryption.
* options - Ored bit options to control AES CCM.
* Valid options: IPFREESCALE_OPT_NONE
* IPFREESCALE_OPT_AESCCM_ICV
* IPFREESCALE_OPT_INPUTDATA_IS_SGT
* IPFREESCALE_OPT_INPUTDATA_IS_HW_SGT
* IPFREESCALE_OPT_OUTPUTDATA_IS_SGT
* IPFREESCALE_OPT_OUTPUTDATA_IS_HW_SGT
*
* Returns: -1 = error
* 0 = timeout
* 1 = ok
*/
IP_GLOBAL int
ipfreescale_aesccm(Ip_u8 *out, IP_CONST Ip_u8 *in, Ip_u32 length,
Ip_u8 *micout, Ip_u8 *micin, Ip_u32 miclen, IP_CONST Ip_u8 *aad, Ip_u32 aadlen,
void *key, Ip_u32 keylen, Ip_u8 *ctxi, int enc,
Ip_bool async, void * asynchandle, Ip_u32 options)
{
ip_assert(out != IP_NULL && in != IP_NULL && (key != IP_NULL || ctxi != IP_NULL));
#ifdef IPFREESCALE_SEC4
return ipfreescale_sec_aesccm(out, in, length, micout, micin, miclen, aad, aadlen,
key, keylen, ctxi, enc, async, asynchandle, options);
#else
IPCOM_LOG0(INFO, "ipfreescale_aesccm() :: AES CCM cipher is not supported on this hardware");
return -1;
#endif
}
/*
*===========================================================================
* ipfreescale_mod_exp
*===========================================================================
* Description: Modular exponentiation. Calculates b^e mod m.
* The size of the base and exponent buffers are assumed to be
* of equal size as the modulus length and zero padded with leading
* zeros if necessary. The size of the result buffer
* is also equal to the modulus length and the result will be zero
* padded if necessary.
* Parameters: out - pointer to buffer for the result.
* base - pointer to buffer with the base.
* e - pointer to buffer with the exponent.
* mod - pointer to buffer with the modulus.
* modlen - length of modulus.
* Returns: -1 = error
* 0 = timeout
* 1 = ok
*/
IP_PUBLIC int
ipfreescale_mod_exp(Ip_u8 *out, IP_CONST Ip_u8 *base, IP_CONST Ip_u8 *e, IP_CONST Ip_u8 *mod, Ip_u32 modlen)
{
ip_assert(out != IP_NULL && base != IP_NULL && e != IP_NULL && mod != IP_NULL);
if(out == IP_NULL || base == IP_NULL || e == IP_NULL || mod == IP_NULL)
return -1;
/* Modulus must be between 97 and 2048 bits */
if(modlen < 16 || modlen > 256)
{
IPCOM_LOG1(INFO, "ipfreescale_mod_exp() :: unsupported modulus length %d", modlen);
return -1;
}
#if defined(IPFREESCALE_SEC2) || defined(IPFREESCALE_SEC4)
return ipfreescale_sec_mod_exp(out, base, e, mod, modlen);
#endif
#ifdef IPFREESCALE_COLDFIRE
/* Coldfire SEC does not provide any public key operations */
IPCOM_LOG0(INFO, "ipfreescale_mod_exp() :: modular exponentiation is not supported in this hardware");
return -1;
#endif
}
/*
*===========================================================================
* ipfreescale_crc
*===========================================================================
* Description: Generate CRC checksum data.
* Parameters: indata - pointer to buffer for data to generate CRC from.
* length - number of valid data bytes in sequence.
* crc - pointer to where to store the CRC result
* polynomial - CRC polynomial to use
* inctx - input context data (initial crc value)
* async - Asynchronous, i.e. return immediately
* asynchandle - Handle for jobs submitted asynchronously
* options - Ored bit options to control CRC generation.
* Valid options: IPFREESCALE_OPT_NONE
* IPFREESCALE_OPT_INPUTDATA_IS_SGT
* IPFREESCALE_OPT_INPUTDATA_IS_HW_SGT
* IPFREESCALE_OPT_CRC_IEEE802
* IPFREESCALE_OPT_CRC_IETF3385
* IPFREESCALE_OPT_CRC_DIS
* IPFREESCALE_OPT_CRC_DOS
* IPFREESCALE_OPT_CRC_DOC
* Returns: -1 = error
* 0 = timeout
* 1 = ok
* 2 = kept
*/
IP_PUBLIC int ipfreescale_crc
(
IP_CONST Ip_u8 *indata,
Ip_u32 length,
Ip_u8 *crc,
Ip_u32 polynomial,
Ip_u32 inctx,
Ip_bool async,
void * asynchandle,
Ip_u32 options
)
{
ip_assert(indata != IP_NULL);
ip_assert(crc != IP_NULL);
if(length > IPFREESCALE_CRYPTO_BUFSIZE)
{
IPCOM_LOG1(ERR, "ipfreescale_chksum_crc_gen() :: Too large buffer %d", length);
return -1;
}
#ifdef IPFREESCALE_SEC4
return ipfreescale_sec_crc(polynomial, indata, length, (Ip_u8 *)&inctx, 4, crc, sizeof(Ip_u32), async, asynchandle, options);
#endif
#if defined(IPFREESCALE_COLDFIRE) || defined(IPFREESCALE_SEC2)
IPCOM_LOG0(INFO, "ipfreescale_crc() :: CRC calculation is not supported on this hardware");
return -1;
#endif
}
/*
*===========================================================================
* ipfreescale_dma
*===========================================================================
* Description: Copy data using the ipfreescale engine.
* Parameters: indata - pointer to buffer for data to copy from.
* length - number of valid data bytes in sequence.
* outdata - pointer to where to copy to
* async - Asynchronous, i.e. return immediately
* asynchandle - Handle for jobs submitted asynchronously
* options - Ored bit options to control CRC generation.
* Valid options: IPFREESCALE_OPT_NONE
* IPFREESCALE_OPT_INPUTDATA_IS_SGT
* IPFREESCALE_OPT_INPUTDATA_IS_HW_SGT
* Returns: -1 = error
* 0 = timeout
* 1 = ok
* 2 = kept
*/
IP_PUBLIC int ipfreescale_dma
(
IP_CONST Ip_u8 *indata,
Ip_u32 length,
Ip_u8 *outdata,
Ip_bool async,
void * asynchandle,
Ip_u32 options
)
{
ip_assert(indata != IP_NULL);
ip_assert(outdata != IP_NULL);
if(length > IPFREESCALE_CRYPTO_BUFSIZE)
{
IPCOM_LOG1(ERR, "ipfreescale_dma() :: Too large buffer %d", length);
return -1;
}
#ifdef IPFREESCALE_SEC4
return ipfreescale_sec_dma(indata, length, outdata, async, asynchandle, options);
#endif
#if defined(IPFREESCALE_COLDFIRE) || defined(IPFREESCALE_SEC2)
IPCOM_LOG0(INFO, "ipfreescale_dma() :: DMA data copy is not supported on this hardware");
return -1;
#endif
}
/*
*===========================================================================
* ipfreescale_version
*===========================================================================
* Description: Returns the version string of the product.
* Parameters: none.
* Returns: pointer to the version string.
*
*/
IP_PUBLIC const char *
ipfreescale_version(void)
{
return "@(#) IPFREESCALE $Name: VXWORKS_ITER40_2019102207 $ - INTERPEAK_COPYRIGHT_STRING";
}
/*
*===========================================================================
* ipfreescale_create
*===========================================================================
* Description: Product create hook. Called by IPCOM at startup.
* Parameters: none.
* Returns: IPCOM_SUCCESS = ok
* IPCOM_ERR_... = error
*
*/
IP_PUBLIC Ip_err
ipfreescale_create(void)
{
return IPCOM_SUCCESS;
}
/*
*===========================================================================
* ipfreescale_start
*===========================================================================
* Description: Product start hook. Called by IPCOM at startup.
* Parameters: none.
* Returns: IPCOM_SUCCESS = ok
* IPCOM_ERR_FAILED = error
*
*/
IP_PUBLIC Ip_err
ipfreescale_start(void)
{
Ip_err ret;
#ifdef IPFREESCALE_SEC2
const char *engine_id = "sec2";
const char *engine_name = "Freescale SEC2 hardware engine support";
#endif
#ifdef IPFREESCALE_COLDFIRE
const char *engine_id = "sec-coldfire";
const char *engine_name = "Freescale SEC Coldfire hardware engine support";
#endif
#ifdef IPFREESCALE_SEC4
const char *engine_id = "sec4";
const char *engine_name = "Freescale SEC4 hardware engine support";
#endif
Ip_bool random = IP_TRUE;
Ip_bool pubkey = IP_TRUE;
#ifdef IPFREESCALE_SEC2
ret = ipfreescale_sec_init();
if(ret != IPCOM_SUCCESS)
return ret;
if (ipfreescale_sec.core_version == 22)
{
Ip_u8 buf[16] = {0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A};
Ip_u8 key[8] = {0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6};
Ip_u8 iv[8] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
/* SEC 2.2 do not support random number generation and public key operations */
random = IP_FALSE;
pubkey = IP_FALSE;
/* Workaround for SEC2.2 device errata (SEC 13 AESU/DEU initial reset requirement)
Launch a dummy DES request before any other requests are attempted */
ipfreescale_des_cbc_cipher(buf, buf, sizeof(buf), key, iv, 1);
}
#endif
#ifdef IPFREESCALE_COLDFIRE
ret = ipfreescale_coldfire_init();
if(ret != IPCOM_SUCCESS)
return ret;
#endif
#ifdef IPFREESCALE_SEC4
ret = ipfreescale_sec_init();
if(ret != IPCOM_SUCCESS)
return ret;
#endif
/* Add an engine to iphwcrypto */
ret = iphwcrypto_engine_add(engine_id, engine_name);
if (ret != IPCOM_SUCCESS)
{
IPCOM_LOG1(ERR, "ipfreescale_create() :: iphwcrypto_engine_add() failed with error %s", ipcom_err_string(ret));
return ret;
}
#ifdef IPIPSEC2
#ifdef IPFREESCALE_USE_IPSEC_ESP_CBC_ENGINE
/* Add ipsec esp handlers */
/* NULL-MD5 */
ret = iphwcrypto_ipsec_engine_add_esp(engine_id, IPHWCRYPTO_ENGINE_ESP_NULL_MD5, ipfreescale_ipsec_esp_null_md5_input, ipfreescale_ipsec_esp_null_md5_output);
if (ret != IPCOM_SUCCESS)
{
IPCOM_LOG1(ERR, "ipfreescale_create() :: iphwcrypto_ipsec_engine_add_esp(IPHWCRYPTO_ENGINE_ESP_NULL_MD5) failed with error %s", ipcom_err_string(ret));
return ret;
}
/* NULL-SHA1 */
ret = iphwcrypto_ipsec_engine_add_esp(engine_id, IPHWCRYPTO_ENGINE_ESP_NULL_SHA1, ipfreescale_ipsec_esp_null_sha1_input, ipfreescale_ipsec_esp_null_sha1_output);
if (ret != IPCOM_SUCCESS)
{
IPCOM_LOG1(ERR, "ipfreescale_create() :: iphwcrypto_ipsec_engine_add_esp(IPHWCRYPTO_ENGINE_ESP_NULL_SHA1) failed with error %s", ipcom_err_string(ret));
return ret;
}
/* DES-CBC-NULL */
ret = iphwcrypto_ipsec_engine_add_esp(engine_id, IPHWCRYPTO_ENGINE_ESP_DES_CBC_NULL, ipfreescale_ipsec_esp_des_cbc_null_input, ipfreescale_ipsec_esp_des_cbc_null_output);
if (ret != IPCOM_SUCCESS)
{
IPCOM_LOG1(ERR, "ipfreescale_create() :: iphwcrypto_ipsec_engine_add_esp(IPHWCRYPTO_ENGINE_ESP_DES_CBC_NULL) failed with error %s", ipcom_err_string(ret));
return ret;
}
/* DES-CBC-MD5 */
ret = iphwcrypto_ipsec_engine_add_esp(engine_id, IPHWCRYPTO_ENGINE_ESP_DES_CBC_MD5, ipfreescale_ipsec_esp_des_cbc_md5_input, ipfreescale_ipsec_esp_des_cbc_md5_output);
if (ret != IPCOM_SUCCESS)
{
IPCOM_LOG1(ERR, "ipfreescale_create() :: iphwcrypto_ipsec_engine_add_esp(IPHWCRYPTO_ENGINE_ESP_DES_CBC_MD5) failed with error %s", ipcom_err_string(ret));
return ret;
}
/* DES-CBC-SHA1 */
ret = iphwcrypto_ipsec_engine_add_esp(engine_id, IPHWCRYPTO_ENGINE_ESP_DES_CBC_SHA1, ipfreescale_ipsec_esp_des_cbc_sha1_input, ipfreescale_ipsec_esp_des_cbc_sha1_output);
if (ret != IPCOM_SUCCESS)
{
IPCOM_LOG1(ERR, "ipfreescale_create() :: iphwcrypto_ipsec_engine_add_esp(IPHWCRYPTO_ENGINE_ESP_DES_CBC_SHA1) failed with error %s", ipcom_err_string(ret));
return ret;
}
/* 3DES-CBC-NULL */
ret = iphwcrypto_ipsec_engine_add_esp(engine_id, IPHWCRYPTO_ENGINE_ESP_3DES_CBC_NULL, ipfreescale_ipsec_esp_3des_cbc_null_input, ipfreescale_ipsec_esp_3des_cbc_null_output);
if (ret != IPCOM_SUCCESS)
{
IPCOM_LOG1(ERR, "ipfreescale_create() :: iphwcrypto_ipsec_engine_add_esp(IPHWCRYPTO_ENGINE_ESP_3DES_CBC_NULL) failed with error %s", ipcom_err_string(ret));
return ret;
}
/* 3DES-CBC-MD5 */
ret = iphwcrypto_ipsec_engine_add_esp(engine_id, IPHWCRYPTO_ENGINE_ESP_3DES_CBC_MD5, ipfreescale_ipsec_esp_3des_cbc_md5_input, ipfreescale_ipsec_esp_3des_cbc_md5_output);
if (ret != IPCOM_SUCCESS)
{
IPCOM_LOG1(ERR, "ipfreescale_create() :: iphwcrypto_ipsec_engine_add_esp(IPHWCRYPTO_ENGINE_ESP_3DES_CBC_MD5) failed with error %s", ipcom_err_string(ret));
return ret;
}
/* 3DES-CBC-SHA1 */
ret = iphwcrypto_ipsec_engine_add_esp(engine_id, IPHWCRYPTO_ENGINE_ESP_3DES_CBC_SHA1, ipfreescale_ipsec_esp_3des_cbc_sha1_input, ipfreescale_ipsec_esp_3des_cbc_sha1_output);
if (ret != IPCOM_SUCCESS)
{
IPCOM_LOG1(ERR, "ipfreescale_create() :: iphwcrypto_ipsec_engine_add_esp(IPHWCRYPTO_ENGINE_ESP_3DES_CBC_SHA1) failed with error %s", ipcom_err_string(ret));
return ret;
}
/* AES-CBC-NULL */
ret = iphwcrypto_ipsec_engine_add_esp(engine_id, IPHWCRYPTO_ENGINE_ESP_AES_CBC_NULL, ipfreescale_ipsec_esp_aes_cbc_null_input, ipfreescale_ipsec_esp_aes_cbc_null_output);
if (ret != IPCOM_SUCCESS)
{
IPCOM_LOG1(ERR, "ipfreescale_create() :: iphwcrypto_ipsec_engine_add_esp(IPHWCRYPTO_ENGINE_ESP_AES_CBC_NULL) failed with error %s", ipcom_err_string(ret));
return ret;
}
/* AES-CBC-MD5 */
ret = iphwcrypto_ipsec_engine_add_esp(engine_id, IPHWCRYPTO_ENGINE_ESP_AES_CBC_MD5, ipfreescale_ipsec_esp_aes_cbc_md5_input, ipfreescale_ipsec_esp_aes_cbc_md5_output);
if (ret != IPCOM_SUCCESS)
{
IPCOM_LOG1(ERR, "ipfreescale_create() :: iphwcrypto_ipsec_engine_add_esp(IPHWCRYPTO_ENGINE_ESP_AES_CBC_MD5) failed with error %s", ipcom_err_string(ret));
return ret;
}
/* AES-CBC-SHA1 */
ret = iphwcrypto_ipsec_engine_add_esp(engine_id, IPHWCRYPTO_ENGINE_ESP_AES_CBC_SHA1, ipfreescale_ipsec_esp_aes_cbc_sha1_input, ipfreescale_ipsec_esp_aes_cbc_sha1_output);
if (ret != IPCOM_SUCCESS)
{
IPCOM_LOG1(ERR, "ipfreescale_create() :: iphwcrypto_ipsec_engine_add_esp(IPHWCRYPTO_ENGINE_ESP_AES_CBC_SHA1) failed with error %s", ipcom_err_string(ret));
return ret;
}
/* Register esp handlers */
ret = iphwcrypto_ipsec_engine_register_esp(engine_id);
if (ret != IPCOM_SUCCESS)
{
IPCOM_LOG1(ERR, "ipfreescale_create() :: iphwcrypto_engine_register_esp() failed with error %s", ipcom_err_string(ret));
return ret;
}
#endif /* #ifdef IPFREESCALE_USE_IPSEC_ESP_CBC_ENGINE */
#endif /* #ifdef IPIPSEC2 */
#ifdef IPCRYPTO
#ifdef IPFREESCALE_USE_DIGEST_ENGINE
/* Add digests */
ret = iphwcrypto_engine_add_digest(engine_id,
IPHWCRYPTO_ENGINE_DIGEST_MD5, sizeof(Ipfreescale_digest_context),
ipfreescale_md5_digest_init,
ipfreescale_md5_digest_update,
ipfreescale_md5_digest_final,
ipfreescale_digest_copy,
ipfreescale_digest_cleanup, 0);
if (ret != IPCOM_SUCCESS)
{
IPCOM_LOG1(ERR, "ipfreescale_create() :: iphwcrypto_engine_add_digest(IPHWCRYPTO_ENGINE_DIGEST_MD5) failed with error %s",
ipcom_err_string(ret));
return ret;
}
ret = iphwcrypto_engine_add_digest(engine_id,
IPHWCRYPTO_ENGINE_DIGEST_SHA1, sizeof(Ipfreescale_digest_context),
ipfreescale_sha1_digest_init,
ipfreescale_sha1_digest_update,
ipfreescale_sha1_digest_final,
ipfreescale_digest_copy,
ipfreescale_digest_cleanup, 0);
if (ret != IPCOM_SUCCESS)
{
IPCOM_LOG1(ERR, "ipfreescale_create() :: iphwcrypto_engine_add_digest(IPHWCRYPTO_ENGINE_DIGEST_SHA1) failed with error %s",
ipcom_err_string(ret));
return ret;
}
/* Last one */
ret = iphwcrypto_engine_add_digest(engine_id,
IPHWCRYPTO_ENGINE_DIGEST_SHA1_DSA, sizeof(Ipfreescale_digest_context),
ipfreescale_sha1_digest_init,
ipfreescale_sha1_digest_update,
ipfreescale_sha1_digest_final,
ipfreescale_digest_copy,
ipfreescale_digest_cleanup, 1);
if (ret != IPCOM_SUCCESS)
{
IPCOM_LOG1(ERR, "ipfreescale_create() :: iphwcrypto_engine_add_digest(IPHWCRYPTO_ENGINE_DIGEST_SHA1_DSA) failed with error %s",
ipcom_err_string(ret));
return ret;
}
/* Register digests */
ret = iphwcrypto_engine_register_digests(engine_id);
if (ret != IPCOM_SUCCESS)
{
IPCOM_LOG1(ERR, "ipfreescale_create() :: iphwcrypto_engine_register_digests() failed with error %s", ipcom_err_string(ret));
return ret;
}
#endif /* #ifdef IPFREESCALE_USE_DIGEST_ENGINE */
#ifdef IPFREESCALE_USE_CIPHER_ENGINE
/* Add ciphers */
ret = iphwcrypto_engine_add_cbc_cipher(engine_id, IPHWCRYPTO_ENGINE_CIPHER_DES_CBC, ipfreescale_des_cbc_cipher, 0);
if (ret != IPCOM_SUCCESS)
{
IPCOM_LOG1(ERR, "ipfreescale_create() :: iphwcrypto_engine_add_cipher(IPHWCRYPTO_ENGINE_CIPHER_DES_CBC) failed with error %s",
ipcom_err_string(ret));
return ret;
}
ret = iphwcrypto_engine_add_ecb_cipher(engine_id, IPHWCRYPTO_ENGINE_CIPHER_DES_ECB, ipfreescale_des_ecb_cipher, 0);
if (ret != IPCOM_SUCCESS)
{
IPCOM_LOG1(ERR, "ipfreescale_create() :: iphwcrypto_engine_add_cipher(IPHWCRYPTO_ENGINE_CIPHER_DES_ECB) failed with error %s",
ipcom_err_string(ret));
return ret;
}
ret = iphwcrypto_engine_add_cbc_cipher(engine_id, IPHWCRYPTO_ENGINE_CIPHER_3DES_CBC, ipfreescale_3des_cbc_cipher, 0);
if (ret != IPCOM_SUCCESS)
{
IPCOM_LOG1(ERR, "ipfreescale_create() :: iphwcrypto_engine_add_cipher(IPHWCRYPTO_ENGINE_CIPHER_3DES_CBC) failed with error %s",
ipcom_err_string(ret));
return ret;
}
ret = iphwcrypto_engine_add_ecb_cipher(engine_id, IPHWCRYPTO_ENGINE_CIPHER_3DES_ECB, ipfreescale_3des_ecb_cipher, 0);
if (ret != IPCOM_SUCCESS)
{
IPCOM_LOG1(ERR, "ipfreescale_create() :: iphwcrypto_engine_add_cipher(IPHWCRYPTO_ENGINE_CIPHER_3DES_ECB) failed with error %s",
ipcom_err_string(ret));
return ret;
}
ret = iphwcrypto_engine_add_cbc_cipher(engine_id, IPHWCRYPTO_ENGINE_CIPHER_AES128_CBC, ipfreescale_aes128_cbc_cipher, 0);
if (ret != IPCOM_SUCCESS)
{
IPCOM_LOG1(ERR, "ipfreescale_create() :: iphwcrypto_engine_add_cipher(IPHWCRYPTO_ENGINE_CIPHER_AES128_CBC) failed with error %s",
ipcom_err_string(ret));
return ret;
}
ret = iphwcrypto_engine_add_ecb_cipher(engine_id, IPHWCRYPTO_ENGINE_CIPHER_AES128_ECB, ipfreescale_aes128_ecb_cipher, 0);
if (ret != IPCOM_SUCCESS)
{
IPCOM_LOG1(ERR, "ipfreescale_create() :: iphwcrypto_engine_add_cipher(IPHWCRYPTO_ENGINE_CIPHER_AES128_ECB) failed with error %s",
ipcom_err_string(ret));
return ret;
}
ret = iphwcrypto_engine_add_cbc_cipher(engine_id, IPHWCRYPTO_ENGINE_CIPHER_AES192_CBC, ipfreescale_aes192_cbc_cipher, 0);
if (ret != IPCOM_SUCCESS)
{
IPCOM_LOG1(ERR, "ipfreescale_create() :: iphwcrypto_engine_add_cipher(IPHWCRYPTO_ENGINE_CIPHER_AES192_CBC) failed with error %s",
ipcom_err_string(ret));
return ret;
}
ret = iphwcrypto_engine_add_ecb_cipher(engine_id, IPHWCRYPTO_ENGINE_CIPHER_AES192_ECB, ipfreescale_aes192_ecb_cipher, 0);
if (ret != IPCOM_SUCCESS)
{
IPCOM_LOG1(ERR, "ipfreescale_create() :: iphwcrypto_engine_add_cipher(IPHWCRYPTO_ENGINE_CIPHER_AES192_ECB) failed with error %s",
ipcom_err_string(ret));
return ret;
}
ret = iphwcrypto_engine_add_cbc_cipher(engine_id, IPHWCRYPTO_ENGINE_CIPHER_AES256_CBC, ipfreescale_aes256_cbc_cipher, 1);
if (ret != IPCOM_SUCCESS)
{
IPCOM_LOG1(ERR, "ipfreescale_create() :: iphwcrypto_engine_add_cipher(IPHWCRYPTO_ENGINE_CIPHER_AES256_CBC) failed with error %s",
ipcom_err_string(ret));
return ret;
}
/* Last one */
ret = iphwcrypto_engine_add_ecb_cipher(engine_id, IPHWCRYPTO_ENGINE_CIPHER_AES256_ECB, ipfreescale_aes256_ecb_cipher, 1);
if (ret != IPCOM_SUCCESS)
{
IPCOM_LOG1(ERR, "ipfreescale_create() :: iphwcrypto_engine_add_cipher(IPHWCRYPTO_ENGINE_CIPHER_AES256_ECB) failed with error %s",
ipcom_err_string(ret));
return ret;
}
/* Register ciphers */
ret = iphwcrypto_engine_register_ciphers(engine_id);
if (ret != IPCOM_SUCCESS)
{
IPCOM_LOG1(ERR, "ipfreescale_create() :: iphwcrypto_engine_register_ciphers() failed with error %s", ipcom_err_string(ret));
return ret;
}
#endif /* #ifdef IPFREESCALE_USE_CIPHER_ENGINE */
#ifdef IPFREESCALE_USE_RANDOM_ENGINE
if (random == IP_TRUE)
{
/* Add random method */
ret = iphwcrypto_engine_add_random(engine_id, ipfreescale_random_gen);
if (ret != IPCOM_SUCCESS)
{
IPCOM_LOG1(ERR, "ipfreescale_create() :: iphwcrypto_engine_add_random() failed with error %s", ipcom_err_string(ret));
return ret;
}
/* Register random method */
ret = iphwcrypto_engine_register_random(engine_id);
if (ret != IPCOM_SUCCESS)
{
IPCOM_LOG1(ERR, "ipfreescale_create() :: iphwcrypto_engine_register_random() failed with error %s", ipcom_err_string(ret));
return ret;
}
}
#endif /* #ifdef IPFREESCALE_USE_RANDOM_ENGINE */
#ifdef IPFREESCALE_USE_DH_ENGINE
if (pubkey == IP_TRUE)
{
/* Add dh method */
ret = iphwcrypto_engine_add_dh(engine_id, ipfreescale_mod_exp);
if (ret != IPCOM_SUCCESS)
{
IPCOM_LOG1(ERR, "ipfreescale_create() :: iphwcrypto_engine_add_dh() failed with error %s", ipcom_err_string(ret));
return ret;
}
/* Register dh method */
ret = iphwcrypto_engine_register_dh(engine_id);
if (ret != IPCOM_SUCCESS)
{
IPCOM_LOG1(ERR, "ipfreescale_create() :: iphwcrypto_engine_register_dh() failed with error %s", ipcom_err_string(ret));
return ret;
}
}
#endif /* #ifdef IPFREESCALE_USE_DH_ENGINE */
#ifdef IPFREESCALE_USE_RSA_ENGINE
if (pubkey == IP_TRUE)
{
/* Add rsa method */
ret = iphwcrypto_engine_add_rsa(engine_id, ipfreescale_mod_exp);
if (ret != IPCOM_SUCCESS)
{
IPCOM_LOG1(ERR, "ipfreescale_create() :: iphwcrypto_engine_add_rsa() failed with error %s", ipcom_err_string(ret));
return ret;
}
/* Register rsa method */
ret = iphwcrypto_engine_register_rsa(engine_id);
if (ret != IPCOM_SUCCESS)
{
IPCOM_LOG1(ERR, "ipfreescale_create() :: iphwcrypto_engine_register_rsa() failed with error %s", ipcom_err_string(ret));
return ret;
}
}
#endif /* #ifdef IPFREESCALE_USE_RSA_ENGINE */
#ifdef IPFREESCALE_USE_DSA_ENGINE
if (pubkey == IP_TRUE)
{
/* Add dsa method */
ret = iphwcrypto_engine_add_dsa(engine_id, ipfreescale_mod_exp);
if (ret != IPCOM_SUCCESS)
{
IPCOM_LOG1(ERR, "ipfreescale_create() :: iphwcrypto_engine_add_dsa() failed with error %s", ipcom_err_string(ret));
return ret;
}
/* Register dsa method */
ret = iphwcrypto_engine_register_dsa(engine_id);
if (ret != IPCOM_SUCCESS)
{
IPCOM_LOG1(ERR, "ipfreescale_create() :: iphwcrypto_engine_register_dsa() failed with error %s", ipcom_err_string(ret));
return ret;
}
}
#endif /* #ifdef IPFREESCALE_USE_DSA_ENGINE */
#endif /* #ifdef IPCRYPTO */
return ret;
}
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/