Skip to content

Files

Latest commit

ea285a6 · Dec 9, 2022

History

History
This branch is 3 commits behind Infineon/optiga-trust-m:develop.

pal

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
Aug 11, 2022
Oct 22, 2021
Oct 22, 2021
Jan 25, 2022
Oct 15, 2021
Oct 22, 2021
Aug 11, 2020
Oct 15, 2021
Feb 28, 2022
Aug 11, 2020

README.md

Porting guide

Port Platfrom Abstraction Layer

To port the Software Framework on you Host platfrom please follow this guidance

Note: If you have a strict requirements on type of memmory allocation, consider changing pal_os_malloc(), pal_os_calloc(), pal_os_free() functions in the pal_os_memory.h file

Port Crypto module for Platfrom Abstraction Layer

The Crypto PAL helps a Host MCU to perfrom shielded communication (protected Infineon I2C protocol) between the Host and the Trust M If you don't use shielded connection you can skip this module

Currently three Crypto PALs are supported via third-party libraries (should be provided at compilation/linking time)

  1. mbed TLS Crypto Library
  2. OpenSSL Crypto Library
  3. WolfSSL Crypto Library

There are three functions required to be implemented by the Crypto PAL, these are:

  1. pal_crypt_tls_prf_sha256

    Test Vectors
    **********************************************************************************************
    
    static const uint8_t example_secret[] = {
        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
    };
    
    static const uint8_t example_label[] = {
        0x42, 0x61, 0x62, 0x79, 0x6c, 0x6f, 0x6e, 0x20,
        0x50, 0x52, 0x46, 0x20, 0x41, 0x70, 0x70, 0x4e,
        0x6f, 0x74, 0x65
    };
    
    static const uint8_t example_seed[] = {
        0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
        0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
        0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f
    };
    
    static const uint8_t example_result[] = {
        0xbf, 0x88, 0xeb, 0xde, 0xfa, 0x78, 0x46, 0xa1,
        0x10, 0x55, 0x91, 0x88, 0xd4, 0x22, 0xf3, 0xf7,
        0xfa, 0xfe, 0xf4, 0xa5, 0x49, 0xbd, 0xaa, 0xce,
        0x37, 0x39, 0xc9, 0x44, 0x65, 0x7f, 0x2d, 0xd9,
        0xbc, 0x30, 0x83, 0x14, 0x47, 0xd0, 0xed, 0x1c,
        0x89, 0xf6, 0x58, 0x23, 0xb2, 0xec, 0xe0, 0x52,
        0xf3, 0xb7, 0x95, 0xed, 0xe8, 0x6c, 0xad, 0x59,
        0xca, 0x47, 0x3b, 0x3a, 0x78, 0x98, 0x63, 0x69,
        0x44, 0x65, 0x62, 0xc9, 0xa4, 0x0d, 0x6a, 0xac,
        0x59, 0xa2, 0x04, 0xfa, 0x0e, 0x44, 0xb7, 0xd7
    };
    
    **********************************************************************************************
    
    // Test Vector from website www.ietf.org/mail-archive/web/tls/current/msg03416.html
    // Secret
    static const uint8_t tls_at_ietf_secret[] = 
    {
        0x9b,0xbe,0x43,0x6b,0xa9,0x40,0xf0,0x17,    
        0xb1,0x76,0x52,0x84,0x9a,0x71,0xdb,0x35      
    };
    
    // Seed
    static const uint8_t tls_at_ietf_seed[] = 
    {
        0xa0,0xba,0x9f,0x93,0x6c,0xda,0x31,0x18,    
        0x27,0xa6,0xf7,0x96,0xff,0xd5,0x19,0x8c       
    };
    
    // Label test label (0x74,0x65,0x73,0x74,0x20,0x6c,0x61,0x62,0x65,0x6c)
    static const uint8_t tls_at_ietf_label[] = 
    {
        0x74,0x65,0x73,0x74,0x20,0x6c,0x61,0x62,
        0x65,0x6c
    };
    
    // Output
    static const uint8_t tls_at_ietf_output[] = 
    {
        0xe3,0xf2,0x29,0xba,0x72,0x7b,0xe1,0x7b,    
        0x8d,0x12,0x26,0x20,0x55,0x7c,0xd4,0x53,    
        0xc2,0xaa,0xb2,0x1d,0x07,0xc3,0xd4,0x95,    
        0x32,0x9b,0x52,0xd4,0xe6,0x1e,0xdb,0x5a,    
        0x6b,0x30,0x17,0x91,0xe9,0x0d,0x35,0xc9,    
        0xc9,0xa4,0x6b,0x4e,0x14,0xba,0xf9,0xaf,    
        0x0f,0xa0,0x22,0xf7,0x07,0x7d,0xef,0x17,    
        0xab,0xfd,0x37,0x97,0xc0,0x56,0x4b,0xab,    
        0x4f,0xbc,0x91,0x66,0x6e,0x9d,0xef,0x9b,    
        0x97,0xfc,0xe3,0x4f,0x79,0x67,0x89,0xba,    
        0xa4,0x80,0x82,0xd1,0x22,0xee,0x42,0xc5,    
        0xa7,0x2e,0x5a,0x51,0x10,0xff,0xf7,0x01,    
        0x87,0x34,0x7b,0x66    
    };
  2. pal_crypt_encrypt_aes128_ccm

    Test Vectors
    /* key */
    static const uint8_t key[] =
    {
        0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
        0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf
    };
    
    /* nonce */
    static const uint8_t nonce[] =
    {
        0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0xa0,
        0xa1, 0xa2, 0xa3, 0xa4, 0xa5
    };
    
    /* plaintext */
    static const uint8_t plainText[] =
    {
        0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
        0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e
    };
    
    //Associated Data
    static const uint8_t aData[] =
    {
        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
    };
    
    //Cipher text
    static const uint8_t cipherText[] =
    {
        0x58, 0x8c, 0x97, 0x9a, 0x61, 0xc6, 0x63, 0xd2,
        0xf0, 0x66, 0xd0, 0xc2, 0xc0, 0xf9, 0x89, 0x80,
        0x6d, 0x5f, 0x6b, 0x61, 0xda, 0xc3, 0x84
    };
    
    //MAC
    static const uint8_t mac[] =
    {
    0x17, 0xe8, 0xd1, 0x2c, 0xfd, 0xf9, 0x26, 0xe0
    };
  3. pal_crypt_decrypt_aes128_ccm

    Test Vectors
    /* key */
    static const uint8_t key[] =
    {
        0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
        0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf
    };
    
    /* nonce */
    static const uint8_t nonce[] =
    {
        0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0xa0,
        0xa1, 0xa2, 0xa3, 0xa4, 0xa5
    };
    
    /* plaintext */
    static const uint8_t plainText[] =
    {
        0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
        0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e
    };
    
    //Associated Data
    static const uint8_t aData[] =
    {
        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
    };
    
    //Cipher text
    static const uint8_t cipherText[] =
    {
        0x58, 0x8c, 0x97, 0x9a, 0x61, 0xc6, 0x63, 0xd2,
        0xf0, 0x66, 0xd0, 0xc2, 0xc0, 0xf9, 0x89, 0x80,
        0x6d, 0x5f, 0x6b, 0x61, 0xda, 0xc3, 0x84
    };
    
    //MAC
    static const uint8_t mac[] =
    {
    0x17, 0xe8, 0xd1, 0x2c, 0xfd, 0xf9, 0x26, 0xe0
    };

A simple test suite can look like following

Simple Test suite
    
static int32_t testTLSPRF256(void)
{
    int32_t ret = 1;
    static uint8_t example_secret[] = {
        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
    };

    static uint8_t example_label[] = {
        0x42, 0x61, 0x62, 0x79, 0x6c, 0x6f, 0x6e, 0x20,
        0x50, 0x52, 0x46, 0x20, 0x41, 0x70, 0x70, 0x4e,
        0x6f, 0x74, 0x65
    };

    static uint8_t example_seed[] = {
        0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
        0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
        0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f
    };

    static uint8_t example_result[] = {
        0xbf, 0x88, 0xeb, 0xde, 0xfa, 0x78, 0x46, 0xa1,
        0x10, 0x55, 0x91, 0x88, 0xd4, 0x22, 0xf3, 0xf7,
        0xfa, 0xfe, 0xf4, 0xa5, 0x49, 0xbd, 0xaa, 0xce,
        0x37, 0x39, 0xc9, 0x44, 0x65, 0x7f, 0x2d, 0xd9,
        0xbc, 0x30, 0x83, 0x14, 0x47, 0xd0, 0xed, 0x1c,
        0x89, 0xf6, 0x58, 0x23, 0xb2, 0xec, 0xe0, 0x52,
        0xf3, 0xb7, 0x95, 0xed, 0xe8, 0x6c, 0xad, 0x59,
        0xca, 0x47, 0x3b, 0x3a, 0x78, 0x98, 0x63, 0x69,
        0x44, 0x65, 0x62, 0xc9, 0xa4, 0x0d, 0x6a, 0xac,
        0x59, 0xa2, 0x04, 0xfa, 0x0e, 0x44, 0xb7, 0xd7
    };
    uint8_t p_derived_key[sizeof(example_result)];
    memset(p_derived_key, 0x00, sizeof(example_result));

    do 
    {
        pal_crypt_tls_prf_sha256(NULL,
                                 example_secret,
                                 sizeof(example_secret),
                                 example_label,
                                 sizeof(example_label),
                                 example_seed,
                                 sizeof(example_seed),
                                 p_derived_key,
                                 sizeof(example_result));
                                 
        if (memcmp(p_derived_key, example_result, sizeof(example_result)) != 0)
        {
            output_result("Derived Key: ", p_derived_key, sizeof(p_derived_key));
            output_result("Expected Key: ", example_result, sizeof(example_result));
            break;
        }
        
        ret = 0;
    }while(0);
    
    return ret;
}

#define NB_TESTS 3
#define CCM_SELFTEST_PT_MAX_LEN 24
#define CCM_SELFTEST_CT_MAX_LEN 32
/*
 * The data is the same for all tests, only the used length changes
 */
static const uint8_t key[] = {
    0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
    0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f
};

static const uint8_t iv[] = {
    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
    0x18, 0x19, 0x1a, 0x1b
};

static const uint8_t ad[] = {
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
    0x10, 0x11, 0x12, 0x13
};

static uint8_t msg[CCM_SELFTEST_PT_MAX_LEN] = {
    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
    0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
};

static const size_t iv_len [NB_TESTS] = { 7, 8,  12 };
static const size_t add_len[NB_TESTS] = { 8, 16, 20 };
static const size_t msg_len[NB_TESTS] = { 4, 16, 24 };
static const size_t tag_len[NB_TESTS] = { 4, 6,  8  };

static  uint8_t res[NB_TESTS][CCM_SELFTEST_CT_MAX_LEN] = {
    {   0x71, 0x62, 0x01, 0x5b, 0x4d, 0xac, 0x25, 0x5d },
    {   0xd2, 0xa1, 0xf0, 0xe0, 0x51, 0xea, 0x5f, 0x62,
        0x08, 0x1a, 0x77, 0x92, 0x07, 0x3d, 0x59, 0x3d,
        0x1f, 0xc6, 0x4f, 0xbf, 0xac, 0xcd },
    {   0xe3, 0xb2, 0x01, 0xa9, 0xf5, 0xb7, 0x1a, 0x7a,
        0x9b, 0x1c, 0xea, 0xec, 0xcd, 0x97, 0xe7, 0x0b,
        0x61, 0x76, 0xaa, 0xd9, 0xa4, 0x42, 0x8a, 0xa5,
        0x48, 0x43, 0x92, 0xfb, 0xc1, 0xb0, 0x99, 0x51 }
};


static int32_t testAES128CCMEncrypt(void)
{
    int32_t ret = 1;
    uint8_t plaintext[CCM_SELFTEST_PT_MAX_LEN];
    uint8_t ciphertext[CCM_SELFTEST_CT_MAX_LEN];

    do 
    {
        for( int i = 0; i < NB_TESTS; i++ )
        {
            memset( plaintext, 0, CCM_SELFTEST_PT_MAX_LEN );
            memset( ciphertext, 0, CCM_SELFTEST_CT_MAX_LEN );
            memcpy( plaintext, msg, msg_len[i] );
            
            pal_crypt_encrypt_aes128_ccm(NULL,
                                         plaintext,
                                         CCM_SELFTEST_PT_MAX_LEN,
                                         key,
                                         iv,
                                         iv_len[i],
                                         ad,
                                         add_len[i],
                                         tag_len[i],
                                         ciphertext);
            if (memcmp(ciphertext, res[i], msg_len[i] + tag_len[i])!= 0)
            {
                output_result("Result Cipher: ", ciphertext, msg_len[i] + tag_len[i]);
                output_result("Expected Cipher: ", res[i], msg_len[i] + tag_len[i]);
                break;
            }
        }
        
        ret = 0;
    }while(0);
    
    return ret;
}

static int32_t testAES128CCMDecrypt(void)
{
    int32_t ret = 1;
    uint8_t plaintext[CCM_SELFTEST_PT_MAX_LEN];
    uint8_t ciphertext[CCM_SELFTEST_CT_MAX_LEN];

    do 
    {
        for( int i = 0; i < NB_TESTS; i++ )
        {
            memset( plaintext, 0, CCM_SELFTEST_PT_MAX_LEN );
            memset( ciphertext, 0, CCM_SELFTEST_CT_MAX_LEN );
            memcpy( plaintext, msg, msg_len[i] );
            
            pal_crypt_decrypt_aes128_ccm( NULL,
                                      res[i],
                                      CCM_SELFTEST_PT_MAX_LEN,
                                      key,
                                      iv,
                                      iv_len[i],
                                      ad,
                                      add_len[i],
                                      tag_len[i],
                                      plaintext);
            if (memcmp(plaintext, msg, msg_len[i]) != 0)
            {
                output_result("Result Plain Text: ", plaintext, msg_len[i]);
                output_result("Expected Plain Text: ", msg, msg_len[i]);
                break;
            }
        }
        
        ret = 0;
    }while(0);
    
    return ret;
}