| /* |
| * Copyright 2015-2016, Freescale Semiconductor, Inc. |
| * Copyright 2017 NXP |
| * All rights reserved. |
| * |
| * |
| * SPDX-License-Identifier: BSD-3-Clause |
| */ |
| |
| #if !defined(MBEDTLS_CONFIG_FILE) |
| #include "mbedtls/config.h" |
| #else |
| #include MBEDTLS_CONFIG_FILE |
| #endif |
| |
| #include "fsl_common.h" |
| |
| #if defined(FSL_FEATURE_SOC_LTC_COUNT) && (FSL_FEATURE_SOC_LTC_COUNT > 0) |
| #include "fsl_ltc.h" |
| #endif |
| #if defined(FSL_FEATURE_SOC_CAAM_COUNT) && (FSL_FEATURE_SOC_CAAM_COUNT > 0) |
| #include "fsl_caam.h" |
| #endif |
| #if defined(FSL_FEATURE_SOC_CAU3_COUNT) && (FSL_FEATURE_SOC_CAU3_COUNT > 0) |
| #include "fsl_cau3.h" |
| #endif |
| #if defined(FSL_FEATURE_SOC_DCP_COUNT) && (FSL_FEATURE_SOC_DCP_COUNT > 0) |
| #include "fsl_dcp.h" |
| #endif |
| #if defined(FSL_FEATURE_SOC_HASHCRYPT_COUNT) && (FSL_FEATURE_SOC_HASHCRYPT_COUNT > 0) |
| #include "fsl_hashcrypt.h" |
| #endif |
| #if defined(FSL_FEATURE_SOC_TRNG_COUNT) && (FSL_FEATURE_SOC_TRNG_COUNT > 0) |
| #include "fsl_trng.h" |
| #elif defined(FSL_FEATURE_SOC_RNG_COUNT) && (FSL_FEATURE_SOC_RNG_COUNT > 0) |
| #include "fsl_rnga.h" |
| #elif defined(FSL_FEATURE_SOC_LPC_RNG1_COUNT) && (FSL_FEATURE_SOC_LPC_RNG1_COUNT > 0) |
| #include "fsl_rng.h" |
| #endif |
| #if defined(FSL_FEATURE_SOC_CASPER_COUNT) && (FSL_FEATURE_SOC_CASPER_COUNT > 0) |
| #include "fsl_casper.h" |
| #endif |
| |
| #define CLEAN_RETURN(value) \ |
| { \ |
| ret = value; \ |
| goto cleanup; \ |
| } |
| |
| /******************************************************************************/ |
| /*************************** CAAM *********************************************/ |
| /******************************************************************************/ |
| #if defined(FSL_FEATURE_SOC_CAAM_COUNT) && (FSL_FEATURE_SOC_CAAM_COUNT > 0) && defined(CRYPTO_USE_DRIVER_CAAM) |
| static caam_handle_t s_caamHandle = {.jobRing = kCAAM_JobRing0}; |
| #endif |
| |
| /******************************************************************************/ |
| /*************************** CAU3 *********************************************/ |
| /******************************************************************************/ |
| #if defined(FSL_FEATURE_SOC_CAU3_COUNT) && (FSL_FEATURE_SOC_CAU3_COUNT > 0) |
| static cau3_handle_t s_cau3Handle = {.taskDone = MBEDTLS_CAU3_COMPLETION_SIGNAL, .keySlot = kCAU3_KeySlot0}; |
| #endif |
| |
| /******************************************************************************/ |
| /**************************** DCP *********************************************/ |
| /******************************************************************************/ |
| #if defined(FSL_FEATURE_SOC_DCP_COUNT) && (FSL_FEATURE_SOC_DCP_COUNT > 0) |
| static dcp_handle_t s_dcpHandle = {.channel = kDCP_Channel0, .keySlot = kDCP_KeySlot0, .swapConfig = kDCP_NoSwap}; |
| #endif |
| |
| /******************************************************************************/ |
| /************************* Key slot management ********************************/ |
| /******************************************************************************/ |
| #if (defined(FSL_FEATURE_SOC_CAU3_COUNT) && (FSL_FEATURE_SOC_CAU3_COUNT > 0)) || (defined(MBEDTLS_FREESCALE_DCP_AES)) |
| static const void *s_mbedtlsCtx[4] = {0}; |
| |
| static void crypto_attach_ctx_to_key_slot(const void *ctx, uint8_t keySlot) |
| { |
| s_mbedtlsCtx[keySlot] = ctx; |
| } |
| |
| static void crypto_detach_ctx_from_key_slot(const void *ctx) |
| { |
| for (int i = 0; i < 4; i++) |
| { |
| if (ctx == s_mbedtlsCtx[i]) |
| { |
| s_mbedtlsCtx[i] = NULL; |
| break; |
| } |
| } |
| } |
| |
| static bool crypto_key_is_loaded(const void *ctx) |
| { |
| bool ret = false; |
| for (int i = 0; i < 4; i++) |
| { |
| if (ctx == s_mbedtlsCtx[i]) |
| { |
| ret = true; |
| break; |
| } |
| } |
| return ret; |
| } |
| #endif |
| |
| #if defined(MBEDTLS_SHA1_ALT) || defined(MBEDTLS_SHA256_ALT) |
| /* Implementation that should never be optimized out by the compiler */ |
| static void mbedtls_zeroize(void *v, size_t n) |
| { |
| volatile unsigned char *p = v; |
| while (n--) |
| *p++ = 0; |
| } |
| #endif /* MBEDTLS_SHA1_ALT || MBEDTLS_SHA256_ALT */ |
| |
| /******************************************************************************/ |
| /******************** CRYPTO_InitHardware **************************************/ |
| /******************************************************************************/ |
| /*! |
| * @brief Application init for various Crypto blocks. |
| * |
| * This function is provided to be called by MCUXpresso SDK applications. |
| * It calls basic init for Crypto Hw acceleration and Hw entropy modules. |
| */ |
| void CRYPTO_InitHardware(void) |
| { |
| #if defined(FSL_FEATURE_SOC_LTC_COUNT) && (FSL_FEATURE_SOC_LTC_COUNT > 0) |
| /* Initialize LTC driver. |
| * This enables clocking and resets the module to a known state. */ |
| LTC_Init(LTC0); |
| #endif |
| #if defined(FSL_FEATURE_SOC_CAAM_COUNT) && (FSL_FEATURE_SOC_CAAM_COUNT > 0) && defined(CRYPTO_USE_DRIVER_CAAM) |
| /* Initialize CAAM driver. */ |
| caam_config_t caamConfig; |
| |
| CAAM_GetDefaultConfig(&caamConfig); |
| caamConfig.jobRingInterface[0] = &s_jrif0; |
| caamConfig.jobRingInterface[1] = &s_jrif1; |
| CAAM_Init(CAAM, &caamConfig); |
| #endif |
| #if defined(FSL_FEATURE_SOC_CAU3_COUNT) && (FSL_FEATURE_SOC_CAU3_COUNT > 0) |
| /* Initialize CAU3 */ |
| CAU3_Init(CAU3); |
| #endif |
| #if defined(FSL_FEATURE_SOC_DCP_COUNT) && (FSL_FEATURE_SOC_DCP_COUNT > 0) |
| /* Initialize DCP */ |
| dcp_config_t dcpConfig; |
| |
| DCP_GetDefaultConfig(&dcpConfig); |
| DCP_Init(DCP, &dcpConfig); |
| #endif |
| #if defined(FSL_FEATURE_SOC_CASPER_COUNT) && (FSL_FEATURE_SOC_CASPER_COUNT > 0) |
| /* Initialize CASPER */ |
| CASPER_Init(CASPER); |
| #endif |
| #if defined(FSL_FEATURE_SOC_HASHCRYPT_COUNT) && (FSL_FEATURE_SOC_HASHCRYPT_COUNT > 0) |
| /* Initialize HASHCRYPT */ |
| HASHCRYPT_Init(HASHCRYPT); |
| /* Secure-lock HASHCRYPT master.*/ |
| HASHCRYPT->LOCK = HASHCRYPT_LOCK_PATTERN(0xA75) | HASHCRYPT_LOCK_SECLOCK(0x1); |
| #endif |
| { /* Init RNG module.*/ |
| #if defined(FSL_FEATURE_SOC_TRNG_COUNT) && (FSL_FEATURE_SOC_TRNG_COUNT > 0) |
| #if defined(TRNG) |
| #define TRNG0 TRNG |
| #endif |
| trng_config_t trngConfig; |
| |
| TRNG_GetDefaultConfig(&trngConfig); |
| /* Set sample mode of the TRNG ring oscillator to Von Neumann, for better random data.*/ |
| /* Initialize TRNG */ |
| TRNG_Init(TRNG0, &trngConfig); |
| #elif defined(FSL_FEATURE_SOC_RNG_COUNT) && (FSL_FEATURE_SOC_RNG_COUNT > 0) |
| RNGA_Init(RNG); |
| RNGA_Seed(RNG, SIM->UIDL); |
| #endif |
| } |
| } |
| |
| /******************************************************************************/ |
| /*************************** DES **********************************************/ |
| /******************************************************************************/ |
| |
| #if defined(MBEDTLS_DES_C) |
| |
| #if defined(MBEDTLS_FREESCALE_LTC_DES) || defined(MBEDTLS_FREESCALE_MMCAU_DES) || \ |
| defined(MBEDTLS_FREESCALE_CAAM_DES) || defined(MBEDTLS_FREESCALE_CAU3_DES) |
| |
| #include "mbedtls/des.h" |
| |
| #if defined(MBEDTLS_FREESCALE_MMCAU_DES) |
| const unsigned char parityLookup[128] = {1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, |
| 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, |
| 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, |
| 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, |
| 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0}; |
| #endif |
| |
| #if defined(MBEDTLS_FREESCALE_MMCAU_DES) || defined(MBEDTLS_FREESCALE_LTC_DES) || defined(MBEDTLS_FREESCALE_CAAM_DES) |
| /* |
| * DES key schedule (56-bit, encryption) |
| */ |
| int mbedtls_des_setkey_enc(mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE]) |
| { |
| #if defined(MBEDTLS_FREESCALE_LTC_DES) || defined(MBEDTLS_FREESCALE_CAAM_DES) |
| memcpy(ctx->sk, key, MBEDTLS_DES_KEY_SIZE); |
| #elif defined(MBEDTLS_FREESCALE_MMCAU_DES) |
| int i; |
| unsigned char *sk_b = (unsigned char *)ctx->sk; |
| |
| /* fix key parity, if needed */ |
| for (i = 0; i < MBEDTLS_DES_KEY_SIZE; i++) |
| { |
| sk_b[i] = ((key[i] & 0xFE) | parityLookup[key[i] >> 1]); |
| } |
| #endif |
| ctx->mode = MBEDTLS_DES_ENCRYPT; |
| |
| return (0); |
| } |
| |
| /* |
| * DES key schedule (56-bit, decryption) |
| */ |
| int mbedtls_des_setkey_dec(mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE]) |
| { |
| #if defined(MBEDTLS_FREESCALE_LTC_DES) || defined(MBEDTLS_FREESCALE_CAAM_DES) |
| memcpy(ctx->sk, key, MBEDTLS_DES_KEY_SIZE); |
| #elif defined(MBEDTLS_FREESCALE_MMCAU_DES) |
| int i; |
| unsigned char *sk_b = (unsigned char *)ctx->sk; |
| |
| /* fix key parity, if needed */ |
| for (i = 0; i < MBEDTLS_DES_KEY_SIZE; i++) |
| { |
| sk_b[i] = ((key[i] & 0xFE) | parityLookup[key[i] >> 1]); |
| } |
| #endif |
| ctx->mode = MBEDTLS_DES_DECRYPT; |
| |
| return (0); |
| } |
| #endif /* MBEDTLS_FREESCALE_MMCAU_DES || MBEDTLS_FREESCALE_LTC_DES || MBEDTLS_FREESCALE_CAAM_DES */ |
| |
| /* |
| * Triple-DES key schedule (112-bit, encryption) |
| */ |
| int mbedtls_des3_set2key_enc(mbedtls_des3_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2]) |
| { |
| #if defined(MBEDTLS_FREESCALE_LTC_DES) || defined(MBEDTLS_FREESCALE_CAAM_DES) || defined(MBEDTLS_FREESCALE_CAU3_DES) |
| memcpy(ctx->sk, key, MBEDTLS_DES_KEY_SIZE * 2); |
| memcpy(&ctx->sk[4], key, MBEDTLS_DES_KEY_SIZE); /* K3 = K1 */ |
| #if defined(MBEDTLS_FREESCALE_CAU3_DES) |
| crypto_detach_ctx_from_key_slot(ctx); |
| #endif |
| #elif defined(MBEDTLS_FREESCALE_MMCAU_DES) |
| int i; |
| unsigned char *sk_b = (unsigned char *)ctx->sk; |
| |
| /* fix key parity, if needed */ |
| for (i = 0; i < MBEDTLS_DES_KEY_SIZE * 2; i++) |
| { |
| sk_b[i] = ((key[i] & 0xFE) | parityLookup[key[i] >> 1]); |
| } |
| for (i = MBEDTLS_DES_KEY_SIZE * 2; i < MBEDTLS_DES_KEY_SIZE * 3; i++) |
| { |
| sk_b[i] = ((key[i - MBEDTLS_DES_KEY_SIZE * 2] & 0xFE) | parityLookup[key[i - MBEDTLS_DES_KEY_SIZE * 2] >> 1]); |
| } |
| #endif |
| ctx->mode = MBEDTLS_DES_ENCRYPT; |
| |
| return (0); |
| } |
| |
| /* |
| * Triple-DES key schedule (112-bit, decryption) |
| */ |
| int mbedtls_des3_set2key_dec(mbedtls_des3_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2]) |
| { |
| #if defined(MBEDTLS_FREESCALE_LTC_DES) || defined(MBEDTLS_FREESCALE_CAAM_DES) || defined(MBEDTLS_FREESCALE_CAU3_DES) |
| memcpy(ctx->sk, key, MBEDTLS_DES_KEY_SIZE * 2); |
| memcpy(&ctx->sk[4], key, MBEDTLS_DES_KEY_SIZE); /* K3 = K1 */ |
| #if defined(MBEDTLS_FREESCALE_CAU3_DES) |
| crypto_detach_ctx_from_key_slot(ctx); |
| #endif |
| #elif defined(MBEDTLS_FREESCALE_MMCAU_DES) |
| int i; |
| unsigned char *sk_b = (unsigned char *)ctx->sk; |
| |
| /* fix key parity, if needed */ |
| for (i = 0; i < MBEDTLS_DES_KEY_SIZE * 2; i++) |
| { |
| sk_b[i] = ((key[i] & 0xFE) | parityLookup[key[i] >> 1]); |
| } |
| for (i = MBEDTLS_DES_KEY_SIZE * 2; i < MBEDTLS_DES_KEY_SIZE * 3; i++) |
| { |
| sk_b[i] = ((key[i - MBEDTLS_DES_KEY_SIZE * 2] & 0xFE) | parityLookup[key[i - MBEDTLS_DES_KEY_SIZE * 2] >> 1]); |
| } |
| #endif |
| ctx->mode = MBEDTLS_DES_DECRYPT; |
| |
| return (0); |
| } |
| |
| /* |
| * Triple-DES key schedule (168-bit, encryption) |
| */ |
| int mbedtls_des3_set3key_enc(mbedtls_des3_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3]) |
| { |
| #if defined(MBEDTLS_FREESCALE_LTC_DES) || defined(MBEDTLS_FREESCALE_CAAM_DES) || defined(MBEDTLS_FREESCALE_CAU3_DES) |
| memcpy(ctx->sk, key, MBEDTLS_DES_KEY_SIZE * 3); |
| #if defined(MBEDTLS_FREESCALE_CAU3_DES) |
| crypto_detach_ctx_from_key_slot(ctx); |
| #endif |
| #elif defined(MBEDTLS_FREESCALE_MMCAU_DES) |
| int i; |
| unsigned char *sk_b = (unsigned char *)ctx->sk; |
| |
| /* fix key parity, if needed */ |
| for (i = 0; i < MBEDTLS_DES_KEY_SIZE * 3; i++) |
| { |
| sk_b[i] = ((key[i] & 0xFE) | parityLookup[key[i] >> 1]); |
| } |
| #endif |
| ctx->mode = MBEDTLS_DES_ENCRYPT; |
| |
| return (0); |
| } |
| |
| /* |
| * Triple-DES key schedule (168-bit, decryption) |
| */ |
| int mbedtls_des3_set3key_dec(mbedtls_des3_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3]) |
| { |
| #if defined(MBEDTLS_FREESCALE_LTC_DES) || defined(MBEDTLS_FREESCALE_CAAM_DES) || defined(MBEDTLS_FREESCALE_CAU3_DES) |
| memcpy(ctx->sk, key, MBEDTLS_DES_KEY_SIZE * 3); |
| #if defined(MBEDTLS_FREESCALE_CAU3_DES) |
| crypto_detach_ctx_from_key_slot(ctx); |
| #endif |
| #elif defined(MBEDTLS_FREESCALE_MMCAU_DES) |
| int i; |
| unsigned char *sk_b = (unsigned char *)ctx->sk; |
| |
| /* fix key parity, if needed */ |
| for (i = 0; i < MBEDTLS_DES_KEY_SIZE * 3; i++) |
| { |
| sk_b[i] = ((key[i] & 0xFE) | parityLookup[key[i] >> 1]); |
| } |
| #endif |
| ctx->mode = MBEDTLS_DES_DECRYPT; |
| return (0); |
| } |
| |
| #if defined(MBEDTLS_FREESCALE_LTC_DES) || defined(MBEDTLS_FREESCALE_MMCAU_DES) || defined(MBEDTLS_FREESCALE_CAAM_DES) |
| /* |
| * DES-ECB block encryption/decryption |
| */ |
| int mbedtls_des_crypt_ecb(mbedtls_des_context *ctx, const unsigned char input[8], unsigned char output[8]) |
| { |
| uint8_t *key = (uint8_t *)ctx->sk; |
| #if defined(MBEDTLS_FREESCALE_LTC_DES) |
| if (ctx->mode == MBEDTLS_DES_ENCRYPT) |
| { |
| LTC_DES_EncryptEcb(LTC_INSTANCE, input, output, 8, key); |
| } |
| else |
| { |
| LTC_DES_DecryptEcb(LTC_INSTANCE, input, output, 8, key); |
| } |
| #elif defined(MBEDTLS_FREESCALE_MMCAU_DES) |
| if (ctx->mode == MBEDTLS_DES_ENCRYPT) |
| { |
| MMCAU_DES_EncryptEcb(input, key, output); |
| } |
| else |
| { |
| MMCAU_DES_DecryptEcb(input, key, output); |
| } |
| #elif defined(MBEDTLS_FREESCALE_CAAM_DES) |
| if (ctx->mode == MBEDTLS_DES_ENCRYPT) |
| { |
| CAAM_DES_EncryptEcb(CAAM_INSTANCE, &s_caamHandle, input, output, 8, key); |
| } |
| else |
| { |
| CAAM_DES_DecryptEcb(CAAM_INSTANCE, &s_caamHandle, input, output, 8, key); |
| } |
| #endif |
| return (0); |
| } |
| #endif /* MBEDTLS_FREESCALE_LTC_DES || MBEDTLS_FREESCALE_MMCAU_DES || MBEDTLS_FREESCALE_CAAM_DES */ |
| |
| /* |
| * 3DES-ECB block encryption/decryption |
| */ |
| int mbedtls_des3_crypt_ecb(mbedtls_des3_context *ctx, const unsigned char input[8], unsigned char output[8]) |
| { |
| uint8_t *key = (uint8_t *)ctx->sk; |
| #if defined(MBEDTLS_FREESCALE_LTC_DES) |
| if (ctx->mode == MBEDTLS_DES_ENCRYPT) |
| { |
| LTC_DES3_EncryptEcb(LTC_INSTANCE, input, output, 8, key, key + 8, key + 16); |
| } |
| else |
| { |
| LTC_DES3_DecryptEcb(LTC_INSTANCE, input, output, 8, key, key + 8, key + 16); |
| } |
| #elif defined(MBEDTLS_FREESCALE_MMCAU_DES) |
| if (ctx->mode == MBEDTLS_DES_ENCRYPT) |
| { |
| MMCAU_DES_EncryptEcb(input, key, output); |
| MMCAU_DES_DecryptEcb(output, key + 8, output); |
| MMCAU_DES_EncryptEcb(output, key + 16, output); |
| } |
| else |
| { |
| MMCAU_DES_DecryptEcb(input, key + 16, output); |
| MMCAU_DES_EncryptEcb(output, key + 8, output); |
| MMCAU_DES_DecryptEcb(output, key, output); |
| } |
| #elif defined(MBEDTLS_FREESCALE_CAAM_DES) |
| if (ctx->mode == MBEDTLS_DES_ENCRYPT) |
| { |
| CAAM_DES3_EncryptEcb(CAAM_INSTANCE, &s_caamHandle, input, output, 8, key, key + 8, key + 16); |
| } |
| else |
| { |
| CAAM_DES3_DecryptEcb(CAAM_INSTANCE, &s_caamHandle, input, output, 8, key, key + 8, key + 16); |
| } |
| #elif defined(MBEDTLS_FREESCALE_CAU3_DES) |
| if (!crypto_key_is_loaded(ctx)) |
| { |
| CAU3_TDES_SetKey(CAU3, &s_cau3Handle, key, 24); |
| crypto_attach_ctx_to_key_slot(ctx, s_cau3Handle.keySlot); |
| } |
| |
| if (ctx->mode == MBEDTLS_DES_ENCRYPT) |
| { |
| CAU3_TDES_Encrypt(CAU3, &s_cau3Handle, input, output); |
| } |
| else |
| { |
| CAU3_TDES_Decrypt(CAU3, &s_cau3Handle, input, output); |
| } |
| #endif |
| return (0); |
| } |
| |
| #if defined(MBEDTLS_CIPHER_MODE_CBC) |
| /* |
| * DES-CBC buffer encryption/decryption |
| */ |
| #if defined(MBEDTLS_FREESCALE_LTC_DES) |
| int mbedtls_des_crypt_cbc(mbedtls_des_context *ctx, |
| int mode, |
| size_t length, |
| unsigned char iv[8], |
| const unsigned char *input, |
| unsigned char *output) |
| { |
| unsigned char temp[8]; |
| uint8_t *key = (uint8_t *)ctx->sk; |
| |
| if (length % 8) |
| return (MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH); |
| |
| if (mode == MBEDTLS_DES_ENCRYPT) |
| { |
| LTC_DES_EncryptCbc(LTC_INSTANCE, input, output, length, iv, key); |
| memcpy(iv, output + length - 8, 8); |
| } |
| else /* MBEDTLS_DES_DECRYPT */ |
| { |
| memcpy(temp, input + length - 8, 8); |
| LTC_DES_DecryptCbc(LTC_INSTANCE, input, output, length, iv, key); |
| memcpy(iv, temp, 8); |
| } |
| return (0); |
| } |
| |
| /* |
| * 3DES-CBC buffer encryption/decryption |
| */ |
| int mbedtls_des3_crypt_cbc(mbedtls_des3_context *ctx, |
| int mode, |
| size_t length, |
| unsigned char iv[8], |
| const unsigned char *input, |
| unsigned char *output) |
| { |
| unsigned char temp[8]; |
| uint8_t *key = (uint8_t *)ctx->sk; |
| |
| if (length % 8) |
| return (MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH); |
| |
| if (mode == MBEDTLS_DES_ENCRYPT) |
| { |
| LTC_DES3_EncryptCbc(LTC_INSTANCE, input, output, length, iv, key, key + 8, key + 16); |
| memcpy(iv, output + length - 8, 8); |
| } |
| else /* MBEDTLS_DES_DECRYPT */ |
| { |
| memcpy(temp, input + length - 8, 8); |
| LTC_DES3_DecryptCbc(LTC_INSTANCE, input, output, length, iv, key, key + 8, key + 16); |
| memcpy(iv, temp, 8); |
| } |
| |
| return (0); |
| } |
| #elif defined(MBEDTLS_FREESCALE_CAAM_DES) |
| int mbedtls_des_crypt_cbc(mbedtls_des_context *ctx, |
| int mode, |
| size_t length, |
| unsigned char iv[8], |
| const unsigned char *input, |
| unsigned char *output) |
| { |
| unsigned char temp[8]; |
| uint8_t *key = (uint8_t *)ctx->sk; |
| |
| if (length % 8) |
| return (MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH); |
| |
| if (mode == MBEDTLS_DES_ENCRYPT) |
| { |
| CAAM_DES_EncryptCbc(CAAM_INSTANCE, &s_caamHandle, input, output, length, iv, key); |
| memcpy(iv, output + length - 8, 8); |
| } |
| else /* MBEDTLS_DES_DECRYPT */ |
| { |
| memcpy(temp, input + length - 8, 8); |
| CAAM_DES_DecryptCbc(CAAM_INSTANCE, &s_caamHandle, input, output, length, iv, key); |
| memcpy(iv, temp, 8); |
| } |
| return (0); |
| } |
| |
| /* |
| * 3DES-CBC buffer encryption/decryption |
| */ |
| int mbedtls_des3_crypt_cbc(mbedtls_des3_context *ctx, |
| int mode, |
| size_t length, |
| unsigned char iv[8], |
| const unsigned char *input, |
| unsigned char *output) |
| { |
| unsigned char temp[8]; |
| uint8_t *key = (uint8_t *)ctx->sk; |
| |
| if (length % 8) |
| return (MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH); |
| |
| if (mode == MBEDTLS_DES_ENCRYPT) |
| { |
| CAAM_DES3_EncryptCbc(CAAM_INSTANCE, &s_caamHandle, input, output, length, iv, key, key + 8, key + 16); |
| memcpy(iv, output + length - 8, 8); |
| } |
| else /* MBEDTLS_DES_DECRYPT */ |
| { |
| memcpy(temp, input + length - 8, 8); |
| CAAM_DES3_DecryptCbc(CAAM_INSTANCE, &s_caamHandle, input, output, length, iv, key, key + 8, key + 16); |
| memcpy(iv, temp, 8); |
| } |
| |
| return (0); |
| } |
| |
| #endif /* MBEDTLS_FREESCALE_LTC_DES */ |
| #endif /* MBEDTLS_CIPHER_MODE_CBC */ |
| |
| #endif /*MBEDTLS_FREESCALE_LTC_DES || MBEDTLS_FREESCALE_MMCAU_DES || MBEDTLS_FREESCALE_CAAM_DES*/ |
| |
| #endif /* MBEDTLS_DES_C */ |
| |
| /******************************************************************************/ |
| /*************************** AES **********************************************/ |
| /******************************************************************************/ |
| |
| #if defined(MBEDTLS_AES_C) |
| |
| #if defined(MBEDTLS_FREESCALE_LTC_AES) || defined(MBEDTLS_FREESCALE_MMCAU_AES) || \ |
| defined(MBEDTLS_FREESCALE_LPC_AES) || defined(MBEDTLS_FREESCALE_CAU3_AES) || \ |
| defined(MBEDTLS_FREESCALE_CAAM_AES) || defined(MBEDTLS_FREESCALE_DCP_AES) |
| |
| #include "mbedtls/aes.h" |
| |
| /* |
| * AES key schedule (encryption) |
| */ |
| int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key, unsigned int keybits) |
| { |
| uint32_t *RK; |
| |
| #ifdef MBEDTLS_AES_ALT_NO_192 |
| if (keybits == 192u) |
| { |
| return (MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE); |
| } |
| #endif |
| |
| #ifdef MBEDTLS_AES_ALT_NO_256 |
| if (keybits == 256u) |
| { |
| return (MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE); |
| } |
| #endif |
| |
| #if defined(MBEDTLS_FREESCALE_LTC_AES) || defined(MBEDTLS_FREESCALE_LPC_AES) || defined(MBEDTLS_FREESCALE_CAU3_AES) || \ |
| defined(MBEDTLS_FREESCALE_CAAM_AES) || defined(MBEDTLS_FREESCALE_DCP_AES) |
| const unsigned char *key_tmp = key; |
| ctx->rk = RK = ctx->buf; |
| memcpy(RK, key_tmp, keybits / 8); |
| |
| #if defined(MBEDTLS_FREESCALE_CAU3_AES) || defined(MBEDTLS_FREESCALE_DCP_AES) |
| crypto_detach_ctx_from_key_slot(ctx); |
| #endif /* MBEDTLS_FREESCALE_CAU3_AES || MBEDTLS_FREESCALE_DCP_AES */ |
| |
| switch (keybits) |
| { /* Set keysize in bytes.*/ |
| case 128: |
| ctx->nr = 16; |
| break; |
| case 192: |
| ctx->nr = 24; |
| break; |
| case 256: |
| ctx->nr = 32; |
| break; |
| default: |
| return (MBEDTLS_ERR_AES_INVALID_KEY_LENGTH); |
| } |
| #elif defined(MBEDTLS_FREESCALE_MMCAU_AES) |
| ctx->rk = RK = ctx->buf; |
| |
| switch (keybits) |
| { |
| case 128: |
| ctx->nr = 10; |
| break; |
| case 192: |
| ctx->nr = 12; |
| break; |
| case 256: |
| ctx->nr = 14; |
| break; |
| default: |
| return (MBEDTLS_ERR_AES_INVALID_KEY_LENGTH); |
| } |
| |
| MMCAU_AES_SetKey(key, keybits / 8, (uint8_t *)RK); |
| #endif |
| |
| return (0); |
| } |
| |
| /* |
| * AES key schedule (decryption) |
| */ |
| int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key, unsigned int keybits) |
| { |
| uint32_t *RK; |
| |
| #ifdef MBEDTLS_AES_ALT_NO_192 |
| if (keybits == 192u) |
| { |
| return (MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE); |
| } |
| #endif |
| |
| #ifdef MBEDTLS_AES_ALT_NO_256 |
| if (keybits == 256u) |
| { |
| return (MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE); |
| } |
| #endif |
| |
| ctx->rk = RK = ctx->buf; |
| |
| #if defined(MBEDTLS_FREESCALE_LTC_AES) || defined(MBEDTLS_FREESCALE_LPC_AES) || defined(MBEDTLS_FREESCALE_CAU3_AES) || \ |
| defined(MBEDTLS_FREESCALE_CAAM_AES) || defined(MBEDTLS_FREESCALE_DCP_AES) |
| const unsigned char *key_tmp = key; |
| memcpy(RK, key_tmp, keybits / 8); |
| |
| #if defined(MBEDTLS_FREESCALE_CAU3_AES) || defined(MBEDTLS_FREESCALE_DCP_AES) |
| crypto_detach_ctx_from_key_slot(ctx); |
| #endif /* MBEDTLS_FREESCALE_CAU3_AES || MBEDTLS_FREESCALE_DCP_AES */ |
| |
| switch (keybits) |
| { |
| case 128: |
| ctx->nr = 16; |
| break; |
| case 192: |
| ctx->nr = 24; |
| break; |
| case 256: |
| ctx->nr = 32; |
| break; |
| default: |
| return (MBEDTLS_ERR_AES_INVALID_KEY_LENGTH); |
| } |
| #elif defined(MBEDTLS_FREESCALE_MMCAU_AES) |
| ctx->rk = RK = ctx->buf; |
| |
| switch (keybits) |
| { |
| case 128: |
| ctx->nr = 10; |
| break; |
| case 192: |
| ctx->nr = 12; |
| break; |
| case 256: |
| ctx->nr = 14; |
| break; |
| default: |
| return (MBEDTLS_ERR_AES_INVALID_KEY_LENGTH); |
| } |
| |
| MMCAU_AES_SetKey(key, keybits / 8, (uint8_t *)RK); |
| #endif |
| |
| return 0; |
| } |
| |
| /* |
| * AES-ECB block encryption |
| */ |
| int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx, const unsigned char input[16], unsigned char output[16]) |
| { |
| uint8_t *key; |
| |
| key = (uint8_t *)ctx->rk; |
| #if defined(MBEDTLS_FREESCALE_LTC_AES) |
| LTC_AES_EncryptEcb(LTC_INSTANCE, input, output, 16, key, ctx->nr); |
| #elif defined(MBEDTLS_FREESCALE_MMCAU_AES) |
| MMCAU_AES_EncryptEcb(input, key, ctx->nr, output); |
| #elif defined(MBEDTLS_FREESCALE_CAU3_AES) |
| if (!crypto_key_is_loaded(ctx)) |
| { |
| CAU3_AES_SetKey(CAU3, &s_cau3Handle, key, ctx->nr); |
| crypto_attach_ctx_to_key_slot(ctx, s_cau3Handle.keySlot); |
| } |
| CAU3_AES_Encrypt(CAU3, &s_cau3Handle, input, output); |
| #elif defined(MBEDTLS_FREESCALE_LPC_AES) |
| AES_SetKey(AES_INSTANCE, key, ctx->nr); |
| AES_EncryptEcb(AES_INSTANCE, input, output, 16); |
| #elif defined(MBEDTLS_FREESCALE_CAAM_AES) |
| CAAM_AES_EncryptEcb(CAAM_INSTANCE, &s_caamHandle, input, output, 16, key, ctx->nr); |
| #elif defined(MBEDTLS_FREESCALE_DCP_AES) |
| if (!crypto_key_is_loaded(ctx)) |
| { |
| DCP_AES_SetKey(DCP, &s_dcpHandle, key, ctx->nr); |
| crypto_attach_ctx_to_key_slot(ctx, s_dcpHandle.keySlot); |
| } |
| DCP_AES_EncryptEcb(DCP, &s_dcpHandle, input, output, 16); |
| #endif |
| |
| return (0); |
| } |
| |
| /* |
| * AES-ECB block decryption |
| */ |
| int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx, const unsigned char input[16], unsigned char output[16]) |
| { |
| uint8_t *key; |
| |
| key = (uint8_t *)ctx->rk; |
| #if defined(MBEDTLS_FREESCALE_LTC_AES) |
| LTC_AES_DecryptEcb(LTC_INSTANCE, input, output, 16, key, ctx->nr, kLTC_EncryptKey); |
| #elif defined(MBEDTLS_FREESCALE_MMCAU_AES) |
| MMCAU_AES_DecryptEcb(input, key, ctx->nr, output); |
| #elif defined(MBEDTLS_FREESCALE_CAU3_AES) |
| if (!crypto_key_is_loaded(ctx)) |
| { |
| CAU3_AES_SetKey(CAU3, &s_cau3Handle, key, ctx->nr); |
| crypto_attach_ctx_to_key_slot(ctx, s_cau3Handle.keySlot); |
| } |
| CAU3_AES_Decrypt(CAU3, &s_cau3Handle, input, output); |
| #elif defined(MBEDTLS_FREESCALE_LPC_AES) |
| AES_SetKey(AES_INSTANCE, key, ctx->nr); |
| AES_DecryptEcb(AES_INSTANCE, input, output, 16); |
| #elif defined(MBEDTLS_FREESCALE_CAAM_AES) |
| CAAM_AES_DecryptEcb(CAAM_INSTANCE, &s_caamHandle, input, output, 16, key, ctx->nr); |
| #elif defined(MBEDTLS_FREESCALE_DCP_AES) |
| if (!crypto_key_is_loaded(ctx)) |
| { |
| DCP_AES_SetKey(DCP, &s_dcpHandle, key, ctx->nr); |
| crypto_attach_ctx_to_key_slot(ctx, s_dcpHandle.keySlot); |
| } |
| DCP_AES_DecryptEcb(DCP, &s_dcpHandle, input, output, 16); |
| #endif |
| |
| return (0); |
| } |
| |
| #if defined(MBEDTLS_CIPHER_MODE_CBC) |
| /* |
| * AES-CBC buffer encryption/decryption |
| */ |
| #if defined(MBEDTLS_FREESCALE_LTC_AES) |
| int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx, |
| int mode, |
| size_t length, |
| unsigned char iv[16], |
| const unsigned char *input, |
| unsigned char *output) |
| { |
| uint8_t *key = (uint8_t *)ctx->rk; |
| uint32_t keySize = ctx->nr; |
| |
| if (length % 16) |
| return (MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH); |
| |
| if (mode == MBEDTLS_AES_DECRYPT) |
| { |
| uint8_t tmp[16]; |
| memcpy(tmp, input + length - 16, 16); |
| LTC_AES_DecryptCbc(LTC_INSTANCE, input, output, length, iv, key, keySize, kLTC_EncryptKey); |
| memcpy(iv, tmp, 16); |
| } |
| else |
| { |
| LTC_AES_EncryptCbc(LTC_INSTANCE, input, output, length, iv, key, keySize); |
| memcpy(iv, output + length - 16, 16); |
| } |
| |
| return (0); |
| } |
| #elif defined(MBEDTLS_FREESCALE_LPC_AES) |
| int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx, |
| int mode, |
| size_t length, |
| unsigned char iv[16], |
| const unsigned char *input, |
| unsigned char *output) |
| { |
| uint8_t *key; |
| size_t keySize; |
| |
| if (length % 16) |
| return (MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH); |
| |
| key = (uint8_t *)ctx->rk; |
| keySize = (size_t)ctx->nr; |
| AES_SetKey(AES_INSTANCE, key, keySize); |
| |
| if (mode == MBEDTLS_AES_DECRYPT) |
| { |
| uint8_t tmp[16]; |
| memcpy(tmp, input + length - 16, 16); |
| AES_DecryptCbc(AES_INSTANCE, tmp, output, length, iv); |
| memcpy(iv, tmp, 16); |
| } |
| else |
| { |
| AES_EncryptCbc(AES_INSTANCE, input, output, length, iv); |
| memcpy(iv, output + length - 16, 16); |
| } |
| |
| return (0); |
| } |
| #elif defined(MBEDTLS_FREESCALE_CAAM_AES) |
| int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx, |
| int mode, |
| size_t length, |
| unsigned char iv[16], |
| const unsigned char *input, |
| unsigned char *output) |
| { |
| uint8_t *key = (uint8_t *)ctx->rk; |
| uint32_t keySize = ctx->nr; |
| |
| if (length % 16) |
| return (MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH); |
| |
| if (mode == MBEDTLS_AES_DECRYPT) |
| { |
| uint8_t tmp[16]; |
| memcpy(tmp, input + length - 16, 16); |
| CAAM_AES_DecryptCbc(CAAM_INSTANCE, &s_caamHandle, input, output, length, iv, key, keySize); |
| memcpy(iv, tmp, 16); |
| } |
| else |
| { |
| CAAM_AES_EncryptCbc(CAAM_INSTANCE, &s_caamHandle, input, output, length, iv, key, keySize); |
| memcpy(iv, output + length - 16, 16); |
| } |
| |
| return (0); |
| } |
| #elif defined(MBEDTLS_FREESCALE_DCP_AES) |
| int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx, |
| int mode, |
| size_t length, |
| unsigned char iv[16], |
| const unsigned char *input, |
| unsigned char *output) |
| { |
| uint8_t *key; |
| |
| if (length % 16) |
| return (MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH); |
| |
| key = (uint8_t *)ctx->rk; |
| if (!crypto_key_is_loaded(ctx)) |
| { |
| DCP_AES_SetKey(DCP, &s_dcpHandle, key, ctx->nr); |
| crypto_attach_ctx_to_key_slot(ctx, s_dcpHandle.keySlot); |
| } |
| |
| if (mode == MBEDTLS_AES_DECRYPT) |
| { |
| uint8_t tmp[16]; |
| memcpy(tmp, input + length - 16, 16); |
| DCP_AES_DecryptCbc(DCP, &s_dcpHandle, input, output, length, iv); |
| memcpy(iv, tmp, 16); |
| } |
| else |
| { |
| DCP_AES_EncryptCbc(DCP, &s_dcpHandle, input, output, length, iv); |
| memcpy(iv, output + length - 16, 16); |
| } |
| |
| return (0); |
| } |
| #endif |
| #endif /* MBEDTLS_CIPHER_MODE_CBC */ |
| |
| #if defined(MBEDTLS_CIPHER_MODE_CFB) |
| #if defined(MBEDTLS_FREESCALE_LPC_AES) |
| /* |
| * AES-CFB128 buffer encryption/decryption |
| */ |
| int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx, |
| int mode, |
| size_t length, |
| size_t *iv_off, |
| unsigned char iv[16], |
| const unsigned char *input, |
| unsigned char *output) |
| { |
| uint8_t *key; |
| size_t keySize; |
| |
| key = (uint8_t *)ctx->rk; |
| keySize = (size_t)ctx->nr; |
| AES_SetKey(AES_INSTANCE, key, keySize); |
| |
| if (mode == MBEDTLS_AES_DECRYPT) |
| { |
| AES_DecryptCfb(AES_INSTANCE, input, output, length, iv); |
| } |
| else |
| { |
| AES_EncryptCfb(AES_INSTANCE, input, output, length, iv); |
| } |
| |
| return (0); |
| } |
| |
| /* |
| * AES-CFB8 buffer encryption/decryption |
| */ |
| int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx, |
| int mode, |
| size_t length, |
| unsigned char iv[16], |
| const unsigned char *input, |
| unsigned char *output) |
| { |
| int status; |
| unsigned char c; |
| unsigned char ov[17]; |
| |
| while (length--) |
| { |
| memcpy(ov, iv, 16); |
| status = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv); |
| if (status != 0) |
| { |
| return status; |
| } |
| |
| if (mode == MBEDTLS_AES_DECRYPT) |
| ov[16] = *input; |
| |
| c = *output++ = (unsigned char)(iv[0] ^ *input++); |
| |
| if (mode == MBEDTLS_AES_ENCRYPT) |
| ov[16] = c; |
| |
| memcpy(iv, ov + 1, 16); |
| } |
| |
| return (0); |
| } |
| #endif /* MBEDTLS_FREESCALE_LPC_AES */ |
| #endif /* MBEDTLS_CIPHER_MODE_CFB */ |
| |
| #if defined(MBEDTLS_CIPHER_MODE_CTR) |
| /* |
| * AES-CTR buffer encryption/decryption |
| */ |
| #if defined(MBEDTLS_FREESCALE_LTC_AES) |
| int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx, |
| size_t length, |
| size_t *nc_off, |
| unsigned char nonce_counter[16], |
| unsigned char stream_block[16], |
| const unsigned char *input, |
| unsigned char *output) |
| { |
| uint8_t *key; |
| uint32_t keySize; |
| |
| key = (uint8_t *)ctx->rk; |
| keySize = ctx->nr; |
| LTC_AES_CryptCtr(LTC_INSTANCE, input, output, length, nonce_counter, key, keySize, stream_block, |
| (uint32_t *)nc_off); |
| |
| return (0); |
| } |
| #elif defined(MBEDTLS_FREESCALE_LPC_AES) |
| int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx, |
| size_t length, |
| size_t *nc_off, |
| unsigned char nonce_counter[16], |
| unsigned char stream_block[16], |
| const unsigned char *input, |
| unsigned char *output) |
| { |
| uint8_t *key; |
| size_t keySize; |
| |
| key = (uint8_t *)ctx->rk; |
| keySize = (size_t)ctx->nr; |
| |
| AES_SetKey(AES_INSTANCE, key, keySize); |
| AES_CryptCtr(AES_INSTANCE, input, output, length, nonce_counter, stream_block, nc_off); |
| |
| return (0); |
| } |
| #elif defined(MBEDTLS_FREESCALE_CAAM_AES) |
| int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx, |
| size_t length, |
| size_t *nc_off, |
| unsigned char nonce_counter[16], |
| unsigned char stream_block[16], |
| const unsigned char *input, |
| unsigned char *output) |
| { |
| uint8_t *key; |
| uint32_t keySize; |
| |
| key = (uint8_t *)ctx->rk; |
| keySize = ctx->nr; |
| |
| CAAM_AES_CryptCtr(CAAM_INSTANCE, &s_caamHandle, input, output, length, nonce_counter, key, keySize, stream_block, |
| nc_off); |
| |
| return (0); |
| } |
| #endif |
| #endif /* MBEDTLS_CIPHER_MODE_CTR */ |
| |
| #if defined(MBEDTLS_CIPHER_CMAC_ALT) && defined(MBEDTLS_CMAC_C) |
| |
| #include "mbedtls/cipher.h" |
| #include "mbedtls/cmac.h" |
| |
| #if defined(MBEDTLS_FREESCALE_CAU3_CIPHER_CMAC) |
| int mbedtls_cipher_cmac(const mbedtls_cipher_info_t *cipher_info, |
| const unsigned char *key, |
| size_t keylen, |
| const unsigned char *input, |
| size_t ilen, |
| unsigned char *output) |
| { |
| mbedtls_cipher_context_t ctx; |
| int ret; |
| |
| if (cipher_info == NULL || key == NULL || input == NULL || output == NULL) |
| return (MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA); |
| |
| mbedtls_cipher_init(&ctx); |
| |
| if ((ret = mbedtls_cipher_setup(&ctx, cipher_info)) != 0) |
| goto exit; |
| |
| ret = mbedtls_cipher_cmac_starts(&ctx, key, keylen); |
| if (ret != 0) |
| goto exit; |
| |
| /* AES-CMAC-128 is directly supported by CAU3 firmware */ |
| if (cipher_info->type == MBEDTLS_CIPHER_AES_128_ECB) |
| { |
| status_t status; |
| uint8_t mac[16]; |
| |
| status = CAU3_AES_SetKey(CAU3, &s_cau3Handle, key, keylen / 8u); |
| if (status != kStatus_Success) |
| { |
| ret = MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; |
| goto exit; |
| } |
| status = CAU3_AES_Cmac(CAU3, &s_cau3Handle, input, ilen, mac); |
| if (status != kStatus_Success) |
| { |
| ret = MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; |
| goto exit; |
| } |
| memcpy(output, mac, 16); |
| } |
| #if defined(MBEDTLS_CIPHER_CMAC_TDES_ENABLED) || defined(MBEDTLS_CIPHER_CMAC_AES_256_ENABLED) |
| else if (cipher_info->type == MBEDTLS_CIPHER_AES_192_ECB) |
| { |
| /* CAU3 initial firmware does not support AES 192 */ |
| ret = MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; |
| goto exit; |
| } |
| else |
| { |
| /* AES-CMAC-256 and TDES-CMAC. |
| * If both MBEDTLS_DES_C and MBEDTLS_CIPHER_CMAC_WANTS_AES_256 are undefined, |
| * this does not compile |
| */ |
| ret = mbedtls_cipher_cmac_update(&ctx, input, ilen); |
| if (ret != 0) |
| goto exit; |
| |
| ret = mbedtls_cipher_cmac_finish(&ctx, output); |
| } |
| #else |
| else |
| { |
| ret = MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; |
| goto exit; |
| } |
| #endif /* MBEDTLS_CIPHER_CMAC_TDES_ENABLED || MBEDTLS_CIPHER_CMAC_AES_256_ENABLED */ |
| |
| exit: |
| mbedtls_cipher_free(&ctx); |
| |
| return (ret); |
| } |
| #endif /* MBEDTLS_FREESCALE_CAU3_CIPHER_CMAC */ |
| #endif /* MBEDTLS_CIPHER_CMAC_ALT && MBEDTLS_CMAC_C */ |
| |
| #if defined(MBEDTLS_CCM_C) |
| |
| #include "mbedtls/ccm.h" |
| |
| #define CCM_ENCRYPT 0 |
| #define CCM_DECRYPT 1 |
| |
| /* |
| * Authenticated encryption or decryption |
| */ |
| #if defined(MBEDTLS_FREESCALE_LTC_AES) |
| static int ccm_auth_crypt(mbedtls_ccm_context *ctx, |
| int mode, |
| size_t length, |
| const unsigned char *iv, |
| size_t iv_len, |
| const unsigned char *add, |
| size_t add_len, |
| const unsigned char *input, |
| unsigned char *output, |
| unsigned char *tag, |
| size_t tag_len) |
| { |
| status_t status; |
| const uint8_t *key; |
| uint8_t keySize; |
| mbedtls_aes_context *aes_ctx; |
| |
| aes_ctx = (mbedtls_aes_context *)ctx->cipher_ctx.cipher_ctx; |
| key = (uint8_t *)aes_ctx->rk; |
| keySize = aes_ctx->nr; |
| if (mode == CCM_ENCRYPT) |
| { |
| status = LTC_AES_EncryptTagCcm(LTC_INSTANCE, input, output, length, iv, iv_len, add, add_len, key, keySize, tag, |
| tag_len); |
| } |
| else |
| { |
| status = LTC_AES_DecryptTagCcm(LTC_INSTANCE, input, output, length, iv, iv_len, add, add_len, key, keySize, tag, |
| tag_len); |
| } |
| |
| if (status == kStatus_InvalidArgument) |
| { |
| return MBEDTLS_ERR_CCM_BAD_INPUT; |
| } |
| else if (status != kStatus_Success) |
| { |
| return MBEDTLS_ERR_CCM_AUTH_FAILED; |
| } |
| |
| return (0); |
| } |
| #elif defined(MBEDTLS_FREESCALE_CAAM_AES) |
| static int ccm_auth_crypt(mbedtls_ccm_context *ctx, |
| int mode, |
| size_t length, |
| const unsigned char *iv, |
| size_t iv_len, |
| const unsigned char *add, |
| size_t add_len, |
| const unsigned char *input, |
| unsigned char *output, |
| unsigned char *tag, |
| size_t tag_len) |
| { |
| status_t status; |
| const uint8_t *key; |
| uint8_t keySize; |
| mbedtls_aes_context *aes_ctx; |
| |
| aes_ctx = (mbedtls_aes_context *)ctx->cipher_ctx.cipher_ctx; |
| key = (uint8_t *)aes_ctx->rk; |
| keySize = aes_ctx->nr; |
| if (mode == CCM_ENCRYPT) |
| { |
| status = CAAM_AES_EncryptTagCcm(CAAM_INSTANCE, &s_caamHandle, input, output, length, iv, iv_len, add, add_len, |
| key, keySize, tag, tag_len); |
| } |
| else |
| { |
| status = CAAM_AES_DecryptTagCcm(CAAM_INSTANCE, &s_caamHandle, input, output, length, iv, iv_len, add, add_len, |
| key, keySize, tag, tag_len); |
| } |
| |
| if (status == kStatus_InvalidArgument) |
| { |
| return MBEDTLS_ERR_CCM_BAD_INPUT; |
| } |
| else if (status != kStatus_Success) |
| { |
| return MBEDTLS_ERR_CCM_AUTH_FAILED; |
| } |
| |
| return (0); |
| } |
| #endif /* MBEDTLS_FREESCALE_LTC_AES */ |
| |
| #if defined(MBEDTLS_FREESCALE_LTC_AES) || defined(MBEDTLS_FREESCALE_CAAM_AES) |
| /* |
| * Authenticated encryption |
| */ |
| int mbedtls_ccm_encrypt_and_tag(mbedtls_ccm_context *ctx, |
| size_t length, |
| const unsigned char *iv, |
| size_t iv_len, |
| const unsigned char *add, |
| size_t add_len, |
| const unsigned char *input, |
| unsigned char *output, |
| unsigned char *tag, |
| size_t tag_len) |
| { |
| return (ccm_auth_crypt(ctx, CCM_ENCRYPT, length, iv, iv_len, add, add_len, input, output, tag, tag_len)); |
| } |
| |
| /* |
| * Authenticated decryption |
| */ |
| int mbedtls_ccm_auth_decrypt(mbedtls_ccm_context *ctx, |
| size_t length, |
| const unsigned char *iv, |
| size_t iv_len, |
| const unsigned char *add, |
| size_t add_len, |
| const unsigned char *input, |
| unsigned char *output, |
| const unsigned char *tag, |
| size_t tag_len) |
| { |
| unsigned char tagCopy[16]; |
| unsigned char *actTag = NULL; |
| if (tag) |
| { |
| memcpy(tagCopy, tag, tag_len); |
| actTag = tagCopy; |
| } |
| return (ccm_auth_crypt(ctx, CCM_DECRYPT, length, iv, iv_len, add, add_len, input, output, actTag, tag_len)); |
| } |
| #endif /* MBEDTLS_FREESCALE_LTC_AES || MBEDTLS_FREESCALE_CAAM_AES */ |
| #endif /* MBEDTLS_CCM_C */ |
| |
| #if defined(MBEDTLS_GCM_C) |
| #if defined(MBEDTLS_FREESCALE_LTC_AES_GCM) |
| |
| #include "mbedtls/gcm.h" |
| |
| int mbedtls_gcm_crypt_and_tag(mbedtls_gcm_context *ctx, |
| int mode, |
| size_t length, |
| const unsigned char *iv, |
| size_t iv_len, |
| const unsigned char *add, |
| size_t add_len, |
| const unsigned char *input, |
| unsigned char *output, |
| size_t tag_len, |
| unsigned char *tag) |
| { |
| status_t status; |
| uint8_t *key; |
| uint32_t keySize; |
| mbedtls_aes_context *aes_ctx; |
| |
| ctx->len = length; |
| ctx->add_len = add_len; |
| aes_ctx = (mbedtls_aes_context *)ctx->cipher_ctx.cipher_ctx; |
| key = (uint8_t *)aes_ctx->rk; |
| keySize = aes_ctx->nr; |
| if (mode == MBEDTLS_GCM_ENCRYPT) |
| { |
| status = LTC_AES_EncryptTagGcm(LTC_INSTANCE, input, output, length, iv, iv_len, add, add_len, key, keySize, tag, |
| tag_len); |
| } |
| else |
| { |
| status = LTC_AES_DecryptTagGcm(LTC_INSTANCE, input, output, length, iv, iv_len, add, add_len, key, keySize, tag, |
| tag_len); |
| } |
| |
| if (status == kStatus_InvalidArgument) |
| { |
| return MBEDTLS_ERR_GCM_BAD_INPUT; |
| } |
| else if (status != kStatus_Success) |
| { |
| return MBEDTLS_ERR_GCM_AUTH_FAILED; |
| } |
| |
| return 0; |
| } |
| |
| int mbedtls_gcm_auth_decrypt(mbedtls_gcm_context *ctx, |
| size_t length, |
| const unsigned char *iv, |
| size_t iv_len, |
| const unsigned char *add, |
| size_t add_len, |
| const unsigned char *tag, |
| size_t tag_len, |
| const unsigned char *input, |
| unsigned char *output) |
| { |
| unsigned char tag_copy[16]; |
| unsigned char *actTag = NULL; |
| if (tag) |
| { |
| memcpy(tag_copy, tag, tag_len); |
| actTag = tag_copy; |
| } |
| return (mbedtls_gcm_crypt_and_tag(ctx, MBEDTLS_GCM_DECRYPT, length, iv, iv_len, add, add_len, input, output, |
| tag_len, actTag)); |
| } |
| |
| #elif defined(MBEDTLS_FREESCALE_LPC_AES_GCM) |
| |
| #include "mbedtls/gcm.h" |
| |
| int mbedtls_gcm_crypt_and_tag(mbedtls_gcm_context *ctx, |
| int mode, |
| size_t length, |
| const unsigned char *iv, |
| size_t iv_len, |
| const unsigned char *add, |
| size_t add_len, |
| const unsigned char *input, |
| unsigned char *output, |
| size_t tag_len, |
| unsigned char *tag) |
| { |
| status_t status; |
| uint8_t *key; |
| size_t keySize; |
| mbedtls_aes_context *aes_ctx; |
| |
| ctx->len = length; |
| ctx->add_len = add_len; |
| aes_ctx = (mbedtls_aes_context *)ctx->cipher_ctx.cipher_ctx; |
| key = (uint8_t *)aes_ctx->rk; |
| keySize = (size_t)aes_ctx->nr; |
| |
| status = AES_SetKey(AES_INSTANCE, key, keySize); |
| if (status != kStatus_Success) |
| { |
| return MBEDTLS_ERR_GCM_BAD_INPUT; |
| } |
| |
| if (mode == MBEDTLS_GCM_ENCRYPT) |
| { |
| status = AES_EncryptTagGcm(AES_INSTANCE, input, output, length, iv, iv_len, add, add_len, tag, tag_len); |
| } |
| else |
| { |
| status = AES_DecryptTagGcm(AES_INSTANCE, input, output, length, iv, iv_len, add, add_len, tag, tag_len); |
| } |
| |
| if (status == kStatus_InvalidArgument) |
| { |
| return MBEDTLS_ERR_GCM_BAD_INPUT; |
| } |
| else if (status != kStatus_Success) |
| { |
| return MBEDTLS_ERR_GCM_AUTH_FAILED; |
| } |
| |
| return 0; |
| } |
| |
| int mbedtls_gcm_auth_decrypt(mbedtls_gcm_context *ctx, |
| size_t length, |
| const unsigned char *iv, |
| size_t iv_len, |
| const unsigned char *add, |
| size_t add_len, |
| const unsigned char *tag, |
| size_t tag_len, |
| const unsigned char *input, |
| unsigned char *output) |
| { |
| unsigned char tag_copy[16]; |
| |
| memcpy(tag_copy, tag, tag_len); |
| return (mbedtls_gcm_crypt_and_tag(ctx, MBEDTLS_GCM_DECRYPT, length, iv, iv_len, add, add_len, input, output, |
| tag_len, tag_copy)); |
| } |
| |
| #elif defined(MBEDTLS_FREESCALE_CAAM_AES_GCM) |
| |
| #include "mbedtls/gcm.h" |
| |
| int mbedtls_gcm_crypt_and_tag(mbedtls_gcm_context *ctx, |
| int mode, |
| size_t length, |
| const unsigned char *iv, |
| size_t iv_len, |
| const unsigned char *add, |
| size_t add_len, |
| const unsigned char *input, |
| unsigned char *output, |
| size_t tag_len, |
| unsigned char *tag) |
| { |
| status_t status; |
| uint8_t *key; |
| uint32_t keySize; |
| mbedtls_aes_context *aes_ctx; |
| |
| ctx->len = length; |
| ctx->add_len = add_len; |
| aes_ctx = (mbedtls_aes_context *)ctx->cipher_ctx.cipher_ctx; |
| key = (uint8_t *)aes_ctx->rk; |
| keySize = aes_ctx->nr; |
| if (mode == MBEDTLS_GCM_ENCRYPT) |
| { |
| status = CAAM_AES_EncryptTagGcm(CAAM_INSTANCE, &s_caamHandle, input, output, length, iv, iv_len, add, add_len, |
| key, keySize, tag, tag_len); |
| } |
| else |
| { |
| status = CAAM_AES_DecryptTagGcm(CAAM_INSTANCE, &s_caamHandle, input, output, length, iv, iv_len, add, add_len, |
| key, keySize, tag, tag_len); |
| } |
| |
| if (status == kStatus_InvalidArgument) |
| { |
| return MBEDTLS_ERR_GCM_BAD_INPUT; |
| } |
| else if (status != kStatus_Success) |
| { |
| return MBEDTLS_ERR_GCM_AUTH_FAILED; |
| } |
| |
| return 0; |
| } |
| |
| int mbedtls_gcm_auth_decrypt(mbedtls_gcm_context *ctx, |
| size_t length, |
| const unsigned char *iv, |
| size_t iv_len, |
| const unsigned char *add, |
| size_t add_len, |
| const unsigned char *tag, |
| size_t tag_len, |
| const unsigned char *input, |
| unsigned char *output) |
| { |
| unsigned char tag_copy[16]; |
| unsigned char *actTag = NULL; |
| if (tag) |
| { |
| memcpy(tag_copy, tag, tag_len); |
| actTag = tag_copy; |
| } |
| return (mbedtls_gcm_crypt_and_tag(ctx, MBEDTLS_GCM_DECRYPT, length, iv, iv_len, add, add_len, input, output, |
| tag_len, actTag)); |
| } |
| #endif |
| #endif /* MBEDTLS_GCM_C */ |
| |
| #endif /* MBEDTLS_FREESCALE_LTC_AES || MBEDTLS_FREESCALE_MMCAU_AES || MBEDTLS_FREESCALE_LPC_AES */ |
| |
| #endif /* MBEDTLS_AES_C */ |
| |
| /******************************************************************************/ |
| /*************************** PKHA *********************************************/ |
| /******************************************************************************/ |
| |
| #if defined(MBEDTLS_FREESCALE_LTC_PKHA) || defined(MBEDTLS_FREESCALE_CAU3_PKHA) || defined(MBEDTLS_FREESCALE_CAAM_PKHA) |
| |
| #if defined(MBEDTLS_PLATFORM_C) |
| #include "mbedtls/platform.h" |
| #else |
| #include <stdio.h> |
| #define mbedtls_calloc calloc |
| #define mbedtls_free free |
| #endif |
| |
| static void ltc_reverse_array(uint8_t *src, size_t src_len) |
| { |
| int i; |
| |
| for (i = 0; i < src_len / 2; i++) |
| { |
| uint8_t tmp; |
| |
| tmp = src[i]; |
| src[i] = src[src_len - 1 - i]; |
| src[src_len - 1 - i] = tmp; |
| } |
| } |
| |
| #if defined(MBEDTLS_BIGNUM_C) |
| |
| #include "mbedtls/bignum.h" |
| |
| #if defined(MBEDTLS_FREESCALE_CAU3_PKHA) |
| #define LTC_PKHA_ModAdd CAU3_PKHA_ModAdd |
| #define LTC_PKHA_ModSub1 CAU3_PKHA_ModSub1 |
| #define LTC_PKHA_ModMul CAU3_PKHA_ModMul |
| #define LTC_PKHA_ModRed CAU3_PKHA_ModRed |
| #define LTC_PKHA_ModExp CAU3_PKHA_ModExp |
| #define LTC_PKHA_GCD CAU3_PKHA_ModGcd |
| #define LTC_PKHA_ModInv CAU3_PKHA_ModInv |
| #define LTC_PKHA_PrimalityTest CAU3_PKHA_PrimalityTest |
| #define LTC_INSTANCE ((CAU3_Type *)CAU3_BASE) |
| |
| #define kLTC_PKHA_IntegerArith kCAU3_PKHA_IntegerArith |
| #define kLTC_PKHA_NormalValue kCAU3_PKHA_NormalValue |
| #define kLTC_PKHA_TimingEqualized kCAU3_PKHA_TimingEqualized |
| |
| #define cau3_reverse_array ltc_reverse_array |
| #define cau3_get_from_mbedtls_mpi ltc_get_from_mbedtls_mpi |
| #endif |
| |
| #if defined(MBEDTLS_FREESCALE_LTC_PKHA) |
| typedef uint16_t pkha_size_t; |
| #else |
| typedef size_t pkha_size_t; |
| #endif |
| |
| #if defined(MBEDTLS_MPI_ADD_ABS_ALT) |
| |
| /* Access to original version of mbedtls_mpi_add_abs function. */ |
| int mbedtls_mpi_add_abs_orig(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B); |
| |
| /* |
| * Unsigned addition: X = |A| + |B| (HAC 14.7) |
| */ |
| #if defined(MBEDTLS_FREESCALE_LTC_PKHA) || defined(MBEDTLS_FREESCALE_CAU3_PKHA) |
| int mbedtls_mpi_add_abs(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B) |
| { |
| pkha_size_t sizeA = mbedtls_mpi_size(A); |
| pkha_size_t sizeB = mbedtls_mpi_size(B); |
| pkha_size_t sizeN = FREESCALE_PKHA_INT_MAX_BYTES; |
| |
| #if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE) |
| /* |
| * Perform HW acceleration only if the size in bytes is less than maximum. |
| * Since modular add is used below, the result would be wrong |
| * if the real sum of operands exceeded LTC maximum number value. |
| */ |
| if ((sizeA < sizeN) && (sizeB < sizeN)) |
| { |
| #endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */ |
| int ret; |
| pkha_size_t sizeC; |
| uint8_t *N = mbedtls_calloc(4, FREESCALE_PKHA_INT_MAX_BYTES); |
| uint8_t *ptrA = N + FREESCALE_PKHA_INT_MAX_BYTES; |
| uint8_t *ptrB = ptrA + FREESCALE_PKHA_INT_MAX_BYTES; |
| uint8_t *ptrC = ptrB + FREESCALE_PKHA_INT_MAX_BYTES; |
| if (NULL == N) |
| { |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED); |
| } |
| |
| memset(N, 0xFF, sizeN); |
| |
| mbedtls_mpi_write_binary(A, ptrA, sizeA); |
| ltc_reverse_array(ptrA, sizeA); |
| |
| mbedtls_mpi_write_binary(B, ptrB, sizeB); |
| ltc_reverse_array(ptrB, sizeB); |
| |
| ret = (int)LTC_PKHA_ModAdd(LTC_INSTANCE, ptrA, sizeA, ptrB, sizeB, N, sizeN, ptrC, &sizeC, |
| kLTC_PKHA_IntegerArith); |
| |
| if (ret != kStatus_Success) |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE); |
| |
| ltc_reverse_array(ptrC, sizeC); |
| mbedtls_mpi_read_binary(X, ptrC, sizeC); |
| X->s = 1; |
| cleanup: |
| if (N) |
| { |
| mbedtls_free(N); |
| } |
| return (ret); |
| #if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE) |
| } |
| else |
| { |
| return mbedtls_mpi_add_abs_orig(X, A, B); |
| } |
| #endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */ |
| } |
| |
| #elif defined(MBEDTLS_FREESCALE_CAAM_PKHA) |
| int mbedtls_mpi_add_abs(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B) |
| { |
| pkha_size_t sizeA = mbedtls_mpi_size(A); |
| pkha_size_t sizeB = mbedtls_mpi_size(B); |
| pkha_size_t sizeN = FREESCALE_PKHA_INT_MAX_BYTES; |
| |
| #if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE) |
| /* |
| * Perform HW acceleration only if the size in bytes is less than maximum. |
| * Since modular add is used below, the result would be wrong |
| * if the real sum of operands exceeded CAAM maximum number value. |
| */ |
| if ((sizeA < sizeN) && (sizeB < sizeN)) |
| { |
| #endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */ |
| int ret; |
| pkha_size_t sizeC; |
| uint8_t *N = mbedtls_calloc(4, FREESCALE_PKHA_INT_MAX_BYTES); |
| uint8_t *ptrA = N + FREESCALE_PKHA_INT_MAX_BYTES; |
| uint8_t *ptrB = ptrA + FREESCALE_PKHA_INT_MAX_BYTES; |
| uint8_t *ptrC = ptrB + FREESCALE_PKHA_INT_MAX_BYTES; |
| if (NULL == N) |
| { |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED); |
| } |
| |
| memset(N, 0xFF, sizeN); |
| |
| mbedtls_mpi_write_binary(A, ptrA, sizeA); |
| mbedtls_mpi_write_binary(B, ptrB, sizeB); |
| |
| ret = (int)CAAM_PKHA_ModAdd(CAAM_INSTANCE, &s_caamHandle, ptrA, sizeA, ptrB, sizeB, N, sizeN, ptrC, &sizeC, |
| kCAAM_PKHA_IntegerArith); |
| |
| if (ret != kStatus_Success) |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE); |
| |
| mbedtls_mpi_read_binary(X, ptrC, sizeC); |
| X->s = 1; |
| cleanup: |
| if (N) |
| { |
| mbedtls_free(N); |
| } |
| return (ret); |
| #if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE) |
| } |
| else |
| { |
| return mbedtls_mpi_add_abs_orig(X, A, B); |
| } |
| #endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */ |
| } |
| #endif /* MBEDTLS_FREESCALE_LTC_PKHA || MBEDTLS_FREESCALE_CAU3_PKHA */ |
| #endif /* MBEDTLS_MPI_ADD_ABS_ALT */ |
| |
| #if defined(MBEDTLS_MPI_SUB_ABS_ALT) |
| |
| /* Access to original version of mbedtls_mpi_sub_abs function. */ |
| int mbedtls_mpi_sub_abs_orig(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B); |
| |
| /* |
| * Unsigned subtraction: X = |A| - |B| (HAC 14.9) |
| */ |
| #if defined(MBEDTLS_FREESCALE_LTC_PKHA) || defined(MBEDTLS_FREESCALE_CAU3_PKHA) |
| int mbedtls_mpi_sub_abs(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B) |
| { |
| pkha_size_t sizeA = mbedtls_mpi_size(A); |
| pkha_size_t sizeB = mbedtls_mpi_size(B); |
| pkha_size_t sizeN = FREESCALE_PKHA_INT_MAX_BYTES; |
| |
| #if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE) |
| /* |
| * Perform HW acceleration only if |A| >= |B|. Since modular subtraction is used below, |
| * the result would be wrong if the real sum of operands exceeded maximum. |
| */ |
| if ((sizeA <= sizeN) && (sizeB <= sizeN) && (mbedtls_mpi_cmp_abs(A, B) >= 0)) |
| { |
| #endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */ |
| int ret; |
| pkha_size_t sizeC; |
| uint8_t *N = mbedtls_calloc(4, FREESCALE_PKHA_INT_MAX_BYTES); |
| uint8_t *ptrA = N + FREESCALE_PKHA_INT_MAX_BYTES; |
| uint8_t *ptrB = ptrA + FREESCALE_PKHA_INT_MAX_BYTES; |
| uint8_t *ptrC = ptrB + FREESCALE_PKHA_INT_MAX_BYTES; |
| if (NULL == N) |
| { |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED); |
| } |
| |
| memset(N, 0xFF, sizeN); |
| |
| mbedtls_mpi_write_binary(A, ptrA, sizeA); |
| ltc_reverse_array(ptrA, sizeA); |
| |
| mbedtls_mpi_write_binary(B, ptrB, sizeB); |
| ltc_reverse_array(ptrB, sizeB); |
| |
| ret = (int)LTC_PKHA_ModSub1(LTC_INSTANCE, ptrA, sizeA, ptrB, sizeB, N, sizeN, ptrC, &sizeC); |
| |
| if (ret != kStatus_Success) |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE); |
| |
| ltc_reverse_array(ptrC, sizeC); |
| mbedtls_mpi_read_binary(X, ptrC, sizeC); |
| X->s = 1; |
| cleanup: |
| if (N) |
| { |
| mbedtls_free(N); |
| } |
| return (ret); |
| #if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE) |
| } |
| else |
| { |
| return mbedtls_mpi_sub_abs_orig(X, A, B); |
| } |
| #endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */ |
| } |
| |
| #elif defined(MBEDTLS_FREESCALE_CAAM_PKHA) |
| int mbedtls_mpi_sub_abs(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B) |
| { |
| pkha_size_t sizeA = mbedtls_mpi_size(A); |
| pkha_size_t sizeB = mbedtls_mpi_size(B); |
| pkha_size_t sizeN = FREESCALE_PKHA_INT_MAX_BYTES; |
| |
| #if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE) |
| /* |
| * Perform HW acceleration only if |A| >= |B|. Since modular subtraction is used below, |
| * the result would be wrong if the real sum of operands exceeded maximum. |
| */ |
| if ((sizeA <= sizeN) && (sizeB <= sizeN) && (mbedtls_mpi_cmp_abs(A, B) >= 0)) |
| { |
| #endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */ |
| int ret; |
| pkha_size_t sizeC; |
| uint8_t *N = mbedtls_calloc(4, FREESCALE_PKHA_INT_MAX_BYTES); |
| uint8_t *ptrA = N + FREESCALE_PKHA_INT_MAX_BYTES; |
| uint8_t *ptrB = ptrA + FREESCALE_PKHA_INT_MAX_BYTES; |
| uint8_t *ptrC = ptrB + FREESCALE_PKHA_INT_MAX_BYTES; |
| if (NULL == N) |
| { |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED); |
| } |
| |
| memset(N, 0xFF, sizeN); |
| |
| mbedtls_mpi_write_binary(A, ptrA, sizeA); |
| mbedtls_mpi_write_binary(B, ptrB, sizeB); |
| |
| ret = (int)CAAM_PKHA_ModSub1(CAAM_INSTANCE, &s_caamHandle, ptrA, sizeA, ptrB, sizeB, N, sizeN, ptrC, &sizeC); |
| |
| if (ret != kStatus_Success) |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE); |
| |
| mbedtls_mpi_read_binary(X, ptrC, sizeC); |
| X->s = 1; |
| cleanup: |
| if (N) |
| { |
| mbedtls_free(N); |
| } |
| return (ret); |
| #if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE) |
| } |
| else |
| { |
| return mbedtls_mpi_sub_abs_orig(X, A, B); |
| } |
| #endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */ |
| } |
| #endif /* MBEDTLS_FREESCALE_LTC_PKHA || MBEDTLS_FREESCALE_CAU3_PKHA */ |
| #endif /* MBEDTLS_MPI_SUB_ABS_ALT */ |
| |
| #if defined(MBEDTLS_MPI_MUL_MPI_ALT) |
| |
| /* Access to original version of mbedtls_mpi_mul_mpi function. */ |
| int mbedtls_mpi_mul_mpi_orig(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B); |
| |
| /* |
| * Baseline multiplication: X = A * B (HAC 14.12) |
| */ |
| #if defined(MBEDTLS_FREESCALE_LTC_PKHA) || defined(MBEDTLS_FREESCALE_CAU3_PKHA) |
| int mbedtls_mpi_mul_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B) |
| { |
| pkha_size_t sizeA = mbedtls_mpi_size(A); |
| pkha_size_t sizeB = mbedtls_mpi_size(B); |
| pkha_size_t sizeN = FREESCALE_PKHA_INT_MAX_BYTES; |
| |
| #if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE) |
| /* |
| * Should be "if ((sizeA + sizeB) <= sizeN)", but if the multiplication result |
| * would be maximum LTC number (the same value as the modulus N below), |
| * zero would be returned instead, which is wrong value. |
| */ |
| if ((sizeA + sizeB) < sizeN) |
| { |
| #endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */ |
| int ret; |
| pkha_size_t sizeC; |
| int sign = A->s * B->s; |
| |
| uint8_t *N = mbedtls_calloc(4, FREESCALE_PKHA_INT_MAX_BYTES); |
| uint8_t *ptrA = N + FREESCALE_PKHA_INT_MAX_BYTES; |
| uint8_t *ptrB = ptrA + FREESCALE_PKHA_INT_MAX_BYTES; |
| uint8_t *ptrC = ptrB + FREESCALE_PKHA_INT_MAX_BYTES; |
| if (NULL == N) |
| { |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED); |
| } |
| |
| memset(N, 0xFF, sizeN); |
| |
| mbedtls_mpi_write_binary(A, ptrA, sizeA); |
| ltc_reverse_array(ptrA, sizeA); |
| |
| mbedtls_mpi_write_binary(B, ptrB, sizeB); |
| ltc_reverse_array(ptrB, sizeB); |
| |
| /* |
| * Modular multiplication operation is used here. Since the modulus N is larger |
| * than the expected result of A * B, the effect is normal multiplication. |
| * TODO use PKHA MUL_IM_OM instead. |
| */ |
| ret = |
| (int)LTC_PKHA_ModMul(LTC_INSTANCE, ptrA, sizeA, ptrB, sizeB, N, sizeN, ptrC, &sizeC, kLTC_PKHA_IntegerArith, |
| kLTC_PKHA_NormalValue, kLTC_PKHA_NormalValue, kLTC_PKHA_TimingEqualized); |
| |
| if (ret != kStatus_Success) |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE); |
| |
| ltc_reverse_array(ptrC, sizeC); |
| mbedtls_mpi_read_binary(X, ptrC, sizeC); |
| X->s = sign; |
| cleanup: |
| if (N) |
| { |
| mbedtls_free(N); |
| } |
| return (ret); |
| #if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE) |
| } |
| else |
| { |
| return mbedtls_mpi_mul_mpi_orig(X, A, B); |
| } |
| #endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */ |
| } |
| |
| #elif defined(MBEDTLS_FREESCALE_CAAM_PKHA) |
| int mbedtls_mpi_mul_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B) |
| { |
| pkha_size_t sizeA = mbedtls_mpi_size(A); |
| pkha_size_t sizeB = mbedtls_mpi_size(B); |
| pkha_size_t sizeN = FREESCALE_PKHA_INT_MAX_BYTES; |
| |
| #if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE) |
| /* |
| * Should be "if ((sizeA + sizeB) <= sizeN)", but if the multiplication result |
| * would be maximum CAAM number (the same value as the modulus N below), |
| * zero would be returned instead, which is wrong value. |
| */ |
| if ((sizeA + sizeB) < sizeN) |
| { |
| #endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */ |
| int ret; |
| pkha_size_t sizeC; |
| int sign = A->s * B->s; |
| |
| uint8_t *N = mbedtls_calloc(4, FREESCALE_PKHA_INT_MAX_BYTES); |
| uint8_t *ptrA = N + FREESCALE_PKHA_INT_MAX_BYTES; |
| uint8_t *ptrB = ptrA + FREESCALE_PKHA_INT_MAX_BYTES; |
| uint8_t *ptrC = ptrB + FREESCALE_PKHA_INT_MAX_BYTES; |
| if (NULL == N) |
| { |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED); |
| } |
| |
| memset(N, 0xFF, sizeN); |
| |
| mbedtls_mpi_write_binary(A, ptrA, sizeA); |
| mbedtls_mpi_write_binary(B, ptrB, sizeB); |
| |
| /* |
| * Modular multiplication operation is used here. Since the modulus N is larger |
| * than the expected result of A * B, the effect is normal multiplication. |
| * TODO use PKHA MUL_IM_OM instead. |
| */ |
| ret = (int)CAAM_PKHA_ModMul(CAAM_INSTANCE, &s_caamHandle, ptrA, sizeA, ptrB, sizeB, N, sizeN, ptrC, &sizeC, |
| kCAAM_PKHA_IntegerArith, kCAAM_PKHA_NormalValue, kCAAM_PKHA_NormalValue, |
| kCAAM_PKHA_TimingEqualized); |
| |
| if (ret != kStatus_Success) |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE); |
| |
| mbedtls_mpi_read_binary(X, ptrC, sizeC); |
| X->s = sign; |
| cleanup: |
| if (N) |
| { |
| mbedtls_free(N); |
| } |
| return (ret); |
| #if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE) |
| } |
| else |
| { |
| return mbedtls_mpi_mul_mpi_orig(X, A, B); |
| } |
| #endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */ |
| } |
| #endif /* MBEDTLS_FREESCALE_LTC_PKHA || MBEDTLS_FREESCALE_CAU3_PKHA */ |
| #endif /* MBEDTLS_MPI_MUL_MPI_ALT */ |
| |
| #if defined(MBEDTLS_MPI_MOD_MPI_ALT) |
| |
| /* Access to original version of mbedtls_mpi_mod_mpi function. */ |
| int mbedtls_mpi_mod_mpi_orig(mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B); |
| |
| /* |
| * Modulo: R = A mod B |
| */ |
| #if defined(MBEDTLS_FREESCALE_LTC_PKHA) || defined(MBEDTLS_FREESCALE_CAU3_PKHA) |
| int mbedtls_mpi_mod_mpi(mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B) |
| { |
| pkha_size_t sizeA = mbedtls_mpi_size(A); |
| pkha_size_t sizeB = mbedtls_mpi_size(B); |
| |
| #if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE) |
| if ((sizeA <= FREESCALE_PKHA_INT_MAX_BYTES) && (sizeB <= FREESCALE_PKHA_INT_MAX_BYTES)) |
| { |
| #endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */ |
| int ret; |
| pkha_size_t sizeC; |
| int sign = A->s; |
| uint8_t *ptrA = mbedtls_calloc(3, FREESCALE_PKHA_INT_MAX_BYTES); |
| uint8_t *ptrB = ptrA + FREESCALE_PKHA_INT_MAX_BYTES; |
| uint8_t *ptrC = ptrB + FREESCALE_PKHA_INT_MAX_BYTES; |
| if (NULL == ptrA) |
| { |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED); |
| } |
| |
| mbedtls_mpi_write_binary(A, ptrA, sizeA); |
| ltc_reverse_array(ptrA, sizeA); |
| |
| mbedtls_mpi_write_binary(B, ptrB, sizeB); |
| ltc_reverse_array(ptrB, sizeB); |
| |
| ret = (int)LTC_PKHA_ModRed(LTC_INSTANCE, ptrA, sizeA, ptrB, sizeB, ptrC, &sizeC, kLTC_PKHA_IntegerArith); |
| |
| if (ret != kStatus_Success) |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE); |
| |
| ltc_reverse_array(ptrC, sizeC); |
| mbedtls_mpi_read_binary(R, ptrC, sizeC); |
| R->s = sign; |
| |
| while (mbedtls_mpi_cmp_int(R, 0) < 0) |
| mbedtls_mpi_add_mpi(R, R, B); /* MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( R, R, B ) ); */ |
| |
| while (mbedtls_mpi_cmp_mpi(R, B) >= 0) |
| mbedtls_mpi_sub_mpi(R, R, B); /* MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( R, R, B ) ); cleanup:*/ |
| cleanup: |
| if (ptrA) |
| { |
| mbedtls_free(ptrA); |
| } |
| return (ret); |
| #if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE) |
| } |
| else |
| { |
| return mbedtls_mpi_mod_mpi_orig(R, A, B); |
| } |
| #endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */ |
| } |
| |
| #elif defined(MBEDTLS_FREESCALE_CAAM_PKHA) |
| int mbedtls_mpi_mod_mpi(mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B) |
| { |
| pkha_size_t sizeA = mbedtls_mpi_size(A); |
| pkha_size_t sizeB = mbedtls_mpi_size(B); |
| |
| #if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE) |
| if ((sizeA <= FREESCALE_PKHA_INT_MAX_BYTES) && (sizeB <= FREESCALE_PKHA_INT_MAX_BYTES)) |
| { |
| #endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */ |
| int ret; |
| pkha_size_t sizeC; |
| int sign = A->s; |
| uint8_t *ptrA = mbedtls_calloc(3, FREESCALE_PKHA_INT_MAX_BYTES); |
| uint8_t *ptrB = ptrA + FREESCALE_PKHA_INT_MAX_BYTES; |
| uint8_t *ptrC = ptrB + FREESCALE_PKHA_INT_MAX_BYTES; |
| if (NULL == ptrA) |
| { |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED); |
| } |
| |
| mbedtls_mpi_write_binary(A, ptrA, sizeA); |
| mbedtls_mpi_write_binary(B, ptrB, sizeB); |
| |
| ret = (int)CAAM_PKHA_ModRed(CAAM_INSTANCE, &s_caamHandle, ptrA, sizeA, ptrB, sizeB, ptrC, &sizeC, |
| kCAAM_PKHA_IntegerArith); |
| |
| if (ret != kStatus_Success) |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE); |
| |
| mbedtls_mpi_read_binary(R, ptrC, sizeC); |
| R->s = sign; |
| |
| while (mbedtls_mpi_cmp_int(R, 0) < 0) |
| mbedtls_mpi_add_mpi(R, R, B); /* MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( R, R, B ) ); */ |
| |
| while (mbedtls_mpi_cmp_mpi(R, B) >= 0) |
| mbedtls_mpi_sub_mpi(R, R, B); /* MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( R, R, B ) ); cleanup:*/ |
| cleanup: |
| if (ptrA) |
| { |
| mbedtls_free(ptrA); |
| } |
| return (ret); |
| #if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE) |
| } |
| else |
| { |
| return mbedtls_mpi_mod_mpi_orig(R, A, B); |
| } |
| #endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */ |
| } |
| #endif /* MBEDTLS_FREESCALE_LTC_PKHA || MBEDTLS_FREESCALE_CAU3_PKHA */ |
| #endif /* MBEDTLS_MPI_MOD_MPI_ALT */ |
| |
| #if defined(MBEDTLS_MPI_EXP_MOD_ALT) |
| |
| /* Access to original version of mbedtls_mpi_exp_mod function. */ |
| int mbedtls_mpi_exp_mod_orig( |
| mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *E, const mbedtls_mpi *N, mbedtls_mpi *_RR); |
| |
| /* |
| * Sliding-window exponentiation: X = A^E mod N (HAC 14.85) |
| */ |
| #if defined(MBEDTLS_FREESCALE_LTC_PKHA) || defined(MBEDTLS_FREESCALE_CAU3_PKHA) |
| int mbedtls_mpi_exp_mod( |
| mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *E, const mbedtls_mpi *N, mbedtls_mpi *_RR) |
| { |
| int ret; |
| pkha_size_t sizeE = mbedtls_mpi_size(E); |
| pkha_size_t sizeN = mbedtls_mpi_size(N); |
| |
| #if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE) |
| if ((sizeE <= FREESCALE_PKHA_INT_MAX_BYTES) && (sizeN <= FREESCALE_PKHA_INT_MAX_BYTES)) |
| { |
| #endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */ |
| mbedtls_mpi *AA; // TODO rename etc. |
| |
| /* |
| * If number is greater than modulus, we must first reduce it due to LTC requirement |
| * on modular exponentiaton that it needs number less than modulus. |
| * We can take advantage of modular arithmetic rule that: A^B mod C = ( (A mod C)^B ) mod C. |
| * So we do (A mod N) first and if the size of A in bytes fits into LTC, it will be done in LTC |
| * (here LTC does not give size requirement on A versus N), otherwise it will be done in SW |
| * and since the size of N fits into LTC, the result of (A mod N) will also fit into LTC. |
| * Then we can do modular exponentiation in LTC. |
| */ |
| if (mbedtls_mpi_cmp_mpi(A, N) >= 0) |
| { |
| /* A >= N, perform X = (A mod N). */ |
| ret = mbedtls_mpi_mod_mpi(X, A, N); |
| |
| if (ret != kStatus_Success) |
| return (MBEDTLS_ERR_MPI_NOT_ACCEPTABLE); |
| |
| /* Exponenciation will be performed with X. */ |
| AA = X; |
| } |
| else |
| { |
| /* Exponentiation will be performed with original A. */ |
| AA = (mbedtls_mpi *)A; |
| } |
| |
| pkha_size_t sizeA = mbedtls_mpi_size(AA); |
| uint8_t *ptrA = mbedtls_calloc(3, FREESCALE_PKHA_INT_MAX_BYTES); |
| uint8_t *ptrE = ptrA + FREESCALE_PKHA_INT_MAX_BYTES; |
| uint8_t *ptrN = ptrE + FREESCALE_PKHA_INT_MAX_BYTES; |
| if (NULL == ptrA) |
| { |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED); |
| } |
| |
| mbedtls_mpi_write_binary(AA, ptrA, sizeA); |
| ltc_reverse_array(ptrA, sizeA); |
| |
| mbedtls_mpi_write_binary(E, ptrE, sizeE); |
| ltc_reverse_array(ptrE, sizeE); |
| |
| mbedtls_mpi_write_binary(N, ptrN, sizeN); |
| ltc_reverse_array(ptrN, sizeN); |
| |
| ret = (int)LTC_PKHA_ModExp(LTC_INSTANCE, ptrA, sizeA, ptrN, sizeN, ptrE, sizeE, ptrN, &sizeN, |
| kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue, kLTC_PKHA_TimingEqualized); |
| |
| if (ret != kStatus_Success) |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE); |
| |
| ltc_reverse_array(ptrN, sizeN); |
| mbedtls_mpi_read_binary(X, ptrN, sizeN); |
| cleanup: |
| if (ptrA) |
| { |
| mbedtls_free(ptrA); |
| } |
| return (ret); |
| #if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE) |
| } |
| else |
| { |
| return mbedtls_mpi_exp_mod_orig(X, A, E, N, _RR); |
| } |
| #endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */ |
| } |
| |
| #elif defined(MBEDTLS_FREESCALE_CAAM_PKHA) |
| int mbedtls_mpi_exp_mod( |
| mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *E, const mbedtls_mpi *N, mbedtls_mpi *_RR) |
| { |
| int ret; |
| pkha_size_t sizeE = mbedtls_mpi_size(E); |
| pkha_size_t sizeN = mbedtls_mpi_size(N); |
| |
| #if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE) |
| if ((sizeE <= FREESCALE_PKHA_INT_MAX_BYTES) && (sizeN <= FREESCALE_PKHA_INT_MAX_BYTES)) |
| { |
| #endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */ |
| mbedtls_mpi *AA; // TODO rename etc. |
| |
| /* |
| * If number is greater than modulus, we must first reduce it due to CAAM requirement |
| * on modular exponentiaton that it needs number less than modulus. |
| * We can take advantage of modular arithmetic rule that: A^B mod C = ( (A mod C)^B ) mod C. |
| * So we do (A mod N) first and if the size of A in bytes fits into CAAM, it will be done in CAAM |
| * (here CAAM does not give size requirement on A versus N), otherwise it will be done in SW |
| * and since the size of N fits into CAAM, the result of (A mod N) will also fit into CAAM. |
| * Then we can do modular exponentiation in CAAM. |
| */ |
| if (mbedtls_mpi_cmp_mpi(A, N) >= 0) |
| { |
| /* A >= N, perform X = (A mod N). */ |
| ret = mbedtls_mpi_mod_mpi(X, A, N); |
| |
| if (ret != kStatus_Success) |
| return (MBEDTLS_ERR_MPI_NOT_ACCEPTABLE); |
| |
| /* Exponenciation will be performed with X. */ |
| AA = X; |
| } |
| else |
| { |
| /* Exponentiation will be performed with original A. */ |
| AA = (mbedtls_mpi *)A; |
| } |
| |
| pkha_size_t sizeA = mbedtls_mpi_size(AA); |
| uint8_t *ptrA = mbedtls_calloc(3, FREESCALE_PKHA_INT_MAX_BYTES); |
| uint8_t *ptrE = ptrA + FREESCALE_PKHA_INT_MAX_BYTES; |
| uint8_t *ptrN = ptrE + FREESCALE_PKHA_INT_MAX_BYTES; |
| if (NULL == ptrA) |
| { |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED); |
| } |
| |
| mbedtls_mpi_write_binary(AA, ptrA, sizeA); |
| mbedtls_mpi_write_binary(E, ptrE, sizeE); |
| mbedtls_mpi_write_binary(N, ptrN, sizeN); |
| |
| ret = (int)CAAM_PKHA_ModExp(CAAM_INSTANCE, &s_caamHandle, ptrA, sizeA, ptrN, sizeN, ptrE, sizeE, ptrN, &sizeN, |
| kCAAM_PKHA_IntegerArith, kCAAM_PKHA_NormalValue, kCAAM_PKHA_TimingEqualized); |
| |
| if (ret != kStatus_Success) |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE); |
| |
| mbedtls_mpi_read_binary(X, ptrN, sizeN); |
| cleanup: |
| if (ptrA) |
| { |
| mbedtls_free(ptrA); |
| } |
| return (ret); |
| #if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE) |
| } |
| else |
| { |
| return mbedtls_mpi_exp_mod_orig(X, A, E, N, _RR); |
| } |
| #endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */ |
| } |
| #endif /* MBEDTLS_FREESCALE_LTC_PKHA || MBEDTLS_FREESCALE_CAU3_PKHA */ |
| #endif /* MBEDTLS_MPI_EXP_MOD_ALT */ |
| |
| #if defined(MBEDTLS_MPI_GCD_ALT) |
| |
| /* Access to original version of mbedtls_mpi_gcd function. */ |
| int mbedtls_mpi_gcd_orig(mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B); |
| |
| /* |
| * Greatest common divisor: G = gcd(A, B) (HAC 14.54) |
| */ |
| #if defined(MBEDTLS_FREESCALE_LTC_PKHA) || defined(MBEDTLS_FREESCALE_CAU3_PKHA) |
| int mbedtls_mpi_gcd(mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B) |
| { |
| pkha_size_t sizeA = mbedtls_mpi_size(A); |
| pkha_size_t sizeB = mbedtls_mpi_size(B); |
| |
| #if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE) |
| if ((sizeA <= FREESCALE_PKHA_INT_MAX_BYTES) && (sizeB <= FREESCALE_PKHA_INT_MAX_BYTES)) |
| { |
| #endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */ |
| int ret; |
| pkha_size_t sizeC; |
| uint8_t *ptrA = mbedtls_calloc(3, FREESCALE_PKHA_INT_MAX_BYTES); |
| uint8_t *ptrB = ptrA + FREESCALE_PKHA_INT_MAX_BYTES; |
| uint8_t *ptrC = ptrB + FREESCALE_PKHA_INT_MAX_BYTES; |
| if (NULL == ptrA) |
| { |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED); |
| } |
| |
| mbedtls_mpi_write_binary(A, ptrA, sizeA); |
| ltc_reverse_array(ptrA, sizeA); |
| |
| mbedtls_mpi_write_binary(B, ptrB, sizeB); |
| ltc_reverse_array(ptrB, sizeB); |
| |
| if (mbedtls_mpi_cmp_mpi(A, B) >= 0) |
| { |
| ret = (int)LTC_PKHA_ModRed(LTC_INSTANCE, ptrA, sizeA, ptrB, sizeB, ptrA, &sizeA, kLTC_PKHA_IntegerArith); |
| |
| if (ret != kStatus_Success) |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE); |
| } |
| |
| ret = (int)LTC_PKHA_GCD(LTC_INSTANCE, ptrA, sizeA, ptrB, sizeB, ptrC, &sizeC, kLTC_PKHA_IntegerArith); |
| |
| if (ret != kStatus_Success) |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE); |
| |
| ltc_reverse_array(ptrC, sizeC); |
| mbedtls_mpi_read_binary(G, ptrC, sizeC); |
| cleanup: |
| if (ptrA) |
| { |
| mbedtls_free(ptrA); |
| } |
| return (ret); |
| #if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE) |
| } |
| else |
| { |
| return mbedtls_mpi_gcd_orig(G, A, B); |
| } |
| #endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */ |
| } |
| |
| #elif defined(MBEDTLS_FREESCALE_CAAM_PKHA) |
| int mbedtls_mpi_gcd(mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B) |
| { |
| pkha_size_t sizeA = mbedtls_mpi_size(A); |
| pkha_size_t sizeB = mbedtls_mpi_size(B); |
| |
| #if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE) |
| if ((sizeA <= FREESCALE_PKHA_INT_MAX_BYTES) && (sizeB <= FREESCALE_PKHA_INT_MAX_BYTES)) |
| { |
| #endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */ |
| int ret; |
| pkha_size_t sizeC; |
| uint8_t *ptrA = mbedtls_calloc(3, FREESCALE_PKHA_INT_MAX_BYTES); |
| uint8_t *ptrB = ptrA + FREESCALE_PKHA_INT_MAX_BYTES; |
| uint8_t *ptrC = ptrB + FREESCALE_PKHA_INT_MAX_BYTES; |
| if (NULL == ptrA) |
| { |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED); |
| } |
| |
| mbedtls_mpi_write_binary(A, ptrA, sizeA); |
| mbedtls_mpi_write_binary(B, ptrB, sizeB); |
| |
| if (mbedtls_mpi_cmp_mpi(A, B) >= 0) |
| { |
| ret = (int)CAAM_PKHA_ModRed(CAAM_INSTANCE, &s_caamHandle, ptrA, sizeA, ptrB, sizeB, ptrA, &sizeA, |
| kCAAM_PKHA_IntegerArith); |
| |
| if (ret != kStatus_Success) |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE); |
| } |
| |
| ret = (int)CAAM_PKHA_ModGcd(CAAM_INSTANCE, &s_caamHandle, ptrA, sizeA, ptrB, sizeB, ptrC, &sizeC, |
| kCAAM_PKHA_IntegerArith); |
| |
| if (ret != kStatus_Success) |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE); |
| |
| mbedtls_mpi_read_binary(G, ptrC, sizeC); |
| cleanup: |
| if (ptrA) |
| { |
| mbedtls_free(ptrA); |
| } |
| return (ret); |
| #if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE) |
| } |
| else |
| { |
| return mbedtls_mpi_gcd_orig(G, A, B); |
| } |
| #endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */ |
| } |
| #endif /* MBEDTLS_FREESCALE_LTC_PKHA || MBEDTLS_FREESCALE_CAU3_PKHA */ |
| #endif /* MBEDTLS_MPI_GCD_ALT */ |
| |
| #if defined(MBEDTLS_MPI_INV_MOD_ALT) |
| |
| /* Access to original version of mbedtls_mpi_inv_mod function. */ |
| int mbedtls_mpi_inv_mod_orig(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N); |
| |
| /* |
| * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64) |
| */ |
| #if defined(MBEDTLS_FREESCALE_LTC_PKHA) || defined(MBEDTLS_FREESCALE_CAU3_PKHA) |
| int mbedtls_mpi_inv_mod(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N) |
| { |
| pkha_size_t sizeA = mbedtls_mpi_size(A); |
| pkha_size_t sizeN = mbedtls_mpi_size(N); |
| |
| #if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE) |
| if ((sizeA <= FREESCALE_PKHA_INT_MAX_BYTES) && (sizeN <= FREESCALE_PKHA_INT_MAX_BYTES)) |
| { |
| #endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */ |
| int ret; |
| pkha_size_t sizeC; |
| uint8_t *ptrA = mbedtls_calloc(3, FREESCALE_PKHA_INT_MAX_BYTES); |
| uint8_t *ptrN = ptrA + FREESCALE_PKHA_INT_MAX_BYTES; |
| uint8_t *ptrC = ptrN + FREESCALE_PKHA_INT_MAX_BYTES; |
| if (NULL == ptrA) |
| { |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED); |
| } |
| |
| /* N cannot be negative */ |
| if (N->s < 0 || mbedtls_mpi_cmp_int(N, 0) == 0) |
| { |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_BAD_INPUT_DATA); |
| } |
| |
| mbedtls_mpi_write_binary(A, ptrA, sizeA); |
| ltc_reverse_array(ptrA, sizeA); |
| |
| mbedtls_mpi_write_binary(N, ptrN, sizeN); |
| ltc_reverse_array(ptrN, sizeN); |
| |
| if (mbedtls_mpi_cmp_mpi(A, N) >= 0) |
| { |
| ret = (int)LTC_PKHA_ModRed(LTC_INSTANCE, ptrA, sizeA, ptrN, sizeN, ptrA, &sizeA, kLTC_PKHA_IntegerArith); |
| |
| if (ret != kStatus_Success) |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE); |
| } |
| |
| ret = (int)LTC_PKHA_ModInv(LTC_INSTANCE, ptrA, sizeA, ptrN, sizeN, ptrC, &sizeC, kLTC_PKHA_IntegerArith); |
| |
| if (ret != kStatus_Success) |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE); |
| |
| ltc_reverse_array(ptrC, sizeC); |
| mbedtls_mpi_read_binary(X, ptrC, sizeC); |
| cleanup: |
| if (ptrA) |
| { |
| mbedtls_free(ptrA); |
| } |
| return (ret); |
| #if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE) |
| } |
| else |
| { |
| return mbedtls_mpi_inv_mod_orig(X, A, N); |
| } |
| #endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */ |
| } |
| |
| #elif defined(MBEDTLS_FREESCALE_CAAM_PKHA) |
| int mbedtls_mpi_inv_mod(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N) |
| { |
| pkha_size_t sizeA = mbedtls_mpi_size(A); |
| pkha_size_t sizeN = mbedtls_mpi_size(N); |
| |
| #if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE) |
| if ((sizeA <= FREESCALE_PKHA_INT_MAX_BYTES) && (sizeN <= FREESCALE_PKHA_INT_MAX_BYTES)) |
| { |
| #endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */ |
| int ret; |
| pkha_size_t sizeC; |
| uint8_t *ptrA = mbedtls_calloc(3, FREESCALE_PKHA_INT_MAX_BYTES); |
| uint8_t *ptrN = ptrA + FREESCALE_PKHA_INT_MAX_BYTES; |
| uint8_t *ptrC = ptrN + FREESCALE_PKHA_INT_MAX_BYTES; |
| if (NULL == ptrA) |
| { |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED); |
| } |
| |
| /* N cannot be negative */ |
| if (N->s < 0 || mbedtls_mpi_cmp_int(N, 0) == 0) |
| { |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_BAD_INPUT_DATA); |
| } |
| |
| mbedtls_mpi_write_binary(A, ptrA, sizeA); |
| mbedtls_mpi_write_binary(N, ptrN, sizeN); |
| |
| if (mbedtls_mpi_cmp_mpi(A, N) >= 0) |
| { |
| ret = (int)CAAM_PKHA_ModRed(CAAM_INSTANCE, &s_caamHandle, ptrA, sizeA, ptrN, sizeN, ptrA, &sizeA, |
| kCAAM_PKHA_IntegerArith); |
| |
| if (ret != kStatus_Success) |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE); |
| } |
| |
| ret = (int)CAAM_PKHA_ModInv(CAAM_INSTANCE, &s_caamHandle, ptrA, sizeA, ptrN, sizeN, ptrC, &sizeC, |
| kCAAM_PKHA_IntegerArith); |
| |
| if (ret != kStatus_Success) |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE); |
| |
| mbedtls_mpi_read_binary(X, ptrC, sizeC); |
| cleanup: |
| if (ptrA) |
| { |
| mbedtls_free(ptrA); |
| } |
| return (ret); |
| #if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE) |
| } |
| else |
| { |
| return mbedtls_mpi_inv_mod_orig(X, A, N); |
| } |
| #endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */ |
| } |
| #endif /* MBEDTLS_FREESCALE_LTC_PKHA || MBEDTLS_FREESCALE_CAU3_PKHA */ |
| #endif /* MBEDTLS_MPI_INV_MOD_ALT */ |
| |
| #if defined(MBEDTLS_MPI_IS_PRIME_ALT) |
| |
| /* Access to original version of mbedtls_mpi_is_prime function. */ |
| int mbedtls_mpi_is_prime_orig(const mbedtls_mpi *X, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng); |
| |
| /* |
| * Pseudo-primality test: small factors, then Miller-Rabin |
| */ |
| #if defined(MBEDTLS_FREESCALE_LTC_PKHA) || defined(MBEDTLS_FREESCALE_CAU3_PKHA) |
| int mbedtls_mpi_is_prime(const mbedtls_mpi *X, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) |
| { |
| pkha_size_t sizeX = mbedtls_mpi_size(X); |
| |
| #if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE) |
| if (sizeX <= FREESCALE_PKHA_INT_MAX_BYTES) |
| { |
| #endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */ |
| int ret; |
| int random; |
| bool result = false; |
| uint8_t *ptrX = mbedtls_calloc(1, FREESCALE_PKHA_INT_MAX_BYTES); |
| if (NULL == ptrX) |
| { |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED); |
| } |
| |
| mbedtls_mpi_write_binary(X, ptrX, FREESCALE_PKHA_INT_MAX_BYTES); |
| ltc_reverse_array(ptrX, FREESCALE_PKHA_INT_MAX_BYTES); |
| |
| // Get the random seed number |
| f_rng(p_rng, (unsigned char *)(&random), sizeof(random)); |
| |
| ret = (int)LTC_PKHA_PrimalityTest(LTC_INSTANCE, (unsigned char *)&random, sizeof(random), (const uint8_t *)"1", |
| 1u, ptrX, sizeX, &result); |
| |
| if (ret != kStatus_Success) |
| { |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE); |
| } |
| |
| if (result == false) |
| { |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE); |
| } |
| cleanup: |
| if (ptrX) |
| { |
| mbedtls_free(ptrX); |
| } |
| return ret; |
| #if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE) |
| } |
| else |
| { |
| return mbedtls_mpi_is_prime_orig(X, f_rng, p_rng); |
| } |
| #endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */ |
| } |
| |
| #elif defined(MBEDTLS_FREESCALE_CAAM_PKHA) |
| int mbedtls_mpi_is_prime(const mbedtls_mpi *X, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) |
| { |
| pkha_size_t sizeX = mbedtls_mpi_size(X); |
| |
| #if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE) |
| if (sizeX <= FREESCALE_PKHA_INT_MAX_BYTES) |
| { |
| #endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */ |
| int ret; |
| int random; |
| bool result = false; |
| uint8_t *ptrX = mbedtls_calloc(1, FREESCALE_PKHA_INT_MAX_BYTES); |
| if (NULL == ptrX) |
| { |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED); |
| } |
| |
| mbedtls_mpi_write_binary(X, ptrX, FREESCALE_PKHA_INT_MAX_BYTES); |
| |
| // Get the random seed number |
| f_rng(p_rng, (unsigned char *)(&random), sizeof(random)); |
| |
| ret = (int)CAAM_PKHA_PrimalityTest(CAAM_INSTANCE, &s_caamHandle, (unsigned char *)&random, sizeof(random), |
| (const uint8_t *)"1", 1u, ptrX, sizeX, &result); |
| |
| if (ret != kStatus_Success) |
| { |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE); |
| } |
| |
| if (result == false) |
| { |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE); |
| } |
| cleanup: |
| if (ptrX) |
| { |
| mbedtls_free(ptrX); |
| } |
| return ret; |
| #if defined(FREESCALE_PKHA_LONG_OPERANDS_ENABLE) |
| } |
| else |
| { |
| return mbedtls_mpi_is_prime_orig(X, f_rng, p_rng); |
| } |
| #endif /* FREESCALE_PKHA_LONG_OPERANDS_ENABLE */ |
| } |
| #endif /* MBEDTLS_FREESCALE_LTC_PKHA || MBEDTLS_FREESCALE_CAU3_PKHA */ |
| #endif /* MBEDTLS_MPI_IS_PRIME_ALT */ |
| |
| #endif /* MBEDTLS_BIGNUM_C */ |
| |
| #if defined(MBEDTLS_ECP_C) |
| |
| #include "mbedtls/ecp.h" |
| |
| #define LTC_MAX_ECC (512) |
| #define CAAM_MAX_ECC (528) |
| #define CAU3_MAX_ECC (512) |
| |
| typedef enum |
| { |
| kBigEndian = 0U, |
| kLittleEndian = 1U |
| } endian_t; |
| |
| /* convert from mbedtls_mpi to LTC or CAAM integer, as array of bytes of size sz. |
| * if mbedtls_mpi has less bytes than sz, add zero bytes at most significant byte positions. |
| * This is when for example modulus is 32 bytes (P-256 curve) |
| * and mbedtls_mpi has only 31 bytes, we add leading zeroes |
| * so that result array has 32 bytes, same as modulus (sz). |
| */ |
| #if defined(MBEDTLS_ECP_MUL_COMB_ALT) || defined(MBEDTLS_ECP_ADD_ALT) |
| static int get_and_extend_mbedtls_mpi(uint8_t *dst, const mbedtls_mpi *a, size_t sz, endian_t endian) |
| { |
| size_t szbin; |
| int offset; |
| int ret; |
| |
| /* check how many bytes are in the mbedtls_mpi */ |
| szbin = mbedtls_mpi_size(a); |
| |
| /* compute offset from dst */ |
| offset = sz - szbin; |
| if (offset < 0) |
| offset = 0; |
| if (offset > sz) |
| offset = sz; |
| |
| /* add leading zeroes */ |
| if (offset) |
| memset(dst, 0, offset); |
| |
| /* convert mbedtls_mpi to array of bytes */ |
| MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(a, dst + offset, szbin)); |
| |
| /* reverse array for LTC direct use */ |
| if (endian == kLittleEndian) |
| ltc_reverse_array(dst, sz); |
| cleanup: |
| return (ret); |
| } |
| |
| #if defined(MBEDTLS_FREESCALE_LTC_PKHA) || defined(MBEDTLS_FREESCALE_CAU3_PKHA) |
| static int ltc_get_from_mbedtls_mpi(uint8_t *dst, const mbedtls_mpi *a, size_t sz) |
| { |
| return get_and_extend_mbedtls_mpi(dst, a, sz, kLittleEndian); |
| } |
| |
| #elif defined(MBEDTLS_FREESCALE_CAAM_PKHA) |
| static int caam_get_from_mbedtls_mpi(uint8_t *dst, const mbedtls_mpi *a, size_t sz) |
| { |
| return get_and_extend_mbedtls_mpi(dst, a, sz, kBigEndian); |
| } |
| #endif /* MBEDTLS_FREESCALE_LTC_PKHA */ |
| #endif /* MBEDTLS_ECP_MUL_COMB_ALT || MBEDTLS_ECP_ADD_ALT */ |
| |
| /* |
| * Multiplication using the comb method, |
| * for curves in short Weierstrass form |
| */ |
| #if defined(MBEDTLS_ECP_MUL_COMB_ALT) |
| #if defined(MBEDTLS_FREESCALE_LTC_PKHA) |
| int ecp_mul_comb(mbedtls_ecp_group *grp, |
| mbedtls_ecp_point *R, |
| const mbedtls_mpi *m, |
| const mbedtls_ecp_point *P, |
| int (*f_rng)(void *, unsigned char *, size_t), |
| void *p_rng) |
| { |
| int ret; |
| bool is_inf; |
| size_t size; |
| size_t size_bin; |
| int sign = m->s; |
| |
| ltc_pkha_ecc_point_t A; |
| ltc_pkha_ecc_point_t result; |
| |
| /* Allocate 7 elements with size of (LTC_MAX_ECC / 8) plus ptrE with size of FREESCALE_PKHA_INT_MAX_BYTES */ |
| uint8_t *ptrAX = mbedtls_calloc((7 * (LTC_MAX_ECC / 8)) + FREESCALE_PKHA_INT_MAX_BYTES, 1); |
| uint8_t *ptrAY = ptrAX + (LTC_MAX_ECC / 8); |
| uint8_t *ptrRX = ptrAY + (LTC_MAX_ECC / 8); |
| uint8_t *ptrRY = ptrRX + (LTC_MAX_ECC / 8); |
| uint8_t *ptrN = ptrRY + (LTC_MAX_ECC / 8); |
| uint8_t *ptrParamA = ptrN + (LTC_MAX_ECC / 8); |
| uint8_t *ptrParamB = ptrParamA + (LTC_MAX_ECC / 8); |
| uint8_t *ptrE = ptrParamB + (LTC_MAX_ECC / 8); |
| if (NULL == ptrAX) |
| { |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED); |
| } |
| |
| A.X = ptrAX; |
| A.Y = ptrAY; |
| result.X = ptrRX; |
| result.Y = ptrRY; |
| size = mbedtls_mpi_size(&grp->P); |
| if (mbedtls_mpi_size(&P->X) > (LTC_MAX_ECC / 8) || (mbedtls_mpi_get_bit(&grp->N, 0) != 1)) |
| { |
| CLEAN_RETURN(MBEDTLS_ERR_ECP_BAD_INPUT_DATA); |
| } |
| |
| /* Convert multi precision integers to arrays */ |
| MBEDTLS_MPI_CHK(ltc_get_from_mbedtls_mpi(A.X, &P->X, size)); |
| MBEDTLS_MPI_CHK(ltc_get_from_mbedtls_mpi(A.Y, &P->Y, size)); |
| MBEDTLS_MPI_CHK(ltc_get_from_mbedtls_mpi(ptrParamA, &grp->A, size)); |
| MBEDTLS_MPI_CHK(ltc_get_from_mbedtls_mpi(ptrParamB, &grp->B, size)); |
| |
| /* scalar multiplier integer of any size */ |
| size_bin = mbedtls_mpi_size(m); |
| MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(m, ptrE, size_bin)); |
| ltc_reverse_array(ptrE, size_bin); |
| |
| /* modulus */ |
| MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&grp->P, ptrN, size)); |
| ltc_reverse_array(ptrN, size); |
| |
| /* Multiply */ |
| LTC_PKHA_ECC_PointMul(LTC_INSTANCE, &A, ptrE, size_bin, ptrN, NULL, ptrParamA, ptrParamB, size, |
| kLTC_PKHA_TimingEqualized, kLTC_PKHA_IntegerArith, &result, &is_inf); |
| /* Convert result */ |
| ltc_reverse_array(ptrRX, size); |
| MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&R->X, ptrRX, size)); |
| ltc_reverse_array(ptrRY, size); |
| MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&R->Y, ptrRY, size)); |
| /* if the integer multiplier is negative, the computation happens with abs() value |
| * and the result (x,y) is changed to (x, -y) |
| */ |
| R->Y.s = sign; |
| MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&R->Z, 1)); |
| |
| cleanup: |
| if (ptrAX) |
| { |
| mbedtls_free(ptrAX); |
| } |
| return (ret); |
| } |
| |
| #elif defined(MBEDTLS_FREESCALE_CAAM_PKHA) |
| int ecp_mul_comb(mbedtls_ecp_group *grp, |
| mbedtls_ecp_point *R, |
| const mbedtls_mpi *m, |
| const mbedtls_ecp_point *P, |
| int (*f_rng)(void *, unsigned char *, size_t), |
| void *p_rng) |
| { |
| int ret; |
| size_t size; |
| size_t size_bin; |
| int sign = m->s; |
| |
| caam_pkha_ecc_point_t A; |
| caam_pkha_ecc_point_t result; |
| |
| /* Allocate 7 elements with size of (CAAM_MAX_ECC / 8) plus ptrE with size of FREESCALE_PKHA_INT_MAX_BYTES */ |
| uint8_t *ptrAX = mbedtls_calloc((7 * (CAAM_MAX_ECC / 8)) + FREESCALE_PKHA_INT_MAX_BYTES, 1); |
| uint8_t *ptrAY = ptrAX + (CAAM_MAX_ECC / 8); |
| uint8_t *ptrRX = ptrAY + (CAAM_MAX_ECC / 8); |
| uint8_t *ptrRY = ptrRX + (CAAM_MAX_ECC / 8); |
| uint8_t *ptrN = ptrRY + (CAAM_MAX_ECC / 8); |
| uint8_t *ptrParamA = ptrN + (CAAM_MAX_ECC / 8); |
| uint8_t *ptrParamB = ptrParamA + (CAAM_MAX_ECC / 8); |
| uint8_t *ptrE = ptrParamB + (CAAM_MAX_ECC / 8); |
| if (NULL == ptrAX) |
| { |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED); |
| } |
| |
| A.X = ptrAX; |
| A.Y = ptrAY; |
| result.X = ptrRX; |
| result.Y = ptrRY; |
| size = mbedtls_mpi_size(&grp->P); |
| if (mbedtls_mpi_size(&P->X) > (CAAM_MAX_ECC / 8) || (mbedtls_mpi_get_bit(&grp->N, 0) != 1)) |
| { |
| CLEAN_RETURN(MBEDTLS_ERR_ECP_BAD_INPUT_DATA); |
| } |
| |
| /* Convert multi precision integers to arrays */ |
| MBEDTLS_MPI_CHK(caam_get_from_mbedtls_mpi(A.X, &P->X, size)); |
| MBEDTLS_MPI_CHK(caam_get_from_mbedtls_mpi(A.Y, &P->Y, size)); |
| MBEDTLS_MPI_CHK(caam_get_from_mbedtls_mpi(ptrParamA, &grp->A, size)); |
| MBEDTLS_MPI_CHK(caam_get_from_mbedtls_mpi(ptrParamB, &grp->B, size)); |
| |
| /* scalar multiplier integer of any size */ |
| size_bin = mbedtls_mpi_size(m); |
| MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(m, ptrE, size_bin)); |
| |
| /* modulus */ |
| MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&grp->P, ptrN, size)); |
| |
| /* Multiply */ |
| CAAM_PKHA_ECC_PointMul(CAAM_INSTANCE, &s_caamHandle, &A, ptrE, size_bin, ptrN, NULL, ptrParamA, ptrParamB, size, |
| kCAAM_PKHA_TimingEqualized, kCAAM_PKHA_IntegerArith, &result); |
| /* Convert result */ |
| MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&R->X, ptrRX, size)); |
| MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&R->Y, ptrRY, size)); |
| /* if the integer multiplier is negative, the computation happens with abs() value |
| * and the result (x,y) is changed to (x, -y) |
| */ |
| R->Y.s = sign; |
| MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&R->Z, 1)); |
| |
| cleanup: |
| if (ptrAX) |
| { |
| mbedtls_free(ptrAX); |
| } |
| return (ret); |
| } |
| |
| #elif defined(MBEDTLS_FREESCALE_CAU3_PKHA) |
| int ecp_mul_comb(mbedtls_ecp_group *grp, |
| mbedtls_ecp_point *R, |
| const mbedtls_mpi *m, |
| const mbedtls_ecp_point *P, |
| int (*f_rng)(void *, unsigned char *, size_t), |
| void *p_rng) |
| { |
| int ret; |
| status_t status; |
| size_t size; |
| size_t size_bin; |
| int sign = m->s; |
| |
| cau3_pkha_ecc_point_t A; |
| cau3_pkha_ecc_point_t result; |
| |
| /* Allocate 7 elements with size of (CAU3_MAX_ECC / 8) plus ptrE with size of FREESCALE_PKHA_INT_MAX_BYTES */ |
| uint8_t *ptrAX = mbedtls_calloc((7 * (CAU3_MAX_ECC / 8)) + FREESCALE_PKHA_INT_MAX_BYTES, 1); |
| uint8_t *ptrAY = ptrAX + (CAU3_MAX_ECC / 8); |
| uint8_t *ptrRX = ptrAY + (CAU3_MAX_ECC / 8); |
| uint8_t *ptrRY = ptrRX + (CAU3_MAX_ECC / 8); |
| uint8_t *ptrN = ptrRY + (CAU3_MAX_ECC / 8); |
| uint8_t *ptrParamA = ptrN + (CAU3_MAX_ECC / 8); |
| uint8_t *ptrParamB = ptrParamA + (CAU3_MAX_ECC / 8); |
| uint8_t *ptrE = ptrParamB + (CAU3_MAX_ECC / 8); |
| if (NULL == ptrAX) |
| { |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED); |
| } |
| |
| A.X = ptrAX; |
| A.Y = ptrAY; |
| result.X = ptrRX; |
| result.Y = ptrRY; |
| size = mbedtls_mpi_size(&grp->P); |
| if (mbedtls_mpi_size(&P->X) > (CAU3_MAX_ECC / 8) || (mbedtls_mpi_get_bit(&grp->N, 0) != 1)) |
| { |
| CLEAN_RETURN(MBEDTLS_ERR_ECP_BAD_INPUT_DATA); |
| } |
| |
| /* Convert multi precision integers to arrays */ |
| MBEDTLS_MPI_CHK(cau3_get_from_mbedtls_mpi(A.X, &P->X, size)); |
| MBEDTLS_MPI_CHK(cau3_get_from_mbedtls_mpi(A.Y, &P->Y, size)); |
| MBEDTLS_MPI_CHK(cau3_get_from_mbedtls_mpi(ptrParamA, &grp->A, size)); |
| MBEDTLS_MPI_CHK(cau3_get_from_mbedtls_mpi(ptrParamB, &grp->B, size)); |
| |
| /* scalar multiplier integer of any size */ |
| size_bin = mbedtls_mpi_size(m); |
| MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(m, ptrE, size_bin)); |
| cau3_reverse_array(ptrE, size_bin); |
| |
| /* modulus */ |
| MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&grp->P, ptrN, size)); |
| cau3_reverse_array(ptrN, size); |
| |
| /* Multiply */ |
| status = CAU3_PKHA_ECC_PointMul(CAU3, &A, ptrE, size_bin, ptrN, NULL, ptrParamA, ptrParamB, size, |
| kCAU3_PKHA_TimingEqualized, kCAU3_PKHA_IntegerArith, &result); |
| |
| if (status != kStatus_Success) |
| { |
| CLEAN_RETURN(MBEDTLS_ERR_ECP_BAD_INPUT_DATA); |
| } |
| |
| /* Convert result */ |
| cau3_reverse_array(ptrRX, size); |
| MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&R->X, ptrRX, size)); |
| cau3_reverse_array(ptrRY, size); |
| MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&R->Y, ptrRY, size)); |
| /* if the integer multiplier is negative, the computation happens with abs() value |
| * and the result (x,y) is changed to (x, -y) |
| */ |
| R->Y.s = sign; |
| MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&R->Z, 1)); |
| |
| cleanup: |
| if (ptrAX) |
| { |
| mbedtls_free(ptrAX); |
| } |
| return (ret); |
| } |
| |
| #endif /* MBEDTLS_FREESCALE_LTC_PKHA */ |
| #endif /* MBEDTLS_ECP_MUL_COMB_ALT */ |
| |
| /* |
| * Curve types: internal for now, might be exposed later |
| */ |
| typedef enum |
| { |
| ECP_TYPE_NONE = 0, |
| ECP_TYPE_SHORT_WEIERSTRASS, /* y^2 = x^3 + a x + b */ |
| ECP_TYPE_MONTGOMERY, /* y^2 = x^3 + a x^2 + x */ |
| } ecp_curve_type; |
| /* |
| * Get the type of a curve |
| */ |
| static inline ecp_curve_type ecp_get_type(const mbedtls_ecp_group *grp) |
| { |
| if (grp->G.X.p == NULL) |
| return (ECP_TYPE_NONE); |
| |
| if (grp->G.Y.p == NULL) |
| return (ECP_TYPE_MONTGOMERY); |
| else |
| return (ECP_TYPE_SHORT_WEIERSTRASS); |
| } |
| |
| /* |
| * Addition: R = P + Q, result's coordinates normalized |
| */ |
| #if defined(MBEDTLS_ECP_ADD_ALT) |
| #if defined(MBEDTLS_FREESCALE_LTC_PKHA) |
| int ecp_add(const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q) |
| { |
| int ret; |
| size_t size; |
| ltc_pkha_ecc_point_t A; |
| ltc_pkha_ecc_point_t B; |
| ltc_pkha_ecc_point_t result; |
| |
| uint8_t *ptrAX = mbedtls_calloc(9, (LTC_MAX_ECC / 8)); |
| uint8_t *ptrAY = ptrAX + (LTC_MAX_ECC / 8); |
| uint8_t *ptrBX = ptrAY + (LTC_MAX_ECC / 8); |
| uint8_t *ptrBY = ptrBX + (LTC_MAX_ECC / 8); |
| uint8_t *ptrRX = ptrBY + (LTC_MAX_ECC / 8); |
| uint8_t *ptrRY = ptrRX + (LTC_MAX_ECC / 8); |
| uint8_t *ptrN = ptrRY + (LTC_MAX_ECC / 8); |
| uint8_t *ptrParamA = ptrN + (LTC_MAX_ECC / 8); |
| uint8_t *ptrParamB = ptrParamA + (LTC_MAX_ECC / 8); |
| if (NULL == ptrAX) |
| { |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED); |
| } |
| |
| if (ecp_get_type(grp) != ECP_TYPE_SHORT_WEIERSTRASS) |
| CLEAN_RETURN(MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE); |
| |
| A.X = ptrAX; |
| A.Y = ptrAY; |
| B.X = ptrBX; |
| B.Y = ptrBY; |
| result.X = ptrRX; |
| result.Y = ptrRY; |
| size = mbedtls_mpi_size(&grp->P); |
| if (mbedtls_mpi_size(&P->X) > (LTC_MAX_ECC / 8) || (mbedtls_mpi_get_bit(&grp->P, 0) != 1)) |
| { |
| CLEAN_RETURN(MBEDTLS_ERR_ECP_BAD_INPUT_DATA); |
| } |
| |
| /* Convert multi precision integers to arrays */ |
| MBEDTLS_MPI_CHK(ltc_get_from_mbedtls_mpi(A.X, &P->X, size)); |
| MBEDTLS_MPI_CHK(ltc_get_from_mbedtls_mpi(A.Y, &P->Y, size)); |
| MBEDTLS_MPI_CHK(ltc_get_from_mbedtls_mpi(B.X, &Q->X, size)); |
| MBEDTLS_MPI_CHK(ltc_get_from_mbedtls_mpi(B.Y, &Q->Y, size)); |
| MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&grp->P, ptrN, size)); |
| ltc_reverse_array(ptrN, size); |
| /* Multiply */ |
| LTC_PKHA_ECC_PointAdd(LTC_INSTANCE, &A, &B, ptrN, NULL, ptrParamA, ptrParamB, size, kLTC_PKHA_IntegerArith, |
| &result); |
| /* Convert result */ |
| ltc_reverse_array(ptrRX, size); |
| MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&R->X, ptrRX, size)); |
| ltc_reverse_array(ptrRY, size); |
| MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&R->Y, ptrRY, size)); |
| R->X.s = P->X.s; |
| R->Y.s = P->Y.s; |
| MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&R->Z, 1)); |
| |
| cleanup: |
| if (ptrAX) |
| { |
| mbedtls_free(ptrAX); |
| } |
| return (ret); |
| } |
| |
| #elif defined(MBEDTLS_FREESCALE_CAAM_PKHA) |
| int ecp_add(const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q) |
| { |
| int ret; |
| size_t size; |
| caam_pkha_ecc_point_t A; |
| caam_pkha_ecc_point_t B; |
| caam_pkha_ecc_point_t result; |
| |
| uint8_t *ptrAX = mbedtls_calloc(9, (CAAM_MAX_ECC / 8)); |
| uint8_t *ptrAY = ptrAX + (CAAM_MAX_ECC / 8); |
| uint8_t *ptrBX = ptrAY + (CAAM_MAX_ECC / 8); |
| uint8_t *ptrBY = ptrBX + (CAAM_MAX_ECC / 8); |
| uint8_t *ptrRX = ptrBY + (CAAM_MAX_ECC / 8); |
| uint8_t *ptrRY = ptrRX + (CAAM_MAX_ECC / 8); |
| uint8_t *ptrN = ptrRY + (CAAM_MAX_ECC / 8); |
| uint8_t *ptrParamA = ptrN + (CAAM_MAX_ECC / 8); |
| uint8_t *ptrParamB = ptrParamA + (CAAM_MAX_ECC / 8); |
| if (NULL == ptrAX) |
| { |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED); |
| } |
| |
| if (ecp_get_type(grp) != ECP_TYPE_SHORT_WEIERSTRASS) |
| CLEAN_RETURN(MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE); |
| |
| A.X = ptrAX; |
| A.Y = ptrAY; |
| B.X = ptrBX; |
| B.Y = ptrBY; |
| result.X = ptrRX; |
| result.Y = ptrRY; |
| size = mbedtls_mpi_size(&grp->P); |
| if (mbedtls_mpi_size(&P->X) > (CAAM_MAX_ECC / 8) || (mbedtls_mpi_get_bit(&grp->P, 0) != 1)) |
| { |
| CLEAN_RETURN(MBEDTLS_ERR_ECP_BAD_INPUT_DATA); |
| } |
| |
| /* Convert multi precision integers to arrays */ |
| MBEDTLS_MPI_CHK(caam_get_from_mbedtls_mpi(A.X, &P->X, size)); |
| MBEDTLS_MPI_CHK(caam_get_from_mbedtls_mpi(A.Y, &P->Y, size)); |
| MBEDTLS_MPI_CHK(caam_get_from_mbedtls_mpi(B.X, &Q->X, size)); |
| MBEDTLS_MPI_CHK(caam_get_from_mbedtls_mpi(B.Y, &Q->Y, size)); |
| MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&grp->P, ptrN, size)); |
| |
| /* Multiply */ |
| CAAM_PKHA_ECC_PointAdd(CAAM_INSTANCE, &s_caamHandle, &A, &B, ptrN, NULL, ptrParamA, ptrParamB, size, |
| kCAAM_PKHA_IntegerArith, &result); |
| /* Convert result */ |
| MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&R->X, ptrRX, size)); |
| MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&R->Y, ptrRY, size)); |
| R->X.s = P->X.s; |
| R->Y.s = P->Y.s; |
| MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&R->Z, 1)); |
| |
| cleanup: |
| if (ptrAX) |
| { |
| mbedtls_free(ptrAX); |
| } |
| return (ret); |
| } |
| |
| #elif defined(MBEDTLS_FREESCALE_CAU3_PKHA) |
| int ecp_add(const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q) |
| { |
| int ret; |
| status_t status; |
| size_t size; |
| cau3_pkha_ecc_point_t A; |
| cau3_pkha_ecc_point_t B; |
| cau3_pkha_ecc_point_t result; |
| |
| uint8_t *ptrAX = mbedtls_calloc(9, (CAU3_MAX_ECC / 8)); |
| uint8_t *ptrAY = ptrAX + (CAU3_MAX_ECC / 8); |
| uint8_t *ptrBX = ptrAY + (CAU3_MAX_ECC / 8); |
| uint8_t *ptrBY = ptrBX + (CAU3_MAX_ECC / 8); |
| uint8_t *ptrRX = ptrBY + (CAU3_MAX_ECC / 8); |
| uint8_t *ptrRY = ptrRX + (CAU3_MAX_ECC / 8); |
| uint8_t *ptrN = ptrRY + (CAU3_MAX_ECC / 8); |
| uint8_t *ptrParamA = ptrN + (CAU3_MAX_ECC / 8); |
| uint8_t *ptrParamB = ptrParamA + (CAU3_MAX_ECC / 8); |
| if (NULL == ptrAX) |
| { |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED); |
| } |
| |
| if (ecp_get_type(grp) != ECP_TYPE_SHORT_WEIERSTRASS) |
| CLEAN_RETURN(MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE); |
| |
| A.X = ptrAX; |
| A.Y = ptrAY; |
| B.X = ptrBX; |
| B.Y = ptrBY; |
| result.X = ptrRX; |
| result.Y = ptrRY; |
| size = mbedtls_mpi_size(&grp->P); |
| if (mbedtls_mpi_size(&P->X) > (CAU3_MAX_ECC / 8) || (mbedtls_mpi_get_bit(&grp->P, 0) != 1)) |
| { |
| CLEAN_RETURN(MBEDTLS_ERR_ECP_BAD_INPUT_DATA); |
| } |
| |
| /* Convert multi precision integers to arrays */ |
| MBEDTLS_MPI_CHK(cau3_get_from_mbedtls_mpi(A.X, &P->X, size)); |
| MBEDTLS_MPI_CHK(cau3_get_from_mbedtls_mpi(A.Y, &P->Y, size)); |
| MBEDTLS_MPI_CHK(cau3_get_from_mbedtls_mpi(B.X, &Q->X, size)); |
| MBEDTLS_MPI_CHK(cau3_get_from_mbedtls_mpi(B.Y, &Q->Y, size)); |
| MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&grp->P, ptrN, size)); |
| cau3_reverse_array(ptrN, size); |
| /* Multiply */ |
| status = |
| CAU3_PKHA_ECC_PointAdd(CAU3, &A, &B, ptrN, NULL, ptrParamA, ptrParamB, size, kCAU3_PKHA_IntegerArith, &result); |
| |
| if (status != kStatus_Success) |
| { |
| CLEAN_RETURN(MBEDTLS_ERR_ECP_BAD_INPUT_DATA); |
| } |
| |
| /* Convert result */ |
| cau3_reverse_array(ptrRX, size); |
| MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&R->X, ptrRX, size)); |
| cau3_reverse_array(ptrRY, size); |
| MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&R->Y, ptrRY, size)); |
| R->X.s = P->X.s; |
| R->Y.s = P->Y.s; |
| MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&R->Z, 1)); |
| |
| cleanup: |
| if (ptrAX) |
| { |
| mbedtls_free(ptrAX); |
| } |
| return (ret); |
| } |
| |
| #endif /* MBEDTLS_FREESCALE_LTC_PKHA */ |
| |
| #endif /* MBEDTLS_ECP_ADD_ALT */ |
| |
| #if defined(MBEDTLS_ECP_MUL_MXZ_ALT) |
| #if defined(MBEDTLS_FREESCALE_CAU3_PKHA) |
| |
| /* curve25519 params - in little endian for CAU3 */ |
| static const uint8_t s_curve25519_A24[] = {0x42, 0xdb, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; |
| |
| static const uint8_t s_curve25519_N[] = {0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
| 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
| 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f}; |
| |
| static const uint8_t s_curve25519_R2modN[] = {0xa4, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; |
| |
| int ecp_mul_mxz(mbedtls_ecp_group *grp, |
| mbedtls_ecp_point *R, |
| const mbedtls_mpi *m, |
| const mbedtls_ecp_point *P, |
| int (*f_rng)(void *, unsigned char *, size_t), |
| void *p_rng) |
| { |
| int ret; |
| status_t status; |
| size_t size; |
| size_t size_bin; |
| |
| cau3_pkha_ecc_point_t A; |
| cau3_pkha_ecc_point_t result; |
| |
| /* Allocate 2 elements with size of (CAU3_MAX_ECC / 8) plus ptrE with size of FREESCALE_PKHA_INT_MAX_BYTES */ |
| uint8_t *ptrAX = mbedtls_calloc((2 * (CAU3_MAX_ECC / 8)) + FREESCALE_PKHA_INT_MAX_BYTES, 1); |
| uint8_t *ptrRX = ptrAX + (CAU3_MAX_ECC / 8); |
| uint8_t *ptrE = ptrRX + (CAU3_MAX_ECC / 8); |
| if (NULL == ptrAX) |
| { |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED); |
| } |
| |
| A.X = ptrAX; |
| result.X = ptrRX; |
| size = mbedtls_mpi_size(&grp->P); |
| if (mbedtls_mpi_size(&P->X) > (CAAM_MAX_ECC / 8)) |
| { |
| CLEAN_RETURN(MBEDTLS_ERR_ECP_BAD_INPUT_DATA); |
| } |
| |
| /* Convert multi precision integers to arrays */ |
| MBEDTLS_MPI_CHK(cau3_get_from_mbedtls_mpi(A.X, &P->X, size)); |
| |
| /* scalar multiplier integer of any size */ |
| size_bin = mbedtls_mpi_size(m); |
| MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(m, ptrE, size_bin)); |
| cau3_reverse_array(ptrE, size_bin); |
| |
| /* Multiply */ |
| status = CAU3_PKHA_ECM_PointMul(CAU3, ptrE, size_bin, A.X, s_curve25519_A24, s_curve25519_N, s_curve25519_R2modN, |
| size, kCAU3_PKHA_TimingEqualized, result.X); |
| |
| if (status != kStatus_Success) |
| { |
| CLEAN_RETURN(MBEDTLS_ERR_ECP_BAD_INPUT_DATA); |
| } |
| |
| /* Convert result */ |
| cau3_reverse_array(ptrRX, size); |
| MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&R->X, ptrRX, size)); |
| MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&R->Z, 1)); |
| |
| cleanup: |
| if (ptrAX) |
| { |
| mbedtls_free(ptrAX); |
| } |
| return (ret); |
| } |
| |
| #endif /* MBEDTLS_FREESCALE_CAU3_PKHA */ |
| #endif /* MBEDTLS_ECP_MUL_MXZ_ALT */ |
| |
| #endif /* MBEDTLS_ECP_C */ |
| |
| #endif /* MBEDTLS_FREESCALE_LTC_PKHA */ |
| |
| #if defined(MBEDTLS_RSA_PUBLIC_ALT) |
| #if defined(MBEDTLS_FREESCALE_CASPER_PKHA) |
| |
| #if defined(MBEDTLS_PLATFORM_C) |
| #include "mbedtls/platform.h" |
| #else |
| #include <stdio.h> |
| #define mbedtls_calloc calloc |
| #define mbedtls_free free |
| #endif |
| |
| #include "mbedtls/bignum.h" |
| #include "mbedtls/rsa.h" |
| |
| static void reverse_array(uint8_t *src, size_t src_len) |
| { |
| int i; |
| |
| for (i = 0; i < src_len / 2; i++) |
| { |
| uint8_t tmp; |
| |
| tmp = src[i]; |
| src[i] = src[src_len - 1 - i]; |
| src[src_len - 1 - i] = tmp; |
| } |
| } |
| /* |
| * Do an RSA public key operation |
| */ |
| static int mbedtls_mpi_exp_mod_shim(mbedtls_mpi *X, |
| const mbedtls_mpi *A, |
| const mbedtls_mpi *E, |
| const mbedtls_mpi *N /*, mbedtls_mpi *_RR */) |
| { |
| int ret = MBEDTLS_ERR_MPI_ALLOC_FAILED; |
| size_t sizeA = mbedtls_mpi_size(A); |
| size_t sizeN = mbedtls_mpi_size(N); |
| uint8_t *ptrX = mbedtls_calloc(3, FREESCALE_PKHA_INT_MAX_BYTES); |
| uint8_t *ptrA = ptrX + FREESCALE_PKHA_INT_MAX_BYTES; |
| uint8_t *ptrN = ptrA + FREESCALE_PKHA_INT_MAX_BYTES; |
| |
| if (NULL == ptrX) |
| { |
| CLEAN_RETURN(MBEDTLS_ERR_MPI_ALLOC_FAILED); |
| } |
| |
| MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(A, ptrA, sizeA)); |
| reverse_array(ptrA, sizeA); |
| |
| MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(N, ptrN, sizeN)); |
| reverse_array(ptrN, sizeN); |
| |
| CASPER_ModExp(CASPER, ptrA, ptrN, sizeN / 4, E->p[0], ptrX); |
| |
| reverse_array(ptrX, sizeN); |
| MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(X, ptrX, sizeN)); |
| cleanup: |
| if (ptrX != NULL) |
| { |
| mbedtls_free(ptrX); |
| } |
| |
| return ret; |
| } |
| |
| int mbedtls_rsa_public(mbedtls_rsa_context *ctx, const unsigned char *input, unsigned char *output) |
| { |
| int ret; |
| size_t olen; |
| mbedtls_mpi T; |
| |
| mbedtls_mpi_init(&T); |
| |
| #if defined(MBEDTLS_THREADING_C) |
| if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) |
| return (ret); |
| #endif |
| |
| MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&T, input, ctx->len)); |
| |
| if (mbedtls_mpi_cmp_mpi(&T, &ctx->N) >= 0) |
| { |
| ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA; |
| goto cleanup; |
| } |
| |
| olen = ctx->len; |
| |
| MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod_shim(&T, &T, &ctx->E, &ctx->N /*, &ctx->RN */)); |
| |
| MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&T, output, olen)); |
| |
| cleanup: |
| #if defined(MBEDTLS_THREADING_C) |
| if (mbedtls_mutex_unlock(&ctx->mutex) != 0) |
| return (MBEDTLS_ERR_THREADING_MUTEX_ERROR); |
| #endif |
| |
| mbedtls_mpi_free(&T); |
| |
| if (ret != 0) |
| return (MBEDTLS_ERR_RSA_PUBLIC_FAILED + ret); |
| |
| return (0); |
| } |
| |
| #endif /* MBEDTLS_FREESCALE_CASPER_PKHA */ |
| #endif /* MBEDTLS_RSA_PUBLIC_ALT */ |
| |
| /******************************************************************************/ |
| /*************************** MD5 **********************************************/ |
| /******************************************************************************/ |
| |
| #if defined(MBEDTLS_MD5_C) |
| |
| #if defined(MBEDTLS_FREESCALE_MMCAU_MD5) |
| |
| #include "mbedtls/md5.h" |
| |
| int mbedtls_internal_md5_process(mbedtls_md5_context *ctx, const unsigned char data[64]) |
| { |
| status_t ret = kStatus_Fail; |
| ret = MMCAU_MD5_HashN(data, 1, ctx->state); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_MD5_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| #endif /* MBEDTLS_FREESCALE_MMCAU_MD5 */ |
| |
| #endif /* MBEDTLS_MD5_C */ |
| |
| /******************************************************************************/ |
| /*************************** SHA1 *********************************************/ |
| /******************************************************************************/ |
| |
| #if defined(MBEDTLS_SHA1_C) |
| |
| #if defined(MBEDTLS_FREESCALE_LTC_SHA1) |
| #include "mbedtls/sha1.h" |
| |
| void mbedtls_sha1_init(mbedtls_sha1_context *ctx) |
| { |
| memset(ctx, 0, sizeof(mbedtls_sha1_context)); |
| } |
| |
| void mbedtls_sha1_free(mbedtls_sha1_context *ctx) |
| { |
| if (ctx == NULL) |
| return; |
| |
| mbedtls_zeroize(ctx, sizeof(mbedtls_sha1_context)); |
| } |
| |
| void mbedtls_sha1_clone(mbedtls_sha1_context *dst, const mbedtls_sha1_context *src) |
| { |
| memcpy(dst, src, sizeof(mbedtls_sha1_context)); |
| } |
| |
| /* |
| * SHA-1 context setup |
| */ |
| int mbedtls_sha1_starts_ret(mbedtls_sha1_context *ctx) |
| { |
| status_t ret = kStatus_Fail; |
| ret = LTC_HASH_Init(LTC_INSTANCE, ctx, kLTC_Sha1, NULL, 0); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| int mbedtls_internal_sha1_process(mbedtls_sha1_context *ctx, const unsigned char data[64]) |
| { |
| status_t ret = kStatus_Fail; |
| ret = LTC_HASH_Update(ctx, data, 64); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| /* |
| * SHA-1 process buffer |
| */ |
| int mbedtls_sha1_update_ret(mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen) |
| { |
| status_t ret = kStatus_Fail; |
| ret = LTC_HASH_Update(ctx, input, ilen); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| /* |
| * SHA-1 final digest |
| */ |
| int mbedtls_sha1_finish_ret(mbedtls_sha1_context *ctx, unsigned char output[20]) |
| { |
| status_t ret = kStatus_Fail; |
| ret = LTC_HASH_Finish(ctx, output, 0); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| #elif defined(MBEDTLS_FREESCALE_MMCAU_SHA1) |
| |
| #include "mbedtls/sha1.h" |
| |
| int mbedtls_internal_sha1_process(mbedtls_sha1_context *ctx, const unsigned char data[64]) |
| { |
| status_t ret = kStatus_Fail; |
| ret = MMCAU_SHA1_HashN(data, 1, ctx->state); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| #elif defined(MBEDTLS_FREESCALE_LPC_SHA1) |
| #include "mbedtls/sha1.h" |
| |
| void mbedtls_sha1_init(mbedtls_sha1_context *ctx) |
| { |
| memset(ctx, 0, sizeof(mbedtls_sha1_context)); |
| } |
| |
| void mbedtls_sha1_free(mbedtls_sha1_context *ctx) |
| { |
| if (ctx == NULL) |
| return; |
| |
| mbedtls_zeroize(ctx, sizeof(mbedtls_sha1_context)); |
| } |
| |
| void mbedtls_sha1_clone(mbedtls_sha1_context *dst, const mbedtls_sha1_context *src) |
| { |
| memcpy(dst, src, sizeof(mbedtls_sha1_context)); |
| } |
| |
| /* |
| * SHA-1 context setup |
| */ |
| int mbedtls_sha1_starts_ret(mbedtls_sha1_context *ctx) |
| { |
| status_t ret = kStatus_Fail; |
| ret = SHA_Init(SHA_INSTANCE, ctx, kSHA_Sha1); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| int mbedtls_internal_sha1_process(mbedtls_sha1_context *ctx, const unsigned char data[64]) |
| { |
| status_t ret = kStatus_Fail; |
| ret = SHA_Update(SHA_INSTANCE, ctx, data, 64, MANUAL_LOAD_SHA_INPUT); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| /* |
| * SHA-1 process buffer |
| */ |
| int mbedtls_sha1_update_ret(mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen) |
| { |
| status_t ret = kStatus_Fail; |
| ret = SHA_Update(SHA_INSTANCE, ctx, input, ilen, MANUAL_LOAD_SHA_INPUT); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| /* |
| * SHA-1 final digest |
| */ |
| int mbedtls_sha1_finish_ret(mbedtls_sha1_context *ctx, unsigned char output[20]) |
| { |
| size_t outputSize = 20u; |
| status_t ret = kStatus_Fail; |
| ret = SHA_Finish(SHA_INSTANCE, ctx, output, &outputSize); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| #elif defined(MBEDTLS_FREESCALE_CAAM_SHA1) |
| #include "mbedtls/sha1.h" |
| |
| void mbedtls_sha1_init(mbedtls_sha1_context *ctx) |
| { |
| memset(ctx, 0, sizeof(mbedtls_sha1_context)); |
| } |
| |
| void mbedtls_sha1_free(mbedtls_sha1_context *ctx) |
| { |
| if (ctx == NULL) |
| return; |
| |
| mbedtls_zeroize(ctx, sizeof(mbedtls_sha1_context)); |
| } |
| |
| void mbedtls_sha1_clone(mbedtls_sha1_context *dst, const mbedtls_sha1_context *src) |
| { |
| memcpy(dst, src, sizeof(mbedtls_sha1_context)); |
| } |
| |
| /* |
| * SHA-1 context setup |
| */ |
| int mbedtls_sha1_starts_ret(mbedtls_sha1_context *ctx) |
| { |
| status_t ret = kStatus_Fail; |
| ret = CAAM_HASH_Init(CAAM_INSTANCE, &s_caamHandle, ctx, kCAAM_Sha1, NULL, 0); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| int mbedtls_internal_sha1_process(mbedtls_sha1_context *ctx, const unsigned char data[64]) |
| { |
| status_t ret = kStatus_Fail; |
| ret = CAAM_HASH_Update(ctx, data, 64); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| /* |
| * SHA-1 process buffer |
| */ |
| int mbedtls_sha1_update_ret(mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen) |
| { |
| status_t ret = kStatus_Fail; |
| ret = CAAM_HASH_Update(ctx, input, ilen); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| /* |
| * SHA-1 final digest |
| */ |
| int mbedtls_sha1_finish_ret(mbedtls_sha1_context *ctx, unsigned char output[20]) |
| { |
| status_t ret = kStatus_Fail; |
| ret = CAAM_HASH_Finish(ctx, output, 0); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| #elif defined(MBEDTLS_FREESCALE_CAU3_SHA1) |
| #include "mbedtls/sha1.h" |
| |
| void mbedtls_sha1_init(mbedtls_sha1_context *ctx) |
| { |
| memset(ctx, 0, sizeof(mbedtls_sha1_context)); |
| } |
| |
| void mbedtls_sha1_free(mbedtls_sha1_context *ctx) |
| { |
| if (ctx == NULL) |
| return; |
| |
| mbedtls_zeroize(ctx, sizeof(mbedtls_sha1_context)); |
| } |
| |
| void mbedtls_sha1_clone(mbedtls_sha1_context *dst, const mbedtls_sha1_context *src) |
| { |
| memcpy(dst, src, sizeof(mbedtls_sha1_context)); |
| } |
| |
| /* |
| * SHA-1 context setup |
| */ |
| int mbedtls_sha1_starts_ret(mbedtls_sha1_context *ctx) |
| { |
| status_t ret = kStatus_Fail; |
| ret = CAU3_HASH_Init(CAU3, ctx, kCAU3_Sha1); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| int mbedtls_internal_sha1_process(mbedtls_sha1_context *ctx, const unsigned char data[64]) |
| { |
| status_t ret = kStatus_Fail; |
| ret = CAU3_HASH_Update(CAU3, ctx, data, 64); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| /* |
| * SHA-1 process buffer |
| */ |
| int mbedtls_sha1_update_ret(mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen) |
| { |
| status_t ret = kStatus_Fail; |
| ret = CAU3_HASH_Update(CAU3, ctx, input, ilen); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| /* |
| * SHA-1 final digest |
| */ |
| int mbedtls_sha1_finish_ret(mbedtls_sha1_context *ctx, unsigned char output[20]) |
| { |
| status_t ret = kStatus_Fail; |
| ret = CAU3_HASH_Finish(CAU3, ctx, output, 0); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| #elif defined(MBEDTLS_FREESCALE_DCP_SHA1) |
| #include "mbedtls/sha1.h" |
| |
| void mbedtls_sha1_init(mbedtls_sha1_context *ctx) |
| { |
| memset(ctx, 0, sizeof(mbedtls_sha1_context)); |
| } |
| |
| void mbedtls_sha1_free(mbedtls_sha1_context *ctx) |
| { |
| if (ctx == NULL) |
| return; |
| |
| mbedtls_zeroize(ctx, sizeof(mbedtls_sha1_context)); |
| } |
| |
| void mbedtls_sha1_clone(mbedtls_sha1_context *dst, const mbedtls_sha1_context *src) |
| { |
| memcpy(dst, src, sizeof(mbedtls_sha1_context)); |
| } |
| |
| /* |
| * SHA-1 context setup |
| */ |
| int mbedtls_sha1_starts_ret(mbedtls_sha1_context *ctx) |
| { |
| status_t ret = kStatus_Fail; |
| ret = DCP_HASH_Init(DCP, &s_dcpHandle, ctx, kDCP_Sha1); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| int mbedtls_internal_sha1_process(mbedtls_sha1_context *ctx, const unsigned char data[64]) |
| { |
| status_t ret = kStatus_Fail; |
| ret = DCP_HASH_Update(DCP, ctx, data, 64); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| /* |
| * SHA-1 process buffer |
| */ |
| int mbedtls_sha1_update_ret(mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen) |
| { |
| status_t ret = kStatus_Fail; |
| ret = DCP_HASH_Update(DCP, ctx, input, ilen); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| /* |
| * SHA-1 final digest |
| */ |
| int mbedtls_sha1_finish_ret(mbedtls_sha1_context *ctx, unsigned char output[20]) |
| { |
| status_t ret = kStatus_Fail; |
| ret = DCP_HASH_Finish(DCP, ctx, output, NULL); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| #elif defined(MBEDTLS_FREESCALE_HASHCRYPT_SHA1) |
| #include "mbedtls/sha1.h" |
| |
| void mbedtls_sha1_init(mbedtls_sha1_context *ctx) |
| { |
| memset(ctx, 0, sizeof(mbedtls_sha1_context)); |
| } |
| |
| void mbedtls_sha1_free(mbedtls_sha1_context *ctx) |
| { |
| if (ctx == NULL) |
| return; |
| |
| mbedtls_zeroize(ctx, sizeof(mbedtls_sha1_context)); |
| } |
| |
| void mbedtls_sha1_clone(mbedtls_sha1_context *dst, const mbedtls_sha1_context *src) |
| { |
| memcpy(dst, src, sizeof(mbedtls_sha1_context)); |
| } |
| |
| /* |
| * SHA-1 context setup |
| */ |
| int mbedtls_sha1_starts_ret(mbedtls_sha1_context *ctx) |
| { |
| status_t ret = kStatus_Fail; |
| ret = HASHCRYPT_SHA_Init(HASHCRYPT, ctx, kHASHCRYPT_Sha1); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| int mbedtls_internal_sha1_process(mbedtls_sha1_context *ctx, const unsigned char data[64]) |
| { |
| status_t ret = kStatus_Fail; |
| ret = HASHCRYPT_SHA_Update(HASHCRYPT, ctx, data, 64); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| /* |
| * SHA-1 process buffer |
| */ |
| int mbedtls_sha1_update_ret(mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen) |
| { |
| status_t ret = kStatus_Fail; |
| ret = HASHCRYPT_SHA_Update(HASHCRYPT, ctx, input, ilen); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| /* |
| * SHA-1 final digest |
| */ |
| int mbedtls_sha1_finish_ret(mbedtls_sha1_context *ctx, unsigned char output[20]) |
| { |
| status_t ret = kStatus_Fail; |
| size_t outputSize = 20; |
| ret = HASHCRYPT_SHA_Finish(HASHCRYPT, ctx, output, &outputSize); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| #endif /* MBEDTLS_FREESCALE_LPC_SHA1 */ |
| #if !defined(MBEDTLS_DEPRECATED_REMOVED) && defined(MBEDTLS_SHA1_ALT) |
| #include "mbedtls/sha1.h" |
| |
| void mbedtls_sha1_starts(mbedtls_sha1_context *ctx) |
| { |
| mbedtls_sha1_starts_ret(ctx); |
| } |
| |
| void mbedtls_sha1_update(mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen) |
| { |
| mbedtls_sha1_update_ret(ctx, input, ilen); |
| } |
| |
| void mbedtls_sha1_finish(mbedtls_sha1_context *ctx, unsigned char output[20]) |
| { |
| mbedtls_sha1_finish_ret(ctx, output); |
| } |
| |
| void mbedtls_sha1_process(mbedtls_sha1_context *ctx, const unsigned char data[64]) |
| { |
| mbedtls_internal_sha1_process(ctx, data); |
| } |
| #endif /* MBEDTLS_DEPRECATED_REMOVED */ |
| #endif /* MBEDTLS_SHA1_C */ |
| |
| /******************************************************************************/ |
| /*************************** SHA256********************************************/ |
| /******************************************************************************/ |
| |
| #if defined(MBEDTLS_SHA256_C) |
| |
| #if defined(MBEDTLS_FREESCALE_LTC_SHA256) |
| #include "mbedtls/sha256.h" |
| |
| void mbedtls_sha256_init(mbedtls_sha256_context *ctx) |
| { |
| memset(ctx, 0, sizeof(mbedtls_sha256_context)); |
| } |
| |
| void mbedtls_sha256_free(mbedtls_sha256_context *ctx) |
| { |
| if (ctx == NULL) |
| return; |
| |
| mbedtls_zeroize(ctx, sizeof(mbedtls_sha256_context)); |
| } |
| |
| void mbedtls_sha256_clone(mbedtls_sha256_context *dst, const mbedtls_sha256_context *src) |
| { |
| memcpy(dst, src, sizeof(*dst)); |
| } |
| |
| /* |
| * SHA-256 context setup |
| */ |
| int mbedtls_sha256_starts_ret(mbedtls_sha256_context *ctx, int is224) |
| { |
| status_t ret = kStatus_Fail; |
| if (is224) |
| { |
| ret = LTC_HASH_Init(LTC_INSTANCE, ctx, kLTC_Sha224, NULL, 0); |
| } |
| else |
| { |
| ret = LTC_HASH_Init(LTC_INSTANCE, ctx, kLTC_Sha256, NULL, 0); |
| } |
| |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx, const unsigned char data[64]) |
| { |
| status_t ret = kStatus_Fail; |
| ret = LTC_HASH_Update(ctx, data, 64); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| /* |
| * SHA-256 process buffer |
| */ |
| int mbedtls_sha256_update_ret(mbedtls_sha256_context *ctx, const unsigned char *input, size_t ilen) |
| { |
| status_t ret = kStatus_Fail; |
| ret = LTC_HASH_Update(ctx, input, ilen); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| /* |
| * SHA-256 final digest |
| */ |
| int mbedtls_sha256_finish_ret(mbedtls_sha256_context *ctx, unsigned char output[32]) |
| { |
| status_t ret = kStatus_Fail; |
| ret = LTC_HASH_Finish(ctx, output, 0); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| #elif defined(MBEDTLS_FREESCALE_MMCAU_SHA256) |
| |
| #include "mbedtls/sha256.h" |
| |
| int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx, const unsigned char data[64]) |
| { |
| status_t ret = kStatus_Fail; |
| ret = MMCAU_SHA256_HashN(data, 1, ctx->state); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| #elif defined(MBEDTLS_FREESCALE_CAU3_SHA256) |
| |
| #include "mbedtls/sha256.h" |
| |
| void mbedtls_sha256_init(mbedtls_sha256_context *ctx) |
| { |
| memset(ctx, 0, sizeof(mbedtls_sha256_context)); |
| } |
| |
| void mbedtls_sha256_free(mbedtls_sha256_context *ctx) |
| { |
| if (ctx == NULL) |
| return; |
| |
| mbedtls_zeroize(ctx, sizeof(mbedtls_sha256_context)); |
| } |
| |
| void mbedtls_sha256_clone(mbedtls_sha256_context *dst, const mbedtls_sha256_context *src) |
| { |
| memcpy(dst, src, sizeof(*dst)); |
| } |
| |
| /* |
| * SHA-256 context setup |
| */ |
| int mbedtls_sha256_starts_ret(mbedtls_sha256_context *ctx, int is224) |
| { |
| status_t ret = kStatus_Fail; |
| if (!is224) /* SHA-224 not supported at the moment */ |
| { |
| ret = CAU3_HASH_Init(CAU3, ctx, kCAU3_Sha256); |
| } |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx, const unsigned char data[64]) |
| { |
| status_t ret = kStatus_Fail; |
| ret = CAU3_HASH_Update(CAU3, ctx, data, 64); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| /* |
| * SHA-256 process buffer |
| */ |
| int mbedtls_sha256_update_ret(mbedtls_sha256_context *ctx, const unsigned char *input, size_t ilen) |
| { |
| status_t ret = kStatus_Fail; |
| ret = CAU3_HASH_Update(CAU3, ctx, input, ilen); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| /* |
| * SHA-256 final digest |
| */ |
| int mbedtls_sha256_finish_ret(mbedtls_sha256_context *ctx, unsigned char output[32]) |
| { |
| status_t ret = kStatus_Fail; |
| ret = CAU3_HASH_Finish(CAU3, ctx, output, 0); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| #elif defined(MBEDTLS_FREESCALE_LPC_SHA256) |
| #include "mbedtls/sha256.h" |
| |
| void mbedtls_sha256_init(mbedtls_sha256_context *ctx) |
| { |
| memset(ctx, 0, sizeof(mbedtls_sha256_context)); |
| } |
| |
| void mbedtls_sha256_free(mbedtls_sha256_context *ctx) |
| { |
| if (ctx == NULL) |
| return; |
| |
| mbedtls_zeroize(ctx, sizeof(mbedtls_sha256_context)); |
| } |
| |
| void mbedtls_sha256_clone(mbedtls_sha256_context *dst, const mbedtls_sha256_context *src) |
| { |
| memcpy(dst, src, sizeof(*dst)); |
| } |
| |
| /* |
| * SHA-256 context setup |
| */ |
| int mbedtls_sha256_starts_ret(mbedtls_sha256_context *ctx, int is224) |
| { |
| status_t ret = kStatus_Fail; |
| if (!is224) /* SHA-224 not supported */ |
| { |
| ret = SHA_Init(SHA_INSTANCE, ctx, kSHA_Sha256); |
| } |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx, const unsigned char data[64]) |
| { |
| status_t ret = kStatus_Fail; |
| ret = SHA_Update(SHA_INSTANCE, ctx, data, 64, MANUAL_LOAD_SHA_INPUT); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| /* |
| * SHA-256 process buffer |
| */ |
| int mbedtls_sha256_update_ret(mbedtls_sha256_context *ctx, const unsigned char *input, size_t ilen) |
| { |
| status_t ret = kStatus_Fail; |
| ret = SHA_Update(SHA_INSTANCE, ctx, input, ilen, MANUAL_LOAD_SHA_INPUT); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| /* |
| * SHA-256 final digest |
| */ |
| int mbedtls_sha256_finish_ret(mbedtls_sha256_context *ctx, unsigned char output[32]) |
| { |
| size_t outputSize = 32u; |
| status_t ret = kStatus_Fail; |
| ret = SHA_Finish(SHA_INSTANCE, ctx, output, &outputSize); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| #elif defined(MBEDTLS_FREESCALE_CAAM_SHA256) |
| #include "mbedtls/sha256.h" |
| |
| void mbedtls_sha256_init(mbedtls_sha256_context *ctx) |
| { |
| memset(ctx, 0, sizeof(mbedtls_sha256_context)); |
| } |
| |
| void mbedtls_sha256_free(mbedtls_sha256_context *ctx) |
| { |
| if (ctx == NULL) |
| return; |
| |
| mbedtls_zeroize(ctx, sizeof(mbedtls_sha256_context)); |
| } |
| |
| void mbedtls_sha256_clone(mbedtls_sha256_context *dst, const mbedtls_sha256_context *src) |
| { |
| memcpy(dst, src, sizeof(*dst)); |
| } |
| |
| /* |
| * SHA-256 context setup |
| */ |
| int mbedtls_sha256_starts_ret(mbedtls_sha256_context *ctx, int is224) |
| { |
| status_t ret = kStatus_Fail; |
| if (is224) |
| { |
| ret = CAAM_HASH_Init(CAAM_INSTANCE, &s_caamHandle, ctx, kCAAM_Sha224, NULL, 0); |
| } |
| else |
| { |
| ret = CAAM_HASH_Init(CAAM_INSTANCE, &s_caamHandle, ctx, kCAAM_Sha256, NULL, 0); |
| } |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx, const unsigned char data[64]) |
| { |
| status_t ret = kStatus_Fail; |
| ret = CAAM_HASH_Update(ctx, data, 64); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| /* |
| * SHA-256 process buffer |
| */ |
| int mbedtls_sha256_update_ret(mbedtls_sha256_context *ctx, const unsigned char *input, size_t ilen) |
| { |
| status_t ret = kStatus_Fail; |
| ret = CAAM_HASH_Update(ctx, input, ilen); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| /* |
| * SHA-256 final digest |
| */ |
| int mbedtls_sha256_finish_ret(mbedtls_sha256_context *ctx, unsigned char output[32]) |
| { |
| status_t ret = kStatus_Fail; |
| ret = CAAM_HASH_Finish(ctx, output, 0); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| #elif defined(MBEDTLS_FREESCALE_DCP_SHA256) |
| #include "mbedtls/sha256.h" |
| |
| void mbedtls_sha256_init(mbedtls_sha256_context *ctx) |
| { |
| memset(ctx, 0, sizeof(mbedtls_sha256_context)); |
| } |
| |
| void mbedtls_sha256_free(mbedtls_sha256_context *ctx) |
| { |
| if (ctx == NULL) |
| return; |
| |
| mbedtls_zeroize(ctx, sizeof(mbedtls_sha256_context)); |
| } |
| |
| void mbedtls_sha256_clone(mbedtls_sha256_context *dst, const mbedtls_sha256_context *src) |
| { |
| memcpy(dst, src, sizeof(*dst)); |
| } |
| |
| /* |
| * SHA-256 context setup |
| */ |
| int mbedtls_sha256_starts_ret(mbedtls_sha256_context *ctx, int is224) |
| { |
| status_t ret = kStatus_Fail; |
| if (!is224) |
| { |
| ret = DCP_HASH_Init(DCP, &s_dcpHandle, ctx, kDCP_Sha256); |
| } |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx, const unsigned char data[64]) |
| { |
| status_t ret = kStatus_Fail; |
| ret = DCP_HASH_Update(DCP, ctx, data, 64); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| /* |
| * SHA-256 process buffer |
| */ |
| int mbedtls_sha256_update_ret(mbedtls_sha256_context *ctx, const unsigned char *input, size_t ilen) |
| { |
| status_t ret = kStatus_Fail; |
| ret = DCP_HASH_Update(DCP, ctx, input, ilen); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| /* |
| * SHA-256 final digest |
| */ |
| int mbedtls_sha256_finish_ret(mbedtls_sha256_context *ctx, unsigned char output[32]) |
| { |
| status_t ret = kStatus_Fail; |
| ret = DCP_HASH_Finish(DCP, ctx, output, NULL); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| #elif defined(MBEDTLS_FREESCALE_HASHCRYPT_SHA256) |
| #include "mbedtls/sha256.h" |
| |
| void mbedtls_sha256_init(mbedtls_sha256_context *ctx) |
| { |
| memset(ctx, 0, sizeof(mbedtls_sha256_context)); |
| } |
| |
| void mbedtls_sha256_free(mbedtls_sha256_context *ctx) |
| { |
| if (ctx == NULL) |
| return; |
| |
| mbedtls_zeroize(ctx, sizeof(mbedtls_sha256_context)); |
| } |
| |
| void mbedtls_sha256_clone(mbedtls_sha256_context *dst, const mbedtls_sha256_context *src) |
| { |
| memcpy(dst, src, sizeof(*dst)); |
| } |
| |
| /* |
| * SHA-256 context setup |
| */ |
| int mbedtls_sha256_starts_ret(mbedtls_sha256_context *ctx, int is224) |
| { |
| status_t ret = kStatus_Fail; |
| if (!is224) /* SHA-224 not supported */ |
| { |
| ret = HASHCRYPT_SHA_Init(HASHCRYPT, ctx, kHASHCRYPT_Sha256); |
| } |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx, const unsigned char data[64]) |
| { |
| status_t ret = kStatus_Fail; |
| ret = HASHCRYPT_SHA_Update(HASHCRYPT, ctx, data, 64); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| /* |
| * SHA-256 process buffer |
| */ |
| int mbedtls_sha256_update_ret(mbedtls_sha256_context *ctx, const unsigned char *input, size_t ilen) |
| { |
| status_t ret = kStatus_Fail; |
| ret = HASHCRYPT_SHA_Update(HASHCRYPT, ctx, input, ilen); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| |
| /* |
| * SHA-256 final digest |
| */ |
| int mbedtls_sha256_finish_ret(mbedtls_sha256_context *ctx, unsigned char output[32]) |
| { |
| status_t ret = kStatus_Fail; |
| size_t outputSize = 32; |
| ret = HASHCRYPT_SHA_Finish(HASHCRYPT, ctx, output, &outputSize); |
| if (ret != kStatus_Success) |
| { |
| return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED; |
| } |
| return 0; |
| } |
| #endif /* MBEDTLS_FREESCALE_LTC_SHA256 */ |
| #if !defined(MBEDTLS_DEPRECATED_REMOVED) && defined(MBEDTLS_SHA256_ALT) |
| #include "mbedtls/sha256.h" |
| |
| void mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224) |
| { |
| mbedtls_sha256_starts_ret(ctx, is224); |
| } |
| |
| void mbedtls_sha256_update(mbedtls_sha256_context *ctx, const unsigned char *input, size_t ilen) |
| { |
| mbedtls_sha256_update_ret(ctx, input, ilen); |
| } |
| |
| void mbedtls_sha256_finish(mbedtls_sha256_context *ctx, unsigned char output[32]) |
| { |
| mbedtls_sha256_finish_ret(ctx, output); |
| } |
| |
| void mbedtls_sha256_process(mbedtls_sha256_context *ctx, const unsigned char data[64]) |
| { |
| mbedtls_internal_sha256_process(ctx, data); |
| } |
| #endif /* MBEDTLS_DEPRECATED_REMOVED */ |
| #endif /* MBEDTLS_SHA256_C */ |
| |
| /* Entropy poll callback for a hardware source */ |
| #if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) |
| |
| #if defined(FSL_FEATURE_SOC_TRNG_COUNT) && (FSL_FEATURE_SOC_TRNG_COUNT > 0) |
| #include "fsl_trng.h" |
| #elif defined(FSL_FEATURE_SOC_RNG_COUNT) && (FSL_FEATURE_SOC_RNG_COUNT > 0) |
| #include "fsl_rnga.h" |
| #elif defined(FSL_FEATURE_SOC_LPC_RNG_COUNT) && (FSL_FEATURE_SOC_LPC_RNG_COUNT > 0) |
| #include "fsl_rng.h" |
| #elif defined(FSL_FEATURE_SOC_LPC_RNG1_COUNT) && (FSL_FEATURE_SOC_LPC_RNG1_COUNT > 0) |
| #include "fsl_rng.h" |
| #endif |
| |
| int mbedtls_hardware_poll(void *data, unsigned char *output, size_t len, size_t *olen) |
| { |
| status_t result = kStatus_Success; |
| |
| #if defined(FSL_FEATURE_SOC_TRNG_COUNT) && (FSL_FEATURE_SOC_TRNG_COUNT > 0) |
| #ifndef TRNG0 |
| #define TRNG0 TRNG |
| #endif |
| result = TRNG_GetRandomData(TRNG0, output, len); |
| #elif defined(FSL_FEATURE_SOC_RNG_COUNT) && (FSL_FEATURE_SOC_RNG_COUNT > 0) |
| result = RNGA_GetRandomData(RNG, (void *)output, len); |
| #elif defined(FSL_FEATURE_SOC_CAAM_COUNT) && (FSL_FEATURE_SOC_CAAM_COUNT > 0) && defined(CRYPTO_USE_DRIVER_CAAM) |
| result = CAAM_RNG_GetRandomData(CAAM_INSTANCE, &s_caamHandle, kCAAM_RngStateHandle0, output, len, kCAAM_RngDataAny, |
| NULL); |
| #elif defined(FSL_FEATURE_SOC_LPC_RNG_COUNT) && (FSL_FEATURE_SOC_LPC_RNG_COUNT > 0) |
| uint32_t rn; |
| size_t length; |
| int i; |
| |
| length = len; |
| |
| while (length > 0) |
| { |
| rn = RNG_GetRandomData(); |
| |
| if (length >= sizeof(uint32_t)) |
| { |
| memcpy(output, &rn, sizeof(uint32_t)); |
| length -= sizeof(uint32_t); |
| output += sizeof(uint32_t); |
| } |
| else |
| { |
| memcpy(output, &rn, length); |
| output += length; |
| len = 0U; |
| } |
| |
| /* Discard next 32 random words for better entropy */ |
| for (i = 0; i < 32; i++) |
| { |
| RNG_GetRandomData(); |
| } |
| } |
| |
| result = kStatus_Success; |
| #elif defined(FSL_FEATURE_SOC_LPC_RNG1_COUNT) && (FSL_FEATURE_SOC_LPC_RNG1_COUNT > 0) |
| status_t status = kStatus_Fail; |
| |
| while(status != kStatus_Success) |
| { |
| status = RNG_GetRandomData(RNG, output, len); |
| |
| if(status == kStatus_Fail) |
| { |
| RNG_Init(RNG); |
| } |
| } |
| |
| result = status; |
| #endif |
| if (result == kStatus_Success) |
| { |
| *olen = len; |
| return 0; |
| } |
| else |
| { |
| return result; |
| } |
| } |
| |
| #endif |
| |
| /******************************************************************************/ |
| /*************************** FreeRTOS ********************************************/ |
| /******************************************************************************/ |
| #if USE_RTOS && defined(FSL_RTOS_FREE_RTOS) && defined(MBEDTLS_FREESCALE_FREERTOS_CALLOC_ALT) |
| #include <stdlib.h> |
| #include "FreeRTOS.h" |
| #include "task.h" |
| |
| /*---------HEAP_3 calloc --------------------------------------------------*/ |
| |
| void *pvPortCalloc(size_t num, size_t size) |
| { |
| void *pvReturn; |
| |
| vTaskSuspendAll(); |
| { |
| pvReturn = calloc(num, size); |
| traceMALLOC(pvReturn, xWantedSize); |
| } |
| (void)xTaskResumeAll(); |
| |
| #if (configUSE_MALLOC_FAILED_HOOK == 1) |
| { |
| if (pvReturn == NULL) |
| { |
| extern void vApplicationMallocFailedHook(void); |
| vApplicationMallocFailedHook(); |
| } |
| } |
| #endif |
| |
| return pvReturn; |
| } |
| #endif /* USE_RTOS && defined(FSL_RTOS_FREE_RTOS) && defined(MBEDTLS_FREESCALE_FREERTOS_CALLOC_ALT) */ |