original files of m241
This commit is contained in:
@@ -0,0 +1,465 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK SOURCE FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipcrypto.c,v $ $Revision: 1.26 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipcrypto/src/ipcrypto.c,v $
|
||||
* $Author: rboden $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Roger Boden <roger@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#ifdef IPCOM_DMALLOC_C
|
||||
#undef IPCOM_DMALLOC_C
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#define IPCOM_USE_CLIB_PROTO
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_clib.h>
|
||||
#include <ipcom_err.h>
|
||||
#include <ipcom_syslog.h>
|
||||
#include <ipcom_autoconf.h>
|
||||
|
||||
#include <e_os.h>
|
||||
#include <ipcrypto_config.h>
|
||||
#include "ipcrypto_h.h"
|
||||
|
||||
#include "openssl/crypto.h"
|
||||
#include "openssl/err.h"
|
||||
#include "openssl/rand.h"
|
||||
#include "openssl/bio.h"
|
||||
#include "openssl/conf.h"
|
||||
#include "openssl/evp.h"
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
#include "openssl/engine.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#ifdef OPENSSL_FIPS
|
||||
unsigned int FIPS_incore_fingerprint(unsigned char *sig,unsigned int len);
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
IP_PUBLIC const char *ipcrypto_version(void);
|
||||
|
||||
IP_STATIC void ipcrypto_lock_callback(int mode, int type, const char* file, int line);
|
||||
|
||||
IPCOM_PROCESS(ipcrypto_rnd_seed);
|
||||
|
||||
IP_GLOBAL int ipcrypto_cmd_memory(int argc, char **argv);
|
||||
|
||||
IP_PUBLIC void ipcrypto_cmds_startup(void);
|
||||
|
||||
IP_PUBLIC Ip_err ipcrypto_create(void);
|
||||
|
||||
IP_PUBLIC Ip_err ipcrypto_start(void);
|
||||
|
||||
void OPENSSL_init(void);
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
CONF *ipcrypto_config = IP_NULL;
|
||||
#ifndef IP_PORT_LAS
|
||||
BIO *bio_err = IP_NULL;
|
||||
#endif
|
||||
char *default_config_file = IPCRYPTO_DEFAULT_CONFIG_FILE;
|
||||
Ipcrypto_data ipcrypto;
|
||||
|
||||
int in_FIPS_mode=0;
|
||||
|
||||
#ifdef OPENSSL_FIPS
|
||||
extern unsigned char FIPS_signature[20];
|
||||
extern unsigned char ipcrypto_fips_signature[20];
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 LOCAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipcrypto_setup_lock_functions
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipcrypto_setup_lock_functions(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
ipcrypto.crypto_locks = ipcom_malloc(sizeof(Ipcom_mutex)*CRYPTO_NUM_LOCKS);
|
||||
if(!ipcrypto.crypto_locks)
|
||||
return IPCOM_ERR_FAILED;
|
||||
|
||||
for(i=0; i<CRYPTO_NUM_LOCKS; i++)
|
||||
{
|
||||
if(ipcom_mutex_create(&(ipcrypto.crypto_locks[i])) != IPCOM_SUCCESS)
|
||||
{
|
||||
while(i>0)
|
||||
{
|
||||
ipcom_mutex_delete(&(ipcrypto.crypto_locks[i]));
|
||||
i--;
|
||||
}
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
CRYPTO_set_locking_callback(ipcrypto_lock_callback);
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipcrypto_lock_callback
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC void
|
||||
ipcrypto_lock_callback(int mode, int type, const char *file, int line)
|
||||
{
|
||||
(void)file;
|
||||
(void)line;
|
||||
|
||||
ip_assert(type < CRYPTO_NUM_LOCKS);
|
||||
ip_assert((mode & CRYPTO_LOCK) || (mode & CRYPTO_UNLOCK));
|
||||
|
||||
if(type >= CRYPTO_NUM_LOCKS)
|
||||
return;
|
||||
|
||||
if(mode & CRYPTO_UNLOCK)
|
||||
{
|
||||
ipcom_mutex_unlock(ipcrypto.crypto_locks[type]);
|
||||
}
|
||||
|
||||
if(mode & CRYPTO_LOCK)
|
||||
{
|
||||
ipcom_mutex_lock(ipcrypto.crypto_locks[type]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipcrypto_rnd_seed
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IPCOM_PROCESS(ipcrypto_rnd_seed)
|
||||
{
|
||||
Ip_u32 i, tmp;
|
||||
|
||||
ipcom_proc_init();
|
||||
|
||||
while(ipcom_random_seed_state() != 100)
|
||||
{
|
||||
tmp = ipcom_random();
|
||||
RAND_seed((char *) &tmp, 4);
|
||||
ipcom_sleep(1); /* Wait for some entryphy to be gathered */
|
||||
}
|
||||
|
||||
for(i=0; i<5; i++)
|
||||
{
|
||||
tmp = ipcom_random();
|
||||
RAND_seed((char*) &tmp, 4);
|
||||
}
|
||||
|
||||
ipcom_proc_exit();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipcrypto_cmd_memory
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
#ifdef IPCRYPTO_USE_TEST
|
||||
IP_GLOBAL int
|
||||
ipcrypto_cmd_memory(int argc, char **argv)
|
||||
{
|
||||
#ifdef CRYPTO_MDEBUG
|
||||
BIO *bio_out;
|
||||
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
MemCheck_off();
|
||||
bio_out = BIO_new_fp(ip_stdout, BIO_NOCLOSE);
|
||||
MemCheck_on();
|
||||
|
||||
CRYPTO_mem_leaks(bio_out);
|
||||
(void)BIO_flush(bio_out);
|
||||
|
||||
BIO_free(bio_out);
|
||||
#else
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#endif /* IPCRYPTO_USE_TEST */
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipcrypto_dmalloc
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
#ifdef IPCOM_USE_DMALLOC
|
||||
IP_STATIC void *
|
||||
ipcrypto_dmalloc(Ip_size_t num, const char *file, int line)
|
||||
{
|
||||
return ipcom_dmalloc(num, file, IP_NULL, line);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipcrypto_drealloc
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC void *
|
||||
ipcrypto_drealloc(void *old_ptr, Ip_size_t num, const char *file, int line)
|
||||
{
|
||||
return ipcom_drealloc(old_ptr, num, file, IP_NULL, line);
|
||||
}
|
||||
#endif /* IPCOM_USE_DMALLOC */
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 PUBLIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipcrypto_cmds_startup
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC void
|
||||
ipcrypto_cmds_startup(void)
|
||||
{
|
||||
#ifndef IP_PORT_LAS
|
||||
/* Free&clear global variable bio_err for new logins. */
|
||||
if (bio_err != IP_NULL)
|
||||
{
|
||||
BIO_free(bio_err);
|
||||
bio_err = IP_NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipcrypto_create
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ip_err
|
||||
ipcrypto_create(void)
|
||||
{
|
||||
static int init = 0;
|
||||
char uninitialized_buf[32];
|
||||
|
||||
if(init == 0)
|
||||
{
|
||||
int ret;
|
||||
init = 1;
|
||||
|
||||
/* Set memory allocation function callbacks. */
|
||||
#ifdef IPCOM_USE_DMALLOC
|
||||
ret = CRYPTO_set_mem_ex_functions(ipcrypto_dmalloc, ipcrypto_drealloc, ipcom_dfree);
|
||||
#else
|
||||
ret = CRYPTO_set_mem_functions(ipcom_malloc, ipcom_realloc, ipcom_free);
|
||||
#endif
|
||||
(void) ret;
|
||||
ip_assert(ret);
|
||||
|
||||
if(ipcrypto_setup_lock_functions() != IPCOM_SUCCESS)
|
||||
return IPCOM_ERR_FAILED;
|
||||
|
||||
OpenSSL_add_all_algorithms();
|
||||
|
||||
/* Init things so we will get meaningful error messages rather than numbers. */
|
||||
ERR_load_crypto_strings();
|
||||
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
ENGINE_load_builtin_engines();
|
||||
#endif
|
||||
|
||||
/* Dummy seed to make RAND functions operational */
|
||||
#ifdef IPVALGRIND
|
||||
ipcom_memset(uninitialized_buf, 0, sizeof(uninitialized_buf));
|
||||
#endif
|
||||
RAND_seed((char *) uninitialized_buf, sizeof(uninitialized_buf));
|
||||
|
||||
#ifdef OPENSSL_FIPS
|
||||
{
|
||||
unsigned int i;
|
||||
Ip_bool enable_fips = IP_FALSE;
|
||||
#if defined(IP_DEBUG) || defined(IPTESTENGINE)
|
||||
int len;
|
||||
|
||||
len=FIPS_incore_fingerprint(ipcrypto_fips_signature, sizeof(ipcrypto_fips_signature));
|
||||
if (len!=sizeof(ipcrypto_fips_signature))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "FIPS_incore_fingerprint() failed");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
#endif
|
||||
for (i=0; i<sizeof(ipcrypto_fips_signature); i++)
|
||||
{
|
||||
if (ipcrypto_fips_signature[i] != 0xEE)
|
||||
{
|
||||
enable_fips = IP_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (enable_fips)
|
||||
{
|
||||
ipcom_memcpy(FIPS_signature, ipcrypto_fips_signature, sizeof(FIPS_signature));
|
||||
FIPS_mode_set(1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipcrypto_start
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_PUBLIC Ip_err
|
||||
ipcrypto_start(void)
|
||||
{
|
||||
Ipcom_proc_attr proc_attr;
|
||||
|
||||
ipcom_proc_attr_init(&proc_attr);
|
||||
proc_attr.stacksize = IPCOM_PROC_STACK_SMALL;
|
||||
proc_attr.flags = IPCOM_PROC_FLAG_FP;
|
||||
(void)ipcom_proc_acreate("ipcrypto_rnd_seed", ipcrypto_rnd_seed, &proc_attr, IP_NULL);
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipcrypto_version
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC const char *
|
||||
ipcrypto_version(void)
|
||||
{
|
||||
#ifdef OPENSSL_FIPS
|
||||
return "@(#) IPCRYPTO FIPS 140-2 $Name: VXWORKS_ITER40_2019102207 $ - INTERPEAK_COPYRIGHT_STRING";
|
||||
#else
|
||||
return "@(#) IPCRYPTO $Name: VXWORKS_ITER40_2019102207 $ - INTERPEAK_COPYRIGHT_STRING";
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
OPENSSL_init(void)
|
||||
{
|
||||
/* Dummy function to make the linker happy */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,390 @@
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
This file implements AES-CMAC as per RFC4493 and AES-CMAC-PRF-128 (RFC 4615)
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#define INCLUDE_AES_CMAC_TESTS
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include <ipcom_type.h>
|
||||
#include <openssl/aes.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <ipcom_syslog.h>
|
||||
#include <ipcrypto.h>
|
||||
#include "ipcrypto_h.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#ifdef __GNUC__
|
||||
#ifndef alloca
|
||||
#define alloca __builtin_alloca
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define _XOR_BLOCK(out, in1, in2) {int i;for( i = 0; i < AES_BLOCKSIZE; i++ ) out[i] = in1[i] ^ in2[i];}
|
||||
#define CMAC_SHIFT_LEFT(in, out) {int n; Ip_u8 oflow = 0; for(n=15;n>=0;n--) { \
|
||||
out[n] = in[n] << 1; out[n] |= oflow; \
|
||||
oflow = (in[n] & 0x80) ? 1 : 0; }}
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 LOCAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* aesCmacGenerateSubKeys
|
||||
*===========================================================================
|
||||
* Description: Generates the two CMAC subkeys given an AES 128 bit key
|
||||
* Parameters: cmacCtx - pointer to AES_CMAC_CTX. k1 and k2 and aesKey are returned via this pointer
|
||||
* key - pointer to the key buffer
|
||||
* keyLengthBits - length of the key in bits
|
||||
* Modify
|
||||
* < cmacCtx->k1 > - K1 (128-bit first subkey)
|
||||
* < cmacCtx->k2 > - K2 (128-bit first subkey)
|
||||
*
|
||||
* Constants: const_Zero is 0x00000000000000000000000000000000
|
||||
* const_Rb is 0x00000000000000000000000000000087
|
||||
*
|
||||
* Variables: L for output of AES-128 applied to 0^128
|
||||
*
|
||||
* Step 1. L <- AES-128(K, const_Zero);
|
||||
* Step 2. if MSB(L) is equal to 0
|
||||
* K1 <- L << 1;
|
||||
* else
|
||||
* K1 <- (L << 1) XOR const_Rb;
|
||||
* Step 3. if MSB(K1) is equal to 0
|
||||
* K2 <- K1 << 1;
|
||||
* else
|
||||
* K2 <- (K1 << 1) XOR const_Rb;
|
||||
* Step 4. return K1, K2;
|
||||
*
|
||||
* Returns: 1 if success
|
||||
* -1 if failure
|
||||
*
|
||||
*/
|
||||
static int aesCmacGenerateSubKeys(AES_CMAC_CTX *cmacCtx,Ip_u8 *key, unsigned int keyLengthBits){
|
||||
|
||||
Ip_u8 L[16],
|
||||
Z[16],
|
||||
IV[16],
|
||||
tmp[16],
|
||||
const_Rb[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87 };
|
||||
|
||||
ipcom_memset( Z, 0, 16 );
|
||||
ipcom_memset( L, 0, 16 );
|
||||
ipcom_memset( IV, 0, 16 );
|
||||
ipcom_memset( cmacCtx->k1, 0, 16 );
|
||||
ipcom_memset( cmacCtx->k2, 0, 16 );
|
||||
ipcom_memset( cmacCtx->IV, 0, AES_BLOCKSIZE );
|
||||
|
||||
|
||||
if ( -1 == AES_set_encrypt_key(key, keyLengthBits, &cmacCtx->aesKey)) {
|
||||
IPCOM_LOG0(ERR,"AES_set_encrypt_key failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
AES_ecb_encrypt(Z, L,&cmacCtx->aesKey, AES_ENCRYPT);
|
||||
|
||||
if ( ( L[0] & 0x80 ) == 0 ) { /* If MSB(L) == 0, K1 = L << 1 */
|
||||
CMAC_SHIFT_LEFT( L, cmacCtx->k1 );
|
||||
} else { /* if MSB(L) != 0, K1 = ( L << 1 ) (+) Rb */
|
||||
CMAC_SHIFT_LEFT( L, tmp );
|
||||
_XOR_BLOCK( cmacCtx->k1, tmp, const_Rb );
|
||||
}
|
||||
if ( ( cmacCtx->k1[0] & 0x80 ) == 0 ) {
|
||||
CMAC_SHIFT_LEFT( cmacCtx->k1, cmacCtx->k2 );
|
||||
} else {
|
||||
CMAC_SHIFT_LEFT( cmacCtx->k1, tmp );
|
||||
_XOR_BLOCK( cmacCtx->k2, tmp, const_Rb );
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 PUBLIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
/*
|
||||
*===========================================================================
|
||||
* aesCmacPrf128
|
||||
*===========================================================================
|
||||
* Description: Implements RFC 4615 for IKEv2
|
||||
* Parameters: key - buffer pointing to the variable length key
|
||||
* keyLength - length of key
|
||||
* input - pointer to buffer with input message
|
||||
* inputLength - length of input buffer
|
||||
* output - pointer to buffer to copy the output to
|
||||
* outputLength - pointer to length of output buffer. On input, *outputMacLength must be at least AES_BLOCKSIZE.
|
||||
* - on output the length is updated to the actual length of data copied to the output buffer
|
||||
* Returns: 1 if success
|
||||
* -1 if any error
|
||||
*
|
||||
*/
|
||||
IP_EXTERN int aesCmacPrf128(Ip_u8 *key, int keyLength, Ip_u8 *input, int inputLength, Ip_u8 *output, int *outputLength)
|
||||
{
|
||||
Ip_u8 fixedKey[AES_BLOCKSIZE];
|
||||
Ip_u8 zerosKey[AES_BLOCKSIZE];
|
||||
int fixedKeyLength = AES_BLOCKSIZE;
|
||||
|
||||
if (keyLength != 16)
|
||||
{
|
||||
ipcom_memset(zerosKey,0,AES_BLOCKSIZE);
|
||||
aesCmacBlock(NULL,zerosKey,AES_BLOCKSIZE, key,keyLength, fixedKey,&fixedKeyLength); /* use CMAC to reduce key to 128 bits */
|
||||
key = fixedKey;
|
||||
keyLength = fixedKeyLength;
|
||||
}
|
||||
return aesCmacBlock(NULL,key,keyLength, input,inputLength,output,outputLength);
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* aesCmacBlock
|
||||
*===========================================================================
|
||||
* Description: Calculates AES-CMAC on a complete input buffer
|
||||
* Parameters: cmacCTx - if NULL - no subkeys are returned
|
||||
* - if !NULL and key != NULL, then the subkeys are calculated and returned in cmacCtx
|
||||
* - if !NULL and key==NULL, then the subkeys from cmacCtx are used (saving a recalculation)
|
||||
* key - buffer pointing to the variable length key
|
||||
* keyLength - length of key
|
||||
* input - pointer to buffer with input message
|
||||
* inputLength - length of input buffer
|
||||
* output - pointer to buffer to copy the output to
|
||||
* outputMacLength - pointer to length of output buffer. On input, *outputMacLength must be at least AES_BLOCKSIZE.
|
||||
* - on output the length is updated to the actual length of data copied to the output buffer
|
||||
* Returns: 1 if success
|
||||
* -1 if any error
|
||||
*
|
||||
*/
|
||||
IP_EXTERN int aesCmacBlock( AES_CMAC_CTX *cmacCtx,Ip_u8 *key,int keyLength, Ip_u8 *input,int inputLength, Ip_u8 *outputMac,int *outputMacLength)
|
||||
{
|
||||
if (cmacCtx == NULL)
|
||||
{
|
||||
cmacCtx = alloca(sizeof(AES_CMAC_CTX));
|
||||
}
|
||||
if (-1 == aesCmacInit(cmacCtx, key, keyLength))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return aesCmacFinal(cmacCtx,input,inputLength,outputMac,outputMacLength);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* aesCmacInit
|
||||
*===========================================================================
|
||||
* Description: Initialize a AES_CMAC_CTX.
|
||||
* Parameters: cmacCtx - pointer to AES_CMAC_CTX to be updated
|
||||
* key - pointer to key buffer. If key == NULL, then the AES_CMAC_CTX subkeys are reused.
|
||||
* keyLength - length of key (bytes)
|
||||
* Returns: 1 on success
|
||||
* -1 on error
|
||||
*
|
||||
*/
|
||||
IP_EXTERN int aesCmacInit( AES_CMAC_CTX *cmacCtx, Ip_u8 *key, int keyLength )
|
||||
{
|
||||
|
||||
/* validate that we either have a key, or a context */
|
||||
AES_CMAC_CTX *pCmacCtx = cmacCtx;
|
||||
Ip_u8 *pKey = key;
|
||||
|
||||
if ( NULL == pCmacCtx && NULL == key)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (NULL == pCmacCtx)
|
||||
{
|
||||
IPCOM_LOG0(ERR,"aesCmacInit fails, no AES_CMAC_CTX");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (NULL != key)
|
||||
{
|
||||
aesCmacGenerateSubKeys(pCmacCtx,pKey, keyLength <<3);
|
||||
|
||||
}
|
||||
|
||||
/* setup the rest of context */
|
||||
|
||||
pCmacCtx->ivLength = AES_BLOCKSIZE;
|
||||
ipcom_memset(pCmacCtx->IV,0,AES_BLOCKSIZE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* aesCmacUpdate
|
||||
*===========================================================================
|
||||
* Description: Add more data to the CMAC. Can be called repeatedly with chunks of the message to be authenticated
|
||||
* Parameters: cmacCTx - pointer to AES_CMAC_CTX that has been initialized via aesCmacInit
|
||||
* key - buffer pointint to the variable length key
|
||||
* keyLength - length of key
|
||||
* input - pointer to buffer with input message
|
||||
* inputLength - length of input buffer. Must be a multiple of AES_BLOCKSIZE
|
||||
* Returns:
|
||||
*
|
||||
*
|
||||
*/
|
||||
IP_EXTERN int aesCmacUpdate(AES_CMAC_CTX *cmacCtx, Ip_u8 * input, Ip_u8 inputLength )
|
||||
{
|
||||
/* inputLength must be multiple of the blocksize */
|
||||
Ip_u8 *out = alloca(sizeof(Ip_u8 ) * inputLength);
|
||||
|
||||
if (inputLength % AES_BLOCKSIZE==0)
|
||||
{
|
||||
AES_cbc_encrypt(input, out, inputLength, &cmacCtx->aesKey,cmacCtx->IV, AES_ENCRYPT);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
IPCOM_LOG0(ERR,"aesCmacUpdate, inputLength is not a multiple of the blocksize");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* aesCmacFinal
|
||||
*===========================================================================
|
||||
* Description: Calculates AES-CMAC on a complete input buffer
|
||||
* Parameters: cmacCtx - pointer to AES_CMAC_CTX that has been initialized via aesCmacInit
|
||||
* input - pointer to buffer with input message
|
||||
* inputLength - length of input buffer
|
||||
* pMac - pointer to buffer to copy the output MAC to
|
||||
* poutputMacLength - pointer to length of output buffer. On input, *outputMacLength must be at least AES_BLOCKSIZE.
|
||||
* - on output the length is updated to the actual length of data copied to the output buffer
|
||||
* Returns: 1 if success
|
||||
* -1 if any error
|
||||
*/
|
||||
IP_EXTERN int aesCmacFinal(AES_CMAC_CTX *cmacCtx, Ip_u8 *input, int inputLength,Ip_u8 *pMac,
|
||||
int *pOutputMacLength)
|
||||
{
|
||||
Ip_u8 mlast[AES_BLOCKSIZE], Y[AES_BLOCKSIZE], IV[AES_BLOCKSIZE], *pMn;
|
||||
int mlastLength,updateLength;
|
||||
|
||||
|
||||
if (*pOutputMacLength < AES_BLOCKSIZE)
|
||||
{
|
||||
IPCOM_LOG0(ERR,"aesCmacFinal fails pMac buffer too small");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (inputLength)
|
||||
{
|
||||
mlastLength = inputLength % AES_BLOCKSIZE;
|
||||
if (mlastLength == 0)
|
||||
{
|
||||
mlastLength = AES_BLOCKSIZE;
|
||||
}
|
||||
updateLength = inputLength - mlastLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* a zero length message is a valid concept */
|
||||
mlastLength = 0;
|
||||
updateLength = 0;
|
||||
}
|
||||
pMn = &input[updateLength];
|
||||
|
||||
/*
|
||||
** ---- process all but the last block
|
||||
*/
|
||||
if (updateLength)
|
||||
{
|
||||
aesCmacUpdate(cmacCtx, input, updateLength );
|
||||
}
|
||||
|
||||
/*
|
||||
** ---- create M_last (using k1 or k2).
|
||||
*/
|
||||
if ( mlastLength == AES_BLOCKSIZE )
|
||||
{
|
||||
_XOR_BLOCK( mlast, cmacCtx->k1, pMn ); /* full block - M_last <- K1 XOR M_n; */
|
||||
}
|
||||
else
|
||||
{
|
||||
ipcom_memset(Y, 0, AES_BLOCKSIZE); /* part block - M_last <- padding(M_n) XOR K2 */
|
||||
ipcom_memcpy(Y, pMn, mlastLength);
|
||||
Y[mlastLength] |= 0x80;
|
||||
_XOR_BLOCK( mlast, cmacCtx->k2, Y );
|
||||
}
|
||||
|
||||
/*
|
||||
** ---- process M_last to get the MAC into the output buffer
|
||||
*/
|
||||
|
||||
ipcom_memset (IV, 0, sizeof (IV));
|
||||
_XOR_BLOCK( Y, mlast, cmacCtx->IV ); /* Y <- M_last XOR X out,in,in */
|
||||
AES_ecb_encrypt(Y,pMac, &cmacCtx->aesKey,AES_ENCRYPT);
|
||||
*pOutputMacLength = AES_BLOCKSIZE;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
@@ -0,0 +1,376 @@
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
This file implements AES-KEYWRAP as per RFC 3394
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <openssl/aes.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ipcom_syslog.h>
|
||||
#include <ipcrypto.h>
|
||||
#include "ipcrypto_h.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#define AES_CHECK_KEYLEN(len) ((len==AES_KEY_128_BYTES)||(len==AES_KEY_192_BYTES)||(len==AES_KEY_256_BYTES))
|
||||
|
||||
#define AESKW_WRAP_MIN_BLOCK 2
|
||||
#define AESKW_UNWRAP_MIN_BLOCK (AESKW_WRAP_MIN_BLOCK+1)
|
||||
#define AESKW_XOR_BLOCK(out, in1, in2) {int ijk;for( ijk = 0; ijk < AESKW_BLOCKSIZE; ijk++ ) out[ijk] = in1[ijk] ^ in2[ijk];}
|
||||
#define AESKW_CVT(b,n) {ipcom_memset(b,0,AESKW_BLOCKSIZE);b[AESKW_BLOCKSIZE-1] = ((n)&0xFF);b[AESKW_BLOCKSIZE-2] = (((n)&0xFF00)>>8);\
|
||||
b[AESKW_BLOCKSIZE-3] = (((n)&0xFF0000)>>16);b[AESKW_BLOCKSIZE-4] = (((n)&0xFF000000)>>24);}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 LOCAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 PUBLIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* aeskw_wrap
|
||||
*===========================================================================
|
||||
* Description: Encrypt (wrap) a key using AES-KEYWRAP
|
||||
* Parameters: key - pointer to key buffer
|
||||
* keyLength - length of key, must be 128 bit, 192 bit or 256 bit (in bytes)
|
||||
* iv - pointer to IV.
|
||||
* ivLength - length of IV. Must be AESKW_BLOCKSIZE
|
||||
* plainText - pointer to buffer to encrypt (wrap)
|
||||
* plainTextLength - length of buffer to encrypt. Must be multiple of AESKW_BLOCKSIZE
|
||||
* cipherText - pointer to buffer in which to copy output
|
||||
* cipherTextLength - pointer to the length of the cipherText buffer. On output,
|
||||
* this is updated to the length of data copied into the cipherText buffer
|
||||
* Returns: -1 if failure
|
||||
*
|
||||
*/
|
||||
IP_EXTERN int aeskw_wrap(Ip_u8 *key, int keyLength,
|
||||
Ip_u8 *iv, int ivLength,
|
||||
Ip_u8 *plainText, int plainTextLength,
|
||||
Ip_u8 *cipherText, int *cipherTextLength )
|
||||
{
|
||||
int status = 1;
|
||||
AES_KEY aesKey;
|
||||
|
||||
/*
|
||||
** --- Check for proper key length
|
||||
*/
|
||||
if (AES_CHECK_KEYLEN(keyLength))
|
||||
{
|
||||
/*
|
||||
** --- Check for proper IV length
|
||||
*/
|
||||
if (ivLength == AESKW_BLOCKSIZE)
|
||||
{
|
||||
/*
|
||||
** --- Make sure the input is aligned to 64-bit boundaries
|
||||
*/
|
||||
if ( !(plainTextLength % AESKW_BLOCKSIZE) )
|
||||
{
|
||||
|
||||
/*
|
||||
** --- Make sure the output buffer is at least
|
||||
** one block (64-bits) larger than the input.
|
||||
*/
|
||||
if (*cipherTextLength >= (plainTextLength+AESKW_BLOCKSIZE))
|
||||
{
|
||||
int numBlocks = plainTextLength/AESKW_BLOCKSIZE;
|
||||
Ip_u8 *R;
|
||||
Ip_u8 A[AESKW_BLOCKSIZE];
|
||||
Ip_u8 B[AES_BLOCKSIZE];
|
||||
Ip_u8 T[AESKW_BLOCKSIZE];
|
||||
int i,j;
|
||||
|
||||
if (numBlocks >= AESKW_WRAP_MIN_BLOCK)
|
||||
{
|
||||
/*
|
||||
** --- Set output buffer size
|
||||
*/
|
||||
*cipherTextLength = plainTextLength+AESKW_BLOCKSIZE;
|
||||
|
||||
/*
|
||||
** --- Initialize variables
|
||||
**
|
||||
** Set A = IV, an initial value (see 2.2.3)
|
||||
** For i = 1 to n
|
||||
** R[i] = P[i]
|
||||
*/
|
||||
ipcom_memcpy(A, iv, AESKW_BLOCKSIZE);
|
||||
R = cipherText + AESKW_BLOCKSIZE;
|
||||
ipcom_memcpy( R, plainText, plainTextLength );
|
||||
|
||||
if ( -1 == AES_set_encrypt_key(key, keyLength << 3,&aesKey)) {
|
||||
IPCOM_LOG0(ERR,"AES_set_encrypt_key failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
for ( j = 0; j < 6; j++ )
|
||||
{
|
||||
for ( i = 0; i < numBlocks; i++ )
|
||||
{
|
||||
/*
|
||||
** --- Do: B = AES(K, A | R[i])
|
||||
** --- Do: R[i] = LSB(64, B)
|
||||
*/
|
||||
ipcom_memcpy( B + AESKW_BLOCKSIZE, R + (i * AESKW_BLOCKSIZE), AESKW_BLOCKSIZE);
|
||||
ipcom_memcpy( B, A, AESKW_BLOCKSIZE);
|
||||
|
||||
AES_ecb_encrypt(B,B, &aesKey,AES_ENCRYPT);
|
||||
/* ccip_aes_encrypt( CCI_MODE_ECB, key, keyLength, B, AES_BLOCKSIZE, B, NULL ); */
|
||||
|
||||
ipcom_memcpy( A, B, AESKW_BLOCKSIZE);
|
||||
ipcom_memcpy( R + (i * AESKW_BLOCKSIZE), B + AESKW_BLOCKSIZE, AESKW_BLOCKSIZE);
|
||||
|
||||
/*
|
||||
** --- Do: A = MSB(64, B) ^ t where t = (n*j)+i
|
||||
*/
|
||||
AESKW_CVT(T,(numBlocks*j)+(i+1));
|
||||
AESKW_XOR_BLOCK(A,T,A);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** --- Do: Set C[0] = A
|
||||
*/
|
||||
ipcom_memcpy( cipherText, A, AESKW_BLOCKSIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
status = -1;
|
||||
IPCOM_LOG0(ERR,"Keywrap: outputBuffer too small\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = -1;
|
||||
IPCOM_LOG0(ERR,"Keywrap: message too short\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = -1;
|
||||
IPCOM_LOG0(ERR,"Keywrap: input buffer not a multiple of the blocksize");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = -1;
|
||||
IPCOM_LOG0(ERR,"Keywrap: invalid blocksize");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = -1;
|
||||
IPCOM_LOG0(ERR,"Keywrap: invalid keylength");
|
||||
}
|
||||
return( status );
|
||||
}
|
||||
/*
|
||||
*===========================================================================
|
||||
* aeskw_unwrap
|
||||
*===========================================================================
|
||||
* Description: Decrypt (unwrap) a key using AES-KEYWRAP
|
||||
* Parameters: key - pointer to key buffer
|
||||
* keyLength - length of key, must be 128 bit, 192 bit or 256 bit (in bytes)
|
||||
* iv - pointer to IV.
|
||||
* ivLength - length of IV. Must be AESKW_BLOCKSIZE
|
||||
* cipherText - pointer to buffer to decrypt (unwrap)
|
||||
* cipherTextLength - length of buffer to decrypt. Must be multiple of AESKW_BLOCKSIZE
|
||||
* plainText - pointer to buffer in which to copy output
|
||||
* plainTextLength - pointer to the length of the plainText buffer. On output,
|
||||
* this is updated to the length of data copied into the plainText buffer
|
||||
* Returns: -1 if failure
|
||||
*
|
||||
*/
|
||||
IP_EXTERN int aeskw_unwrap(Ip_u8 *key, int keyLength,
|
||||
Ip_u8 *iv, int ivLength,
|
||||
Ip_u8 *cipherText, int cipherTextLength,
|
||||
Ip_u8 *plainText, int *plainTextLength)
|
||||
{
|
||||
int status = 1;
|
||||
AES_KEY aesKey;
|
||||
|
||||
|
||||
/*
|
||||
** --- Check for proper key length
|
||||
*/
|
||||
if (AES_CHECK_KEYLEN(keyLength))
|
||||
{
|
||||
/*
|
||||
** --- Check for proper IV length
|
||||
*/
|
||||
if (ivLength == AESKW_BLOCKSIZE)
|
||||
{
|
||||
/*
|
||||
** --- Make sure the input is aligned to 64-bit boundaries
|
||||
*/
|
||||
if ( !(cipherTextLength % AESKW_BLOCKSIZE) )
|
||||
{
|
||||
|
||||
/*
|
||||
** --- Make sure the output buffer is at least
|
||||
** one block (64-bits) smaller than the input
|
||||
*/
|
||||
if (*plainTextLength >= (cipherTextLength-AESKW_BLOCKSIZE))
|
||||
{
|
||||
int numBlocks = (cipherTextLength/AESKW_BLOCKSIZE)-1;
|
||||
Ip_u8 *R, *A;
|
||||
Ip_u8 B[AES_BLOCKSIZE];
|
||||
Ip_u8 T[AESKW_BLOCKSIZE];
|
||||
int i,j;
|
||||
|
||||
if ((numBlocks+1) >= AESKW_UNWRAP_MIN_BLOCK)
|
||||
{
|
||||
/*
|
||||
** --- Set output buffer size
|
||||
*/
|
||||
*plainTextLength = cipherTextLength-AESKW_BLOCKSIZE;
|
||||
|
||||
/*
|
||||
** --- Initialize variables
|
||||
**
|
||||
** Set A = C[0]
|
||||
** For i = 1 to n
|
||||
** R[i] = C[i]
|
||||
*/
|
||||
A = cipherText;
|
||||
R = plainText;
|
||||
ipcom_memcpy( R, cipherText + AESKW_BLOCKSIZE, cipherTextLength-AESKW_BLOCKSIZE );
|
||||
|
||||
if ( -1 == AES_set_decrypt_key(key, keyLength << 3,&aesKey)) {
|
||||
IPCOM_LOG0(ERR,"AES_set_decrypt_key failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
for ( j = 6; j > 0; j-- )
|
||||
{
|
||||
for ( i = numBlocks; i > 0; i-- )
|
||||
{
|
||||
/*
|
||||
** --- Do: (A ^ t)
|
||||
*/
|
||||
AESKW_CVT(T,((numBlocks)*(j-1))+(i));
|
||||
AESKW_XOR_BLOCK(A,T,A);
|
||||
|
||||
/*
|
||||
** --- Do: B = AES(K, A | R[i])
|
||||
** --- Do: R[i] = LSB(64, B)
|
||||
*/
|
||||
ipcom_memcpy( B + AESKW_BLOCKSIZE, R + ((i-1) * AESKW_BLOCKSIZE), AESKW_BLOCKSIZE);
|
||||
ipcom_memcpy( B, A, AESKW_BLOCKSIZE);
|
||||
AES_ecb_encrypt(B, B,&aesKey, AES_DECRYPT);
|
||||
|
||||
ipcom_memcpy( A, B, AESKW_BLOCKSIZE);
|
||||
ipcom_memcpy( R + ((i-1) * AESKW_BLOCKSIZE), B + AESKW_BLOCKSIZE, AESKW_BLOCKSIZE);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** --- Make sure the first block is equal to the IV
|
||||
*/
|
||||
if (ipcom_memcmp( A, iv, AESKW_BLOCKSIZE))
|
||||
{
|
||||
status = -1;
|
||||
IPCOM_LOG0(ERR,"Keyunwrap: decoding error");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
IPCOM_LOG0(ERR,"Keyunwrap:message too short");
|
||||
status = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = -1;
|
||||
IPCOM_LOG0(ERR,"keyunwrap: output buffer too small");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
IPCOM_LOG0(ERR,"keyunwrap: input buffer not a multiple of the blocksize");
|
||||
status = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
IPCOM_LOG0(ERR,"keyunwrap: invalid iv length");
|
||||
status = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
IPCOM_LOG0(ERR,"invalid key length");
|
||||
status = -1;
|
||||
}
|
||||
|
||||
return( status );
|
||||
}
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
*
|
||||
* As far as I am concerned, the code I have written for this software
|
||||
* can be used freely for any purpose. Any derived versions of this
|
||||
* software must be clearly marked as such, and if the derived work is
|
||||
* incompatible with the protocol description in the RFC file, it must be
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef IPCOM_DMALLOC_C
|
||||
#undef IPCOM_DMALLOC_C
|
||||
#endif
|
||||
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
|
||||
#define IPCOM_USE_CLIB_PROTO
|
||||
#include <ipcom_clib.h>
|
||||
|
||||
#include <ipcrypto.h>
|
||||
|
||||
|
||||
|
||||
IP_GLOBAL char *
|
||||
ipcrypto_key_fingerprint_bubblebabble(Ip_u8* dgst_raw, unsigned int dgst_raw_len)
|
||||
{
|
||||
char vowels[] = { 'a', 'e', 'i', 'o', 'u', 'y' };
|
||||
char consonants[] = { 'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm',
|
||||
'n', 'p', 'r', 's', 't', 'v', 'z', 'x' };
|
||||
unsigned int i, j = 0, rounds, seed = 1;
|
||||
char *retval;
|
||||
|
||||
rounds = (dgst_raw_len / 2) + 1;
|
||||
retval = ipcom_malloc(sizeof(char) * (rounds*6));
|
||||
if (retval==IP_NULL)
|
||||
{
|
||||
IP_PANIC();
|
||||
}
|
||||
retval[j++] = 'x';
|
||||
for (i = 0; i < rounds; i++) {
|
||||
unsigned int idx0, idx1, idx2, idx3, idx4;
|
||||
if ((i + 1 < rounds) || (dgst_raw_len % 2 != 0)) {
|
||||
idx0 = (((((unsigned int)(dgst_raw[2 * i])) >> 6) & 3) +
|
||||
seed) % 6;
|
||||
idx1 = (((unsigned int)(dgst_raw[2 * i])) >> 2) & 15;
|
||||
idx2 = ((((unsigned int)(dgst_raw[2 * i])) & 3) +
|
||||
(seed / 6)) % 6;
|
||||
retval[j++] = vowels[idx0];
|
||||
retval[j++] = consonants[idx1];
|
||||
retval[j++] = vowels[idx2];
|
||||
if ((i + 1) < rounds) {
|
||||
idx3 = (((unsigned int)(dgst_raw[(2 * i) + 1])) >> 4) & 15;
|
||||
idx4 = (((unsigned int)(dgst_raw[(2 * i) + 1]))) & 15;
|
||||
retval[j++] = consonants[idx3];
|
||||
retval[j++] = '-';
|
||||
retval[j++] = consonants[idx4];
|
||||
seed = ((seed * 5) +
|
||||
((((unsigned int)(dgst_raw[2 * i])) * 7) +
|
||||
((unsigned int)(dgst_raw[(2 * i) + 1])))) % 36;
|
||||
}
|
||||
} else {
|
||||
idx0 = seed % 6;
|
||||
idx1 = 16;
|
||||
idx2 = seed / 6;
|
||||
retval[j++] = vowels[idx0];
|
||||
retval[j++] = consonants[idx1];
|
||||
retval[j++] = vowels[idx2];
|
||||
}
|
||||
}
|
||||
retval[j++] = 'x';
|
||||
retval[j] = '\0';
|
||||
return retval;
|
||||
}
|
||||
@@ -0,0 +1,372 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK SOURCE FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipcrypto_cmd_aescmac_test.c,v $ $Revision: 1.1 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipcrypto/src/ipcrypto_cmd_aescmac_test.c,v $
|
||||
* $Author: roger $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by FirstName LastName <email@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipcrypto_config.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
#define IPCOM_USE_CLIB_PROTO
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_clib.h>
|
||||
|
||||
#include "ipcrypto.h"
|
||||
#include "ipcrypto_h.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
#define VALIDATE_TEST_RESULT(expected,actual,length,description) \
|
||||
if(ipcom_memcmp(expected,actual,length)!= 0) \
|
||||
{ \
|
||||
ipcom_printf("%s Failed\n",description); \
|
||||
show_buffer("Expected",expected,length,16); \
|
||||
show_buffer("Actual",actual,length,16); \
|
||||
ipcom_free(pCmacCtx); \
|
||||
return -1; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
ipcom_printf("%s Passed\n",description); \
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
IP_STATIC void show_buffer( char *title, void *buffer, int length, int lineLen );
|
||||
IP_GLOBAL int ipcrypto_cmd_aescmac_test(int argc, char **argv);
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 STATIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
IP_STATIC void
|
||||
show_buffer(char *title,
|
||||
void *buffer,
|
||||
int length,
|
||||
int lineLen)
|
||||
{
|
||||
char *ptr = (char *)buffer;
|
||||
int i, rowLen = 0, colLen = 0, llen;
|
||||
|
||||
if ( ptr && length )
|
||||
{
|
||||
if ( !lineLen ) lineLen = 16;
|
||||
|
||||
llen = (lineLen * 3) + 6 + (((lineLen/4) + 1) * 2);
|
||||
ipcom_printf("\n\n( %s ) (%u-bytes, %u-bits)\n", title, length, (length*8));
|
||||
for ( i = 0; i < llen; i++ ) ipcom_printf("*");
|
||||
|
||||
ipcom_printf("\n %04X :: ", rowLen++);
|
||||
for ( i = 0; i < length; i++ )
|
||||
{
|
||||
ipcom_printf("%02X ", (unsigned char)ptr[i] );
|
||||
colLen++;
|
||||
|
||||
if (colLen && !(colLen%4) && (colLen != lineLen))
|
||||
ipcom_printf("| ");
|
||||
|
||||
if ((colLen == lineLen) & (i!=(length-1)))
|
||||
{
|
||||
colLen = 0;
|
||||
ipcom_printf("\n %04X :: ", rowLen * lineLen);
|
||||
rowLen++;
|
||||
}
|
||||
}
|
||||
|
||||
ipcom_printf("\n");
|
||||
for ( i = 0; i < llen; i++ ) ipcom_printf("*");
|
||||
ipcom_printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 GLOBAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
IP_GLOBAL int
|
||||
ipcrypto_cmd_aescmac_test(int argc, char **argv)
|
||||
{
|
||||
/* messages common across the different key size tests (input message to be MAC'd), we just use subsets of message for 16 byte, 40 byte and 64 byte inputs */
|
||||
Ip_u8 message[] = {0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96,0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a,0xae,0x2d,0x8a,0x57,0x1e,0x03,0xac,0x9c,0x9e,0xb7,0x6f,0xac,0x45,0xaf,0x8e,0x51,0x30,0xc8,0x1c,0x46,0xa3,0x5c,0xe4,0x11,0xe5,0xfb,0xc1,0x19,0x1a,0x0a,0x52,0xef,0xf6,0x9f,0x24,0x45,0xdf,0x4f,0x9b,0x17,0xad,0x2b,0x41,0x7b,0xe6,0x6c,0x37,0x10};
|
||||
|
||||
/* Using AES-128 as the Cipher */
|
||||
|
||||
Ip_u8 key128[] ={0x2b,0x7e,0x15,0x16,0x28,0xae,0xd2,0xa6,0xab,0xf7,0x15,0x88,0x09,0xcf,0x4f,0x3c};
|
||||
Ip_u8 expectedK1_128[] = {0xfb,0xee,0xd6,0x18,0x35,0x71,0x33,0x66,0x7c,0x85,0xe0,0x8f,0x72,0x36,0xa8,0xde};
|
||||
Ip_u8 expectedK2_128[] = {0xf7,0xdd,0xac,0x30,0x6a,0xe2,0x66,0xcc,0xf9,0x0b,0xc1,0x1e,0xe4,0x6d,0x51,0x3b};
|
||||
Ip_u8 expectedOutputMessage0_128[] = {0xbb,0x1d,0x69,0x29,0xe9,0x59,0x37,0x28,0x7f,0xa3,0x7d,0x12,0x9b,0x75,0x67,0x46};
|
||||
Ip_u8 expectedOutputMessage16_128[] = {0x07,0x0a,0x16,0xb4,0x6b,0x4d,0x41,0x44,0xf7,0x9b,0xdd,0x9d,0xd0,0x4a,0x28,0x7c};
|
||||
Ip_u8 expectedOutputMessage40_128[] = {0xdf,0xa6,0x67,0x47,0xde,0x9a,0xe6,0x30,0x30,0xca,0x32,0x61,0x14,0x97,0xc8,0x27};
|
||||
Ip_u8 expectedOutputMessage64_128[] = {0x51,0xf0,0xbe,0xbf,0x7e,0x3b,0x9d,0x92,0xfc,0x49,0x74,0x17,0x79,0x36,0x3c,0xfe};
|
||||
|
||||
/* Using AES-192 as the Cipher */
|
||||
Ip_u8 key192[] ={ 0x8e,0x73,0xb0,0xf7,0xda,0x0e,0x64,0x52,0xc8,0x10,0xf3,0x2b,0x80,0x90,0x79,0xe5,0x62,0xf8,0xea,0xd2,0x52,0x2c,0x6b,0x7b};
|
||||
Ip_u8 expectedK1_192[] = {0x44,0x8a,0x5b,0x1c,0x93,0x51,0x4b,0x27,0x3e,0xe6,0x43,0x9d,0xd4,0xda,0xa2,0x96};
|
||||
Ip_u8 expectedK2_192[] = {0x89,0x14,0xb6,0x39,0x26,0xa2,0x96,0x4e,0x7d,0xcc,0x87,0x3b,0xa9,0xb5,0x45,0x2c};
|
||||
Ip_u8 expectedOutputMessage0_192[] = {0xd1,0x7d,0xdf,0x46,0xad,0xaa,0xcd,0xe5,0x31,0xca,0xc4,0x83,0xde,0x7a,0x93,0x67};
|
||||
Ip_u8 expectedOutputMessage16_192[] = {0x9e,0x99,0xa7,0xbf,0x31,0xe7,0x10,0x90,0x06,0x62,0xf6,0x5e,0x61,0x7c,0x51,0x84};
|
||||
Ip_u8 expectedOutputMessage40_192[] = {0x8a,0x1d,0xe5,0xbe,0x2e,0xb3,0x1a,0xad,0x08,0x9a,0x82,0xe6,0xee,0x90,0x8b,0x0e};
|
||||
Ip_u8 expectedOutputMessage64_192[] = {0xa1,0xd5,0xdf,0x0e,0xed,0x79,0x0f,0x79,0x4d,0x77,0x58,0x96,0x59,0xf3,0x9a,0x11};
|
||||
|
||||
/* Using AES-256 as the Cipher */
|
||||
|
||||
Ip_u8 key256[] ={ 0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe,0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81,0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7,0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4};
|
||||
Ip_u8 expectedK1_256[] = {0xca,0xd1,0xed,0x03,0x29,0x9e,0xed,0xac,0x2e,0x9a,0x99,0x80,0x86,0x21,0x50,0x2f};
|
||||
Ip_u8 expectedK2_256[] = {0x95,0xa3,0xda,0x06,0x53,0x3d,0xdb,0x58,0x5d,0x35,0x33,0x01,0x0c,0x42,0xa0,0xd9};
|
||||
Ip_u8 expectedOutputMessage0_256[] = {0x02,0x89,0x62,0xf6,0x1b,0x7b,0xf8,0x9e,0xfc,0x6b,0x55,0x1f,0x46,0x67,0xd9,0x83};
|
||||
Ip_u8 expectedOutputMessage16_256[] = {0x28,0xa7,0x02,0x3f,0x45,0x2e,0x8f,0x82,0xbd,0x4b,0xf2,0x8d,0x8c,0x37,0xc3,0x5c};
|
||||
Ip_u8 expectedOutputMessage40_256[] = {0xaa,0xf3,0xd8,0xf1,0xde,0x56,0x40,0xc2,0x32,0xf5,0xb1,0x69,0xb9,0xc9,0x11,0xe6};
|
||||
Ip_u8 expectedOutputMessage64_256[] = {0xe1,0x99,0x21,0x90,0x54,0x9f,0x6e,0xd5,0x69,0x6a,0x2c,0x05,0x6c,0x31,0x54,0x10};
|
||||
|
||||
/* AES-CMAC-PRF128 Test vectors */
|
||||
|
||||
Ip_u8 keyPRF128[] ={ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xed,0xcb};
|
||||
Ip_u8 messagePRF128[] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13};
|
||||
Ip_u8 expectedOutputPRF128_18[] = {0x84,0xa3,0x48,0xa4,0xa4,0x5d,0x23,0x5b,0xab,0xff,0xfc,0x0d,0x2b,0x4d,0xa0,0x9a};
|
||||
Ip_u8 expectedOutputPRF128_16[] = {0x98,0x0a,0xe8,0x7b,0x5f,0x4c,0x9c,0x52,0x14,0xf5,0xb6,0xa8,0x45,0x5e,0x4c,0x2d};
|
||||
Ip_u8 expectedOutputPRF128_10[] = {0x29,0x0d,0x9e,0x11,0x2e,0xdb,0x09,0xee,0x14,0x1f,0xcf,0x64,0xc0,0xb7,0x2f,0x3d};
|
||||
|
||||
/* begin Tests */
|
||||
|
||||
Ip_u8 output[AES_BLOCKSIZE];
|
||||
Ip_u8 *input =IP_NULL;
|
||||
int outputLength;
|
||||
AES_CMAC_CTX *pCmacCtx;
|
||||
|
||||
pCmacCtx = ipcom_malloc(sizeof(AES_CMAC_CTX));
|
||||
if(!pCmacCtx)
|
||||
{
|
||||
ipcom_printf("Failed. Out of memory");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* TEST1: passing IP_NULL Ctx and IP_NULL key, should fail */
|
||||
if (-1 != aesCmacInit(IP_NULL,IP_NULL,0))
|
||||
{
|
||||
ipcom_printf("aesCmacInit Failed IP_NULL, IP_NULL test\n");
|
||||
ipcom_free(pCmacCtx);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ipcom_memset(pCmacCtx,0,sizeof(AES_CMAC_CTX));
|
||||
/* AES-128 Reusing CTX, and checking sub keys generated and stored in CTX from a known key */
|
||||
aesCmacInit(pCmacCtx,key128,sizeof(key128));
|
||||
|
||||
VALIDATE_TEST_RESULT(expectedK1_128,pCmacCtx->k1,AES_BLOCKSIZE,"AES128 Gen Sub Key1");
|
||||
VALIDATE_TEST_RESULT(expectedK2_128,pCmacCtx->k2,AES_BLOCKSIZE,"AES128 Gen Sub Key2");
|
||||
|
||||
|
||||
|
||||
/* Test: passing too small of output buffer */
|
||||
|
||||
outputLength = 2;
|
||||
if (-1 != aesCmacFinal(pCmacCtx, input,0,output,&outputLength))
|
||||
{
|
||||
ipcom_printf("invalid outputLength test fails\n");
|
||||
ipcom_free(pCmacCtx);
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ipcom_printf("Invalid outputLength test pass\n");
|
||||
}
|
||||
|
||||
/* AES-128 empty string for input*/
|
||||
outputLength = sizeof(output);
|
||||
aesCmacFinal(pCmacCtx, input,0,output,&outputLength);
|
||||
|
||||
VALIDATE_TEST_RESULT(expectedOutputMessage0_128,output,sizeof(expectedOutputMessage0_128),"AES128 0 Byte Message");
|
||||
|
||||
ipcom_memset(output,0,AES_BLOCKSIZE);
|
||||
/* AES-128, reusing CTX (since key, subkeys did not change) , empty string block mode*/
|
||||
aesCmacBlock(pCmacCtx,key128,sizeof(key128),input,0,output,&outputLength);
|
||||
VALIDATE_TEST_RESULT(expectedOutputMessage0_128,output,sizeof(expectedOutputMessage0_128),"AES128 0 Byte Message Blockmode, Context reuse");
|
||||
|
||||
|
||||
/* AES-128, reusing CTX (since key, subkeys did not change) , 16 byte input message*/
|
||||
ipcom_memset(output,0,AES_BLOCKSIZE);
|
||||
aesCmacBlock(pCmacCtx,key128,sizeof(key128),message,16,output,&outputLength);
|
||||
VALIDATE_TEST_RESULT(expectedOutputMessage16_128,output,sizeof(expectedOutputMessage16_128),"AES128 16 Byte Message aesCmacBlock");
|
||||
|
||||
/* AES-128, reusing CTX (since key, subkeys did not change) , 40 byte input message*/
|
||||
ipcom_memset(output,0,AES_BLOCKSIZE);
|
||||
aesCmacBlock(pCmacCtx,key128,sizeof(key128),message,40,output,&outputLength);
|
||||
VALIDATE_TEST_RESULT(expectedOutputMessage40_128,output,sizeof(expectedOutputMessage40_128),"AES128 40 Byte Message aesCmacBlock");
|
||||
|
||||
/* AES-128, reusing CTX (since key, subkeys did not change) , 64 byte input message*/
|
||||
ipcom_memset(output,0,AES_BLOCKSIZE);
|
||||
aesCmacBlock(pCmacCtx,key128,sizeof(key128),message,64,output,&outputLength);
|
||||
VALIDATE_TEST_RESULT(expectedOutputMessage64_128,output,sizeof(expectedOutputMessage64_128),"AES128 64 Byte Message aesCmacBlock");
|
||||
|
||||
/***********************************************************************************************
|
||||
AES-192 CMAC tests
|
||||
***********************************************************************************************/
|
||||
|
||||
ipcom_memset(pCmacCtx,0,sizeof(AES_CMAC_CTX));
|
||||
/*AES-192 Reusing CTX, and checking sub keys generated and stored in CTX from a known key */
|
||||
aesCmacInit(pCmacCtx,key192,sizeof(key192));
|
||||
|
||||
VALIDATE_TEST_RESULT(expectedK1_192,pCmacCtx->k1,AES_BLOCKSIZE,"AES192 Gen Sub Key1");
|
||||
VALIDATE_TEST_RESULT(expectedK2_192,pCmacCtx->k2,AES_BLOCKSIZE,"AES192 Gen Sub Key2");
|
||||
|
||||
/* AES-192 empty string for input*/
|
||||
outputLength = sizeof(output);
|
||||
aesCmacFinal(pCmacCtx, input,0,output,&outputLength);
|
||||
VALIDATE_TEST_RESULT(expectedOutputMessage0_192,output,sizeof(expectedOutputMessage0_192),"AES192 0 Byte Message");
|
||||
|
||||
ipcom_memset(output,0,AES_BLOCKSIZE);
|
||||
/* AES-192, reusing CTX (since key, subkeys did not change) , empty string block mode*/
|
||||
aesCmacBlock(pCmacCtx,key192,sizeof(key192),input,0,output,&outputLength);
|
||||
VALIDATE_TEST_RESULT(expectedOutputMessage0_192,output,sizeof(expectedOutputMessage0_192),"AES192 0 Byte Message Blockmode, Context reuse");
|
||||
|
||||
|
||||
/* AES-192, reusing CTX (since key, subkeys did not change) , 16 byte input message*/
|
||||
ipcom_memset(output,0,AES_BLOCKSIZE);
|
||||
aesCmacBlock(pCmacCtx,key192,sizeof(key192),message,16,output,&outputLength);
|
||||
VALIDATE_TEST_RESULT(expectedOutputMessage16_192,output,sizeof(expectedOutputMessage16_192),"AES192 16 Byte Message aesCmacBlock");
|
||||
|
||||
/* AES-192, reusing CTX (since key, subkeys did not change) , 40 byte input message*/
|
||||
ipcom_memset(output,0,AES_BLOCKSIZE);
|
||||
aesCmacBlock(pCmacCtx,key192,sizeof(key192),message,40,output,&outputLength);
|
||||
VALIDATE_TEST_RESULT(expectedOutputMessage40_192,output,sizeof(expectedOutputMessage40_192),"AES192 40 Byte Message aesCmacBlock");
|
||||
|
||||
/* AES-192, reusing CTX (since key, subkeys did not change) , 64 byte input message*/
|
||||
ipcom_memset(output,0,AES_BLOCKSIZE);
|
||||
aesCmacBlock(pCmacCtx,key192,sizeof(key192),message,64,output,&outputLength);
|
||||
VALIDATE_TEST_RESULT(expectedOutputMessage64_192,output,sizeof(expectedOutputMessage64_192),"AES192 64 Byte Message aesCmacBlock");
|
||||
|
||||
/***********************************************************************************************
|
||||
AES-256 CMAC tests
|
||||
***********************************************************************************************/
|
||||
|
||||
ipcom_memset(pCmacCtx,0,sizeof(AES_CMAC_CTX));
|
||||
/*AES-256 Reusing CTX, and checking sub keys generated and stored in CTX from a known key */
|
||||
aesCmacInit(pCmacCtx,key256,sizeof(key256));
|
||||
|
||||
VALIDATE_TEST_RESULT(expectedK1_256,pCmacCtx->k1,AES_BLOCKSIZE,"AES256 Gen Sub Key1");
|
||||
VALIDATE_TEST_RESULT(expectedK2_256,pCmacCtx->k2,AES_BLOCKSIZE,"AES256 Gen Sub Key2");
|
||||
|
||||
/* AES-256 empty string for input*/
|
||||
outputLength = sizeof(output);
|
||||
aesCmacFinal(pCmacCtx, input,0,output,&outputLength);
|
||||
VALIDATE_TEST_RESULT(expectedOutputMessage0_256,output,sizeof(expectedOutputMessage0_256),"AES256 0 Byte Message");
|
||||
|
||||
ipcom_memset(output,0,AES_BLOCKSIZE);
|
||||
/* AES-256, reusing CTX from Test3 (since key, subkeys did not change) , empty string block mode*/
|
||||
aesCmacBlock(pCmacCtx,key256,sizeof(key256),input,0,output,&outputLength);
|
||||
VALIDATE_TEST_RESULT(expectedOutputMessage0_256,output,sizeof(expectedOutputMessage0_256),"AES256 0 Byte Message Blockmode, Context reuse");
|
||||
|
||||
|
||||
/* AES-256, reusing CTX (since key, subkeys did not change) , 16 byte input message*/
|
||||
ipcom_memset(output,0,AES_BLOCKSIZE);
|
||||
aesCmacBlock(pCmacCtx,key256,sizeof(key256),message,16,output,&outputLength);
|
||||
VALIDATE_TEST_RESULT(expectedOutputMessage16_256,output,sizeof(expectedOutputMessage16_256),"AES256 16 Byte Message aesCmacBlock");
|
||||
|
||||
/* AES-256, reusing CTX (since key, subkeys did not change) , 40 byte input message*/
|
||||
ipcom_memset(output,0,AES_BLOCKSIZE);
|
||||
aesCmacBlock(pCmacCtx,key256,sizeof(key256),message,40,output,&outputLength);
|
||||
VALIDATE_TEST_RESULT(expectedOutputMessage40_256,output,sizeof(expectedOutputMessage40_256),"AES256 40 Byte Message aesCmacBlock");
|
||||
|
||||
/* AES-256, reusing CTX (since key, subkeys did not change) , 64 byte input message*/
|
||||
ipcom_memset(output,0,AES_BLOCKSIZE);
|
||||
aesCmacBlock(pCmacCtx,key256,sizeof(key256),message,64,output,&outputLength);
|
||||
VALIDATE_TEST_RESULT(expectedOutputMessage64_256,output,sizeof(expectedOutputMessage64_256),"AES256 64 Byte Message aesCmacBlock");
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
AES-CMAC-PRF-128 CMAC tests
|
||||
***********************************************************************************************/
|
||||
|
||||
ipcom_memset(output,0,AES_BLOCKSIZE);
|
||||
aesCmacPrf128(keyPRF128, 18, messagePRF128, sizeof(messagePRF128), output, &outputLength);
|
||||
VALIDATE_TEST_RESULT(expectedOutputPRF128_18,output,sizeof(expectedOutputPRF128_18),"AES-CMAC-PRF-128 18 byte key");
|
||||
|
||||
ipcom_memset(output,0,AES_BLOCKSIZE);
|
||||
aesCmacPrf128(keyPRF128, 16, messagePRF128, sizeof(messagePRF128), output, &outputLength);
|
||||
VALIDATE_TEST_RESULT(expectedOutputPRF128_16,output,sizeof(expectedOutputPRF128_16),"AES-CMAC-PRF-128 16 byte key");
|
||||
|
||||
ipcom_memset(output,0,AES_BLOCKSIZE);
|
||||
aesCmacPrf128(keyPRF128, 10, messagePRF128, sizeof(messagePRF128), output, &outputLength);
|
||||
VALIDATE_TEST_RESULT(expectedOutputPRF128_10,output,sizeof(expectedOutputPRF128_10),"AES-CMAC-PRF-128 10 byte key");
|
||||
|
||||
|
||||
ipcom_printf("cmactest succeeds\n");
|
||||
|
||||
ipcom_free(pCmacCtx);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 11 PUBLIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,300 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK SOURCE FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipcrypto_cmd_aeskeywrap_test.c,v $ $Revision: 1.1 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipcrypto/src/ipcrypto_cmd_aeskeywrap_test.c,v $
|
||||
* $Author: roger $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* Copyright 2000-2007 Interpeak AB (http://www.interpeak.se). All rights reserved.
|
||||
* Design and implementation by FirstName LastName <email@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipcrypto_config.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
#define IPCOM_USE_CLIB_PROTO
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_clib.h>
|
||||
|
||||
#include "ipcrypto.h"
|
||||
#include "ipcrypto_h.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
#define VALIDATE_TEST_RESULT(expected,actual,length,description) \
|
||||
if(ipcom_memcmp(expected,actual,length)!= 0) \
|
||||
{ \
|
||||
ipcom_printf("%s Failed\n",description); \
|
||||
show_buffer("Expected",expected,length,16); \
|
||||
show_buffer("Actual",actual,length,16); \
|
||||
return -1; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
ipcom_printf("%s Passed\n",description); \
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
IP_STATIC void show_buffer( char *title, void *buffer, int length, int lineLen );
|
||||
IP_GLOBAL int ipcrypto_cmd_aeskeywrap_test(int argc, char **argv);
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 STATIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
IP_STATIC void
|
||||
show_buffer(char *title,
|
||||
void *buffer,
|
||||
int length,
|
||||
int lineLen)
|
||||
{
|
||||
char *ptr = (char *)buffer;
|
||||
int i, rowLen = 0, colLen = 0, llen;
|
||||
|
||||
if ( ptr && length )
|
||||
{
|
||||
if ( !lineLen ) lineLen = 16;
|
||||
|
||||
llen = (lineLen * 3) + 6 + (((lineLen/4) + 1) * 2);
|
||||
ipcom_printf("\n\n( %s ) (%u-bytes, %u-bits)\n", title, length, (length*8));
|
||||
for ( i = 0; i < llen; i++ ) ipcom_printf("*");
|
||||
|
||||
ipcom_printf("\n %04X :: ", rowLen++);
|
||||
for ( i = 0; i < length; i++ )
|
||||
{
|
||||
ipcom_printf("%02X ", (unsigned char)ptr[i] );
|
||||
colLen++;
|
||||
|
||||
if (colLen && !(colLen%4) && (colLen != lineLen))
|
||||
ipcom_printf("| ");
|
||||
|
||||
if ((colLen == lineLen) & (i!=(length-1)))
|
||||
{
|
||||
colLen = 0;
|
||||
ipcom_printf("\n %04X :: ", rowLen * lineLen);
|
||||
rowLen++;
|
||||
}
|
||||
}
|
||||
|
||||
ipcom_printf("\n");
|
||||
for ( i = 0; i < llen; i++ ) ipcom_printf("*");
|
||||
ipcom_printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 GLOBAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
IP_GLOBAL int
|
||||
ipcrypto_cmd_aeskeywrap_test(int argc, char **argv)
|
||||
{
|
||||
Ip_u8 orig_iv[] = {0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6,0xA6};
|
||||
Ip_u8 kek[] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F};
|
||||
Ip_u8 keydata[] = {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F};
|
||||
Ip_u8 ciphertext_key128_keydata128[] = {0x1F,0xA6,0x8B,0x0A,0x81,0x12,0xB4,0x47,0xAE,0xF3,0x4B,0xD8,0xFB,0x5A,0x7B,0x82,0x9D,0x3E,0x86,0x23,0x71,0xD2,0xCF,0xE5};
|
||||
Ip_u8 ciphertext_key192_keydata128[] = {0x96,0x77,0x8B,0x25,0xAE,0x6C,0xA4,0x35,0xF9,0x2B,0x5B,0x97,0xC0,0x50,0xAE,0xD2,0x46,0x8A,0xB8,0xA1,0x7A,0xD8,0x4E,0x5D};
|
||||
Ip_u8 ciphertext_key256_keydata128[] = {0x64,0xE8,0xC3,0xF9,0xCE,0x0F,0x5B,0xA2,0x63,0xE9,0x77,0x79,0x05,0x81,0x8A,0x2A,0x93,0xC8,0x19,0x1E,0x7D,0x6E,0x8A,0xE7};
|
||||
Ip_u8 ciphertext_key192_keydata_192[] = {0x03,0x1D,0x33,0x26,0x4E,0x15,0xD3,0x32,0x68,0xF2,0x4E,0xC2,0x60,0x74,0x3E,0xDC,0xE1,0xC6,0xC7,0xDD,0xEE,0x72,0x5A,0x93,0x6B,0xA8,0x14,0x91,0x5C,0x67,0x62,0xD2};
|
||||
Ip_u8 ciphertext_key256_keydata_192[] = {0xA8,0xF9,0xBC,0x16,0x12,0xC6,0x8B,0x3F,0xF6,0xE6,0xF4,0xFB,0xE3,0x0E,0x71,0xE4,0x76,0x9C,0x8B,0x80,0xA3,0x2C,0xB8,0x95,0x8C,0xD5,0xD1,0x7D,0x6B,0x25,0x4D,0xA1};
|
||||
Ip_u8 ciphertext_key256_keydata_256[] = {0x28,0xC9,0xF4,0x04,0xC4,0xB8,0x10,0xF4,0xCB,0xCC,0xB3,0x5C,0xFB,0x87,0xF8,0x26,0x3F,0x57,0x86,0xE2,0xD8,0x0E,0xD3,0x26,0xCB,0xC7,0xF0,0xE7,0x1A,0x99,0xF4,0x3B,0xFB,0x98,0x8B,0x9B,0x7A,0x02,0xDD,0x21};
|
||||
|
||||
#define AES_KEY_128 16
|
||||
#define AES_KEY_192 24
|
||||
#define AES_KEY_256 32
|
||||
|
||||
#define AES_KEK_128 16
|
||||
#define AES_KEK_192 24
|
||||
#define AES_KEK_256 32
|
||||
|
||||
|
||||
Ip_u8 output[128];
|
||||
Ip_u8 decryptedKey[128];
|
||||
Ip_u8 iv[AESKW_BLOCKSIZE];
|
||||
int outputLength,decryptedKeyLength;
|
||||
|
||||
|
||||
ipcom_printf("aeskeywrap test\n");
|
||||
|
||||
/* Test Vectors from RFC */
|
||||
/* 128 Bit Key Encryption Key, 128 Bit Key */
|
||||
|
||||
ipcom_memset(output,0,sizeof(output));
|
||||
outputLength = sizeof(output);
|
||||
ipcom_memcpy(iv,orig_iv,AESKW_BLOCKSIZE);
|
||||
aeskw_wrap(kek,AES_KEK_128,iv,sizeof(iv),keydata,AES_KEY_128,output,&outputLength);
|
||||
VALIDATE_TEST_RESULT(ciphertext_key128_keydata128,output,outputLength, "AES Keywrap: 128 KEK, 128 Key Encrypt");
|
||||
|
||||
|
||||
ipcom_memset(decryptedKey,0,sizeof(decryptedKey));
|
||||
decryptedKeyLength = sizeof(decryptedKey);
|
||||
ipcom_memcpy(iv,orig_iv,AESKW_BLOCKSIZE);
|
||||
|
||||
aeskw_unwrap(kek, AES_KEK_128,iv,sizeof(iv),output,outputLength,decryptedKey,&decryptedKeyLength);
|
||||
|
||||
VALIDATE_TEST_RESULT(keydata,decryptedKey,decryptedKeyLength,"AES Keywrap: 128 KEK, 128 Key Decrypt");
|
||||
|
||||
/* 192 Bit Key Encryption Key, 128 Bit Key */
|
||||
|
||||
ipcom_memset(output,0,sizeof(output));
|
||||
outputLength = sizeof(output);
|
||||
ipcom_memcpy(iv,orig_iv,AESKW_BLOCKSIZE);
|
||||
aeskw_wrap(kek,AES_KEK_192,iv,sizeof(iv),keydata,AES_KEY_128,output,&outputLength);
|
||||
VALIDATE_TEST_RESULT(ciphertext_key192_keydata128,output,outputLength, "AES Keywrap: 192 KEK, 128 Key Encrypt");
|
||||
|
||||
|
||||
ipcom_memset(decryptedKey,0,sizeof(decryptedKey));
|
||||
decryptedKeyLength = sizeof(decryptedKey);
|
||||
ipcom_memcpy(iv,orig_iv,AESKW_BLOCKSIZE);
|
||||
|
||||
aeskw_unwrap(kek, AES_KEK_192,iv,sizeof(iv),output,outputLength,decryptedKey,&decryptedKeyLength);
|
||||
|
||||
VALIDATE_TEST_RESULT(keydata,decryptedKey,decryptedKeyLength,"AES Keywrap: 192 KEK, 128 Key Decrypt");
|
||||
|
||||
|
||||
/* 256 Bit Key Encryption Key, 128 Bit Key */
|
||||
|
||||
ipcom_memset(output,0,sizeof(output));
|
||||
outputLength = sizeof(output);
|
||||
ipcom_memcpy(iv,orig_iv,AESKW_BLOCKSIZE);
|
||||
aeskw_wrap(kek,AES_KEK_256,iv,sizeof(iv),keydata,AES_KEY_128,output,&outputLength);
|
||||
VALIDATE_TEST_RESULT(ciphertext_key256_keydata128,output,outputLength, "AES Keywrap: 256 KEK, 128 Key Encrypt");
|
||||
|
||||
|
||||
ipcom_memset(decryptedKey,0,sizeof(decryptedKey));
|
||||
decryptedKeyLength = sizeof(decryptedKey);
|
||||
ipcom_memcpy(iv,orig_iv,AESKW_BLOCKSIZE);
|
||||
|
||||
aeskw_unwrap(kek, AES_KEK_256,iv,sizeof(iv),output,outputLength,decryptedKey,&decryptedKeyLength);
|
||||
|
||||
VALIDATE_TEST_RESULT(keydata,decryptedKey,decryptedKeyLength,"AES Keywrap: 256 KEK, 128 Key Decrypt");
|
||||
|
||||
|
||||
|
||||
/* 192 Bit Key Encryption Key, 192 Bit Key */
|
||||
|
||||
ipcom_memset(output,0,sizeof(output));
|
||||
outputLength = sizeof(output);
|
||||
ipcom_memcpy(iv,orig_iv,AESKW_BLOCKSIZE);
|
||||
aeskw_wrap(kek,AES_KEK_192,iv,sizeof(iv),keydata,AES_KEY_192,output,&outputLength);
|
||||
VALIDATE_TEST_RESULT(ciphertext_key192_keydata_192,output,outputLength, "AES Keywrap: 192 KEK, 192 Key Encrypt");
|
||||
|
||||
|
||||
ipcom_memset(decryptedKey,0,sizeof(decryptedKey));
|
||||
decryptedKeyLength = sizeof(decryptedKey);
|
||||
ipcom_memcpy(iv,orig_iv,AESKW_BLOCKSIZE);
|
||||
|
||||
aeskw_unwrap(kek, AES_KEK_192,iv,sizeof(iv),output,outputLength,decryptedKey,&decryptedKeyLength);
|
||||
|
||||
VALIDATE_TEST_RESULT(keydata,decryptedKey,decryptedKeyLength,"AES Keywrap: 192 KEK, 192 Key Decrypt");
|
||||
|
||||
/* 256 Bit Key Encryption Key, 192 Bit Key */
|
||||
|
||||
ipcom_memset(output,0,sizeof(output));
|
||||
outputLength = sizeof(output);
|
||||
ipcom_memcpy(iv,orig_iv,AESKW_BLOCKSIZE);
|
||||
aeskw_wrap(kek,AES_KEK_256,iv,sizeof(iv),keydata,AES_KEY_192,output,&outputLength);
|
||||
VALIDATE_TEST_RESULT(ciphertext_key256_keydata_192,output,outputLength, "AES Keywrap: 256 KEK, 192 Key Encrypt");
|
||||
|
||||
|
||||
ipcom_memset(decryptedKey,0,sizeof(decryptedKey));
|
||||
decryptedKeyLength = sizeof(decryptedKey);
|
||||
ipcom_memcpy(iv,orig_iv,AESKW_BLOCKSIZE);
|
||||
|
||||
aeskw_unwrap(kek, AES_KEK_256,iv,sizeof(iv),output,outputLength,decryptedKey,&decryptedKeyLength);
|
||||
|
||||
VALIDATE_TEST_RESULT(keydata,decryptedKey,decryptedKeyLength,"AES Keywrap: 256 KEK, 192 Key Decrypt");
|
||||
|
||||
|
||||
/*256 Bit Key Encryption Key, 256 Bit Key */
|
||||
|
||||
ipcom_memset(output,0,sizeof(output));
|
||||
outputLength = sizeof(output);
|
||||
ipcom_memcpy(iv,orig_iv,AESKW_BLOCKSIZE);
|
||||
aeskw_wrap(kek,AES_KEK_256,iv,sizeof(iv),keydata,AES_KEY_256,output,&outputLength);
|
||||
VALIDATE_TEST_RESULT(ciphertext_key256_keydata_256,output,outputLength, "AES Keywrap: 256 KEK, 256 KEK Encrypt");
|
||||
|
||||
|
||||
ipcom_memset(decryptedKey,0,sizeof(decryptedKey));
|
||||
decryptedKeyLength = sizeof(decryptedKey);
|
||||
ipcom_memcpy(iv,orig_iv,AESKW_BLOCKSIZE);
|
||||
|
||||
aeskw_unwrap(kek, AES_KEK_256,iv,sizeof(iv),output,outputLength,decryptedKey,&decryptedKeyLength);
|
||||
|
||||
VALIDATE_TEST_RESULT(keydata,decryptedKey,decryptedKeyLength,"AES Keywrap: 256 KEK, 256 KEK Decrypt");
|
||||
|
||||
ipcom_printf("aeskeywraptest succeeds\n");
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 11 PUBLIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,350 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* SOURCE FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipcrypto_cmd_cmp.c,v $ $Revision: 1.6 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipcrypto/src/ipcrypto_cmd_cmp.c,v $
|
||||
* $Author: rboden $ $Date: 2009-04-22 08:25:43 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* Copyright Interpeak AB 2000-2002 <www.interpeak.se>. All rights reserved.
|
||||
* Ported to IPCOM by Lennart Bang <lob@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 COPYRIGHTS
|
||||
****************************************************************************
|
||||
* Copyright (c) 1987, 1990, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#define IPCOM_USE_CLIB_PROTO
|
||||
#include <ipcom_getopt.h>
|
||||
#include <ipcom_file.h>
|
||||
#include <ipcom_clib.h>
|
||||
#include <ipcom_clib2.h>
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
#define SIZE_T_MAX UINT_MAX /* max value for a size_t */
|
||||
|
||||
#define OK_EXIT 0
|
||||
#define DIFF_EXIT 10
|
||||
#define ERR_EXIT 20 /* error exit code */
|
||||
|
||||
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
static void usage(void);
|
||||
static void c_special(int fd1, char *file1, Ip_off_t skip1, int fd2, char *file2, Ip_off_t skip2);
|
||||
static void eofmsg(char *file);
|
||||
static void diffmsg(char *file1, char *file2, Ip_off_t byte, Ip_off_t line);
|
||||
|
||||
int ipcrypto_cmd_cmp(int argc, char **argv);
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
static int lflag, sflag;
|
||||
|
||||
static const char __progname[] = "cmp";
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* errx
|
||||
*===========================================================================
|
||||
*/
|
||||
static void
|
||||
errx(int eval, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
ipcom_fprintf(ip_stderr, "%s", __progname);
|
||||
if(fmt != IP_NULL)
|
||||
ipcom_fprintf(ip_stderr, ": ");
|
||||
if (fmt != IP_NULL)
|
||||
{
|
||||
va_start(ap, fmt);
|
||||
ipcom_vfprintf(ip_stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
ipcom_fprintf(ip_stderr, IP_LF);
|
||||
|
||||
ipcom_exit(eval);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipcrypto_cmd_cmp
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_PUBLIC int
|
||||
ipcrypto_cmd_cmp(int argc, char **argv)
|
||||
{
|
||||
struct Ip_stat sb1, sb2;
|
||||
Ip_off_t skip1, skip2;
|
||||
int ch, fd1, fd2, special;
|
||||
char *file1, *file2;
|
||||
|
||||
ipcom_getopt_clear();
|
||||
lflag = 0;
|
||||
sflag = 0;
|
||||
|
||||
while ((ch = ipcom_getopt(argc, argv, "ls")) != -1)
|
||||
switch (ch) {
|
||||
case 'l': /* print all differences */
|
||||
lflag = 1;
|
||||
break;
|
||||
case 's': /* silent run */
|
||||
sflag = 1;
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
argv += ip_optind;
|
||||
argc -= ip_optind;
|
||||
|
||||
if (lflag && sflag)
|
||||
errx(ERR_EXIT, "only one of -l and -s may be specified");
|
||||
|
||||
if (argc < 2 || argc > 4)
|
||||
usage();
|
||||
|
||||
/* Backward compatibility -- handle "-" meaning stdin. */
|
||||
special = 0;
|
||||
if (ipcom_strcmp(file1 = argv[0], "-") == 0) {
|
||||
special = 1;
|
||||
fd1 = 0;
|
||||
file1 = "stdin";
|
||||
}
|
||||
else if ((fd1 = ipcom_fileopen(file1, IP_O_RDONLY, 0)) < 0) {
|
||||
if (!sflag)
|
||||
errx(ERR_EXIT, "%s", file1);
|
||||
else
|
||||
ipcom_exit(1);
|
||||
}
|
||||
if (ipcom_strcmp(file2 = argv[1], "-") == 0) {
|
||||
if (special)
|
||||
errx(ERR_EXIT,
|
||||
"standard input may only be specified once");
|
||||
special = 1;
|
||||
fd2 = 0;
|
||||
file2 = "stdin";
|
||||
}
|
||||
else if ((fd2 = ipcom_fileopen(file2, IP_O_RDONLY, 0)) < 0) {
|
||||
if (!sflag)
|
||||
errx(ERR_EXIT, "%s", file2);
|
||||
else
|
||||
ipcom_exit(1);
|
||||
}
|
||||
|
||||
skip1 = argc > 2 ? ipcom_atol(argv[2]) : 0;
|
||||
skip2 = argc == 4 ? ipcom_atol(argv[3]) : 0;
|
||||
|
||||
if (!special) {
|
||||
if (ipcom_fstat(fd1, &sb1)) {
|
||||
if (!sflag)
|
||||
errx(ERR_EXIT, "%s", file1);
|
||||
else
|
||||
ipcom_exit(1);
|
||||
}
|
||||
if (!IP_S_ISREG(sb1.st_mode))
|
||||
special = 1;
|
||||
else {
|
||||
if (ipcom_fstat(fd2, &sb2)) {
|
||||
if (!sflag)
|
||||
errx(ERR_EXIT, "%s", file2);
|
||||
else
|
||||
ipcom_exit(1);
|
||||
}
|
||||
if (!IP_S_ISREG(sb2.st_mode))
|
||||
special = 1;
|
||||
}
|
||||
}
|
||||
|
||||
c_special(fd1, file1, skip1, fd2, file2, skip2);
|
||||
ipcom_exit(0);
|
||||
return 0; /* will never get here. */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* usage
|
||||
*===========================================================================
|
||||
*/
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
(void)ipcom_fprintf(ip_stderr,
|
||||
"usage: cmp [-l | -s] file1 file2 [skip1 [skip2]]"IP_LF);
|
||||
ipcom_exit(ERR_EXIT);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* eofmsg
|
||||
*===========================================================================
|
||||
* from misc.c
|
||||
*/
|
||||
static void
|
||||
eofmsg(char *file)
|
||||
{
|
||||
if (!sflag)
|
||||
{
|
||||
(void)ipcom_fprintf(ip_stderr, "%s: ", __progname);
|
||||
ipcom_fprintf(ip_stderr, "EOF on %s, file"IP_LF, file);
|
||||
}
|
||||
ipcom_exit(DIFF_EXIT);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* diffmsg
|
||||
*===========================================================================
|
||||
* from misc.c
|
||||
*/
|
||||
static void
|
||||
diffmsg(char *file1, char *file2, Ip_off_t byte, Ip_off_t line)
|
||||
{
|
||||
if (!sflag)
|
||||
(void)ipcom_printf("%s %s differ: char %d, line %d"IP_LF,
|
||||
file1, file2, (int)byte, (int)line);
|
||||
ipcom_exit(DIFF_EXIT);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* c_special
|
||||
*===========================================================================
|
||||
* from special.c
|
||||
*/
|
||||
static void
|
||||
c_special(int fd1, char *file1, Ip_off_t skip1, int fd2, char *file2, Ip_off_t skip2)
|
||||
{
|
||||
int ch1, ch2;
|
||||
Ip_off_t byte, line;
|
||||
IP_FILE *fp1, *fp2;
|
||||
int dfound;
|
||||
|
||||
if ((fp1 = ipcom_fdopen(fd1, "r")) == IP_NULL)
|
||||
errx(ERR_EXIT, "%s", file1);
|
||||
if ((fp2 = ipcom_fdopen(fd2, "r")) == IP_NULL)
|
||||
errx(ERR_EXIT, "%s", file2);
|
||||
|
||||
dfound = 0;
|
||||
while (skip1--)
|
||||
if (ipcom_getc(fp1) == IP_EOF)
|
||||
goto eof;
|
||||
while (skip2--)
|
||||
if (ipcom_getc(fp2) == IP_EOF)
|
||||
goto eof;
|
||||
|
||||
for (byte = line = 1;; ++byte) {
|
||||
ch1 = ipcom_getc(fp1);
|
||||
ch2 = ipcom_getc(fp2);
|
||||
if (ch1 == IP_EOF || ch2 == IP_EOF)
|
||||
break;
|
||||
if (ch1 != ch2)
|
||||
{
|
||||
if (lflag) {
|
||||
dfound = 1;
|
||||
(void)ipcom_printf("%6d %3o %3o"IP_LF, (int)byte, ch1, ch2);
|
||||
} else
|
||||
diffmsg(file1, file2, byte, line);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
if (ch1 == '\n')
|
||||
++line;
|
||||
}
|
||||
|
||||
eof:
|
||||
if(ipcom_ferror(fp1))
|
||||
errx(ERR_EXIT, "%s", file1);
|
||||
if (ipcom_ferror(fp2))
|
||||
errx(ERR_EXIT, "%s", file2);
|
||||
if (ipcom_feof(fp1)) {
|
||||
if (!ipcom_feof(fp2))
|
||||
eofmsg(file1);
|
||||
} else
|
||||
if (ipcom_feof(fp2))
|
||||
eofmsg(file2);
|
||||
if (dfound)
|
||||
ipcom_exit(DIFF_EXIT);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,298 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK SOURCE FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipcrypto_cmd_fips_ctrl.c,v $ $Revision: 1.3 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipcrypto/src/ipcrypto_cmd_fips_ctrl.c,v $
|
||||
* $Author: rboden $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Roger Boden <roger.boden@windriver.com>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipcrypto_config.h"
|
||||
|
||||
#ifdef OPENSSL_FIPS
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
#define IPCOM_USE_CLIB_PROTO
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_clib.h>
|
||||
#include <ipcom_err.h>
|
||||
|
||||
#include <openssl/fips.h>
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#define IPCRYPTO_CMD_FIPS_CTRL_MODE 1
|
||||
#define IPCRYPTO_CMD_FIPS_CTRL_HASH 2
|
||||
|
||||
#define IPCRYPTO_CMD_FIPS_CTRL_MODE_ON 10
|
||||
#define IPCRYPTO_CMD_FIPS_CTRL_MODE_OFF 11
|
||||
#define IPCRYPTO_CMD_FIPS_CTRL_MODE_SHOW 12
|
||||
|
||||
#define bin2ascii(c) ((c)>=10?(((c)-10)+'A'):((c)+'0'))
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
struct Ipcrypto_cmd_fips_ctrl_str_map_st
|
||||
{
|
||||
const char* name;
|
||||
int value;
|
||||
};
|
||||
typedef struct Ipcrypto_cmd_fips_ctrl_str_map_st Ipcrypto_cmd_fips_ctrl_str_map;
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
unsigned int FIPS_incore_fingerprint(unsigned char *sig,unsigned int len);
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
IP_STATIC void
|
||||
ipcrypto_cmd_fips_ctrl_usage(void)
|
||||
{
|
||||
ipcom_printf("fips_ctrl command [args]\n"
|
||||
" The following commands are supported:\n"
|
||||
" - mode <on|off|show> Sets the FIPS mode on or off, \n"
|
||||
" or prints current mode\n"
|
||||
" - hash Prints incore hash value of\n"
|
||||
" the FIPS module\n");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
Ipcrypto_cmd_fips_ctrl_str_map cmd_str_map [] =
|
||||
{ {"mode", IPCRYPTO_CMD_FIPS_CTRL_MODE},
|
||||
{"hash", IPCRYPTO_CMD_FIPS_CTRL_HASH},
|
||||
{IP_NULL, -1} };
|
||||
|
||||
Ipcrypto_cmd_fips_ctrl_str_map mode_str_map [] =
|
||||
{ {"on", IPCRYPTO_CMD_FIPS_CTRL_MODE_ON},
|
||||
{"off", IPCRYPTO_CMD_FIPS_CTRL_MODE_OFF},
|
||||
{"show", IPCRYPTO_CMD_FIPS_CTRL_MODE_SHOW},
|
||||
{IP_NULL, -1} };
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 STATIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipcrypto_cmd_fips_ctrl_do_mode
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC int
|
||||
ipcrypto_cmd_fips_ctrl_do_mode(const char* sub_cmd)
|
||||
{
|
||||
int mode_cmd = 0;
|
||||
Ipcrypto_cmd_fips_ctrl_str_map *str_map = mode_str_map;
|
||||
|
||||
while (str_map->name)
|
||||
{
|
||||
if (ipcom_strcmp(str_map->name, sub_cmd) == 0)
|
||||
{
|
||||
mode_cmd = str_map->value;
|
||||
}
|
||||
str_map++;
|
||||
}
|
||||
|
||||
if (mode_cmd == 0)
|
||||
{
|
||||
ipcom_printf("Unknown mode sub-command: %s\n", sub_cmd);
|
||||
ipcrypto_cmd_fips_ctrl_usage();
|
||||
return -IP_ERRNO_EINVAL;
|
||||
}
|
||||
|
||||
switch (mode_cmd)
|
||||
{
|
||||
case IPCRYPTO_CMD_FIPS_CTRL_MODE_ON:
|
||||
if (FIPS_mode())
|
||||
{
|
||||
ipcom_printf("Already in FIPS mode\n");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
RAND_set_rand_method(IP_NULL);
|
||||
if (!FIPS_mode_set(1))
|
||||
{
|
||||
ipcom_printf("Failed to enable FIPS mode\n");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
ipcom_printf("FIPS mode on\n");
|
||||
return IPCOM_SUCCESS;
|
||||
|
||||
case IPCRYPTO_CMD_FIPS_CTRL_MODE_OFF:
|
||||
if (!FIPS_mode())
|
||||
{
|
||||
ipcom_printf("Not in FIPS mode\n");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
if (!FIPS_mode_set(0))
|
||||
{
|
||||
ipcom_printf("Failed to disable FIPS mode\n");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
ipcom_printf("FIPS mode off\n");
|
||||
return IPCOM_SUCCESS;
|
||||
|
||||
case IPCRYPTO_CMD_FIPS_CTRL_MODE_SHOW:
|
||||
if (FIPS_mode())
|
||||
ipcom_printf("FIPS mode on\n");
|
||||
else
|
||||
ipcom_printf("FIPS mode off\n");
|
||||
return IPCOM_SUCCESS;
|
||||
|
||||
default:
|
||||
IP_PANIC();
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipcrypto_cmd_fips_ctrl_do_hash
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC int
|
||||
ipcrypto_cmd_fips_ctrl_do_hash(void)
|
||||
{
|
||||
unsigned char sig[20];
|
||||
int i;
|
||||
int len;
|
||||
|
||||
len=FIPS_incore_fingerprint (sig,sizeof(sig));
|
||||
if (len!=sizeof(sig))
|
||||
{
|
||||
ipcom_printf("Failed to calculate incore hash of FIPS module\n");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
for (i=0; i<sizeof(sig); i++)
|
||||
ipcom_printf("0x%c%c, ", bin2ascii(sig[i]>>4), bin2ascii(sig[i]&0xf));
|
||||
ipcom_printf("\n");
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 GLOBAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
IP_GLOBAL int
|
||||
ipcrypto_cmd_fips_ctrl(int argc, char** argv)
|
||||
{
|
||||
int cmd = 0;
|
||||
Ipcrypto_cmd_fips_ctrl_str_map *str_map = cmd_str_map;
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
ipcrypto_cmd_fips_ctrl_usage();
|
||||
return -IP_ERRNO_EINVAL;
|
||||
}
|
||||
|
||||
while (str_map->name)
|
||||
{
|
||||
if (ipcom_strcmp(str_map->name, argv[1]) == 0)
|
||||
cmd = str_map->value;
|
||||
str_map++;
|
||||
}
|
||||
|
||||
if (cmd == 0)
|
||||
{
|
||||
ipcom_printf("Unknown command: %s\n", argv[1]);
|
||||
ipcrypto_cmd_fips_ctrl_usage();
|
||||
return -IP_ERRNO_EINVAL;
|
||||
}
|
||||
|
||||
if (cmd == IPCRYPTO_CMD_FIPS_CTRL_MODE)
|
||||
{
|
||||
if (argc != 3)
|
||||
{
|
||||
ipcrypto_cmd_fips_ctrl_usage();
|
||||
return -IP_ERRNO_EINVAL;
|
||||
}
|
||||
|
||||
return ipcrypto_cmd_fips_ctrl_do_mode(argv[2]);
|
||||
}
|
||||
|
||||
if (cmd == IPCRYPTO_CMD_FIPS_CTRL_HASH)
|
||||
{
|
||||
if (argc != 2)
|
||||
{
|
||||
ipcrypto_cmd_fips_ctrl_usage();
|
||||
return -IP_ERRNO_EINVAL;
|
||||
}
|
||||
return ipcrypto_cmd_fips_ctrl_do_hash();
|
||||
|
||||
}
|
||||
|
||||
/* We should never get here */
|
||||
IP_PANIC();
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 11 PUBLIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#endif /* OPENSSL_FIPS */
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
|
||||
* code or tables extracted from it, as desired without restriction.
|
||||
*
|
||||
* First, the polynomial itself and its table of feedback terms. The
|
||||
* polynomial is
|
||||
* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0
|
||||
*
|
||||
* Note that we take it "backwards" and put the highest-order term in
|
||||
* the lowest-order bit. The X^32 term is "implied"; the LSB is the
|
||||
* X^31 term, etc. The X^0 term (usually shown as "+1") results in
|
||||
* the MSB being 1
|
||||
*
|
||||
* Note that the usual hardware shift register implementation, which
|
||||
* is what we're using (we're merely optimizing it by doing eight-bit
|
||||
* chunks at a time) shifts bits into the lowest-order term. In our
|
||||
* implementation, that means shifting towards the right. Why do we
|
||||
* do it this way? Because the calculated CRC must be transmitted in
|
||||
* order from highest-order term to lowest-order term. UARTs transmit
|
||||
* characters in order from LSB to MSB. By storing the CRC this way
|
||||
* we hand it to the UART in the order low-byte to high-byte; the UART
|
||||
* sends each low-bit to hight-bit; and the result is transmission bit
|
||||
* by bit from highest- to lowest-order term without requiring any bit
|
||||
* shuffling on our part. Reception works similarly
|
||||
*
|
||||
* The feedback terms table consists of 256, 32-bit entries. Notes
|
||||
*
|
||||
* The table can be generated at runtime if desired; code to do so
|
||||
* is shown later. It might not be obvious, but the feedback
|
||||
* terms simply represent the results of eight shift/xor opera
|
||||
* tions for all combinations of data and CRC register values
|
||||
*
|
||||
* The values must be right-shifted by eight bits by the "updcrc
|
||||
* logic; the shift must be u_(bring in zeroes). On some
|
||||
* hardware you could probably optimize the shift in assembler by
|
||||
* using byte-swap instructions
|
||||
* polynomial $edb88320
|
||||
*/
|
||||
|
||||
|
||||
#include <ipcom_type.h>
|
||||
|
||||
#include "ipcrypto.h"
|
||||
|
||||
static Ip_u32 crc32_tab[] = {
|
||||
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
|
||||
0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
|
||||
0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
|
||||
0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
|
||||
0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
|
||||
0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
|
||||
0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
|
||||
0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
|
||||
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
|
||||
0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
|
||||
0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
|
||||
0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
|
||||
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
|
||||
0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
|
||||
0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
|
||||
0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
|
||||
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
|
||||
0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
|
||||
0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
|
||||
0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
|
||||
0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
|
||||
0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
|
||||
0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
|
||||
0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
|
||||
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
|
||||
0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
|
||||
0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
|
||||
0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
|
||||
0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
|
||||
0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
|
||||
0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
|
||||
0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
|
||||
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
|
||||
0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
|
||||
0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
|
||||
0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
|
||||
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
|
||||
0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
|
||||
0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
|
||||
0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
|
||||
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
|
||||
0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
|
||||
0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
|
||||
0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
|
||||
0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
|
||||
0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
|
||||
0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
|
||||
0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
|
||||
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
|
||||
0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
|
||||
0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
|
||||
0x2d02ef8dL
|
||||
};
|
||||
|
||||
/* Return a 32-bit CRC of the contents of the buffer. */
|
||||
|
||||
Ip_u32
|
||||
ipcrypto_crc32(const Ip_u8* s, Ip_u32 len)
|
||||
{
|
||||
Ip_u32 i;
|
||||
Ip_u32 crc32val;
|
||||
|
||||
crc32val = 0;
|
||||
for (i = 0; i < len; i ++) {
|
||||
crc32val = crc32_tab[(crc32val ^ s[i]) & 0xff] ^ (crc32val >> 8);
|
||||
}
|
||||
return crc32val;
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK INTERNAL API HEADER FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipcrypto_h.h,v $ $Revision: 1.2 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipcrypto/src/ipcrypto_h.h,v $
|
||||
* $Author: roger $ $Date: 2007-05-11 07:50:07 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* Copyright Interpeak AB 2000-2003 <www.interpeak.se>. All rights reserved.
|
||||
* Design and implementation by Roger Boden <roger@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef IPCRYPTO_H_H
|
||||
#define IPCRYPTO_H_H
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipcrypto_config.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_os.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* syslog
|
||||
*===========================================================================
|
||||
*/
|
||||
#define IPCOM_SYSLOG_PRIORITY IPCRYPTO_SYSLOG_PRIORITY
|
||||
#define IPCOM_SYSLOG_FACILITY IPCOM_LOG_IPCRYPTO
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
struct Ipcrypto_data_st
|
||||
{
|
||||
Ipcom_mutex* crypto_locks;
|
||||
};
|
||||
|
||||
typedef struct Ipcrypto_data_st Ipcrypto_data;
|
||||
|
||||
IP_EXTERN Ipcrypto_data ipcrypto;
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
@@ -0,0 +1,168 @@
|
||||
#define IPCOM_USE_CLIB_PROTO
|
||||
#include <ipcom_clib.h>
|
||||
#include <ipcrypto_config.h>
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_err.h>
|
||||
|
||||
#include <openssl/evp.h>
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipcrypto_oaep_mask
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
static void
|
||||
ipcrypto_oaep_mask(const EVP_MD* hash,
|
||||
Ip_u8* seed,
|
||||
int seed_len,
|
||||
Ip_u8* data,
|
||||
int data_len)
|
||||
|
||||
{
|
||||
unsigned count = 0;
|
||||
|
||||
ip_assert(EVP_MD_size(hash) <= EVP_MAX_MD_SIZE);
|
||||
|
||||
while (data_len > 0) {
|
||||
int i, max = (data_len > EVP_MD_size(hash) ? EVP_MD_size(hash) : data_len);
|
||||
EVP_MD_CTX md_ctx;
|
||||
unsigned char counter[4], hash_buf[EVP_MAX_MD_SIZE];
|
||||
unsigned int hash_size = sizeof(hash_buf);
|
||||
|
||||
|
||||
IP_SET_HTONL(counter, count);
|
||||
|
||||
EVP_MD_CTX_init(&md_ctx);
|
||||
EVP_DigestInit(&md_ctx, hash);
|
||||
EVP_DigestUpdate(&md_ctx, seed, seed_len);
|
||||
EVP_DigestUpdate(&md_ctx, counter, 4);
|
||||
EVP_DigestFinal(&md_ctx, hash_buf, &hash_size);
|
||||
count++;
|
||||
|
||||
for (i = 0; i < max; i++)
|
||||
data[i] ^= hash_buf[i];
|
||||
|
||||
data += max;
|
||||
data_len -= max;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipcrypto_rsa_oaep
|
||||
*===========================================================================
|
||||
* Description:
|
||||
|
||||
+----------+---------+-------+
|
||||
DB = | lHash | PS | M |
|
||||
+----------+---------+-------+
|
||||
|
|
||||
+----------+ V
|
||||
| seed |--> MGF ---> xor
|
||||
+----------+ |
|
||||
| |
|
||||
+--+ V |
|
||||
|00| xor <----- MGF <-----|
|
||||
+--+ | |
|
||||
| | |
|
||||
V V V
|
||||
+--+----------+----------------------------+
|
||||
EM = |00|maskedSeed| maskedDB |
|
||||
+--+----------+----------------------------+
|
||||
* Parameters:
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL void
|
||||
ipcrypto_rsa_oaep_encode(const EVP_MD* hash,
|
||||
unsigned char *in,
|
||||
int inlen,
|
||||
unsigned char *out,
|
||||
int outlen)
|
||||
{
|
||||
int k = outlen; /* length in octets of the RSA modulus */
|
||||
int i;
|
||||
const int hLen = EVP_MD_size(hash);
|
||||
unsigned int md_size;
|
||||
|
||||
/* The length of the input data must be at most k - 2hLen - 2. */
|
||||
ip_assert(inlen > 0 && inlen <= k - 2*hLen - 2);
|
||||
|
||||
/* Leading byte zero. */
|
||||
out[0] = 0;
|
||||
/* At position 1, the seed: hLen bytes of random data. */
|
||||
for (i = 1; i < hLen+1; i+=4)
|
||||
{
|
||||
Ip_u32 rnd;
|
||||
rnd = ipcom_random();
|
||||
if ((hLen+1)-i >=4)
|
||||
ipcom_memcpy(&out[i], &rnd, 4);
|
||||
else
|
||||
ipcom_memcpy(&out[i], &rnd, (hLen+1)-i);
|
||||
}
|
||||
/* The data block DB starts at position 1+hLen, consisting of: */
|
||||
/* The hash of the label (only an empty label supported) */
|
||||
EVP_Digest(IP_NULL, 0, &out[1+hLen], &md_size, hash, IP_NULL);
|
||||
/* Zero octets padding */
|
||||
ipcom_memset(out + 2*hLen + 1, 0, outlen - (2*hLen + 1));
|
||||
/* A single 1 octet, thereafter the input message data. */
|
||||
out[outlen - inlen - 1] = 1;
|
||||
ipcom_memcpy(out + outlen - inlen, in, inlen);
|
||||
|
||||
/* Use the seed data to mask the block DB with the seed data */
|
||||
ipcrypto_oaep_mask(hash, out+1, hLen, out+hLen+1, outlen-hLen-1);
|
||||
|
||||
/* Mask the masked DB with the seed. */
|
||||
ipcrypto_oaep_mask(hash, out+hLen+1, outlen-hLen-1, out+1, hLen);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipcrypto_rsa_oaep_decode
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipcrypto_rsa_oaep_decode(const EVP_MD* hash,
|
||||
unsigned char *in,
|
||||
int in_len,
|
||||
unsigned char *out,
|
||||
int* out_len)
|
||||
{
|
||||
const int hLen = EVP_MD_size(hash);
|
||||
int pos;
|
||||
|
||||
/* Unmask seed */
|
||||
ipcrypto_oaep_mask(hash, in+1+hLen, in_len-(1+hLen), in+1, hLen);
|
||||
|
||||
/* Unmask cleartext message, using seed */
|
||||
ipcrypto_oaep_mask(hash, in+1, hLen, in+1+hLen, in_len-(1+hLen));
|
||||
|
||||
/* Proceed past section of null padding */
|
||||
pos = 2*hLen+1;
|
||||
while (in[pos] == 0 && pos < in_len)
|
||||
pos++;
|
||||
if (in[pos] != 1 || pos > in_len-1)
|
||||
return IPCOM_ERR_INVALID_ARG;
|
||||
pos++; /* Proceed past '1' byte */
|
||||
|
||||
if (*out_len < in_len-pos-1)
|
||||
return IPCOM_ERR_INVALID_ARG;
|
||||
|
||||
*out_len = in_len-pos;
|
||||
ipcom_memcpy(out, &in[pos], *out_len);
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
Reference in New Issue
Block a user