Jump to main content

# 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;
    }

Rev: G