/* ****************************************************************************** * SOURCE FILE * * Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipike_payload_nonce.c,v $ $Revision: 1.19.10.1 $ * $Source: /home/interpeak/CVSRoot/ipike/src/ipike_payload_nonce.c,v $ * $Author: zan $ $Date: 2013-01-10 03:36:54 $ * $State: Exp $ $Locker: $ * * INTERPEAK_COPYRIGHT_STRING * Design and implementation by Kenneth Jonsson ****************************************************************************** */ /* **************************************************************************** * 1 DESCRIPTION **************************************************************************** */ /* Nonce payload (RFC 2408, chapter 3.13) */ /* **************************************************************************** * 2 CONFIGURATION **************************************************************************** */ #include "ipike_config.h" /* **************************************************************************** * 3 INCLUDE FILES **************************************************************************** */ #include "ipike_h.h" #include "ipike_payload_nonce.h" #include "ipike_util.h" #include "ipike_sadb.h" #include #include #include /* **************************************************************************** * 4 EXTERN PROTOTYPES **************************************************************************** */ /* **************************************************************************** * 5 DEFINES **************************************************************************** */ /* **************************************************************************** * 6 TYPES **************************************************************************** */ /* **************************************************************************** * 7 LOCAL PROTOTYPES **************************************************************************** */ /* *=========================================================================== * ipike_payload_nonce_data *=========================================================================== * Description: Returns a pointer to the nonce data in the payload. * Parameters: nonce - a nonce payload. * Returns: A pointer to the nonce data. * */ IP_STATIC Ip_u8 * ipike_payload_nonce_data(Ipike_nonce_payload* nonce); /* *=========================================================================== * ipike_payload_nonce_data_length *=========================================================================== * Description: Returns the length of the nonce data. * Parameters: nonce - nonce payload. * Returns: The length of the nonce data (in bytes). * */ IP_STATIC Ip_u16 ipike_payload_nonce_data_length(Ipike_nonce_payload* nonce); /* **************************************************************************** * 8 DATA **************************************************************************** */ /* **************************************************************************** * 9 LOCAL FUNCTIONS **************************************************************************** */ /* *=========================================================================== * ipike_payload_nonce_data *=========================================================================== */ IP_STATIC Ip_u8 * ipike_payload_nonce_data(Ipike_nonce_payload* nonce) { return (Ip_u8*) nonce + IPIKE_NONCE_HEADER_LENGTH; } /* *=========================================================================== * ipike_payload_nonce_data_length *=========================================================================== */ IP_STATIC Ip_u16 ipike_payload_nonce_data_length(Ipike_nonce_payload* nonce) { return IPIKE_PAYLOAD_DATA_LENGTH(nonce->header.length, IPIKE_NONCE_HEADER_LENGTH); } /* **************************************************************************** * 10 PUBLIC FUNCTIONS **************************************************************************** */ /* *=========================================================================== * ipike_payload_nonce_data_length *=========================================================================== */ IP_GLOBAL Ipike_nonce_payload * ipike_payload_nonce_new(const Ip_u8* nonce_data, Ip_u16 nonce_len) { Ipike_nonce_payload* ret; if (IP_NULL == (ret = ipcom_calloc(1, IPIKE_NONCE_HEADER_LENGTH + nonce_len))) { IPCOM_LOG0(CRIT, "ipike_payload_nonce_new() :: out of memory"); return IP_NULL; } ret->header.length = ip_htons(IPIKE_NONCE_HEADER_LENGTH + nonce_len); ret->header.next_payload = IPIKE_PAYLOAD_NONCE; ipcom_memcpy(ipike_payload_nonce_data(ret), nonce_data, nonce_len); return ret; } /* *=========================================================================== * ipike_payload_nonce_create *=========================================================================== */ IP_GLOBAL Ipike_error ipike_payload_nonce_create(Ipike_value* n, Ipike_nonce_payload** nonce) { if (n->len == 0) { /* There is not any nonce to send, so don't generate any payload */ *nonce = IP_NULL; } else { *nonce = ipike_payload_nonce_new(n->value, (Ip_u16) n->len); if (IP_NULL == *nonce) { IP_PANIC(); return IPIKE_OUT_OF_MEMORY; } } return IPIKE_SUCCESS; } /* *=========================================================================== * ipike_payload_nonce_check *=========================================================================== */ IP_GLOBAL Ipike_error ipike_payload_nonce_check(Ipike_nonce_payload* nonce) { /* The length of nonce payload MUST be between 8 and 256 bytes inclusive. */ if (ipike_payload_nonce_data_length(nonce) < IPIKE_NONCE_MIN_LEN || ipike_payload_nonce_data_length(nonce) > IPIKE_NONCE_MAX_LEN) { IPCOM_LOG3(ERR, "ipike_payload_nonce_check() :: the nonce size must be between %d"\ " and %d, this nonce was %d", IPIKE_NONCE_MIN_LEN, IPIKE_NONCE_MAX_LEN, ipike_payload_nonce_data_length(nonce)); return IPIKE_NONCE_INVALID_SIZE; } return IPIKE_SUCCESS; } /* *=========================================================================== * ipike2_payload_nonce_check *=========================================================================== */ IP_GLOBAL Ipike_error ipike2_payload_nonce_check(Ipike_nonce_payload* nonce) { /* The length of nonce payload MUST be at lease 16 bytes. */ if (ipike_payload_nonce_data_length(nonce) < IPIKE2_NONCE_MIN_LEN ) { IPCOM_LOG2(ERR, "ipike_payload_nonce_check() :: the nonce size must be at lease %d"\ " , this nonce was %d", IPIKE2_NONCE_MIN_LEN, ipike_payload_nonce_data_length(nonce)); return IPIKE_NONCE_INVALID_SIZE; } return IPIKE_SUCCESS; } /* *=========================================================================== * ipike_payload_nonce_print *=========================================================================== */ IP_GLOBAL void ipike_payload_nonce_print(Ipike_nonce_payload* nonce) { char* nonce_hex; nonce_hex = ipike_memory_to_string(ipike_payload_nonce_data(nonce), ipike_payload_nonce_data_length(nonce), 4); if (IP_NULL == nonce_hex) { IPCOM_LOG0(CRIT, "ipike_print_nonce_payload() :: out of memory"); return; } IPCOM_LOG1(DEBUG2, " data: \n%s", nonce_hex); ipcom_free(nonce_hex); } /* *=========================================================================== * ipike_payload_nonce_extract *=========================================================================== */ IP_GLOBAL Ipike_error ipike_payload_nonce_extract(Ipike_nonce_payload *payload, Ipike_value *nonce) { nonce->len = ipike_payload_nonce_data_length(payload); ipcom_free(nonce->value); if (IP_NULL == (nonce->value = ipcom_malloc(nonce->len))) { IP_PANIC(); return IPIKE_OUT_OF_MEMORY; } ipcom_memcpy(nonce->value, ipike_payload_nonce_data(payload), nonce->len); return IPIKE_SUCCESS; } /* *=========================================================================== * ipike_payload_nonce_generate *=========================================================================== */ IP_GLOBAL Ipike_error ipike_payload_nonce_generate(Ipike_value* nonce) { int noice_size = ipcom_sysvar_get_as_int("ipike.nonce_size", 64); ipcom_free(nonce->value); if (IP_NULL == (nonce->value = ipcom_malloc((Ip_size_t) noice_size))) { IP_PANIC(); return IPIKE_OUT_OF_MEMORY; } nonce->len = (Ip_size_t) noice_size; if (RAND_bytes(nonce->value, noice_size) == 0) { IPCOM_LOG0(CRIT, "ipike_payload_nonce_generate() :: failed to generate random."); return IPIKE_FAILED; } return IPIKE_SUCCESS; } /* *=========================================================================== * ipike_payload_nonce_cmp *=========================================================================== */ IP_GLOBAL int ipike_payload_nonce_cmp(Ipike_value* nonce1, Ipike_value* nonce2) { Ip_u8 *n1_data; Ip_u8 *n1_data_end; Ip_u8 *n2_data; Ip_u8 *n2_data_end; n1_data = nonce1->value; n1_data_end = n1_data + nonce1->len; n2_data = nonce2->value; n2_data_end = n2_data + nonce2->len; /* Compare nonce byte by byte until a differance has been found */ while (n1_data < n1_data_end && n2_data < n2_data_end) { if ( *n1_data < *n2_data ) return -1; else if ( *n1_data > *n2_data ) return 1; n1_data++; n2_data++; } /* Nonce n1 has reached the end before n2 => n1 < n2 */ if ( n1_data == n1_data_end && n2_data != n2_data_end ) return -1; /* Nonce n2 has reached the end before n1 => n2 < n1 */ if ( n2_data == n2_data_end && n1_data != n1_data_end ) return 1; /* Nonces are equal */ return 0; } /* **************************************************************************** * END OF FILE **************************************************************************** */