/* * Copyright 2016-2020 NXP * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * o Redistributions of source code must retain the above copyright notice, this list * of conditions and the following disclaimer. * * o 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. * * o Neither the name of NXP Semiconductor, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. */ /** * @file Test_SE_project.c * @brief Application entry point. */ #include #include "board.h" #include "peripherals.h" #include "pin_mux.h" #include "clock_config.h" #include "MK64F12.h" #include "fsl_debug_console.h" /* TODO: insert other include files here. */ #include "se05x_APDU_apis.h" #include "ex_sss_objid.h" //include "nxLog_Api.h" #include #include #include #include "se050_tests.h" /* TODO: insert other definitions and declarations here. */ #define STATIC_HOSKEY_MAC_ID 200 #define STATIC_HOSKEY_ENC_ID 201 #define STATIC_HOSKEY_DEK_ID 202 #define STATIC_AES_SESSION_KEY 220 #define DYN_HOSKEY_MAC_ID 203 #define DYN_HOSKEY_ENC_ID 204 #define DYN_HOSKEY_DEK_ID 205 extern uint8_t SCP03_key_2[16]; sss_status_t JCOP4_GetDataIdentify(void *conn_ctx); U16 GP_Select(void *conn_ctx, const U8 *appletName, U16 appletNameLen, U8 *response, U16 *responseLen); U32 smCom_TransceiveRaw(void *conn_ctx, U8 *pTx, U16 txLen, U8 *pRx, U32 *pRxLen); SE_Connect_Ctx_t se05_connect_ctx; sss_se05x_session_t se050session; sss_se05x_key_store_t se05KeyStore; uint8_t dummy_key[32]; NXSCP03_DynCtx_t dyn_keys_ctx; NXSCP03_StaticCtx_t static_keys; // SE050C1 #define SSS_AUTH_SE050C1_KEY_ENC \ {0x85, 0x2b, 0x59, 0x62, 0xe9, 0xcc, 0xe5, 0xd0, 0xbe, 0x74, 0x6b, 0x83, 0x3b, 0xcc, 0x62, 0x87 } #define SSS_AUTH_SE050C1_KEY_MAC \ {0xdb, 0x0a, 0xa3, 0x19, 0xa4, 0x08, 0x69, 0x6c, 0x8e, 0x10, 0x7a, 0xb4, 0xe3, 0xc2, 0x6b, 0x47 } #define SSS_AUTH_SE050C1_KEY_DEK \ {0x4c, 0x2f, 0x75, 0xc6, 0xa2, 0x78, 0xa4, 0xae, 0xe5, 0xc9, 0xaf, 0x7c, 0x50, 0xee, 0xa8, 0x0c } #define SSS_AUTH_SE050C2_KEY_ENC \ {0xbd, 0x1d, 0xe2, 0x0a, 0x81, 0xea, 0xb2, 0xbf, 0x3b, 0x70, 0x9a, 0x9d, 0x69, 0xa3, 0x12, 0x54 } #define SSS_AUTH_SE050C2_KEY_MAC \ {0x9a, 0x76, 0x1b, 0x8d, 0xba, 0x6b, 0xed, 0xf2, 0x27, 0x41, 0xe4, 0x5d, 0x8d, 0x42, 0x36, 0xf5 } #define SSS_AUTH_SE050C2_KEY_DEK \ {0x9b, 0x99, 0x3b, 0x60, 0x0f, 0x1c, 0x64, 0xf5, 0xad, 0xc0, 0x63, 0x19, 0x2a, 0x96, 0xc9, 0x47 } #define SSS_AUTH_SE050_DEVKIT_KEY_ENC \ {0x35, 0xc2, 0x56, 0x45, 0x89, 0x58, 0xa3, 0x4f, 0x61, 0x36, 0x15, 0x5f, 0x82, 0x09, 0xd6, 0xcd } #define SSS_AUTH_SE050_DEVKIT_KEY_MAC \ {0xaf, 0x17, 0x7d, 0x5d, 0xbd, 0xf7, 0xc0, 0xd5, 0xc1, 0x0a, 0x05, 0xb9, 0xf1, 0x60, 0x7f, 0x78 } #define SSS_AUTH_SE050_DEVKIT_KEY_DEK \ {0xa1, 0xbc, 0x84, 0x38, 0xbf, 0x77, 0x93, 0x5b, 0x36, 0x1a, 0x44, 0x25, 0xfe, 0x79, 0xfa, 0x29 } //uint8_t scp_enc_key[SCP03_KEYLEN] = SSS_AUTH_SE050_DEVKIT_KEY_ENC; //uint8_t scp_mac_key[SCP03_KEYLEN] = SSS_AUTH_SE050_DEVKIT_KEY_MAC; //uint8_t scp_dek_key[SCP03_KEYLEN] = SSS_AUTH_SE050_DEVKIT_KEY_DEK; uint8_t scp_enc_key[SCP03_KEYLEN] = SCP03_NEW_KEY; uint8_t scp_mac_key[SCP03_KEYLEN] = SCP03_NEW_KEY; uint8_t scp_dek_key[SCP03_KEYLEN] = SCP03_NEW_KEY; // uint8_t aes_key_128[] = { 0xfb, 0x44, 0xda, 0xdc, 0xd7, 0xb3, 0x78, 0x3b, 0x5a, 0xb4, 0xe4, 0x7d, 0xc4, 0xab, 0x0d, 0xe1}; uint8_t aes_key_256[] = { 0x5b, 0x92, 0x5a, 0xf1, 0x7a, 0x76, 0xca, 0xcd, 0x8e, 0x21, 0x3c, 0xd4, 0x70, 0xa8, 0x7a, 0x02, 0x54, 0x78, 0x3c, 0x17, 0x10, 0x0e, 0x73, 0x50, 0xf2, 0xbe, 0xd7, 0x20, 0xe7, 0xc9, 0x06, 0xf5 }; uint8_t binary_data[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' }; static sss_status_t Alloc_Scp03key_toSE05xAuthctx(sss_object_t *keyObject, sss_key_store_t *pKs, uint32_t keyId, uint32_t keylen) { sss_status_t status = kStatus_SSS_Fail; status = sss_host_key_object_init(keyObject, pKs); if (status != kStatus_SSS_Success) { return status; } status = sss_host_key_object_allocate_handle( keyObject, keyId, kSSS_KeyPart_Default, kSSS_CipherType_AES, keylen, kKeyObject_Mode_Transient); if(status == kStatus_SSS_Success) { // explicitly set the cipher type keyObject->cipherType = kSSS_CipherType_AES; } return status; } static sss_status_t create_scp03_keys(void) { sss_status_t status = kStatus_SSS_Fail; static_keys.keyVerNo = 0xB; Alloc_Scp03key_toSE05xAuthctx(&static_keys.Mac, (sss_key_store_t*)&se05KeyStore, STATIC_HOSKEY_MAC_ID, sizeof(scp_mac_key)); /* Set MAC Static Key */ status = sss_host_key_store_set_key((sss_key_store_t*)&se05KeyStore, &static_keys.Mac, scp_mac_key, sizeof(scp_mac_key), sizeof(scp_mac_key) * 8, NULL, 0); if (status != kStatus_SSS_Success) { return status; } /* Setup ENC Static Key */ Alloc_Scp03key_toSE05xAuthctx(&static_keys.Enc, (sss_key_store_t*)&se05KeyStore, STATIC_HOSKEY_ENC_ID, sizeof(scp_enc_key)); status = sss_host_key_store_set_key((sss_key_store_t*)&se05KeyStore, &static_keys.Enc, scp_enc_key, sizeof(scp_enc_key), sizeof(scp_enc_key) * 8, NULL, 0); if (status != kStatus_SSS_Success) { return status; } /* Set up DEK Static Key */ Alloc_Scp03key_toSE05xAuthctx(&static_keys.Dek, (sss_key_store_t*)&se05KeyStore, STATIC_HOSKEY_DEK_ID, sizeof(scp_dek_key)); status = sss_host_key_store_set_key((sss_key_store_t*)&se05KeyStore, &static_keys.Dek, scp_dek_key, sizeof(scp_dek_key), sizeof(scp_dek_key) * 8, NULL, 0); if (status != kStatus_SSS_Success) { return status; } // allocate memory for dynamic keys status = Alloc_Scp03key_toSE05xAuthctx(&dyn_keys_ctx.Mac, (sss_key_store_t*)&se05KeyStore, DYN_HOSKEY_MAC_ID, 16); status |= Alloc_Scp03key_toSE05xAuthctx(&dyn_keys_ctx.Enc, (sss_key_store_t*)&se05KeyStore, DYN_HOSKEY_ENC_ID, 16); status |= Alloc_Scp03key_toSE05xAuthctx(&dyn_keys_ctx.Rmac, (sss_key_store_t*)&se05KeyStore, DYN_HOSKEY_DEK_ID, 16); return status; } extern uint8_t aes_auth_key[16]; extern uint8_t aes_auth_key_2[16]; extern uint8_t aes_factoryreset_key[16]; static sss_status_t create_aes_authkey(uint32_t keyid) { sss_status_t status; uint8_t *key; uint32_t keylen; switch(keyid) { case AES_AUTH_ID: key = aes_auth_key; keylen = sizeof(aes_auth_key); break; case AES_AUTH_ID_2: key = aes_auth_key_2; keylen = sizeof(aes_auth_key_2); break; case kSE05x_AppletResID_FACTORY_RESET: key = aes_factoryreset_key; keylen = sizeof(aes_factoryreset_key); break; case kSE05x_AppletResID_TRANSPORT: key = xport_lock_key; keylen = sizeof(xport_lock_key); break; default: return kStatus_SSS_InvalidArgument; break; } Alloc_Scp03key_toSE05xAuthctx(&static_keys.Mac, (sss_key_store_t*)&se05KeyStore, STATIC_HOSKEY_MAC_ID, keylen); /* Set MAC Static Key */ status = sss_host_key_store_set_key((sss_key_store_t*)&se05KeyStore, &static_keys.Mac, key, keylen, keylen * 8, NULL, 0); if (status != kStatus_SSS_Success) { return status; } /* Set up DEK Static Key */ Alloc_Scp03key_toSE05xAuthctx(&static_keys.Dek, (sss_key_store_t*)&se05KeyStore, STATIC_HOSKEY_DEK_ID, keylen); status = sss_host_key_store_set_key((sss_key_store_t*)&se05KeyStore, &static_keys.Dek, key, keylen, keylen * 8, NULL, 0); if (status != kStatus_SSS_Success) { return status; } /* Setup ENC Static Key */ Alloc_Scp03key_toSE05xAuthctx(&static_keys.Enc, (sss_key_store_t*)&se05KeyStore, STATIC_AES_SESSION_KEY, keylen); status = sss_host_key_store_set_key((sss_key_store_t*)&se05KeyStore, &static_keys.Enc, key, keylen, keylen * 8, NULL, 0); if (status != kStatus_SSS_Success) { return status; } // allocate memory for dynamic keys status = Alloc_Scp03key_toSE05xAuthctx(&dyn_keys_ctx.Mac, (sss_key_store_t*)&se05KeyStore, DYN_HOSKEY_MAC_ID, keylen); status |= Alloc_Scp03key_toSE05xAuthctx(&dyn_keys_ctx.Enc, (sss_key_store_t*)&se05KeyStore, DYN_HOSKEY_ENC_ID, keylen); status |= Alloc_Scp03key_toSE05xAuthctx(&dyn_keys_ctx.Rmac, (sss_key_store_t*)&se05KeyStore, DYN_HOSKEY_DEK_ID, keylen); return status; } #define CHECK_FEATURE_PRESENT(AppletConfig, ITEM) \ if (((kSE05x_AppletConfig_##ITEM) == ((AppletConfig) & (kSE05x_AppletConfig_##ITEM)))) { \ LOG_I("With " #ITEM); \ } \ else { \ LOG_I("WithOut " #ITEM); \ } static sss_status_t get_se050_info(sss_se05x_session_t *pSession) { smStatus_t sw_status; uint8_t applet_versinfo[7] = {0}; size_t verslen = sizeof(applet_versinfo); sw_status = Se05x_API_GetVersion(&pSession->s_ctx, applet_versinfo, &verslen); if (sw_status != SM_OK) { return kStatus_SSS_Fail; } // VersionInfo is a 7 - byte value consisting of : // - 1 - byte Major applet version // - 1 - byte Minor applet version // - 1 - byte patch applet version // - 2 - byte AppletConfig, indicating the supported applet features // - 2-byte Secure Box version: major version (MSB) concatenated with minor version (LSB). LOG_I("Applet Major = %d", applet_versinfo[0]); LOG_I("Applet Minor = %d", applet_versinfo[1]); LOG_I("Applet patch = %d", applet_versinfo[2]); U16 AppletConfig = applet_versinfo[3] << 8 | applet_versinfo[4]; CHECK_FEATURE_PRESENT(AppletConfig, ECDAA); CHECK_FEATURE_PRESENT(AppletConfig, ECDSA_ECDH_ECDHE); CHECK_FEATURE_PRESENT(AppletConfig, EDDSA); CHECK_FEATURE_PRESENT(AppletConfig, DH_MONT); CHECK_FEATURE_PRESENT(AppletConfig, HMAC); CHECK_FEATURE_PRESENT(AppletConfig, RSA_PLAIN); CHECK_FEATURE_PRESENT(AppletConfig, RSA_CRT); CHECK_FEATURE_PRESENT(AppletConfig, AES); CHECK_FEATURE_PRESENT(AppletConfig, DES); CHECK_FEATURE_PRESENT(AppletConfig, PBKDF); CHECK_FEATURE_PRESENT(AppletConfig, TLS); CHECK_FEATURE_PRESENT(AppletConfig, MIFARE); CHECK_FEATURE_PRESENT(AppletConfig, I2CM); //JCOP4_GetDataIdentify(&pSession->s_ctx); return kStatus_SSS_Success; } static void deinit_se050(void) { sss_se05x_session_close(&se050session); } typedef enum { SE_AUTH_NONE = 0, SE_AUTH_AES, SE_AUTH_AES_2, SE_AUTH_SCP03_PLAT, SE_AUTH_FACTORY_RESET, SE_AUTH_XPORT_LOCK } se_auth_type_t; static sss_status_t init_se050(void) { sss_status_t status = kStatus_SSS_Fail; sss_connection_type_t conn_type; uint32_t app_id = 0; se_auth_type_t auth_type = SE_AUTH_AES; //SE_AUTH_NONE; //SE_AUTH_SCP03_PLAT; //SE_AUTH_AES; SE_AUTH_FACTORY_RESET sss_se05x_key_store_context_init(&se05KeyStore, &se050session); switch(auth_type) { case SE_AUTH_AES: se05_connect_ctx.auth.authType = kSSS_AuthType_AESKey; conn_type = kSSS_ConnectionType_Encrypted; app_id = AES_AUTH_ID; create_aes_authkey(AES_AUTH_ID); break; case SE_AUTH_AES_2: se05_connect_ctx.auth.authType = kSSS_AuthType_AESKey; conn_type = kSSS_ConnectionType_Encrypted; app_id = AES_AUTH_ID_2; create_aes_authkey(AES_AUTH_ID_2); break; case SE_AUTH_SCP03_PLAT: se05_connect_ctx.auth.authType = kSSS_AuthType_SCP03; conn_type = kSSS_ConnectionType_Encrypted; create_scp03_keys(); break; case SE_AUTH_FACTORY_RESET: create_aes_authkey(kSE05x_AppletResID_FACTORY_RESET); se05_connect_ctx.auth.authType = kSSS_AuthType_AESKey; app_id = kSE05x_AppletResID_FACTORY_RESET; conn_type = kSSS_ConnectionType_Encrypted; break; case SE_AUTH_XPORT_LOCK: create_aes_authkey(kSE05x_AppletResID_TRANSPORT); se05_connect_ctx.auth.authType = kSSS_AuthType_AESKey; app_id = kSE05x_AppletResID_TRANSPORT; conn_type = kSSS_ConnectionType_Encrypted; break; case SE_AUTH_NONE: // No encryption or authentication se05_connect_ctx.auth.authType = kSSS_AuthType_None; conn_type = kSSS_ConnectionType_Plain; app_id = 0; break; default: break; } se05_connect_ctx.connType = kType_SE_Conn_Type_T1oI2C; // step pointers to keys used for SCP se05_connect_ctx.auth.ctx.scp03.pDyn_ctx = &dyn_keys_ctx; se05_connect_ctx.auth.ctx.scp03.pStatic_ctx = &static_keys; //se05_connect_ctx.session_policy TBD // -------- Memory Leak with sss_se05x_session_open() -------- // NOTE: This call allocates memory here: se050session.s_ctx.conn_ctx // when creating the T1-I2C connection. The function phNxpEse_open(), // in phNxpEse_Api.c, allocates memory with this statement: // pnxpese_ctxt = (phNxpEse_Context_t*)malloc(sizeof(phNxpEse_Context_t)); // // This memory isn't freed when the session closed resulting // in a memory leak. //se05_connect_ctx.skip_select_applet = 1; status = sss_se05x_session_open(&se050session, kType_SSS_SE_SE05x, app_id, conn_type, &se05_connect_ctx); return status; } static sss_status_t create_random_value(sss_se05x_session_t *pSession) { // get random number sss_se05x_rng_context_t rng_context = {0}; uint8_t random_data[34] = {0}; sss_status_t status = kStatus_SSS_Success; status = sss_se05x_rng_context_init(&rng_context, pSession); if(status != kStatus_SSS_Success) { return status; } status = sss_se05x_rng_get_random(&rng_context, random_data, sizeof(random_data)); sss_se05x_rng_context_free(&rng_context); if(status != kStatus_SSS_Success) { LOG_E("sss_se05x_rng_get_random Failed"); } return status; } static sss_status_t create_ecc_key_with_policy(sss_se05x_session_t *pSession, uint32_t keyid) { uint32_t keyId = keyid; /*We demonstrate for cipher type and key size corresponding to NISTP-256 keypair only*/ sss_se05x_object_t obj; sss_key_part_t keyPart = kSSS_KeyPart_Pair; sss_cipher_type_t cipherType = kSSS_CipherType_EC_NIST_P; size_t keyBitLen = 256; sss_status_t status; sss_se05x_key_store_t keystore; sss_se05x_key_store_context_init(&keystore, pSession); status = sss_se05x_key_object_init(&obj, &keystore); status = sss_se05x_key_object_allocate_handle(&obj, keyId, keyPart, cipherType, keyBitLen * 8, kKeyObject_Mode_Persistent); if(status != kStatus_SSS_Success) { LOG_E("Failed to alloc handle"); } /*Logic to pass sign policy*/ const int enable = 1; /* doc:start:allow-policy-sign-part1 */ /* Policies for key */ const sss_policy_u key_withPol = { .type = KPolicy_Asym_Key, /*Authentication object based on SE05X_AUTH*/ .auth_obj_id = kSSS_AuthType_SCP03, // AES_AUTH_ID, .policy = { /*Asymmetric key policy*/ .asymmkey = { /*Policy for sign*/ .can_Sign = enable, /*Policy for verify*/ .can_Verify = 1, /*Policy for encrypt*/ .can_Encrypt = 1, /*Policy for decrypt*/ .can_Decrypt = 1, /*Policy for Key Derivation*/ .can_KD = 1, /*Policy for wrapped object*/ .can_Wrap = 1, /*Policy to re-write object*/ .can_Write = 1, /*Policy for reading object*/ .can_Read = 1, /*Policy to use object for attestation*/ .can_Attest = 1, } } }; /* Common rules */ const sss_policy_u common = { .type = KPolicy_Common, /*Authentication object based on SE05X_AUTH*/ .auth_obj_id = kSSS_AuthType_SCP03, //AES_AUTH_ID, //kSSS_AuthType_SCP03, .policy = { .common = { /*Secure Messaging*/ .req_Sm = 0, /*Policy to Delete object*/ .can_Delete = 1, /*Forbid all operations on object*/ .forbid_All = 0, } } }; /* create policy set */ sss_policy_t policy_for_ec_key = { .nPolicies = 2, .policies = { &key_withPol, &common } }; /* doc:end:allow-policy-sign-part1 */ status = sss_se05x_key_store_generate_key(&keystore, &obj, keyBitLen, &policy_for_ec_key); if(status != kStatus_SSS_Success) { LOG_E("Failed to generate ECC key"); } // free the key object sss_se05x_key_object_free(&obj); return status; } static sss_status_t get_ecc_pubkey_key(sss_se05x_session_t *pSession, uint32_t keyid) { sss_status_t status; sss_se05x_object_t obj; size_t keyBitLen = 256; uint8_t key[256] = {0}; size_t keyByteLen = sizeof(key); sss_se05x_key_store_t keystore; sss_se05x_key_store_context_init(&keystore, pSession); status = sss_se05x_key_object_init(&obj, &keystore); if(status != kStatus_SSS_Success) { LOG_E("Failed to init object"); return status; } status = sss_se05x_key_object_get_handle(&obj, keyid); if(status != kStatus_SSS_Success) { LOG_E("Failed to get object handle for key"); return status; } status = sss_se05x_key_store_get_key(&keystore, &obj, key, &keyByteLen, &keyBitLen); if(status != kStatus_SSS_Success) { LOG_E("Failed to get public key"); return status; } // free the key object sss_se05x_key_object_free(&obj); return status; } sss_status_t delete_all(sss_se05x_session_t *pSession) { smStatus_t status = Se05x_API_DeleteAll(&pSession->s_ctx); if(status == SM_OK) { LOG_I("Successfully deleted all secure objects."); } else { LOG_E("Failed to delete all secure objects."); } return kStatus_SSS_Success; } static sss_status_t list_all_secureobjects(sss_se05x_session_t *pSession) { uint8_t pmore = kSE05x_MoreIndicator_NA; uint8_t list[1024]; size_t listlen = sizeof(list); uint32_t secure_obj_id; uint16_t outputOffset = 0; uint16_t secobj_size; uint32_t total_len = 0; SE05x_SecureObjectType_t secobj_type; uint8_t transient; smStatus_t status; do { status = Se05x_API_ReadIDList(&pSession->s_ctx, outputOffset, 0xFF, &pmore, list, &listlen); if(status != SM_OK) { LOG_E("Failed to get secure object ids"); return kStatus_SSS_Fail; } outputOffset = (uint16_t)listlen; LOG_I("Got secure object ids, count: %d", listlen / 4); for(uint32_t i = 0; i < listlen ; i += 4) { secure_obj_id = ( (list[i + 0] << 24) | (list[i + 1] << 16) | (list[i + 2] << 8) | list[i + 3] ); secobj_type = 0; status = Se05x_API_ReadType(&pSession->s_ctx, secure_obj_id, &secobj_type, &transient, kSE05x_AttestationType_None); // get size status = Se05x_API_ReadSize(&pSession->s_ctx, secure_obj_id, &secobj_size); if(status == SM_OK) { total_len += secobj_size; } LOG_I("Secure Object id: 0x%x, type: 0x%x, size: %d", secure_obj_id, secobj_type, secobj_size); } } while(pmore == kSE05x_MoreIndicator_MORE); // Log total len LOG_I("Total bytes: %d", total_len); status = Se05x_API_ReadCryptoObjectList(&pSession->s_ctx, list, &listlen); if(status == SM_OK) { LOG_I("Crypto object count: %d", listlen / 4); } return kStatus_SSS_Success; } uint8_t tempbuf[500]; static sss_status_t test_se050(sss_se05x_session_t *pSession) { static sss_status_t status = kStatus_SSS_Success; size_t actualLen = 0; //list_all_secureobjects(pSession); //status = setest_read_attest(pSession, 700); //status = setest_set_factoryreset_authkey(pSession); //status = setest_deleteall(pSession); //return status; //status = setest_create_authkey(pSession); //status = setest_create_aes2_authkey(pSession); //return status; //status = setest_create_aeskey(pSession, aes_key_256, sizeof(aes_key_256), 1001); //actualLen = sizeof(tempbuf); //status = setest_read_object(pSession, 1001, tempbuf, &actualLen); //status = setest_create_binary_object(pSession, 3700, binary_data, sizeof(binary_data)); //status = setest_create_binaryobj_with_policy(pSession, binary_data, sizeof(binary_data), 5000); //actualLen = sizeof(tempbuf); //status = setest_read_object(pSession, 5000, tempbuf, &actualLen); //status = setest_AES_Encrypt(pSession); //status = setest_roll_scp03_keys(pSession, &se05_connect_ctx); //status = setest_create_authkey(pSession); status = setest_test_access(pSession, 0x5920); return status; //status = get_ecc_pubkey_key(pSession, 516); status = create_ecc_key_with_policy(pSession, 753); if(status == kStatus_SSS_Success) { // now try to delete status = setest_delete_secure_object(pSession, 753); if(status != kStatus_SSS_Success) { LOG_E("Failed to delete secure object"); } } else { LOG_E("Failed to create secure object"); } status = setest_delete_secure_object(pSession, 500); if(status != kStatus_SSS_Success) { LOG_E("Failed to delete key."); } //delete_all(pSession); status = create_ecc_key_with_policy(pSession, 500); if(status != kStatus_SSS_Success) { LOG_E("Failed to create key w/policy."); } // get random value status = create_random_value(pSession); if(status != kStatus_SSS_Success) { LOG_E("Failed to create random value."); } // create key status = setest_create_ecc_key(pSession, 100); if(status != kStatus_SSS_Success) { LOG_E("Failed to create ECC key"); return status; } status = get_ecc_pubkey_key(pSession, 100); if(status != kStatus_SSS_Success) { LOG_E("Failed to get ECC key public key"); return status; } setest_delete_secure_object(pSession, 100); list_all_secureobjects(pSession); return status; } // DAG DEBUG BEG void axReset_HostConfigure(void); void axReset_PowerUp(void); uint32_t sm_initSleep(void); // DAG DEUG END /* * @brief Application entry point. */ int main(void) { /* Init board hardware. */ BOARD_InitBootPins(); BOARD_InitBootClocks(); BOARD_InitBootPeripherals(); /* Init FSL debug console. */ BOARD_InitDebugConsole(); axReset_HostConfigure(); axReset_PowerUp(); sm_initSleep(); //PRINTF("Hello World\n"); if(init_se050() == kStatus_SSS_Success) { test_se050(&se050session); //setest_xport_tests(&se050session); deinit_se050(); } /* Force the counter to be placed into memory. */ volatile static int i = 0 ; /* Enter an infinite loop, just incrementing a counter. */ while(1) { i++ ; /* 'Dummy' NOP to allow source level single stepping of tight while() loop */ __asm volatile ("nop"); } return 0 ; } sss_status_t JCOP4_GetDataIdentify(void *conn_ctx) { sss_status_t status = kStatus_SSS_Fail; smStatus_t rxStatus; char jcop_platform_id[17] = {0}; /* Must be packed */ typedef struct { //0xFE Tag value - proprietary data Only present if class byte is 0x80 uint8_t vTag_value_proprietary_data; //0x49 / 0x45 Length of following data Only present if class byte is 0x80 uint8_t vLength_of_following_data; //0xDF28 Tag card identification data Only present if class byte is 0x80 uint8_t vTag_card_identification_data[0x02]; //0x46 Length of card identification data Only present if class byte is 0x80 uint8_t vLength_of_card_identification_data; //0x01 Tag configuration ID Identifies the configuration content uint8_t vTag_configuration_ID; uint8_t vLength_configuration_ID; //0x0C Length configuration ID uint8_t vConfiguration_ID[0x0C]; //var Configuration ID uint8_t vTag_patch_ID; //0x02 Tag patch ID Identifies the patch level uint8_t vLength_patch_ID; //0x08 Length patch ID uint8_t vPatch_ID[0x08]; //var Patch ID //0x03 Tag platform build ID1 Identifies the JCOP platform uint8_t vTag_platform_build_ID1; uint8_t vLength_platform_build_ID; //0x18 Length platform build ID uint8_t vPlatform_build_ID[0x18]; //var Platform build ID uint8_t vTag_FIPS_mode; //0x052 Tag FIPS mode FIPS mode active uint8_t vLength_FIPS_mode; //0x01 Length FIPS mode //var FIPS mode 0x00 - FIPS mode not active, 0x01 - FIPS mode active uint8_t vFIPS_mode; //uint8_t vTag_modules_enabled; //0x06 Tag modules enabled Lists enabled and disabled modules //uint8_t vLength_modules_enabled; //0x02 Length modules enabled Big endian format //uint8_t vBit_mask_of_enabled_modules[0x02]; //var Bit mask of enabled modules See Table 5.3 //0x07 Tag pre-perso state Lists pre-perso state uint8_t vTag_pre_perso_state; //0x01 Length pre-perso state uint8_t vLength_pre_perso_state; //var Bit mask of pre-perso state bit0 = 1 = config module available, // bit1 = 1 = transport state is active. // Unused bits are set to 0x0. uint8_t vBit_mask_of_pre_perso_state; uint8_t vTag_ROM_ID; //'08' Tag ROM ID Indentifies the ROM content uint8_t vLength_ROM_ID; //'08' Length ROM ID Normal ending uint8_t vROM_ID[0x08]; //var ROM ID uint8_t vStatus_Word_SW_[0x02]; //9000h Status Word (SW) } identifyRsp_t; const uint8_t cmd[] = { 0x80, // CLA '80' / '00' GlobalPlatform / ISO / IEC 0xCA, // INS 'CA' GET DATA(IDENTIFY) 0x00, // P1 '00' High order tag value 0xFE, // P2 'FE' Low order tag value - proprietary data 0x02, // Lc '02' Length of data field 0xDF, 0x28, // Data 'DF28' Card identification data 0x00 // Le '00' Length of response data }; identifyRsp_t identifyRsp = {0}; U32 prspLen = sizeof(identifyRsp_t); U16 dummyResponse16 = sizeof(identifyRsp_t); /* Select card manager / ISD * (ReUsing same dummy buffers) */ rxStatus = GP_Select(conn_ctx, (uint8_t *)&identifyRsp /* dummy */, 0, (uint8_t *)&identifyRsp, &dummyResponse16); if (rxStatus != SM_OK) { LOG_E("Could not select ISD."); goto cleanup; } rxStatus = smCom_TransceiveRaw(conn_ctx, (uint8_t *)cmd, sizeof(cmd), (uint8_t *)&identifyRsp, &prspLen); if (rxStatus == SM_OK && prspLen == sizeof(identifyRsp)) { LOG_W("#####################################################"); LOG_I("%s = 0x%02X", "Tag value - proprietary data 0xFE", identifyRsp.vTag_value_proprietary_data); LOG_I("%s = 0x%02X", "Length of following data 0x45", identifyRsp.vLength_of_following_data); LOG_MAU8_I("Tag card identification data", identifyRsp.vTag_card_identification_data, sizeof(identifyRsp.vTag_card_identification_data)); LOG_I("%s = 0x%02X", "Length of card identification data", // 0x46 identifyRsp.vLength_of_card_identification_data); LOG_I("%s = 0x%02X", "Tag configuration ID (Must be 0x01)", identifyRsp.vTag_configuration_ID); LOG_D("%s = 0x%02X", "Length configuration ID 0x0C", identifyRsp.vLength_configuration_ID); LOG_MAU8_I("Configuration ID", identifyRsp.vConfiguration_ID, sizeof(identifyRsp.vConfiguration_ID)); //Third and fourth Byte of vConfiguration_ID is the OEF ID LOG_MAU8_I("OEF ID", &identifyRsp.vConfiguration_ID[2], 2); LOG_I("%s = 0x%02X", "Tag patch ID (Must be 0x02)", identifyRsp.vTag_patch_ID); LOG_D("%s = 0x%02X", "Length patch ID 0x08", identifyRsp.vLength_patch_ID); LOG_MAU8_I("Patch ID", identifyRsp.vPatch_ID, sizeof(identifyRsp.vPatch_ID)); LOG_I("%s = 0x%02X", "Tag platform build ID1 (Must be 0x03)", identifyRsp.vTag_platform_build_ID1); LOG_D("%s = 0x%02X", "Length platform build ID 0x18", identifyRsp.vLength_platform_build_ID); LOG_MAU8_I("Platform build ID", identifyRsp.vPlatform_build_ID, sizeof(identifyRsp.vPlatform_build_ID)); memcpy(jcop_platform_id, identifyRsp.vPlatform_build_ID, 16); LOG_I("%s = %s", "JCOP Platform ID", jcop_platform_id); LOG_I("%s = 0x%02X", "Tag FIPS mode (Must be 0x05)", identifyRsp.vTag_FIPS_mode); LOG_D("%s = 0x%02X", "Length FIPS mode 0x01", identifyRsp.vLength_FIPS_mode); LOG_I("%s = 0x%02X", "FIPS mode var", identifyRsp.vFIPS_mode); //LOG_I("%s = 0x%02X", "Tag modules enabled 0x06", identifyRsp.vTag_modules_enabled); //LOG_I("%s = 0x%02X", "Length modules enabled 0x02", identifyRsp.vLength_modules_enabled); //LOG_MAU8_I("Bit mask of enabled modules", identifyRsp.vBit_mask_of_enabled_modules, sizeof(identifyRsp.vBit_mask_of_enabled_modules)); LOG_I("%s = 0x%02X", "Tag pre-perso state (Must be 0x07)", identifyRsp.vTag_pre_perso_state); LOG_D("%s = 0x%02X", "Length pre-perso state 0x01", identifyRsp.vLength_pre_perso_state); LOG_I("%s = 0x%02X", "Bit mask of pre-perso state var", identifyRsp.vBit_mask_of_pre_perso_state); LOG_I("%s = 0x%02X", "Tag ROM ID (Must be 0x08)", identifyRsp.vTag_ROM_ID); LOG_D("%s = 0x%02X", "Length ROM ID 0x08", identifyRsp.vLength_ROM_ID); LOG_MAU8_I("ROM ID", identifyRsp.vROM_ID, sizeof(identifyRsp.vROM_ID)); LOG_MAU8_I("Status Word (SW)", identifyRsp.vStatus_Word_SW_, sizeof(identifyRsp.vStatus_Word_SW_)); } else { LOG_E("Error in retreiving the JCOP Identifier. Response is as follows"); LOG_AU8_E((uint8_t *)&identifyRsp, sizeof(identifyRsp)); goto cleanup; } status = kStatus_SSS_Success; cleanup: return status; }