1.2.11.2 Using The Library
The SE Security library is called perform cryptographic operations.
The following example, which is an extract from G3 LBP eap_psk.c file, illustrates how the Security service can be used.
Example of SE Security library usage
// ***************************************************************************** // ***************************************************************************** // Section: File includes // ***************************************************************************** // ***************************************************************************** #include <stdbool.h> #include <stdint.h> #include <string.h> #include "adp_api_types.h" #include "eap_psk.h" #include "service/security/aes_wrapper.h" #include "service/security/cipher_wrapper.h" // ***************************************************************************** // ***************************************************************************** // Section: Macro Definitions // ***************************************************************************** // ***************************************************************************** #define member_size(type, member) sizeof(((type *)0)->member) /* IANA allocated value */ #define EAP_PSK_IANA_TYPE 0x2F // ***************************************************************************** // ***************************************************************************** // Section: Interface Function Definitions // ***************************************************************************** // ***************************************************************************** void EAP_PSK_Initialize(EAP_PSK_KEY *pKey, EAP_PSK_CONTEXT *pPskContext) { uint8_t block[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; uint8_t res[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; (void) memset(pPskContext, 0, sizeof(EAP_PSK_CONTEXT)); /* Set key and trigger the AES ECB */ AES_Wrapper_SetEncryptEcbKey(pKey->value); AES_Wrapper_EncryptEcb(block, res); /* Xor with c1 = "1" */ res[15] ^= 0x01U; /* Generate AK */ AES_Wrapper_EncryptEcb(res, pPskContext->ak.value); /* Generate AK */ /* Xor with c1 = "2" */ res[15] ^= 0x03U; /* 3 instead of 2 because it has been already xor'ed with 1 and we want to get back the initial value */ /* Generate KDK */ AES_Wrapper_EncryptEcb(res, pPskContext->kdk.value); } uint16_t EAP_PSK_EncodeMessage3( EAP_PSK_CONTEXT *pPskContext, uint8_t identifier, EAP_PSK_RAND *pRandS, EAP_PSK_RAND *pRandP, EAP_PSK_NETWORK_ACCESS_ID_S *pIdS, uint32_t nonce, uint8_t PChannelResult, uint16_t PChannelDataLength, uint8_t *pPChannelData, uint16_t memoryBufferLength, uint8_t *pMemoryBuffer ) { uint16_t encodeSize = 0U; uint8_t macS[16]; uint8_t *pProtectedData = NULL; uint16_t protectedDataLength = 0U; uint8_t *pTag = NULL; uint8_t auxNonce[16]; int32_t ret; uint8_t seed[LBP_NETWORK_ACCESS_ID_MAX_SIZE_S + member_size(EAP_PSK_RAND, value)]; uint8_t seedSize = pIdS->size + (uint8_t)member_size(EAP_PSK_RAND, value); /* check the size of the buffer */ if (memoryBufferLength >= FIXED_LEN + PChannelDataLength) { (void) memcpy(seed, pIdS->value, pIdS->size); (void) memcpy(&seed[pIdS->size], pRandP->value, sizeof(pRandP->value)); ret = CIPHER_Wrapper_AesCmacDirect(seed, seedSize, macS, pPskContext->ak.value); /* Encode the EAP header; length field will be set at the end of the block */ pMemoryBuffer[0] = EAP_REQUEST; pMemoryBuffer[1] = identifier; pMemoryBuffer[4] = EAP_PSK_IANA_TYPE; pMemoryBuffer[5] = EAP_PSK_T2; encodeSize = 6U; /* EAP message: add PSK fields */ (void) memcpy(&pMemoryBuffer[encodeSize], pRandS->value, sizeof(pRandS->value)); encodeSize += (uint16_t)sizeof(pRandS->value); (void) memcpy(&pMemoryBuffer[encodeSize], macS, sizeof(macS)); encodeSize += (uint16_t)sizeof(macS); /* Prepare P-Channel content */ (void) memset(auxNonce, 0, sizeof(auxNonce)); auxNonce[12] = pMemoryBuffer[encodeSize++] = (uint8_t)(nonce >> 24); auxNonce[13] = pMemoryBuffer[encodeSize++] = (uint8_t)(nonce >> 16); auxNonce[14] = pMemoryBuffer[encodeSize++] = (uint8_t)(nonce >> 8); auxNonce[15] = pMemoryBuffer[encodeSize++] = (uint8_t)nonce; /* tag will be added later */ pTag = &pMemoryBuffer[encodeSize]; encodeSize += 16U; /* protected data */ pProtectedData = &pMemoryBuffer[encodeSize]; if (PChannelDataLength > 0U) { /* result / extension = 1 */ pProtectedData[protectedDataLength] = (PChannelResult << 6) | 0x20U; protectedDataLength++; (void) memcpy(&pProtectedData[protectedDataLength], pPChannelData, PChannelDataLength); protectedDataLength += PChannelDataLength; } else { /* result / extension = 0 */ pProtectedData[protectedDataLength] = (PChannelResult << 6); protectedDataLength++; } encodeSize += protectedDataLength; /* Update the EAP header length field */ pMemoryBuffer[2] = (uint8_t)(encodeSize >> 8); pMemoryBuffer[3] = (uint8_t)encodeSize; /* right shift Code field with 2 bits as indicated in the EAP specification */ pMemoryBuffer[0] >>= 2; /* Encrypt P-Channel using TEK key */ if (CIPHER_WRAPPER_RETURN_GOOD != CIPHER_Wrapper_AesEaxEncrypt( pProtectedData, /* the message buffer */ protectedDataLength, /* and its length in bytes */ auxNonce, /* the initialization vector */ 16U, /* and its length in bytes */ pMemoryBuffer, /* the header buffer */ 22U, /* and its length in bytes */ pTag, /* the buffer for the tag */ 16U, /* and its length in bytes */ pPskContext->tek.value)) /* the key */ { encodeSize = 0U; } /* Fix EAP header: left shift Code field with 2 bits as indicated in the G3 specification */ pMemoryBuffer[0] <<= 2; } return encodeSize; }