| /* |
| * |
| * Copyright 2018,2020 NXP |
| * SPDX-License-Identifier: Apache-2.0 |
| * |
| */ |
| #include <fsl_sscp_a71ch.h> |
| #include <fsl_sss_api.h> |
| #include <smCom.h> |
| #include <stdint.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| |
| #if defined(SSS_USE_FTR_FILE) |
| #include "fsl_sss_ftr.h" |
| #else |
| #include "fsl_sss_ftr_default.h" |
| #endif |
| |
| #if SSS_HAVE_MBEDTLS |
| #include <fsl_sss_mbedtls_apis.h> |
| #include <mbedtls/version.h> |
| #endif |
| |
| #if SSS_HAVE_OPENSSL |
| #include <fsl_sss_openssl_apis.h> |
| #include <openssl/opensslv.h> |
| #endif |
| |
| #if SSS_HAVE_SSCP |
| #include <fsl_sss_sscp.h> |
| #include <sm_types.h> |
| #endif |
| |
| #if SSS_HAVE_SE05X |
| #include <fsl_sss_se05x_apis.h> |
| #endif |
| |
| #if SSS_HAVE_A71XX |
| #include <HLSEAPI.h> |
| #include <fsl_sscp_a71ch.h> |
| #endif |
| #if SSS_HAVE_A71CL || SSS_HAVE_SE050_L |
| #include <a71cl_api.h> |
| #include <fsl_sscp_a71cl.h> |
| #endif /* SSS_HAVE_A71CH / EAR */ |
| |
| #include <ex_sss_boot.h> |
| #include "sm_apdu.h" |
| |
| #include "nxLog_App.h" |
| |
| #define MAX_TX_RX_BUFFER 1024 |
| |
| static ex_sss_boot_ctx_t gex_sss_gen_cert; |
| |
| #define EX_SSS_BOOT_PCONTEXT (&gex_sss_gen_cert) |
| #define EX_SSS_BOOT_DO_ERASE 0 |
| #define EX_SSS_BOOT_EXPOSE_ARGC_ARGV 1 |
| |
| #include <ex_sss_main_inc.h> |
| |
| void print_usage() |
| { |
| printf("Execute APDUs on a SE\n"); |
| printf(" Usage:\n"); |
| printf("apdu_player [apdu-file] <port>\n"); |
| printf("\n"); |
| printf( |
| "The apdu file contains hex strings of APDUs, one APDU per line in the " |
| "following format:\n"); |
| printf("/send APDU [EXPECTED_RESPONSE]\n"); |
| printf("All lines not following this format are ignored.\n"); |
| } |
| |
| |
| sss_status_t ex_sss_entry(ex_sss_boot_ctx_t *pCtx) |
| { |
| sss_status_t status = kStatus_SSS_Fail; |
| int argc = gex_sss_argc; |
| const char **argv = gex_sss_argv; |
| void * conn_ctx = NULL; |
| if (argc < 2) { |
| print_usage(); |
| return status; |
| } |
| |
| #if SSS_HAVE_SE05X |
| conn_ctx = &((sss_se05x_session_t *)&pCtx->session)->s_ctx; |
| #endif |
| |
| FILE *fp = fopen(argv[1], "r"); |
| if (fp == NULL) { |
| LOG_E("error opening file %s\n", argv[1]); |
| print_usage(); |
| return status; |
| } |
| |
| char buf[MAX_TX_RX_BUFFER * 8] = {0}; |
| char apdu_str[MAX_TX_RX_BUFFER * 8] = {0}; |
| char resp_str[MAX_TX_RX_BUFFER * 8] = {0}; |
| |
| while (fgets(buf, sizeof(buf), fp) != NULL) { |
| size_t len = strlen(buf) - 1; |
| |
| if (buf[len] == '\r' || buf[len] == '\n') { |
| buf[len] = '\0'; // eat the newline fgets() stores |
| } |
| |
| int found = sscanf(buf, "/send %s %s", apdu_str, resp_str); |
| if (found <= 0) { |
| LOG_I("discarding [%s]\n", buf); |
| continue; |
| } |
| |
| uint8_t apdu[SE05X_MAX_BUF_SIZE_CMD] = { 0 }; |
| uint8_t resp[SE05X_MAX_BUF_SIZE_RSP] = { 0 }; |
| size_t apdu_len = 0; |
| size_t resp_len = 0; |
| |
| bool compare_full_response = true; |
| char *resp_to_compare_str = resp_str; |
| |
| if (!smApduGetArrayBytes(apdu_str, &apdu_len, apdu, SE05X_MAX_BUF_SIZE_CMD)) { |
| LOG_E("invalid hexstr in [%s]\n", buf); |
| return 1; |
| } |
| if (found > 1) { |
| // the response CAN be prepended with a star signifying that |
| // there can be more characters. ignore those. |
| if (resp_str[0] == '*') { |
| compare_full_response = false; |
| resp_to_compare_str = &resp_str[1]; |
| } |
| smApduGetArrayBytes(resp_to_compare_str, &resp_len, resp, SE05X_MAX_BUF_SIZE_RSP); |
| } |
| |
| uint8_t rx[MAX_TX_RX_BUFFER]; |
| size_t rlen = sizeof(rx); |
| printf("Executing [%s]\n", buf); |
| if (SM_OK != DoAPDUTxRx(conn_ctx, apdu, (uint16_t)apdu_len, &rx[0], &rlen)) |
| { |
| LOG_E("Unable to send apdu [%s]\n", buf); |
| return status; |
| } |
| |
| if (resp_len != 0) { |
| if ((rlen < resp_len) || |
| ((compare_full_response) ? |
| (memcmp(resp, rx, resp_len) != 0) : |
| (memcmp(resp, rx + (rlen - resp_len), resp_len) != |
| 0))) { |
| LOG_E("Unexpected response for apdu [%s]\n", buf); |
| return status; |
| } |
| else { |
| LOG_I("Success"); |
| } |
| } |
| else { |
| LOG_W("resp is null. Not checking response"); |
| } |
| } |
| |
| fclose(fp); |
| status = kStatus_SSS_Success; |
| LOG_I("Example finished successfully"); |
| return status; |
| } |