diff --git a/port/mbedtls/removed/des.c b/port/mbedtls/removed/des.c new file mode 100644 index 0000000000..8b853b3a8b --- /dev/null +++ b/port/mbedtls/removed/des.c @@ -0,0 +1,1032 @@ +/* + * FIPS-46-3 compliant Triple-DES implementation + * + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ +/* + * DES, on which TDES is based, was originally designed by Horst Feistel + * at IBM in 1974, and was adopted as a standard by NIST (formerly NBS). + * + * http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf + */ + +#include "tf_psa_crypto_common.h" + +#if defined(MBEDTLS_DES_C) + +#include "mbedtls/des.h" +#include "mbedtls/private/error_common.h" +#include "mbedtls/platform_util.h" + +#include + +#include "mbedtls/platform.h" + +/* + * Expanded DES S-boxes + */ +static const uint32_t SB1[64] = +{ + 0x01010400, 0x00000000, 0x00010000, 0x01010404, + 0x01010004, 0x00010404, 0x00000004, 0x00010000, + 0x00000400, 0x01010400, 0x01010404, 0x00000400, + 0x01000404, 0x01010004, 0x01000000, 0x00000004, + 0x00000404, 0x01000400, 0x01000400, 0x00010400, + 0x00010400, 0x01010000, 0x01010000, 0x01000404, + 0x00010004, 0x01000004, 0x01000004, 0x00010004, + 0x00000000, 0x00000404, 0x00010404, 0x01000000, + 0x00010000, 0x01010404, 0x00000004, 0x01010000, + 0x01010400, 0x01000000, 0x01000000, 0x00000400, + 0x01010004, 0x00010000, 0x00010400, 0x01000004, + 0x00000400, 0x00000004, 0x01000404, 0x00010404, + 0x01010404, 0x00010004, 0x01010000, 0x01000404, + 0x01000004, 0x00000404, 0x00010404, 0x01010400, + 0x00000404, 0x01000400, 0x01000400, 0x00000000, + 0x00010004, 0x00010400, 0x00000000, 0x01010004 +}; + +static const uint32_t SB2[64] = +{ + 0x80108020, 0x80008000, 0x00008000, 0x00108020, + 0x00100000, 0x00000020, 0x80100020, 0x80008020, + 0x80000020, 0x80108020, 0x80108000, 0x80000000, + 0x80008000, 0x00100000, 0x00000020, 0x80100020, + 0x00108000, 0x00100020, 0x80008020, 0x00000000, + 0x80000000, 0x00008000, 0x00108020, 0x80100000, + 0x00100020, 0x80000020, 0x00000000, 0x00108000, + 0x00008020, 0x80108000, 0x80100000, 0x00008020, + 0x00000000, 0x00108020, 0x80100020, 0x00100000, + 0x80008020, 0x80100000, 0x80108000, 0x00008000, + 0x80100000, 0x80008000, 0x00000020, 0x80108020, + 0x00108020, 0x00000020, 0x00008000, 0x80000000, + 0x00008020, 0x80108000, 0x00100000, 0x80000020, + 0x00100020, 0x80008020, 0x80000020, 0x00100020, + 0x00108000, 0x00000000, 0x80008000, 0x00008020, + 0x80000000, 0x80100020, 0x80108020, 0x00108000 +}; + +static const uint32_t SB3[64] = +{ + 0x00000208, 0x08020200, 0x00000000, 0x08020008, + 0x08000200, 0x00000000, 0x00020208, 0x08000200, + 0x00020008, 0x08000008, 0x08000008, 0x00020000, + 0x08020208, 0x00020008, 0x08020000, 0x00000208, + 0x08000000, 0x00000008, 0x08020200, 0x00000200, + 0x00020200, 0x08020000, 0x08020008, 0x00020208, + 0x08000208, 0x00020200, 0x00020000, 0x08000208, + 0x00000008, 0x08020208, 0x00000200, 0x08000000, + 0x08020200, 0x08000000, 0x00020008, 0x00000208, + 0x00020000, 0x08020200, 0x08000200, 0x00000000, + 0x00000200, 0x00020008, 0x08020208, 0x08000200, + 0x08000008, 0x00000200, 0x00000000, 0x08020008, + 0x08000208, 0x00020000, 0x08000000, 0x08020208, + 0x00000008, 0x00020208, 0x00020200, 0x08000008, + 0x08020000, 0x08000208, 0x00000208, 0x08020000, + 0x00020208, 0x00000008, 0x08020008, 0x00020200 +}; + +static const uint32_t SB4[64] = +{ + 0x00802001, 0x00002081, 0x00002081, 0x00000080, + 0x00802080, 0x00800081, 0x00800001, 0x00002001, + 0x00000000, 0x00802000, 0x00802000, 0x00802081, + 0x00000081, 0x00000000, 0x00800080, 0x00800001, + 0x00000001, 0x00002000, 0x00800000, 0x00802001, + 0x00000080, 0x00800000, 0x00002001, 0x00002080, + 0x00800081, 0x00000001, 0x00002080, 0x00800080, + 0x00002000, 0x00802080, 0x00802081, 0x00000081, + 0x00800080, 0x00800001, 0x00802000, 0x00802081, + 0x00000081, 0x00000000, 0x00000000, 0x00802000, + 0x00002080, 0x00800080, 0x00800081, 0x00000001, + 0x00802001, 0x00002081, 0x00002081, 0x00000080, + 0x00802081, 0x00000081, 0x00000001, 0x00002000, + 0x00800001, 0x00002001, 0x00802080, 0x00800081, + 0x00002001, 0x00002080, 0x00800000, 0x00802001, + 0x00000080, 0x00800000, 0x00002000, 0x00802080 +}; + +static const uint32_t SB5[64] = +{ + 0x00000100, 0x02080100, 0x02080000, 0x42000100, + 0x00080000, 0x00000100, 0x40000000, 0x02080000, + 0x40080100, 0x00080000, 0x02000100, 0x40080100, + 0x42000100, 0x42080000, 0x00080100, 0x40000000, + 0x02000000, 0x40080000, 0x40080000, 0x00000000, + 0x40000100, 0x42080100, 0x42080100, 0x02000100, + 0x42080000, 0x40000100, 0x00000000, 0x42000000, + 0x02080100, 0x02000000, 0x42000000, 0x00080100, + 0x00080000, 0x42000100, 0x00000100, 0x02000000, + 0x40000000, 0x02080000, 0x42000100, 0x40080100, + 0x02000100, 0x40000000, 0x42080000, 0x02080100, + 0x40080100, 0x00000100, 0x02000000, 0x42080000, + 0x42080100, 0x00080100, 0x42000000, 0x42080100, + 0x02080000, 0x00000000, 0x40080000, 0x42000000, + 0x00080100, 0x02000100, 0x40000100, 0x00080000, + 0x00000000, 0x40080000, 0x02080100, 0x40000100 +}; + +static const uint32_t SB6[64] = +{ + 0x20000010, 0x20400000, 0x00004000, 0x20404010, + 0x20400000, 0x00000010, 0x20404010, 0x00400000, + 0x20004000, 0x00404010, 0x00400000, 0x20000010, + 0x00400010, 0x20004000, 0x20000000, 0x00004010, + 0x00000000, 0x00400010, 0x20004010, 0x00004000, + 0x00404000, 0x20004010, 0x00000010, 0x20400010, + 0x20400010, 0x00000000, 0x00404010, 0x20404000, + 0x00004010, 0x00404000, 0x20404000, 0x20000000, + 0x20004000, 0x00000010, 0x20400010, 0x00404000, + 0x20404010, 0x00400000, 0x00004010, 0x20000010, + 0x00400000, 0x20004000, 0x20000000, 0x00004010, + 0x20000010, 0x20404010, 0x00404000, 0x20400000, + 0x00404010, 0x20404000, 0x00000000, 0x20400010, + 0x00000010, 0x00004000, 0x20400000, 0x00404010, + 0x00004000, 0x00400010, 0x20004010, 0x00000000, + 0x20404000, 0x20000000, 0x00400010, 0x20004010 +}; + +static const uint32_t SB7[64] = +{ + 0x00200000, 0x04200002, 0x04000802, 0x00000000, + 0x00000800, 0x04000802, 0x00200802, 0x04200800, + 0x04200802, 0x00200000, 0x00000000, 0x04000002, + 0x00000002, 0x04000000, 0x04200002, 0x00000802, + 0x04000800, 0x00200802, 0x00200002, 0x04000800, + 0x04000002, 0x04200000, 0x04200800, 0x00200002, + 0x04200000, 0x00000800, 0x00000802, 0x04200802, + 0x00200800, 0x00000002, 0x04000000, 0x00200800, + 0x04000000, 0x00200800, 0x00200000, 0x04000802, + 0x04000802, 0x04200002, 0x04200002, 0x00000002, + 0x00200002, 0x04000000, 0x04000800, 0x00200000, + 0x04200800, 0x00000802, 0x00200802, 0x04200800, + 0x00000802, 0x04000002, 0x04200802, 0x04200000, + 0x00200800, 0x00000000, 0x00000002, 0x04200802, + 0x00000000, 0x00200802, 0x04200000, 0x00000800, + 0x04000002, 0x04000800, 0x00000800, 0x00200002 +}; + +static const uint32_t SB8[64] = +{ + 0x10001040, 0x00001000, 0x00040000, 0x10041040, + 0x10000000, 0x10001040, 0x00000040, 0x10000000, + 0x00040040, 0x10040000, 0x10041040, 0x00041000, + 0x10041000, 0x00041040, 0x00001000, 0x00000040, + 0x10040000, 0x10000040, 0x10001000, 0x00001040, + 0x00041000, 0x00040040, 0x10040040, 0x10041000, + 0x00001040, 0x00000000, 0x00000000, 0x10040040, + 0x10000040, 0x10001000, 0x00041040, 0x00040000, + 0x00041040, 0x00040000, 0x10041000, 0x00001000, + 0x00000040, 0x10040040, 0x00001000, 0x00041040, + 0x10001000, 0x00000040, 0x10000040, 0x10040000, + 0x10040040, 0x10000000, 0x00040000, 0x10001040, + 0x00000000, 0x10041040, 0x00040040, 0x10000040, + 0x10040000, 0x10001000, 0x10001040, 0x00000000, + 0x10041040, 0x00041000, 0x00041000, 0x00001040, + 0x00001040, 0x00040040, 0x10000000, 0x10041000 +}; + +/* + * PC1: left and right halves bit-swap + */ +static const uint32_t LHs[16] = +{ + 0x00000000, 0x00000001, 0x00000100, 0x00000101, + 0x00010000, 0x00010001, 0x00010100, 0x00010101, + 0x01000000, 0x01000001, 0x01000100, 0x01000101, + 0x01010000, 0x01010001, 0x01010100, 0x01010101 +}; + +static const uint32_t RHs[16] = +{ + 0x00000000, 0x01000000, 0x00010000, 0x01010000, + 0x00000100, 0x01000100, 0x00010100, 0x01010100, + 0x00000001, 0x01000001, 0x00010001, 0x01010001, + 0x00000101, 0x01000101, 0x00010101, 0x01010101, +}; + +/* + * Initial Permutation macro + */ +#define DES_IP(X, Y) \ + do \ + { \ + T = (((X) >> 4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T << 4); \ + T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \ + T = (((Y) >> 2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T << 2); \ + T = (((Y) >> 8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T << 8); \ + (Y) = (((Y) << 1) | ((Y) >> 31)) & 0xFFFFFFFF; \ + T = ((X) ^ (Y)) & 0xAAAAAAAA; (Y) ^= T; (X) ^= T; \ + (X) = (((X) << 1) | ((X) >> 31)) & 0xFFFFFFFF; \ + } while (0) + +/* + * Final Permutation macro + */ +#define DES_FP(X, Y) \ + do \ + { \ + (X) = (((X) << 31) | ((X) >> 1)) & 0xFFFFFFFF; \ + T = ((X) ^ (Y)) & 0xAAAAAAAA; (X) ^= T; (Y) ^= T; \ + (Y) = (((Y) << 31) | ((Y) >> 1)) & 0xFFFFFFFF; \ + T = (((Y) >> 8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T << 8); \ + T = (((Y) >> 2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T << 2); \ + T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \ + T = (((X) >> 4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T << 4); \ + } while (0) + +/* + * DES round macro + */ +#define DES_ROUND(X, Y) \ + do \ + { \ + T = *SK++ ^ (X); \ + (Y) ^= SB8[(T) & 0x3F] ^ \ + SB6[(T >> 8) & 0x3F] ^ \ + SB4[(T >> 16) & 0x3F] ^ \ + SB2[(T >> 24) & 0x3F]; \ + \ + T = *SK++ ^ (((X) << 28) | ((X) >> 4)); \ + (Y) ^= SB7[(T) & 0x3F] ^ \ + SB5[(T >> 8) & 0x3F] ^ \ + SB3[(T >> 16) & 0x3F] ^ \ + SB1[(T >> 24) & 0x3F]; \ + } while (0) + +#define SWAP(a, b) \ + do \ + { \ + uint32_t t = (a); (a) = (b); (b) = t; t = 0; \ + } while (0) + +void mbedtls_des_init(mbedtls_des_context *ctx) +{ + memset(ctx, 0, sizeof(mbedtls_des_context)); +} + +void mbedtls_des_free(mbedtls_des_context *ctx) +{ + if (ctx == NULL) { + return; + } + + mbedtls_platform_zeroize(ctx, sizeof(mbedtls_des_context)); +} + +void mbedtls_des3_init(mbedtls_des3_context *ctx) +{ + memset(ctx, 0, sizeof(mbedtls_des3_context)); +} + +void mbedtls_des3_free(mbedtls_des3_context *ctx) +{ + if (ctx == NULL) { + return; + } + + mbedtls_platform_zeroize(ctx, sizeof(mbedtls_des3_context)); +} + +static const unsigned char odd_parity_table[128] = { 1, 2, 4, 7, 8, + 11, 13, 14, 16, 19, 21, 22, 25, 26, 28, 31, 32, + 35, 37, 38, 41, 42, 44, + 47, 49, 50, 52, 55, 56, 59, 61, 62, 64, 67, 69, + 70, 73, 74, 76, 79, 81, + 82, 84, 87, 88, 91, 93, 94, 97, 98, 100, 103, + 104, 107, 109, 110, 112, + 115, 117, 118, 121, 122, 124, 127, 128, 131, + 133, 134, 137, 138, 140, + 143, 145, 146, 148, 151, 152, 155, 157, 158, + 161, 162, 164, 167, 168, + 171, 173, 174, 176, 179, 181, 182, 185, 186, + 188, 191, 193, 194, 196, + 199, 200, 203, 205, 206, 208, 211, 213, 214, + 217, 218, 220, 223, 224, + 227, 229, 230, 233, 234, 236, 239, 241, 242, + 244, 247, 248, 251, 253, + 254 }; + +void mbedtls_des_key_set_parity(unsigned char key[MBEDTLS_DES_KEY_SIZE]) +{ + int i; + + for (i = 0; i < MBEDTLS_DES_KEY_SIZE; i++) { + key[i] = odd_parity_table[key[i] / 2]; + } +} + +/* + * Check the given key's parity, returns 1 on failure, 0 on SUCCESS + */ +int mbedtls_des_key_check_key_parity(const unsigned char key[MBEDTLS_DES_KEY_SIZE]) +{ + int i; + + for (i = 0; i < MBEDTLS_DES_KEY_SIZE; i++) { + if (key[i] != odd_parity_table[key[i] / 2]) { + return 1; + } + } + + return 0; +} + +/* + * Table of weak and semi-weak keys + * + * Source: http://en.wikipedia.org/wiki/Weak_key + * + * Weak: + * Alternating ones + zeros (0x0101010101010101) + * Alternating 'F' + 'E' (0xFEFEFEFEFEFEFEFE) + * '0xE0E0E0E0F1F1F1F1' + * '0x1F1F1F1F0E0E0E0E' + * + * Semi-weak: + * 0x011F011F010E010E and 0x1F011F010E010E01 + * 0x01E001E001F101F1 and 0xE001E001F101F101 + * 0x01FE01FE01FE01FE and 0xFE01FE01FE01FE01 + * 0x1FE01FE00EF10EF1 and 0xE01FE01FF10EF10E + * 0x1FFE1FFE0EFE0EFE and 0xFE1FFE1FFE0EFE0E + * 0xE0FEE0FEF1FEF1FE and 0xFEE0FEE0FEF1FEF1 + * + */ + +#define WEAK_KEY_COUNT 16 + +static const unsigned char weak_key_table[WEAK_KEY_COUNT][MBEDTLS_DES_KEY_SIZE] = +{ + { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE }, + { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E }, + { 0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1 }, + + { 0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E }, + { 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01 }, + { 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1 }, + { 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01 }, + { 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE }, + { 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01 }, + { 0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1 }, + { 0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E }, + { 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE }, + { 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E }, + { 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE }, + { 0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1 } +}; + +int mbedtls_des_key_check_weak(const unsigned char key[MBEDTLS_DES_KEY_SIZE]) +{ + int i; + + for (i = 0; i < WEAK_KEY_COUNT; i++) { + if (memcmp(weak_key_table[i], key, MBEDTLS_DES_KEY_SIZE) == 0) { + return 1; + } + } + + return 0; +} + +static void mbedtls_des_setkey(uint32_t SK[32], const unsigned char key[MBEDTLS_DES_KEY_SIZE]) +{ + int i; + uint32_t X, Y, T; + + X = MBEDTLS_GET_UINT32_BE(key, 0); + Y = MBEDTLS_GET_UINT32_BE(key, 4); + + /* + * Permuted Choice 1 + */ + T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4); + T = ((Y) ^ X) & 0x10101010; X ^= T; Y ^= (T); + + X = (LHs[(X) & 0xF] << 3) | (LHs[(X >> 8) & 0xF] << 2) + | (LHs[(X >> 16) & 0xF] << 1) | (LHs[(X >> 24) & 0xF]) + | (LHs[(X >> 5) & 0xF] << 7) | (LHs[(X >> 13) & 0xF] << 6) + | (LHs[(X >> 21) & 0xF] << 5) | (LHs[(X >> 29) & 0xF] << 4); + + Y = (RHs[(Y >> 1) & 0xF] << 3) | (RHs[(Y >> 9) & 0xF] << 2) + | (RHs[(Y >> 17) & 0xF] << 1) | (RHs[(Y >> 25) & 0xF]) + | (RHs[(Y >> 4) & 0xF] << 7) | (RHs[(Y >> 12) & 0xF] << 6) + | (RHs[(Y >> 20) & 0xF] << 5) | (RHs[(Y >> 28) & 0xF] << 4); + + X &= 0x0FFFFFFF; + Y &= 0x0FFFFFFF; + + /* + * calculate subkeys + */ + for (i = 0; i < 16; i++) { + if (i < 2 || i == 8 || i == 15) { + X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF; + Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF; + } else { + X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF; + Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF; + } + + *SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000) + | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000) + | ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000) + | ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000) + | ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000) + | ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000) + | ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400) + | ((Y >> 14) & 0x00000200) | ((Y) & 0x00000100) + | ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010) + | ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004) + | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001); + + *SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000) + | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000) + | ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000) + | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000) + | ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000) + | ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000) + | ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000) + | ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400) + | ((Y) & 0x00000200) | ((Y << 7) & 0x00000100) + | ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011) + | ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002); + } +} + +/* + * DES key schedule (56-bit, encryption) + */ +int mbedtls_des_setkey_enc(mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE]) +{ + mbedtls_des_setkey(ctx->sk, key); + + 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]) +{ + int i; + + mbedtls_des_setkey(ctx->sk, key); + + for (i = 0; i < 16; i += 2) { + SWAP(ctx->sk[i], ctx->sk[30 - i]); + SWAP(ctx->sk[i + 1], ctx->sk[31 - i]); + } + + return 0; +} + +static void des3_set2key(uint32_t esk[96], + uint32_t dsk[96], + const unsigned char key[MBEDTLS_DES_KEY_SIZE*2]) +{ + int i; + + mbedtls_des_setkey(esk, key); + mbedtls_des_setkey(dsk + 32, key + 8); + + for (i = 0; i < 32; i += 2) { + dsk[i] = esk[30 - i]; + dsk[i + 1] = esk[31 - i]; + + esk[i + 32] = dsk[62 - i]; + esk[i + 33] = dsk[63 - i]; + + esk[i + 64] = esk[i]; + esk[i + 65] = esk[i + 1]; + + dsk[i + 64] = dsk[i]; + dsk[i + 65] = dsk[i + 1]; + } +} + +/* + * 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]) +{ + uint32_t sk[96]; + + des3_set2key(ctx->sk, sk, key); + mbedtls_platform_zeroize(sk, sizeof(sk)); + + 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]) +{ + uint32_t sk[96]; + + des3_set2key(sk, ctx->sk, key); + mbedtls_platform_zeroize(sk, sizeof(sk)); + + return 0; +} + +static void des3_set3key(uint32_t esk[96], + uint32_t dsk[96], + const unsigned char key[24]) +{ + int i; + + mbedtls_des_setkey(esk, key); + mbedtls_des_setkey(dsk + 32, key + 8); + mbedtls_des_setkey(esk + 64, key + 16); + + for (i = 0; i < 32; i += 2) { + dsk[i] = esk[94 - i]; + dsk[i + 1] = esk[95 - i]; + + esk[i + 32] = dsk[62 - i]; + esk[i + 33] = dsk[63 - i]; + + dsk[i + 64] = esk[30 - i]; + dsk[i + 65] = esk[31 - i]; + } +} + +/* + * 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]) +{ + uint32_t sk[96]; + + des3_set3key(ctx->sk, sk, key); + mbedtls_platform_zeroize(sk, sizeof(sk)); + + 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]) +{ + uint32_t sk[96]; + + des3_set3key(sk, ctx->sk, key); + mbedtls_platform_zeroize(sk, sizeof(sk)); + + return 0; +} + +/* + * DES-ECB block encryption/decryption + */ +int mbedtls_des_crypt_ecb(mbedtls_des_context *ctx, + const unsigned char input[8], + unsigned char output[8]) +{ + int i; + uint32_t X, Y, T, *SK; + + SK = ctx->sk; + + X = MBEDTLS_GET_UINT32_BE(input, 0); + Y = MBEDTLS_GET_UINT32_BE(input, 4); + + DES_IP(X, Y); + + for (i = 0; i < 8; i++) { + DES_ROUND(Y, X); + DES_ROUND(X, Y); + } + + DES_FP(Y, X); + + MBEDTLS_PUT_UINT32_BE(Y, output, 0); + MBEDTLS_PUT_UINT32_BE(X, output, 4); + + return 0; +} + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +/* + * DES-CBC buffer encryption/decryption + */ +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) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + unsigned char temp[8]; + + if (length % 8) { + return MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH; + } + + if (mode == MBEDTLS_DES_ENCRYPT) { + while (length > 0) { + mbedtls_xor(output, input, iv, 8); + + ret = mbedtls_des_crypt_ecb(ctx, output, output); + if (ret != 0) { + goto exit; + } + memcpy(iv, output, 8); + + input += 8; + output += 8; + length -= 8; + } + } else { /* MBEDTLS_DES_DECRYPT */ + while (length > 0) { + memcpy(temp, input, 8); + ret = mbedtls_des_crypt_ecb(ctx, input, output); + if (ret != 0) { + goto exit; + } + + mbedtls_xor(output, output, iv, 8); + + memcpy(iv, temp, 8); + + input += 8; + output += 8; + length -= 8; + } + } + ret = 0; + +exit: + return ret; +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +/* + * 3DES-ECB block encryption/decryption + */ +int mbedtls_des3_crypt_ecb(mbedtls_des3_context *ctx, + const unsigned char input[8], + unsigned char output[8]) +{ + int i; + uint32_t X, Y, T, *SK; + + SK = ctx->sk; + + X = MBEDTLS_GET_UINT32_BE(input, 0); + Y = MBEDTLS_GET_UINT32_BE(input, 4); + + DES_IP(X, Y); + + for (i = 0; i < 8; i++) { + DES_ROUND(Y, X); + DES_ROUND(X, Y); + } + + for (i = 0; i < 8; i++) { + DES_ROUND(X, Y); + DES_ROUND(Y, X); + } + + for (i = 0; i < 8; i++) { + DES_ROUND(Y, X); + DES_ROUND(X, Y); + } + + DES_FP(Y, X); + + MBEDTLS_PUT_UINT32_BE(Y, output, 0); + MBEDTLS_PUT_UINT32_BE(X, output, 4); + + return 0; +} + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +/* + * 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) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + unsigned char temp[8]; + + if (length % 8) { + return MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH; + } + + if (mode == MBEDTLS_DES_ENCRYPT) { + while (length > 0) { + mbedtls_xor(output, input, iv, 8); + + ret = mbedtls_des3_crypt_ecb(ctx, output, output); + if (ret != 0) { + goto exit; + } + memcpy(iv, output, 8); + + input += 8; + output += 8; + length -= 8; + } + } else { /* MBEDTLS_DES_DECRYPT */ + while (length > 0) { + memcpy(temp, input, 8); + ret = mbedtls_des3_crypt_ecb(ctx, input, output); + if (ret != 0) { + goto exit; + } + + mbedtls_xor(output, output, iv, 8); + + memcpy(iv, temp, 8); + + input += 8; + output += 8; + length -= 8; + } + } + ret = 0; + +exit: + return ret; +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_SELF_TEST) +/* + * DES and 3DES test vectors from: + * + * http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip + */ +static const unsigned char des3_test_keys[24] = +{ + 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, + 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23 +}; + +static const unsigned char des3_test_buf[8] = +{ + 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74 +}; + +static const unsigned char des3_test_ecb_dec[3][8] = +{ + { 0x37, 0x2B, 0x98, 0xBF, 0x52, 0x65, 0xB0, 0x59 }, + { 0xC2, 0x10, 0x19, 0x9C, 0x38, 0x5A, 0x65, 0xA1 }, + { 0xA2, 0x70, 0x56, 0x68, 0x69, 0xE5, 0x15, 0x1D } +}; + +static const unsigned char des3_test_ecb_enc[3][8] = +{ + { 0x1C, 0xD5, 0x97, 0xEA, 0x84, 0x26, 0x73, 0xFB }, + { 0xB3, 0x92, 0x4D, 0xF3, 0xC5, 0xB5, 0x42, 0x93 }, + { 0xDA, 0x37, 0x64, 0x41, 0xBA, 0x6F, 0x62, 0x6F } +}; + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const unsigned char des3_test_iv[8] = +{ + 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, +}; + +static const unsigned char des3_test_cbc_dec[3][8] = +{ + { 0x58, 0xD9, 0x48, 0xEF, 0x85, 0x14, 0x65, 0x9A }, + { 0x5F, 0xC8, 0x78, 0xD4, 0xD7, 0x92, 0xD9, 0x54 }, + { 0x25, 0xF9, 0x75, 0x85, 0xA8, 0x1E, 0x48, 0xBF } +}; + +static const unsigned char des3_test_cbc_enc[3][8] = +{ + { 0x91, 0x1C, 0x6D, 0xCF, 0x48, 0xA7, 0xC3, 0x4D }, + { 0x60, 0x1A, 0x76, 0x8F, 0xA1, 0xF9, 0x66, 0xF1 }, + { 0xA1, 0x50, 0x0F, 0x99, 0xB2, 0xCD, 0x64, 0x76 } +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +/* + * Checkup routine + */ +int mbedtls_des_self_test(int verbose) +{ + int i, j, u, v, ret = 0; + mbedtls_des_context ctx; + mbedtls_des3_context ctx3; + unsigned char buf[8]; +#if defined(MBEDTLS_CIPHER_MODE_CBC) + unsigned char prv[8]; + unsigned char iv[8]; +#endif + + mbedtls_des_init(&ctx); + mbedtls_des3_init(&ctx3); + /* + * ECB mode + */ + for (i = 0; i < 6; i++) { + u = i >> 1; + v = i & 1; + + if (verbose != 0) { + mbedtls_printf(" DES%c-ECB-%3d (%s): ", + (u == 0) ? ' ' : '3', 56 + u * 56, + (v == MBEDTLS_DES_DECRYPT) ? "dec" : "enc"); + } + + memcpy(buf, des3_test_buf, 8); + + switch (i) { + case 0: + ret = mbedtls_des_setkey_dec(&ctx, des3_test_keys); + break; + + case 1: + ret = mbedtls_des_setkey_enc(&ctx, des3_test_keys); + break; + + case 2: + ret = mbedtls_des3_set2key_dec(&ctx3, des3_test_keys); + break; + + case 3: + ret = mbedtls_des3_set2key_enc(&ctx3, des3_test_keys); + break; + + case 4: + ret = mbedtls_des3_set3key_dec(&ctx3, des3_test_keys); + break; + + case 5: + ret = mbedtls_des3_set3key_enc(&ctx3, des3_test_keys); + break; + + default: + return 1; + } + if (ret != 0) { + goto exit; + } + + for (j = 0; j < 100; j++) { + if (u == 0) { + ret = mbedtls_des_crypt_ecb(&ctx, buf, buf); + } else { + ret = mbedtls_des3_crypt_ecb(&ctx3, buf, buf); + } + if (ret != 0) { + goto exit; + } + } + + if ((v == MBEDTLS_DES_DECRYPT && + memcmp(buf, des3_test_ecb_dec[u], 8) != 0) || + (v != MBEDTLS_DES_DECRYPT && + memcmp(buf, des3_test_ecb_enc[u], 8) != 0)) { + if (verbose != 0) { + mbedtls_printf("failed\n"); + } + + ret = 1; + goto exit; + } + + if (verbose != 0) { + mbedtls_printf("passed\n"); + } + } + + if (verbose != 0) { + mbedtls_printf("\n"); + } + +#if defined(MBEDTLS_CIPHER_MODE_CBC) + /* + * CBC mode + */ + for (i = 0; i < 6; i++) { + u = i >> 1; + v = i & 1; + + if (verbose != 0) { + mbedtls_printf(" DES%c-CBC-%3d (%s): ", + (u == 0) ? ' ' : '3', 56 + u * 56, + (v == MBEDTLS_DES_DECRYPT) ? "dec" : "enc"); + } + + memcpy(iv, des3_test_iv, 8); + memcpy(prv, des3_test_iv, 8); + memcpy(buf, des3_test_buf, 8); + + switch (i) { + case 0: + ret = mbedtls_des_setkey_dec(&ctx, des3_test_keys); + break; + + case 1: + ret = mbedtls_des_setkey_enc(&ctx, des3_test_keys); + break; + + case 2: + ret = mbedtls_des3_set2key_dec(&ctx3, des3_test_keys); + break; + + case 3: + ret = mbedtls_des3_set2key_enc(&ctx3, des3_test_keys); + break; + + case 4: + ret = mbedtls_des3_set3key_dec(&ctx3, des3_test_keys); + break; + + case 5: + ret = mbedtls_des3_set3key_enc(&ctx3, des3_test_keys); + break; + + default: + return 1; + } + if (ret != 0) { + goto exit; + } + + if (v == MBEDTLS_DES_DECRYPT) { + for (j = 0; j < 100; j++) { + if (u == 0) { + ret = mbedtls_des_crypt_cbc(&ctx, v, 8, iv, buf, buf); + } else { + ret = mbedtls_des3_crypt_cbc(&ctx3, v, 8, iv, buf, buf); + } + if (ret != 0) { + goto exit; + } + } + } else { + for (j = 0; j < 100; j++) { + unsigned char tmp[8]; + + if (u == 0) { + ret = mbedtls_des_crypt_cbc(&ctx, v, 8, iv, buf, buf); + } else { + ret = mbedtls_des3_crypt_cbc(&ctx3, v, 8, iv, buf, buf); + } + if (ret != 0) { + goto exit; + } + + memcpy(tmp, prv, 8); + memcpy(prv, buf, 8); + memcpy(buf, tmp, 8); + } + + memcpy(buf, prv, 8); + } + + if ((v == MBEDTLS_DES_DECRYPT && + memcmp(buf, des3_test_cbc_dec[u], 8) != 0) || + (v != MBEDTLS_DES_DECRYPT && + memcmp(buf, des3_test_cbc_enc[u], 8) != 0)) { + if (verbose != 0) { + mbedtls_printf("failed\n"); + } + + ret = 1; + goto exit; + } + + if (verbose != 0) { + mbedtls_printf("passed\n"); + } + } +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + + if (verbose != 0) { + mbedtls_printf("\n"); + } + +exit: + mbedtls_des_free(&ctx); + mbedtls_des3_free(&ctx3); + + if (ret != 0) { + ret = 1; + } + return ret; +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_DES_C */ diff --git a/port/mbedtls/removed/dhm.c b/port/mbedtls/removed/dhm.c new file mode 100644 index 0000000000..35223ea48c --- /dev/null +++ b/port/mbedtls/removed/dhm.c @@ -0,0 +1,709 @@ +/* + * Diffie-Hellman-Merkle key exchange + * + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ +/* + * The following sources were referenced in the design of this implementation + * of the Diffie-Hellman-Merkle algorithm: + * + * [1] Handbook of Applied Cryptography - 1997, Chapter 12 + * Menezes, van Oorschot and Vanstone + * + */ + +#include "tf_psa_crypto_common.h" + +#if defined(MBEDTLS_DHM_C) + +#include "mbedtls/dhm.h" +#include "mbedtls/platform_util.h" +#include "mbedtls/error_common.h" + +#include + +#if defined(MBEDTLS_PEM_PARSE_C) +#include "mbedtls/pem.h" +#endif + +#if defined(MBEDTLS_ASN1_PARSE_C) +#include "mbedtls/asn1.h" +#endif + +#include "mbedtls/platform.h" + +/* + * helper to validate the mbedtls_mpi size and import it + */ +static int dhm_read_bignum(mbedtls_mpi *X, + unsigned char **p, + const unsigned char *end) +{ + int ret, n; + + if (end - *p < 2) { + return MBEDTLS_ERR_DHM_BAD_INPUT_DATA; + } + + n = MBEDTLS_GET_UINT16_BE(*p, 0); + (*p) += 2; + + if ((size_t) (end - *p) < (size_t) n) { + return MBEDTLS_ERR_DHM_BAD_INPUT_DATA; + } + + if ((ret = mbedtls_mpi_read_binary(X, *p, n)) != 0) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_READ_PARAMS_FAILED, ret); + } + + (*p) += n; + + return 0; +} + +/* + * Verify sanity of parameter with regards to P + * + * Parameter should be: 2 <= public_param <= P - 2 + * + * This means that we need to return an error if + * public_param < 2 or public_param > P-2 + * + * For more information on the attack, see: + * http://www.cl.cam.ac.uk/~rja14/Papers/psandqs.pdf + * http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2005-2643 + */ +static int dhm_check_range(const mbedtls_mpi *param, const mbedtls_mpi *P) +{ + mbedtls_mpi U; + int ret = 0; + + mbedtls_mpi_init(&U); + + MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&U, P, 2)); + + if (mbedtls_mpi_cmp_int(param, 2) < 0 || + mbedtls_mpi_cmp_mpi(param, &U) > 0) { + ret = MBEDTLS_ERR_DHM_BAD_INPUT_DATA; + } + +cleanup: + mbedtls_mpi_free(&U); + return ret; +} + +void mbedtls_dhm_init(mbedtls_dhm_context *ctx) +{ + memset(ctx, 0, sizeof(mbedtls_dhm_context)); +} + +size_t mbedtls_dhm_get_bitlen(const mbedtls_dhm_context *ctx) +{ + return mbedtls_mpi_bitlen(&ctx->P); +} + +size_t mbedtls_dhm_get_len(const mbedtls_dhm_context *ctx) +{ + return mbedtls_mpi_size(&ctx->P); +} + +int mbedtls_dhm_get_value(const mbedtls_dhm_context *ctx, + mbedtls_dhm_parameter param, + mbedtls_mpi *dest) +{ + const mbedtls_mpi *src = NULL; + switch (param) { + case MBEDTLS_DHM_PARAM_P: + src = &ctx->P; + break; + case MBEDTLS_DHM_PARAM_G: + src = &ctx->G; + break; + case MBEDTLS_DHM_PARAM_X: + src = &ctx->X; + break; + case MBEDTLS_DHM_PARAM_GX: + src = &ctx->GX; + break; + case MBEDTLS_DHM_PARAM_GY: + src = &ctx->GY; + break; + case MBEDTLS_DHM_PARAM_K: + src = &ctx->K; + break; + default: + return MBEDTLS_ERR_DHM_BAD_INPUT_DATA; + } + return mbedtls_mpi_copy(dest, src); +} + +/* + * Parse the ServerKeyExchange parameters + */ +int mbedtls_dhm_read_params(mbedtls_dhm_context *ctx, + unsigned char **p, + const unsigned char *end) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + if ((ret = dhm_read_bignum(&ctx->P, p, end)) != 0 || + (ret = dhm_read_bignum(&ctx->G, p, end)) != 0 || + (ret = dhm_read_bignum(&ctx->GY, p, end)) != 0) { + return ret; + } + + if ((ret = dhm_check_range(&ctx->GY, &ctx->P)) != 0) { + return ret; + } + + return 0; +} + +/* + * Pick a random R in the range [2, M-2] for blinding or key generation. + */ +static int dhm_random_below(mbedtls_mpi *R, const mbedtls_mpi *M, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) +{ + int ret; + + MBEDTLS_MPI_CHK(mbedtls_mpi_random(R, 3, M, f_rng, p_rng)); + MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(R, R, 1)); + +cleanup: + return ret; +} + +static int dhm_make_common(mbedtls_dhm_context *ctx, int x_size, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng) +{ + int ret = 0; + + if (mbedtls_mpi_cmp_int(&ctx->P, 0) == 0) { + return MBEDTLS_ERR_DHM_BAD_INPUT_DATA; + } + if (x_size < 0) { + return MBEDTLS_ERR_DHM_BAD_INPUT_DATA; + } + + if ((unsigned) x_size < mbedtls_mpi_size(&ctx->P)) { + MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(&ctx->X, x_size, f_rng, p_rng)); + } else { + /* Generate X as large as possible ( <= P - 2 ) */ + ret = dhm_random_below(&ctx->X, &ctx->P, f_rng, p_rng); + if (ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) { + return MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED; + } + if (ret != 0) { + return ret; + } + } + + /* + * Calculate GX = G^X mod P + */ + MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&ctx->GX, &ctx->G, &ctx->X, + &ctx->P, &ctx->RP)); + + if ((ret = dhm_check_range(&ctx->GX, &ctx->P)) != 0) { + return ret; + } + +cleanup: + return ret; +} + +/* + * Setup and write the ServerKeyExchange parameters + */ +int mbedtls_dhm_make_params(mbedtls_dhm_context *ctx, int x_size, + unsigned char *output, size_t *olen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng) +{ + int ret; + size_t n1, n2, n3; + unsigned char *p; + + ret = dhm_make_common(ctx, x_size, f_rng, p_rng); + if (ret != 0) { + goto cleanup; + } + + /* + * Export P, G, GX. RFC 5246 §4.4 states that "leading zero octets are + * not required". We omit leading zeros for compactness. + */ +#define DHM_MPI_EXPORT(X, n) \ + do { \ + MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary((X), \ + p + 2, \ + (n))); \ + *p++ = MBEDTLS_BYTE_1(n); \ + *p++ = MBEDTLS_BYTE_0(n); \ + p += (n); \ + } while (0) + + n1 = mbedtls_mpi_size(&ctx->P); + n2 = mbedtls_mpi_size(&ctx->G); + n3 = mbedtls_mpi_size(&ctx->GX); + + p = output; + DHM_MPI_EXPORT(&ctx->P, n1); + DHM_MPI_EXPORT(&ctx->G, n2); + DHM_MPI_EXPORT(&ctx->GX, n3); + + *olen = (size_t) (p - output); + +cleanup: + if (ret != 0 && ret > -128) { + ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED, ret); + } + return ret; +} + +/* + * Set prime modulus and generator + */ +int mbedtls_dhm_set_group(mbedtls_dhm_context *ctx, + const mbedtls_mpi *P, + const mbedtls_mpi *G) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + if ((ret = mbedtls_mpi_copy(&ctx->P, P)) != 0 || + (ret = mbedtls_mpi_copy(&ctx->G, G)) != 0) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_SET_GROUP_FAILED, ret); + } + + return 0; +} + +/* + * Import the peer's public value G^Y + */ +int mbedtls_dhm_read_public(mbedtls_dhm_context *ctx, + const unsigned char *input, size_t ilen) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + if (ilen < 1 || ilen > mbedtls_dhm_get_len(ctx)) { + return MBEDTLS_ERR_DHM_BAD_INPUT_DATA; + } + + if ((ret = mbedtls_mpi_read_binary(&ctx->GY, input, ilen)) != 0) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED, ret); + } + + return 0; +} + +/* + * Create own private value X and export G^X + */ +int mbedtls_dhm_make_public(mbedtls_dhm_context *ctx, int x_size, + unsigned char *output, size_t olen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng) +{ + int ret; + + if (olen < 1 || olen > mbedtls_dhm_get_len(ctx)) { + return MBEDTLS_ERR_DHM_BAD_INPUT_DATA; + } + + ret = dhm_make_common(ctx, x_size, f_rng, p_rng); + if (ret == MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED) { + return MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED; + } + if (ret != 0) { + goto cleanup; + } + + MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&ctx->GX, output, olen)); + +cleanup: + if (ret != 0 && ret > -128) { + ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED, ret); + } + return ret; +} + + +/* + * Use the blinding method and optimisation suggested in section 10 of: + * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA, + * DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer + * Berlin Heidelberg, 1996. p. 104-113. + */ +static int dhm_update_blinding(mbedtls_dhm_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) +{ + int ret; + mbedtls_mpi R; + + mbedtls_mpi_init(&R); + + /* + * Don't use any blinding the first time a particular X is used, + * but remember it to use blinding next time. + */ + if (mbedtls_mpi_cmp_mpi(&ctx->X, &ctx->pX) != 0) { + MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&ctx->pX, &ctx->X)); + MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&ctx->Vi, 1)); + MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&ctx->Vf, 1)); + + return 0; + } + + /* + * Ok, we need blinding. Can we re-use existing values? + * If yes, just update them by squaring them. + */ + if (mbedtls_mpi_cmp_int(&ctx->Vi, 1) != 0) { + MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vi, &ctx->Vi, &ctx->Vi)); + MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vi, &ctx->Vi, &ctx->P)); + + MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vf, &ctx->Vf, &ctx->Vf)); + MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vf, &ctx->Vf, &ctx->P)); + + return 0; + } + + /* + * We need to generate blinding values from scratch + */ + + /* Vi = random( 2, P-2 ) */ + MBEDTLS_MPI_CHK(dhm_random_below(&ctx->Vi, &ctx->P, f_rng, p_rng)); + + /* Vf = Vi^-X mod P + * First compute Vi^-1 = R * (R Vi)^-1, (avoiding leaks from inv_mod), + * then elevate to the Xth power. */ + MBEDTLS_MPI_CHK(dhm_random_below(&R, &ctx->P, f_rng, p_rng)); + MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vf, &ctx->Vi, &R)); + MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vf, &ctx->Vf, &ctx->P)); + MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(&ctx->Vf, &ctx->Vf, &ctx->P)); + MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vf, &ctx->Vf, &R)); + MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vf, &ctx->Vf, &ctx->P)); + + MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&ctx->Vf, &ctx->Vf, &ctx->X, &ctx->P, &ctx->RP)); + +cleanup: + mbedtls_mpi_free(&R); + + return ret; +} + +/* + * Derive and export the shared secret (G^Y)^X mod P + */ +int mbedtls_dhm_calc_secret(mbedtls_dhm_context *ctx, + unsigned char *output, size_t output_size, size_t *olen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + mbedtls_mpi GYb; + + if (f_rng == NULL) { + return MBEDTLS_ERR_DHM_BAD_INPUT_DATA; + } + + if (output_size < mbedtls_dhm_get_len(ctx)) { + return MBEDTLS_ERR_DHM_BAD_INPUT_DATA; + } + + if ((ret = dhm_check_range(&ctx->GY, &ctx->P)) != 0) { + return ret; + } + + mbedtls_mpi_init(&GYb); + + /* Blind peer's value */ + MBEDTLS_MPI_CHK(dhm_update_blinding(ctx, f_rng, p_rng)); + MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&GYb, &ctx->GY, &ctx->Vi)); + MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&GYb, &GYb, &ctx->P)); + + /* Do modular exponentiation */ + MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&ctx->K, &GYb, &ctx->X, + &ctx->P, &ctx->RP)); + + /* Unblind secret value */ + MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->K, &ctx->K, &ctx->Vf)); + MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->K, &ctx->K, &ctx->P)); + + /* Output the secret without any leading zero byte. This is mandatory + * for TLS per RFC 5246 §8.1.2. */ + *olen = mbedtls_mpi_size(&ctx->K); + MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&ctx->K, output, *olen)); + +cleanup: + mbedtls_mpi_free(&GYb); + + if (ret != 0) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_CALC_SECRET_FAILED, ret); + } + + return 0; +} + +/* + * Free the components of a DHM key + */ +void mbedtls_dhm_free(mbedtls_dhm_context *ctx) +{ + if (ctx == NULL) { + return; + } + + mbedtls_mpi_free(&ctx->pX); + mbedtls_mpi_free(&ctx->Vf); + mbedtls_mpi_free(&ctx->Vi); + mbedtls_mpi_free(&ctx->RP); + mbedtls_mpi_free(&ctx->K); + mbedtls_mpi_free(&ctx->GY); + mbedtls_mpi_free(&ctx->GX); + mbedtls_mpi_free(&ctx->X); + mbedtls_mpi_free(&ctx->G); + mbedtls_mpi_free(&ctx->P); + + mbedtls_platform_zeroize(ctx, sizeof(mbedtls_dhm_context)); +} + +#if defined(MBEDTLS_ASN1_PARSE_C) +/* + * Parse DHM parameters + */ +int mbedtls_dhm_parse_dhm(mbedtls_dhm_context *dhm, const unsigned char *dhmin, + size_t dhminlen) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t len; + unsigned char *p, *end; +#if defined(MBEDTLS_PEM_PARSE_C) + mbedtls_pem_context pem; +#endif /* MBEDTLS_PEM_PARSE_C */ + +#if defined(MBEDTLS_PEM_PARSE_C) + mbedtls_pem_init(&pem); + + /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ + if (dhminlen == 0 || dhmin[dhminlen - 1] != '\0') { + ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; + } else { + ret = mbedtls_pem_read_buffer(&pem, + "-----BEGIN DH PARAMETERS-----", + "-----END DH PARAMETERS-----", + dhmin, NULL, 0, &dhminlen); + } + + if (ret == 0) { + /* + * Was PEM encoded + */ + dhminlen = pem.buflen; + } else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) { + goto exit; + } + + p = (ret == 0) ? pem.buf : (unsigned char *) dhmin; +#else + p = (unsigned char *) dhmin; +#endif /* MBEDTLS_PEM_PARSE_C */ + end = p + dhminlen; + + /* + * DHParams ::= SEQUENCE { + * prime INTEGER, -- P + * generator INTEGER, -- g + * privateValueLength INTEGER OPTIONAL + * } + */ + if ((ret = mbedtls_asn1_get_tag(&p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { + ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_INVALID_FORMAT, ret); + goto exit; + } + + end = p + len; + + if ((ret = mbedtls_asn1_get_mpi(&p, end, &dhm->P)) != 0 || + (ret = mbedtls_asn1_get_mpi(&p, end, &dhm->G)) != 0) { + ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_INVALID_FORMAT, ret); + goto exit; + } + + if (p != end) { + /* This might be the optional privateValueLength. + * If so, we can cleanly discard it */ + mbedtls_mpi rec; + mbedtls_mpi_init(&rec); + ret = mbedtls_asn1_get_mpi(&p, end, &rec); + mbedtls_mpi_free(&rec); + if (ret != 0) { + ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_INVALID_FORMAT, ret); + goto exit; + } + if (p != end) { + ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_INVALID_FORMAT, + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); + goto exit; + } + } + + ret = 0; + +exit: +#if defined(MBEDTLS_PEM_PARSE_C) + mbedtls_pem_free(&pem); +#endif + if (ret != 0) { + mbedtls_dhm_free(dhm); + } + + return ret; +} + +#if defined(MBEDTLS_FS_IO) +/* + * Load all data from a file into a given buffer. + * + * The file is expected to contain either PEM or DER encoded data. + * A terminating null byte is always appended. It is included in the announced + * length only if the data looks like it is PEM encoded. + */ +static int load_file(const char *path, unsigned char **buf, size_t *n) +{ + FILE *f; + long size; + + if ((f = fopen(path, "rb")) == NULL) { + return MBEDTLS_ERR_DHM_FILE_IO_ERROR; + } + /* The data loaded here is public, so don't bother disabling buffering. */ + + fseek(f, 0, SEEK_END); + if ((size = ftell(f)) == -1) { + fclose(f); + return MBEDTLS_ERR_DHM_FILE_IO_ERROR; + } + fseek(f, 0, SEEK_SET); + + *n = (size_t) size; + + if (*n + 1 == 0 || + (*buf = mbedtls_calloc(1, *n + 1)) == NULL) { + fclose(f); + return MBEDTLS_ERR_DHM_ALLOC_FAILED; + } + + if (fread(*buf, 1, *n, f) != *n) { + fclose(f); + + mbedtls_zeroize_and_free(*buf, *n + 1); + + return MBEDTLS_ERR_DHM_FILE_IO_ERROR; + } + + fclose(f); + + (*buf)[*n] = '\0'; + + if (strstr((const char *) *buf, "-----BEGIN ") != NULL) { + ++*n; + } + + return 0; +} + +/* + * Load and parse DHM parameters + */ +int mbedtls_dhm_parse_dhmfile(mbedtls_dhm_context *dhm, const char *path) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t n; + unsigned char *buf; + + if ((ret = load_file(path, &buf, &n)) != 0) { + return ret; + } + + ret = mbedtls_dhm_parse_dhm(dhm, buf, n); + + mbedtls_zeroize_and_free(buf, n); + + return ret; +} +#endif /* MBEDTLS_FS_IO */ +#endif /* MBEDTLS_ASN1_PARSE_C */ + +#if defined(MBEDTLS_SELF_TEST) + +#if defined(MBEDTLS_PEM_PARSE_C) +static const char mbedtls_test_dhm_params[] = + "-----BEGIN DH PARAMETERS-----\r\n" + "MIGHAoGBAJ419DBEOgmQTzo5qXl5fQcN9TN455wkOL7052HzxxRVMyhYmwQcgJvh\r\n" + "1sa18fyfR9OiVEMYglOpkqVoGLN7qd5aQNNi5W7/C+VBdHTBJcGZJyyP5B3qcz32\r\n" + "9mLJKudlVudV0Qxk5qUJaPZ/xupz0NyoVpviuiBOI1gNi8ovSXWzAgEC\r\n" + "-----END DH PARAMETERS-----\r\n"; +#else /* MBEDTLS_PEM_PARSE_C */ +static const char mbedtls_test_dhm_params[] = { + 0x30, 0x81, 0x87, 0x02, 0x81, 0x81, 0x00, 0x9e, 0x35, 0xf4, 0x30, 0x44, + 0x3a, 0x09, 0x90, 0x4f, 0x3a, 0x39, 0xa9, 0x79, 0x79, 0x7d, 0x07, 0x0d, + 0xf5, 0x33, 0x78, 0xe7, 0x9c, 0x24, 0x38, 0xbe, 0xf4, 0xe7, 0x61, 0xf3, + 0xc7, 0x14, 0x55, 0x33, 0x28, 0x58, 0x9b, 0x04, 0x1c, 0x80, 0x9b, 0xe1, + 0xd6, 0xc6, 0xb5, 0xf1, 0xfc, 0x9f, 0x47, 0xd3, 0xa2, 0x54, 0x43, 0x18, + 0x82, 0x53, 0xa9, 0x92, 0xa5, 0x68, 0x18, 0xb3, 0x7b, 0xa9, 0xde, 0x5a, + 0x40, 0xd3, 0x62, 0xe5, 0x6e, 0xff, 0x0b, 0xe5, 0x41, 0x74, 0x74, 0xc1, + 0x25, 0xc1, 0x99, 0x27, 0x2c, 0x8f, 0xe4, 0x1d, 0xea, 0x73, 0x3d, 0xf6, + 0xf6, 0x62, 0xc9, 0x2a, 0xe7, 0x65, 0x56, 0xe7, 0x55, 0xd1, 0x0c, 0x64, + 0xe6, 0xa5, 0x09, 0x68, 0xf6, 0x7f, 0xc6, 0xea, 0x73, 0xd0, 0xdc, 0xa8, + 0x56, 0x9b, 0xe2, 0xba, 0x20, 0x4e, 0x23, 0x58, 0x0d, 0x8b, 0xca, 0x2f, + 0x49, 0x75, 0xb3, 0x02, 0x01, 0x02 +}; +#endif /* MBEDTLS_PEM_PARSE_C */ + +static const size_t mbedtls_test_dhm_params_len = sizeof(mbedtls_test_dhm_params); + +/* + * Checkup routine + */ +int mbedtls_dhm_self_test(int verbose) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + mbedtls_dhm_context dhm; + + mbedtls_dhm_init(&dhm); + + if (verbose != 0) { + mbedtls_printf(" DHM parameter load: "); + } + + if ((ret = mbedtls_dhm_parse_dhm(&dhm, + (const unsigned char *) mbedtls_test_dhm_params, + mbedtls_test_dhm_params_len)) != 0) { + if (verbose != 0) { + mbedtls_printf("failed\n"); + } + + ret = 1; + goto exit; + } + + if (verbose != 0) { + mbedtls_printf("passed\n\n"); + } + +exit: + mbedtls_dhm_free(&dhm); + + return ret; +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_DHM_C */ diff --git a/port/mbedtls/removed/ecdh.c b/port/mbedtls/removed/ecdh.c new file mode 100644 index 0000000000..f7690b8e30 --- /dev/null +++ b/port/mbedtls/removed/ecdh.c @@ -0,0 +1,690 @@ +/* + * Elliptic curve Diffie-Hellman + * + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +/* + * References: + * + * SEC1 https://www.secg.org/sec1-v2.pdf + * RFC 4492 + */ + +#include "tf_psa_crypto_common.h" + +#if defined(MBEDTLS_ECDH_C) + +#include "mbedtls/ecdh.h" +#include "mbedtls/platform_util.h" +#include "mbedtls/private/error_common.h" + +#include + +#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) +typedef mbedtls_ecdh_context mbedtls_ecdh_context_mbed; +#endif + +static mbedtls_ecp_group_id mbedtls_ecdh_grp_id( + const mbedtls_ecdh_context *ctx) +{ +#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) + return ctx->grp.id; +#else + return ctx->grp_id; +#endif +} + +int mbedtls_ecdh_can_do(mbedtls_ecp_group_id gid) +{ + /* At this time, all groups support ECDH. */ + (void) gid; + return 1; +} + +/* + * Generate public key (restartable version) + * + * Note: this internal function relies on its caller preserving the value of + * the output parameter 'd' across continuation calls. This would not be + * acceptable for a public function but is OK here as we control call sites. + */ +static int ecdh_gen_public_restartable(mbedtls_ecp_group *grp, + mbedtls_mpi *d, mbedtls_ecp_point *Q, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + mbedtls_ecp_restart_ctx *rs_ctx) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + int restarting = 0; +#if defined(MBEDTLS_ECP_RESTARTABLE) + restarting = (rs_ctx != NULL && rs_ctx->rsm != NULL); +#endif + /* If multiplication is in progress, we already generated a privkey */ + if (!restarting) { + MBEDTLS_MPI_CHK(mbedtls_ecp_gen_privkey(grp, d, f_rng, p_rng)); + } + + MBEDTLS_MPI_CHK(mbedtls_ecp_mul_restartable(grp, Q, d, &grp->G, + f_rng, p_rng, rs_ctx)); + +cleanup: + return ret; +} + +/* + * Generate public key + */ +int mbedtls_ecdh_gen_public(mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng) +{ + return ecdh_gen_public_restartable(grp, d, Q, f_rng, p_rng, NULL); +} + +/* + * Compute shared secret (SEC1 3.3.1) + */ +static int ecdh_compute_shared_restartable(mbedtls_ecp_group *grp, + mbedtls_mpi *z, + const mbedtls_ecp_point *Q, const mbedtls_mpi *d, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + mbedtls_ecp_restart_ctx *rs_ctx) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + mbedtls_ecp_point P; + + mbedtls_ecp_point_init(&P); + + MBEDTLS_MPI_CHK(mbedtls_ecp_mul_restartable(grp, &P, d, Q, + f_rng, p_rng, rs_ctx)); + + if (mbedtls_ecp_is_zero(&P)) { + ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + goto cleanup; + } + + MBEDTLS_MPI_CHK(mbedtls_mpi_copy(z, &P.X)); + +cleanup: + mbedtls_ecp_point_free(&P); + + return ret; +} + +/* + * Compute shared secret (SEC1 3.3.1) + */ +int mbedtls_ecdh_compute_shared(mbedtls_ecp_group *grp, mbedtls_mpi *z, + const mbedtls_ecp_point *Q, const mbedtls_mpi *d, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng) +{ + return ecdh_compute_shared_restartable(grp, z, Q, d, + f_rng, p_rng, NULL); +} + +static void ecdh_init_internal(mbedtls_ecdh_context_mbed *ctx) +{ + mbedtls_ecp_group_init(&ctx->grp); + mbedtls_mpi_init(&ctx->d); + mbedtls_ecp_point_init(&ctx->Q); + mbedtls_ecp_point_init(&ctx->Qp); + mbedtls_mpi_init(&ctx->z); + +#if defined(MBEDTLS_ECP_RESTARTABLE) + mbedtls_ecp_restart_init(&ctx->rs); +#endif +} + +mbedtls_ecp_group_id mbedtls_ecdh_get_grp_id(mbedtls_ecdh_context *ctx) +{ +#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) + return ctx->MBEDTLS_PRIVATE(grp).id; +#else + return ctx->MBEDTLS_PRIVATE(grp_id); +#endif +} + +/* + * Initialize context + */ +void mbedtls_ecdh_init(mbedtls_ecdh_context *ctx) +{ +#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) + ecdh_init_internal(ctx); + mbedtls_ecp_point_init(&ctx->Vi); + mbedtls_ecp_point_init(&ctx->Vf); + mbedtls_mpi_init(&ctx->_d); +#else + memset(ctx, 0, sizeof(mbedtls_ecdh_context)); + + ctx->var = MBEDTLS_ECDH_VARIANT_NONE; +#endif + ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED; +#if defined(MBEDTLS_ECP_RESTARTABLE) + ctx->restart_enabled = 0; +#endif +} + +static int ecdh_setup_internal(mbedtls_ecdh_context_mbed *ctx, + mbedtls_ecp_group_id grp_id) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + ret = mbedtls_ecp_group_load(&ctx->grp, grp_id); + if (ret != 0) { + return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; + } + + return 0; +} + +/* + * Setup context + */ +int mbedtls_ecdh_setup(mbedtls_ecdh_context *ctx, mbedtls_ecp_group_id grp_id) +{ +#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) + return ecdh_setup_internal(ctx, grp_id); +#else + switch (grp_id) { +#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) + case MBEDTLS_ECP_DP_CURVE25519: + ctx->point_format = MBEDTLS_ECP_PF_COMPRESSED; + ctx->var = MBEDTLS_ECDH_VARIANT_EVEREST; + ctx->grp_id = grp_id; + return mbedtls_everest_setup(&ctx->ctx.everest_ecdh, grp_id); +#endif + default: + ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED; + ctx->var = MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0; + ctx->grp_id = grp_id; + ecdh_init_internal(&ctx->ctx.mbed_ecdh); + return ecdh_setup_internal(&ctx->ctx.mbed_ecdh, grp_id); + } +#endif +} + +static void ecdh_free_internal(mbedtls_ecdh_context_mbed *ctx) +{ + mbedtls_ecp_group_free(&ctx->grp); + mbedtls_mpi_free(&ctx->d); + mbedtls_ecp_point_free(&ctx->Q); + mbedtls_ecp_point_free(&ctx->Qp); + mbedtls_mpi_free(&ctx->z); + +#if defined(MBEDTLS_ECP_RESTARTABLE) + mbedtls_ecp_restart_free(&ctx->rs); +#endif +} + +#if defined(MBEDTLS_ECP_RESTARTABLE) +/* + * Enable restartable operations for context + */ +void mbedtls_ecdh_enable_restart(mbedtls_ecdh_context *ctx) +{ + ctx->restart_enabled = 1; +} +#endif + +/* + * Free context + */ +void mbedtls_ecdh_free(mbedtls_ecdh_context *ctx) +{ + if (ctx == NULL) { + return; + } + +#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) + mbedtls_ecp_point_free(&ctx->Vi); + mbedtls_ecp_point_free(&ctx->Vf); + mbedtls_mpi_free(&ctx->_d); + ecdh_free_internal(ctx); +#else + switch (ctx->var) { +#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) + case MBEDTLS_ECDH_VARIANT_EVEREST: + mbedtls_everest_free(&ctx->ctx.everest_ecdh); + break; +#endif + case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: + ecdh_free_internal(&ctx->ctx.mbed_ecdh); + break; + default: + break; + } + + ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED; + ctx->var = MBEDTLS_ECDH_VARIANT_NONE; + ctx->grp_id = MBEDTLS_ECP_DP_NONE; +#endif +} + +static int ecdh_make_params_internal(mbedtls_ecdh_context_mbed *ctx, + size_t *olen, int point_format, + unsigned char *buf, size_t blen, + int (*f_rng)(void *, + unsigned char *, + size_t), + void *p_rng, + int restart_enabled) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t grp_len, pt_len; +#if defined(MBEDTLS_ECP_RESTARTABLE) + mbedtls_ecp_restart_ctx *rs_ctx = NULL; +#endif + + if (ctx->grp.pbits == 0) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + +#if defined(MBEDTLS_ECP_RESTARTABLE) + if (restart_enabled) { + rs_ctx = &ctx->rs; + } +#else + (void) restart_enabled; +#endif + + +#if defined(MBEDTLS_ECP_RESTARTABLE) + if ((ret = ecdh_gen_public_restartable(&ctx->grp, &ctx->d, &ctx->Q, + f_rng, p_rng, rs_ctx)) != 0) { + return ret; + } +#else + if ((ret = mbedtls_ecdh_gen_public(&ctx->grp, &ctx->d, &ctx->Q, + f_rng, p_rng)) != 0) { + return ret; + } +#endif /* MBEDTLS_ECP_RESTARTABLE */ + + if ((ret = mbedtls_ecp_tls_write_group(&ctx->grp, &grp_len, buf, + blen)) != 0) { + return ret; + } + + buf += grp_len; + blen -= grp_len; + + if ((ret = mbedtls_ecp_tls_write_point(&ctx->grp, &ctx->Q, point_format, + &pt_len, buf, blen)) != 0) { + return ret; + } + + *olen = grp_len + pt_len; + return 0; +} + +/* + * Setup and write the ServerKeyExchange parameters (RFC 4492) + * struct { + * ECParameters curve_params; + * ECPoint public; + * } ServerECDHParams; + */ +int mbedtls_ecdh_make_params(mbedtls_ecdh_context *ctx, size_t *olen, + unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng) +{ + int restart_enabled = 0; +#if defined(MBEDTLS_ECP_RESTARTABLE) + restart_enabled = ctx->restart_enabled; +#else + (void) restart_enabled; +#endif + +#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) + return ecdh_make_params_internal(ctx, olen, ctx->point_format, buf, blen, + f_rng, p_rng, restart_enabled); +#else + switch (ctx->var) { +#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) + case MBEDTLS_ECDH_VARIANT_EVEREST: + return mbedtls_everest_make_params(&ctx->ctx.everest_ecdh, olen, + buf, blen, f_rng, p_rng); +#endif + case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: + return ecdh_make_params_internal(&ctx->ctx.mbed_ecdh, olen, + ctx->point_format, buf, blen, + f_rng, p_rng, + restart_enabled); + default: + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } +#endif +} + +static int ecdh_read_params_internal(mbedtls_ecdh_context_mbed *ctx, + const unsigned char **buf, + const unsigned char *end) +{ + return mbedtls_ecp_tls_read_point(&ctx->grp, &ctx->Qp, buf, + (size_t) (end - *buf)); +} + +/* + * Read the ServerKeyExchange parameters (RFC 4492) + * struct { + * ECParameters curve_params; + * ECPoint public; + * } ServerECDHParams; + */ +int mbedtls_ecdh_read_params(mbedtls_ecdh_context *ctx, + const unsigned char **buf, + const unsigned char *end) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + mbedtls_ecp_group_id grp_id; + if ((ret = mbedtls_ecp_tls_read_group_id(&grp_id, buf, (size_t) (end - *buf))) + != 0) { + return ret; + } + + if ((ret = mbedtls_ecdh_setup(ctx, grp_id)) != 0) { + return ret; + } + +#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) + return ecdh_read_params_internal(ctx, buf, end); +#else + switch (ctx->var) { +#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) + case MBEDTLS_ECDH_VARIANT_EVEREST: + return mbedtls_everest_read_params(&ctx->ctx.everest_ecdh, + buf, end); +#endif + case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: + return ecdh_read_params_internal(&ctx->ctx.mbed_ecdh, + buf, end); + default: + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } +#endif +} + +static int ecdh_get_params_internal(mbedtls_ecdh_context_mbed *ctx, + const mbedtls_ecp_keypair *key, + mbedtls_ecdh_side side) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + /* If it's not our key, just import the public part as Qp */ + if (side == MBEDTLS_ECDH_THEIRS) { + return mbedtls_ecp_copy(&ctx->Qp, &key->Q); + } + + /* Our key: import public (as Q) and private parts */ + if (side != MBEDTLS_ECDH_OURS) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + + if ((ret = mbedtls_ecp_copy(&ctx->Q, &key->Q)) != 0 || + (ret = mbedtls_mpi_copy(&ctx->d, &key->d)) != 0) { + return ret; + } + + return 0; +} + +/* + * Get parameters from a keypair + */ +int mbedtls_ecdh_get_params(mbedtls_ecdh_context *ctx, + const mbedtls_ecp_keypair *key, + mbedtls_ecdh_side side) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + if (side != MBEDTLS_ECDH_OURS && side != MBEDTLS_ECDH_THEIRS) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + + if (mbedtls_ecdh_grp_id(ctx) == MBEDTLS_ECP_DP_NONE) { + /* This is the first call to get_params(). Set up the context + * for use with the group. */ + if ((ret = mbedtls_ecdh_setup(ctx, key->grp.id)) != 0) { + return ret; + } + } else { + /* This is not the first call to get_params(). Check that the + * current key's group is the same as the context's, which was set + * from the first key's group. */ + if (mbedtls_ecdh_grp_id(ctx) != key->grp.id) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + } + +#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) + return ecdh_get_params_internal(ctx, key, side); +#else + switch (ctx->var) { +#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) + case MBEDTLS_ECDH_VARIANT_EVEREST: + { + mbedtls_everest_ecdh_side s = side == MBEDTLS_ECDH_OURS ? + MBEDTLS_EVEREST_ECDH_OURS : + MBEDTLS_EVEREST_ECDH_THEIRS; + return mbedtls_everest_get_params(&ctx->ctx.everest_ecdh, + key, s); + } +#endif + case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: + return ecdh_get_params_internal(&ctx->ctx.mbed_ecdh, + key, side); + default: + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } +#endif +} + +static int ecdh_make_public_internal(mbedtls_ecdh_context_mbed *ctx, + size_t *olen, int point_format, + unsigned char *buf, size_t blen, + int (*f_rng)(void *, + unsigned char *, + size_t), + void *p_rng, + int restart_enabled) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; +#if defined(MBEDTLS_ECP_RESTARTABLE) + mbedtls_ecp_restart_ctx *rs_ctx = NULL; +#endif + + if (ctx->grp.pbits == 0) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + +#if defined(MBEDTLS_ECP_RESTARTABLE) + if (restart_enabled) { + rs_ctx = &ctx->rs; + } +#else + (void) restart_enabled; +#endif + +#if defined(MBEDTLS_ECP_RESTARTABLE) + if ((ret = ecdh_gen_public_restartable(&ctx->grp, &ctx->d, &ctx->Q, + f_rng, p_rng, rs_ctx)) != 0) { + return ret; + } +#else + if ((ret = mbedtls_ecdh_gen_public(&ctx->grp, &ctx->d, &ctx->Q, + f_rng, p_rng)) != 0) { + return ret; + } +#endif /* MBEDTLS_ECP_RESTARTABLE */ + + return mbedtls_ecp_tls_write_point(&ctx->grp, &ctx->Q, point_format, olen, + buf, blen); +} + +/* + * Setup and export the client public value + */ +int mbedtls_ecdh_make_public(mbedtls_ecdh_context *ctx, size_t *olen, + unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng) +{ + int restart_enabled = 0; +#if defined(MBEDTLS_ECP_RESTARTABLE) + restart_enabled = ctx->restart_enabled; +#endif + +#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) + return ecdh_make_public_internal(ctx, olen, ctx->point_format, buf, blen, + f_rng, p_rng, restart_enabled); +#else + switch (ctx->var) { +#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) + case MBEDTLS_ECDH_VARIANT_EVEREST: + return mbedtls_everest_make_public(&ctx->ctx.everest_ecdh, olen, + buf, blen, f_rng, p_rng); +#endif + case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: + return ecdh_make_public_internal(&ctx->ctx.mbed_ecdh, olen, + ctx->point_format, buf, blen, + f_rng, p_rng, + restart_enabled); + default: + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } +#endif +} + +static int ecdh_read_public_internal(mbedtls_ecdh_context_mbed *ctx, + const unsigned char *buf, size_t blen) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + const unsigned char *p = buf; + + if ((ret = mbedtls_ecp_tls_read_point(&ctx->grp, &ctx->Qp, &p, + blen)) != 0) { + return ret; + } + + if ((size_t) (p - buf) != blen) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + + return 0; +} + +/* + * Parse and import the client's public value + */ +int mbedtls_ecdh_read_public(mbedtls_ecdh_context *ctx, + const unsigned char *buf, size_t blen) +{ +#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) + return ecdh_read_public_internal(ctx, buf, blen); +#else + switch (ctx->var) { +#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) + case MBEDTLS_ECDH_VARIANT_EVEREST: + return mbedtls_everest_read_public(&ctx->ctx.everest_ecdh, + buf, blen); +#endif + case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: + return ecdh_read_public_internal(&ctx->ctx.mbed_ecdh, + buf, blen); + default: + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } +#endif +} + +static int ecdh_calc_secret_internal(mbedtls_ecdh_context_mbed *ctx, + size_t *olen, unsigned char *buf, + size_t blen, + int (*f_rng)(void *, + unsigned char *, + size_t), + void *p_rng, + int restart_enabled) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; +#if defined(MBEDTLS_ECP_RESTARTABLE) + mbedtls_ecp_restart_ctx *rs_ctx = NULL; +#endif + + if (ctx == NULL || ctx->grp.pbits == 0) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + +#if defined(MBEDTLS_ECP_RESTARTABLE) + if (restart_enabled) { + rs_ctx = &ctx->rs; + } +#else + (void) restart_enabled; +#endif + +#if defined(MBEDTLS_ECP_RESTARTABLE) + if ((ret = ecdh_compute_shared_restartable(&ctx->grp, &ctx->z, &ctx->Qp, + &ctx->d, f_rng, p_rng, + rs_ctx)) != 0) { + return ret; + } +#else + if ((ret = mbedtls_ecdh_compute_shared(&ctx->grp, &ctx->z, &ctx->Qp, + &ctx->d, f_rng, p_rng)) != 0) { + return ret; + } +#endif /* MBEDTLS_ECP_RESTARTABLE */ + + if (mbedtls_mpi_size(&ctx->z) > blen) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + + *olen = ctx->grp.pbits / 8 + ((ctx->grp.pbits % 8) != 0); + + if (mbedtls_ecp_get_type(&ctx->grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) { + return mbedtls_mpi_write_binary_le(&ctx->z, buf, *olen); + } + + return mbedtls_mpi_write_binary(&ctx->z, buf, *olen); +} + +/* + * Derive and export the shared secret + */ +int mbedtls_ecdh_calc_secret(mbedtls_ecdh_context *ctx, size_t *olen, + unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng) +{ + int restart_enabled = 0; +#if defined(MBEDTLS_ECP_RESTARTABLE) + restart_enabled = ctx->restart_enabled; +#endif + +#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) + return ecdh_calc_secret_internal(ctx, olen, buf, blen, f_rng, p_rng, + restart_enabled); +#else + switch (ctx->var) { +#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) + case MBEDTLS_ECDH_VARIANT_EVEREST: + return mbedtls_everest_calc_secret(&ctx->ctx.everest_ecdh, olen, + buf, blen, f_rng, p_rng); +#endif + case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: + return ecdh_calc_secret_internal(&ctx->ctx.mbed_ecdh, olen, buf, + blen, f_rng, p_rng, + restart_enabled); + default: + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } +#endif +} +#endif /* MBEDTLS_ECDH_C */ diff --git a/port/mbedtls/removed/mbedtls/des.h b/port/mbedtls/removed/mbedtls/des.h new file mode 100644 index 0000000000..32c778f790 --- /dev/null +++ b/port/mbedtls/removed/mbedtls/des.h @@ -0,0 +1,370 @@ +/** + * \file des.h + * + * \brief DES block cipher + * + * \warning DES/3DES are considered weak ciphers and their use constitutes a + * security risk. We recommend considering stronger ciphers + * instead. + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + * + */ +#ifndef MBEDTLS_DES_H +#define MBEDTLS_DES_H +#include "mbedtls/private_access.h" + +#include "tf-psa-crypto/build_info.h" +#include "mbedtls/platform_util.h" + +#include +#include + +#if defined(MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS) +#define MBEDTLS_DES_ENCRYPT 1 +#define MBEDTLS_DES_DECRYPT 0 +#endif /* MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS */ + +/** The data input has an invalid length. */ +#define MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH (-0x0032) + +#if defined(MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS) +#define MBEDTLS_DES_KEY_SIZE 8 +#endif /* MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS) +/** + * \brief DES context structure + * + * \warning DES/3DES are considered weak ciphers and their use constitutes a + * security risk. We recommend considering stronger ciphers + * instead. + */ +typedef struct mbedtls_des_context { + uint32_t MBEDTLS_PRIVATE(sk)[32]; /*!< DES subkeys */ +} +mbedtls_des_context; + +/** + * \brief Triple-DES context structure + * + * \warning DES/3DES are considered weak ciphers and their use constitutes a + * security risk. We recommend considering stronger ciphers + * instead. + */ +typedef struct mbedtls_des3_context { + uint32_t MBEDTLS_PRIVATE(sk)[96]; /*!< 3DES subkeys */ +} +mbedtls_des3_context; + + +/** + * \brief Initialize DES context + * + * \param ctx DES context to be initialized + * + * \warning DES/3DES are considered weak ciphers and their use constitutes a + * security risk. We recommend considering stronger ciphers + * instead. + */ +void mbedtls_des_init(mbedtls_des_context *ctx); + +/** + * \brief Clear DES context + * + * \param ctx DES context to be cleared + * + * \warning DES/3DES are considered weak ciphers and their use constitutes a + * security risk. We recommend considering stronger ciphers + * instead. + */ +void mbedtls_des_free(mbedtls_des_context *ctx); + +/** + * \brief Initialize Triple-DES context + * + * \param ctx DES3 context to be initialized + * + * \warning DES/3DES are considered weak ciphers and their use constitutes a + * security risk. We recommend considering stronger ciphers + * instead. + */ +void mbedtls_des3_init(mbedtls_des3_context *ctx); + +/** + * \brief Clear Triple-DES context + * + * \param ctx DES3 context to be cleared + * + * \warning DES/3DES are considered weak ciphers and their use constitutes a + * security risk. We recommend considering stronger ciphers + * instead. + */ +void mbedtls_des3_free(mbedtls_des3_context *ctx); + +/** + * \brief Set key parity on the given key to odd. + * + * DES keys are 56 bits long, but each byte is padded with + * a parity bit to allow verification. + * + * \param key 8-byte secret key + * + * \warning DES/3DES are considered weak ciphers and their use constitutes a + * security risk. We recommend considering stronger ciphers + * instead. + */ +void mbedtls_des_key_set_parity(unsigned char key[MBEDTLS_DES_KEY_SIZE]); + +/** + * \brief Check that key parity on the given key is odd. + * + * DES keys are 56 bits long, but each byte is padded with + * a parity bit to allow verification. + * + * \param key 8-byte secret key + * + * \return 0 is parity was ok, 1 if parity was not correct. + * + * \warning DES/3DES are considered weak ciphers and their use constitutes a + * security risk. We recommend considering stronger ciphers + * instead. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_des_key_check_key_parity(const unsigned char key[MBEDTLS_DES_KEY_SIZE]); + +/** + * \brief Check that key is not a weak or semi-weak DES key + * + * \param key 8-byte secret key + * + * \return 0 if no weak key was found, 1 if a weak key was identified. + * + * \warning DES/3DES are considered weak ciphers and their use constitutes a + * security risk. We recommend considering stronger ciphers + * instead. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_des_key_check_weak(const unsigned char key[MBEDTLS_DES_KEY_SIZE]); + +/** + * \brief DES key schedule (56-bit, encryption) + * + * \param ctx DES context to be initialized + * \param key 8-byte secret key + * + * \return 0 + * + * \warning DES/3DES are considered weak ciphers and their use constitutes a + * security risk. We recommend considering stronger ciphers + * instead. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_des_setkey_enc(mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE]); + +/** + * \brief DES key schedule (56-bit, decryption) + * + * \param ctx DES context to be initialized + * \param key 8-byte secret key + * + * \return 0 + * + * \warning DES/3DES are considered weak ciphers and their use constitutes a + * security risk. We recommend considering stronger ciphers + * instead. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_des_setkey_dec(mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE]); + +/** + * \brief Triple-DES key schedule (112-bit, encryption) + * + * \param ctx 3DES context to be initialized + * \param key 16-byte secret key + * + * \return 0 + * + * \warning DES/3DES are considered weak ciphers and their use constitutes a + * security risk. We recommend considering stronger ciphers + * instead. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_des3_set2key_enc(mbedtls_des3_context *ctx, + const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2]); + +/** + * \brief Triple-DES key schedule (112-bit, decryption) + * + * \param ctx 3DES context to be initialized + * \param key 16-byte secret key + * + * \return 0 + * + * \warning DES/3DES are considered weak ciphers and their use constitutes a + * security risk. We recommend considering stronger ciphers + * instead. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_des3_set2key_dec(mbedtls_des3_context *ctx, + const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2]); + +/** + * \brief Triple-DES key schedule (168-bit, encryption) + * + * \param ctx 3DES context to be initialized + * \param key 24-byte secret key + * + * \return 0 + * + * \warning DES/3DES are considered weak ciphers and their use constitutes a + * security risk. We recommend considering stronger ciphers + * instead. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_des3_set3key_enc(mbedtls_des3_context *ctx, + const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3]); + +/** + * \brief Triple-DES key schedule (168-bit, decryption) + * + * \param ctx 3DES context to be initialized + * \param key 24-byte secret key + * + * \return 0 + * + * \warning DES/3DES are considered weak ciphers and their use constitutes a + * security risk. We recommend considering stronger ciphers + * instead. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_des3_set3key_dec(mbedtls_des3_context *ctx, + const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3]); + +/** + * \brief DES-ECB block encryption/decryption + * + * \param ctx DES context + * \param input 64-bit input block + * \param output 64-bit output block + * + * \return 0 if successful + * + * \warning DES/3DES are considered weak ciphers and their use constitutes a + * security risk. We recommend considering stronger ciphers + * instead. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_des_crypt_ecb(mbedtls_des_context *ctx, + const unsigned char input[8], + unsigned char output[8]); + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +/** + * \brief DES-CBC buffer encryption/decryption + * + * \note Upon exit, the content of the IV is updated so that you can + * call the function same function again on the following + * block(s) of data and get the same result as if it was + * encrypted in one call. This allows a "streaming" usage. + * If on the other hand you need to retain the contents of the + * IV, you should either save it manually or use the cipher + * module instead. + * + * \param ctx DES context + * \param mode MBEDTLS_DES_ENCRYPT or MBEDTLS_DES_DECRYPT + * \param length length of the input data + * \param iv initialization vector (updated after use) + * \param input buffer holding the input data + * \param output buffer holding the output data + * + * \warning DES/3DES are considered weak ciphers and their use constitutes a + * security risk. We recommend considering stronger ciphers + * instead. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +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); +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +/** + * \brief 3DES-ECB block encryption/decryption + * + * \param ctx 3DES context + * \param input 64-bit input block + * \param output 64-bit output block + * + * \return 0 if successful + * + * \warning DES/3DES are considered weak ciphers and their use constitutes a + * security risk. We recommend considering stronger ciphers + * instead. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_des3_crypt_ecb(mbedtls_des3_context *ctx, + const unsigned char input[8], + unsigned char output[8]); + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +/** + * \brief 3DES-CBC buffer encryption/decryption + * + * \note Upon exit, the content of the IV is updated so that you can + * call the function same function again on the following + * block(s) of data and get the same result as if it was + * encrypted in one call. This allows a "streaming" usage. + * If on the other hand you need to retain the contents of the + * IV, you should either save it manually or use the cipher + * module instead. + * + * \param ctx 3DES context + * \param mode MBEDTLS_DES_ENCRYPT or MBEDTLS_DES_DECRYPT + * \param length length of the input data + * \param iv initialization vector (updated after use) + * \param input buffer holding the input data + * \param output buffer holding the output data + * + * \return 0 if successful, or MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH + * + * \warning DES/3DES are considered weak ciphers and their use constitutes a + * security risk. We recommend considering stronger ciphers + * instead. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +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); +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_SELF_TEST) + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +MBEDTLS_CHECK_RETURN_CRITICAL +int mbedtls_des_self_test(int verbose); + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS */ + +#ifdef __cplusplus +} +#endif + +#endif /* des.h */ diff --git a/port/mbedtls/removed/mbedtls/dhm.h b/port/mbedtls/removed/mbedtls/dhm.h new file mode 100644 index 0000000000..11b0931536 --- /dev/null +++ b/port/mbedtls/removed/mbedtls/dhm.h @@ -0,0 +1,966 @@ +/** + * \file dhm.h + * + * \brief This file contains Diffie-Hellman-Merkle (DHM) key exchange + * definitions and functions. + * + * Diffie-Hellman-Merkle (DHM) key exchange is defined in + * RFC-2631: Diffie-Hellman Key Agreement Method and + * Public-Key Cryptography Standards (PKCS) #3: Diffie + * Hellman Key Agreement Standard. + * + * RFC-3526: More Modular Exponential (MODP) Diffie-Hellman groups for + * Internet Key Exchange (IKE) defines a number of standardized + * Diffie-Hellman groups for IKE. + * + * RFC-5114: Additional Diffie-Hellman Groups for Use with IETF + * Standards defines a number of standardized Diffie-Hellman + * groups that can be used. + * + * \warning The security of the DHM key exchange relies on the proper choice + * of prime modulus - optimally, it should be a safe prime. The usage + * of non-safe primes both decreases the difficulty of the underlying + * discrete logarithm problem and can lead to small subgroup attacks + * leaking private exponent bits when invalid public keys are used + * and not detected. This is especially relevant if the same DHM + * parameters are reused for multiple key exchanges as in static DHM, + * while the criticality of small-subgroup attacks is lower for + * ephemeral DHM. + * + * \warning For performance reasons, the code does neither perform primality + * nor safe primality tests, nor the expensive checks for invalid + * subgroups. Moreover, even if these were performed, non-standardized + * primes cannot be trusted because of the possibility of backdoors + * that can't be effectively checked for. + * + * \warning Diffie-Hellman-Merkle is therefore a security risk when not using + * standardized primes generated using a trustworthy ("nothing up + * my sleeve") method, such as the RFC 3526 / 7919 primes. In the TLS + * protocol, DH parameters need to be negotiated, so using the default + * primes systematically is not always an option. If possible, use + * Elliptic Curve Diffie-Hellman (ECDH), which has better performance, + * and for which the TLS protocol mandates the use of standard + * parameters. + * + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#ifndef MBEDTLS_DHM_H +#define MBEDTLS_DHM_H +#include "mbedtls/private_access.h" + +#include "tf-psa-crypto/build_info.h" +#include "mbedtls/bignum.h" + +/* + * DHM Error codes + */ +/** Bad input parameters. */ +#define MBEDTLS_ERR_DHM_BAD_INPUT_DATA -0x3080 +/** Reading of the DHM parameters failed. */ +#define MBEDTLS_ERR_DHM_READ_PARAMS_FAILED -0x3100 +/** Making of the DHM parameters failed. */ +#define MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED -0x3180 +/** Reading of the public values failed. */ +#define MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED -0x3200 +/** Making of the public value failed. */ +#define MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED -0x3280 +/** Calculation of the DHM secret failed. */ +#define MBEDTLS_ERR_DHM_CALC_SECRET_FAILED -0x3300 +/** The ASN.1 data is not formatted correctly. */ +#define MBEDTLS_ERR_DHM_INVALID_FORMAT -0x3380 +/** Allocation of memory failed. */ +#define MBEDTLS_ERR_DHM_ALLOC_FAILED -0x3400 +/** Read or write of file failed. */ +#define MBEDTLS_ERR_DHM_FILE_IO_ERROR -0x3480 +/** Setting the modulus and generator failed. */ +#define MBEDTLS_ERR_DHM_SET_GROUP_FAILED -0x3580 + +/** Which parameter to access in mbedtls_dhm_get_value(). */ +typedef enum { + MBEDTLS_DHM_PARAM_P, /*!< The prime modulus. */ + MBEDTLS_DHM_PARAM_G, /*!< The generator. */ + MBEDTLS_DHM_PARAM_X, /*!< Our secret value. */ + MBEDTLS_DHM_PARAM_GX, /*!< Our public key = \c G^X mod \c P. */ + MBEDTLS_DHM_PARAM_GY, /*!< The public key of the peer = \c G^Y mod \c P. */ + MBEDTLS_DHM_PARAM_K, /*!< The shared secret = \c G^(XY) mod \c P. */ +} mbedtls_dhm_parameter; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief The DHM context structure. + */ +typedef struct mbedtls_dhm_context { + mbedtls_mpi MBEDTLS_PRIVATE(P); /*!< The prime modulus. */ + mbedtls_mpi MBEDTLS_PRIVATE(G); /*!< The generator. */ + mbedtls_mpi MBEDTLS_PRIVATE(X); /*!< Our secret value. */ + mbedtls_mpi MBEDTLS_PRIVATE(GX); /*!< Our public key = \c G^X mod \c P. */ + mbedtls_mpi MBEDTLS_PRIVATE(GY); /*!< The public key of the peer = \c G^Y mod \c P. */ + mbedtls_mpi MBEDTLS_PRIVATE(K); /*!< The shared secret = \c G^(XY) mod \c P. */ + mbedtls_mpi MBEDTLS_PRIVATE(RP); /*!< The cached value = \c R^2 mod \c P. */ + mbedtls_mpi MBEDTLS_PRIVATE(Vi); /*!< The blinding value. */ + mbedtls_mpi MBEDTLS_PRIVATE(Vf); /*!< The unblinding value. */ + mbedtls_mpi MBEDTLS_PRIVATE(pX); /*!< The previous \c X. */ +} +mbedtls_dhm_context; + +/** + * \brief This function initializes the DHM context. + * + * \param ctx The DHM context to initialize. + */ +void mbedtls_dhm_init(mbedtls_dhm_context *ctx); + +/** + * \brief This function parses the DHM parameters in a + * TLS ServerKeyExchange handshake message + * (DHM modulus, generator, and public key). + * + * \note In a TLS handshake, this is the how the client + * sets up its DHM context from the server's public + * DHM key material. + * + * \param ctx The DHM context to use. This must be initialized. + * \param p On input, *p must be the start of the input buffer. + * On output, *p is updated to point to the end of the data + * that has been read. On success, this is the first byte + * past the end of the ServerKeyExchange parameters. + * On error, this is the point at which an error has been + * detected, which is usually not useful except to debug + * failures. + * \param end The end of the input buffer. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_DHM_XXX error code on failure. + */ +int mbedtls_dhm_read_params(mbedtls_dhm_context *ctx, + unsigned char **p, + const unsigned char *end); + +/** + * \brief This function generates a DHM key pair and exports its + * public part together with the DHM parameters in the format + * used in a TLS ServerKeyExchange handshake message. + * + * \note This function assumes that the DHM parameters \c ctx->P + * and \c ctx->G have already been properly set. For that, use + * mbedtls_dhm_set_group() below in conjunction with + * mbedtls_mpi_read_binary() and mbedtls_mpi_read_string(). + * + * \note In a TLS handshake, this is the how the server generates + * and exports its DHM key material. + * + * \param ctx The DHM context to use. This must be initialized + * and have the DHM parameters set. It may or may not + * already have imported the peer's public key. + * \param x_size The private key size in Bytes. + * \param olen The address at which to store the number of Bytes + * written on success. This must not be \c NULL. + * \param output The destination buffer. This must be a writable buffer of + * sufficient size to hold the reduced binary presentation of + * the modulus, the generator and the public key, each wrapped + * with a 2-byte length field. It is the responsibility of the + * caller to ensure that enough space is available. Refer to + * mbedtls_mpi_size() to computing the byte-size of an MPI. + * \param f_rng The RNG function. Must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may be + * \c NULL if \p f_rng doesn't need a context parameter. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_DHM_XXX error code on failure. + */ +int mbedtls_dhm_make_params(mbedtls_dhm_context *ctx, int x_size, + unsigned char *output, size_t *olen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng); + +/** + * \brief This function sets the prime modulus and generator. + * + * \note This function can be used to set \c ctx->P, \c ctx->G + * in preparation for mbedtls_dhm_make_params(). + * + * \param ctx The DHM context to configure. This must be initialized. + * \param P The MPI holding the DHM prime modulus. This must be + * an initialized MPI. + * \param G The MPI holding the DHM generator. This must be an + * initialized MPI. + * + * \return \c 0 if successful. + * \return An \c MBEDTLS_ERR_DHM_XXX error code on failure. + */ +int mbedtls_dhm_set_group(mbedtls_dhm_context *ctx, + const mbedtls_mpi *P, + const mbedtls_mpi *G); + +/** + * \brief This function imports the raw public value of the peer. + * + * \note In a TLS handshake, this is the how the server imports + * the Client's public DHM key. + * + * \param ctx The DHM context to use. This must be initialized and have + * its DHM parameters set, e.g. via mbedtls_dhm_set_group(). + * It may or may not already have generated its own private key. + * \param input The input buffer containing the \c G^Y value of the peer. + * This must be a readable buffer of size \p ilen Bytes. + * \param ilen The size of the input buffer \p input in Bytes. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_DHM_XXX error code on failure. + */ +int mbedtls_dhm_read_public(mbedtls_dhm_context *ctx, + const unsigned char *input, size_t ilen); + +/** + * \brief This function creates a DHM key pair and exports + * the raw public key in big-endian format. + * + * \note The destination buffer is always fully written + * so as to contain a big-endian representation of G^X mod P. + * If it is larger than \c ctx->len, it is padded accordingly + * with zero-bytes at the beginning. + * + * \param ctx The DHM context to use. This must be initialized and + * have the DHM parameters set. It may or may not already + * have imported the peer's public key. + * \param x_size The private key size in Bytes. + * \param output The destination buffer. This must be a writable buffer of + * size \p olen Bytes. + * \param olen The length of the destination buffer. This must be at least + * equal to `ctx->len` (the size of \c P). + * \param f_rng The RNG function. This must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may be \c NULL + * if \p f_rng doesn't need a context argument. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_DHM_XXX error code on failure. + */ +int mbedtls_dhm_make_public(mbedtls_dhm_context *ctx, int x_size, + unsigned char *output, size_t olen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng); + +/** + * \brief This function derives and exports the shared secret + * \c (G^Y)^X mod \c P. + * + * \note If \p f_rng is not \c NULL, it is used to blind the input as + * a countermeasure against timing attacks. Blinding is used + * only if our private key \c X is re-used, and not used + * otherwise. We recommend always passing a non-NULL + * \p f_rng argument. + * + * \param ctx The DHM context to use. This must be initialized + * and have its own private key generated and the peer's + * public key imported. + * \param output The buffer to write the generated shared key to. This + * must be a writable buffer of size \p output_size Bytes. + * \param output_size The size of the destination buffer. This must be at + * least the size of \c ctx->len (the size of \c P). + * \param olen On exit, holds the actual number of Bytes written. + * \param f_rng The RNG function. Must not be \c NULL. Used for + * blinding. + * \param p_rng The RNG context to be passed to \p f_rng. This may be + * \c NULL if \p f_rng doesn't need a context parameter. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_DHM_XXX error code on failure. + */ +int mbedtls_dhm_calc_secret(mbedtls_dhm_context *ctx, + unsigned char *output, size_t output_size, size_t *olen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng); + +/** + * \brief This function returns the size of the prime modulus in bits. + * + * \param ctx The DHM context to query. + * + * \return The size of the prime modulus in bits, + * i.e. the number n such that 2^(n-1) <= P < 2^n. + */ +size_t mbedtls_dhm_get_bitlen(const mbedtls_dhm_context *ctx); + +/** + * \brief This function returns the size of the prime modulus in bytes. + * + * \param ctx The DHM context to query. + * + * \return The size of the prime modulus in bytes, + * i.e. the number n such that 2^(8*(n-1)) <= P < 2^(8*n). + */ +size_t mbedtls_dhm_get_len(const mbedtls_dhm_context *ctx); + +/** + * \brief This function copies a parameter of a DHM key. + * + * \param ctx The DHM context to query. + * \param param The parameter to copy. + * \param dest The MPI object to copy the value into. It must be + * initialized. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_DHM_BAD_INPUT_DATA if \p param is invalid. + * \return An \c MBEDTLS_ERR_MPI_XXX error code if the copy fails. + */ +int mbedtls_dhm_get_value(const mbedtls_dhm_context *ctx, + mbedtls_dhm_parameter param, + mbedtls_mpi *dest); + +/** + * \brief This function frees and clears the components + * of a DHM context. + * + * \param ctx The DHM context to free and clear. This may be \c NULL, + * in which case this function is a no-op. If it is not \c NULL, + * it must point to an initialized DHM context. + */ +void mbedtls_dhm_free(mbedtls_dhm_context *ctx); + +#if defined(MBEDTLS_ASN1_PARSE_C) +/** + * \brief This function parses DHM parameters in PEM or DER format. + * + * \param dhm The DHM context to import the DHM parameters into. + * This must be initialized. + * \param dhmin The input buffer. This must be a readable buffer of + * length \p dhminlen Bytes. + * \param dhminlen The size of the input buffer \p dhmin, including the + * terminating \c NULL Byte for PEM data. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_DHM_XXX or \c MBEDTLS_ERR_PEM_XXX error + * code on failure. + */ +int mbedtls_dhm_parse_dhm(mbedtls_dhm_context *dhm, const unsigned char *dhmin, + size_t dhminlen); + +#if defined(MBEDTLS_FS_IO) +/** + * \brief This function loads and parses DHM parameters from a file. + * + * \param dhm The DHM context to load the parameters to. + * This must be initialized. + * \param path The filename to read the DHM parameters from. + * This must not be \c NULL. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_DHM_XXX or \c MBEDTLS_ERR_PEM_XXX + * error code on failure. + */ +int mbedtls_dhm_parse_dhmfile(mbedtls_dhm_context *dhm, const char *path); +#endif /* MBEDTLS_FS_IO */ +#endif /* MBEDTLS_ASN1_PARSE_C */ + +#if defined(MBEDTLS_SELF_TEST) + +/** + * \brief The DMH checkup routine. + * + * \return \c 0 on success. + * \return \c 1 on failure. + */ +int mbedtls_dhm_self_test(int verbose); + +#endif /* MBEDTLS_SELF_TEST */ +#ifdef __cplusplus +} +#endif + +/** + * RFC 3526, RFC 5114 and RFC 7919 standardize a number of + * Diffie-Hellman groups, some of which are included here + * for use within the SSL/TLS module and the user's convenience + * when configuring the Diffie-Hellman parameters by hand + * through \c mbedtls_ssl_conf_dh_param. + * + * The following lists the source of the above groups in the standards: + * - RFC 5114 section 2.2: 2048-bit MODP Group with 224-bit Prime Order Subgroup + * - RFC 3526 section 3: 2048-bit MODP Group + * - RFC 3526 section 4: 3072-bit MODP Group + * - RFC 3526 section 5: 4096-bit MODP Group + * - RFC 7919 section A.1: ffdhe2048 + * - RFC 7919 section A.2: ffdhe3072 + * - RFC 7919 section A.3: ffdhe4096 + * - RFC 7919 section A.4: ffdhe6144 + * - RFC 7919 section A.5: ffdhe8192 + * + * The constants with suffix "_p" denote the chosen prime moduli, while + * the constants with suffix "_g" denote the chosen generator + * of the associated prime field. + * + * The constants further suffixed with "_bin" are provided in binary format, + * while all other constants represent null-terminated strings holding the + * hexadecimal presentation of the respective numbers. + * + * The primes from RFC 3526 and RFC 7919 have been generating by the following + * trust-worthy procedure: + * - Fix N in { 2048, 3072, 4096, 6144, 8192 } and consider the N-bit number + * the first and last 64 bits are all 1, and the remaining N - 128 bits of + * which are 0x7ff...ff. + * - Add the smallest multiple of the first N - 129 bits of the binary expansion + * of pi (for RFC 5236) or e (for RFC 7919) to this intermediate bit-string + * such that the resulting integer is a safe-prime. + * - The result is the respective RFC 3526 / 7919 prime, and the corresponding + * generator is always chosen to be 2 (which is a square for these prime, + * hence the corresponding subgroup has order (p-1)/2 and avoids leaking a + * bit in the private exponent). + * + */ + +/* + * Trustworthy DHM parameters in binary form + */ + +#define MBEDTLS_DHM_RFC3526_MODP_2048_P_BIN { \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ + 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, \ + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, \ + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, \ + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, \ + 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, \ + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, \ + 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, \ + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, \ + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, \ + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, \ + 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, \ + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, \ + 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, \ + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, \ + 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, \ + 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, \ + 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, \ + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, \ + 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, \ + 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, \ + 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, \ + 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, \ + 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, \ + 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, \ + 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, \ + 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, \ + 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, \ + 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, \ + 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, \ + 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } + +#define MBEDTLS_DHM_RFC3526_MODP_2048_G_BIN { 0x02 } + +#define MBEDTLS_DHM_RFC3526_MODP_3072_P_BIN { \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ + 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, \ + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, \ + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, \ + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, \ + 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, \ + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, \ + 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, \ + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, \ + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, \ + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, \ + 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, \ + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, \ + 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, \ + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, \ + 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, \ + 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, \ + 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, \ + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, \ + 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, \ + 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, \ + 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, \ + 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, \ + 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, \ + 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, \ + 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, \ + 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, \ + 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, \ + 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, \ + 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, \ + 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, \ + 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33, \ + 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, \ + 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, \ + 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, \ + 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, \ + 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, \ + 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, \ + 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, \ + 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, \ + 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, \ + 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, \ + 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, \ + 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2, \ + 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, \ + 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, \ + 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x3A, 0xD2, 0xCA, \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } + +#define MBEDTLS_DHM_RFC3526_MODP_3072_G_BIN { 0x02 } + +#define MBEDTLS_DHM_RFC3526_MODP_4096_P_BIN { \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ + 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, \ + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, \ + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, \ + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, \ + 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, \ + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, \ + 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, \ + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, \ + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, \ + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, \ + 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, \ + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, \ + 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, \ + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, \ + 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, \ + 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, \ + 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, \ + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, \ + 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, \ + 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, \ + 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, \ + 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, \ + 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, \ + 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, \ + 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, \ + 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, \ + 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, \ + 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, \ + 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, \ + 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, \ + 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33, \ + 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, \ + 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, \ + 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, \ + 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, \ + 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, \ + 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, \ + 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, \ + 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, \ + 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, \ + 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, \ + 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, \ + 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2, \ + 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, \ + 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, \ + 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01, \ + 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7, \ + 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, \ + 0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C, \ + 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA, \ + 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, \ + 0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9, \ + 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6, \ + 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, \ + 0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2, \ + 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED, \ + 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, \ + 0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C, \ + 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9, \ + 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, \ + 0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F, \ + 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99, \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } + +#define MBEDTLS_DHM_RFC3526_MODP_4096_G_BIN { 0x02 } + +#define MBEDTLS_DHM_RFC7919_FFDHE2048_P_BIN { \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ + 0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, \ + 0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, \ + 0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, \ + 0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, \ + 0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, \ + 0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, \ + 0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, \ + 0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, \ + 0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, \ + 0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, \ + 0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, \ + 0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, \ + 0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, \ + 0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, \ + 0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, \ + 0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, \ + 0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, \ + 0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, \ + 0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, \ + 0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, \ + 0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, \ + 0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, \ + 0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, \ + 0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, \ + 0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, \ + 0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, \ + 0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, \ + 0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, \ + 0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, \ + 0x88, 0x6B, 0x42, 0x38, 0x61, 0x28, 0x5C, 0x97, \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, } + +#define MBEDTLS_DHM_RFC7919_FFDHE2048_G_BIN { 0x02 } + +#define MBEDTLS_DHM_RFC7919_FFDHE3072_P_BIN { \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ + 0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, \ + 0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, \ + 0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, \ + 0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, \ + 0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, \ + 0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, \ + 0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, \ + 0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, \ + 0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, \ + 0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, \ + 0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, \ + 0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, \ + 0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, \ + 0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, \ + 0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, \ + 0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, \ + 0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, \ + 0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, \ + 0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, \ + 0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, \ + 0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, \ + 0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, \ + 0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, \ + 0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, \ + 0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, \ + 0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, \ + 0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, \ + 0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, \ + 0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, \ + 0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC, \ + 0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B, \ + 0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38, \ + 0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07, \ + 0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE, \ + 0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C, \ + 0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70, \ + 0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44, \ + 0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3, \ + 0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF, \ + 0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E, \ + 0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D, \ + 0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA, \ + 0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E, \ + 0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF, \ + 0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C, \ + 0x25, 0xE4, 0x1D, 0x2B, 0x66, 0xC6, 0x2E, 0x37, \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } + +#define MBEDTLS_DHM_RFC7919_FFDHE3072_G_BIN { 0x02 } + +#define MBEDTLS_DHM_RFC7919_FFDHE4096_P_BIN { \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ + 0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, \ + 0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, \ + 0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, \ + 0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, \ + 0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, \ + 0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, \ + 0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, \ + 0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, \ + 0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, \ + 0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, \ + 0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, \ + 0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, \ + 0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, \ + 0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, \ + 0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, \ + 0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, \ + 0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, \ + 0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, \ + 0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, \ + 0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, \ + 0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, \ + 0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, \ + 0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, \ + 0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, \ + 0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, \ + 0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, \ + 0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, \ + 0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, \ + 0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, \ + 0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC, \ + 0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B, \ + 0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38, \ + 0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07, \ + 0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE, \ + 0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C, \ + 0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70, \ + 0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44, \ + 0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3, \ + 0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF, \ + 0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E, \ + 0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D, \ + 0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA, \ + 0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E, \ + 0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF, \ + 0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C, \ + 0x25, 0xE4, 0x1D, 0x2B, 0x66, 0x9E, 0x1E, 0xF1, \ + 0x6E, 0x6F, 0x52, 0xC3, 0x16, 0x4D, 0xF4, 0xFB, \ + 0x79, 0x30, 0xE9, 0xE4, 0xE5, 0x88, 0x57, 0xB6, \ + 0xAC, 0x7D, 0x5F, 0x42, 0xD6, 0x9F, 0x6D, 0x18, \ + 0x77, 0x63, 0xCF, 0x1D, 0x55, 0x03, 0x40, 0x04, \ + 0x87, 0xF5, 0x5B, 0xA5, 0x7E, 0x31, 0xCC, 0x7A, \ + 0x71, 0x35, 0xC8, 0x86, 0xEF, 0xB4, 0x31, 0x8A, \ + 0xED, 0x6A, 0x1E, 0x01, 0x2D, 0x9E, 0x68, 0x32, \ + 0xA9, 0x07, 0x60, 0x0A, 0x91, 0x81, 0x30, 0xC4, \ + 0x6D, 0xC7, 0x78, 0xF9, 0x71, 0xAD, 0x00, 0x38, \ + 0x09, 0x29, 0x99, 0xA3, 0x33, 0xCB, 0x8B, 0x7A, \ + 0x1A, 0x1D, 0xB9, 0x3D, 0x71, 0x40, 0x00, 0x3C, \ + 0x2A, 0x4E, 0xCE, 0xA9, 0xF9, 0x8D, 0x0A, 0xCC, \ + 0x0A, 0x82, 0x91, 0xCD, 0xCE, 0xC9, 0x7D, 0xCF, \ + 0x8E, 0xC9, 0xB5, 0x5A, 0x7F, 0x88, 0xA4, 0x6B, \ + 0x4D, 0xB5, 0xA8, 0x51, 0xF4, 0x41, 0x82, 0xE1, \ + 0xC6, 0x8A, 0x00, 0x7E, 0x5E, 0x65, 0x5F, 0x6A, \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } + +#define MBEDTLS_DHM_RFC7919_FFDHE4096_G_BIN { 0x02 } + +#define MBEDTLS_DHM_RFC7919_FFDHE6144_P_BIN { \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ + 0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, \ + 0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, \ + 0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, \ + 0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, \ + 0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, \ + 0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, \ + 0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, \ + 0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, \ + 0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, \ + 0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, \ + 0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, \ + 0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, \ + 0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, \ + 0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, \ + 0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, \ + 0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, \ + 0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, \ + 0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, \ + 0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, \ + 0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, \ + 0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, \ + 0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, \ + 0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, \ + 0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, \ + 0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, \ + 0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, \ + 0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, \ + 0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, \ + 0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, \ + 0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC, \ + 0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B, \ + 0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38, \ + 0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07, \ + 0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE, \ + 0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C, \ + 0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70, \ + 0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44, \ + 0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3, \ + 0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF, \ + 0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E, \ + 0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D, \ + 0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA, \ + 0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E, \ + 0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF, \ + 0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C, \ + 0x25, 0xE4, 0x1D, 0x2B, 0x66, 0x9E, 0x1E, 0xF1, \ + 0x6E, 0x6F, 0x52, 0xC3, 0x16, 0x4D, 0xF4, 0xFB, \ + 0x79, 0x30, 0xE9, 0xE4, 0xE5, 0x88, 0x57, 0xB6, \ + 0xAC, 0x7D, 0x5F, 0x42, 0xD6, 0x9F, 0x6D, 0x18, \ + 0x77, 0x63, 0xCF, 0x1D, 0x55, 0x03, 0x40, 0x04, \ + 0x87, 0xF5, 0x5B, 0xA5, 0x7E, 0x31, 0xCC, 0x7A, \ + 0x71, 0x35, 0xC8, 0x86, 0xEF, 0xB4, 0x31, 0x8A, \ + 0xED, 0x6A, 0x1E, 0x01, 0x2D, 0x9E, 0x68, 0x32, \ + 0xA9, 0x07, 0x60, 0x0A, 0x91, 0x81, 0x30, 0xC4, \ + 0x6D, 0xC7, 0x78, 0xF9, 0x71, 0xAD, 0x00, 0x38, \ + 0x09, 0x29, 0x99, 0xA3, 0x33, 0xCB, 0x8B, 0x7A, \ + 0x1A, 0x1D, 0xB9, 0x3D, 0x71, 0x40, 0x00, 0x3C, \ + 0x2A, 0x4E, 0xCE, 0xA9, 0xF9, 0x8D, 0x0A, 0xCC, \ + 0x0A, 0x82, 0x91, 0xCD, 0xCE, 0xC9, 0x7D, 0xCF, \ + 0x8E, 0xC9, 0xB5, 0x5A, 0x7F, 0x88, 0xA4, 0x6B, \ + 0x4D, 0xB5, 0xA8, 0x51, 0xF4, 0x41, 0x82, 0xE1, \ + 0xC6, 0x8A, 0x00, 0x7E, 0x5E, 0x0D, 0xD9, 0x02, \ + 0x0B, 0xFD, 0x64, 0xB6, 0x45, 0x03, 0x6C, 0x7A, \ + 0x4E, 0x67, 0x7D, 0x2C, 0x38, 0x53, 0x2A, 0x3A, \ + 0x23, 0xBA, 0x44, 0x42, 0xCA, 0xF5, 0x3E, 0xA6, \ + 0x3B, 0xB4, 0x54, 0x32, 0x9B, 0x76, 0x24, 0xC8, \ + 0x91, 0x7B, 0xDD, 0x64, 0xB1, 0xC0, 0xFD, 0x4C, \ + 0xB3, 0x8E, 0x8C, 0x33, 0x4C, 0x70, 0x1C, 0x3A, \ + 0xCD, 0xAD, 0x06, 0x57, 0xFC, 0xCF, 0xEC, 0x71, \ + 0x9B, 0x1F, 0x5C, 0x3E, 0x4E, 0x46, 0x04, 0x1F, \ + 0x38, 0x81, 0x47, 0xFB, 0x4C, 0xFD, 0xB4, 0x77, \ + 0xA5, 0x24, 0x71, 0xF7, 0xA9, 0xA9, 0x69, 0x10, \ + 0xB8, 0x55, 0x32, 0x2E, 0xDB, 0x63, 0x40, 0xD8, \ + 0xA0, 0x0E, 0xF0, 0x92, 0x35, 0x05, 0x11, 0xE3, \ + 0x0A, 0xBE, 0xC1, 0xFF, 0xF9, 0xE3, 0xA2, 0x6E, \ + 0x7F, 0xB2, 0x9F, 0x8C, 0x18, 0x30, 0x23, 0xC3, \ + 0x58, 0x7E, 0x38, 0xDA, 0x00, 0x77, 0xD9, 0xB4, \ + 0x76, 0x3E, 0x4E, 0x4B, 0x94, 0xB2, 0xBB, 0xC1, \ + 0x94, 0xC6, 0x65, 0x1E, 0x77, 0xCA, 0xF9, 0x92, \ + 0xEE, 0xAA, 0xC0, 0x23, 0x2A, 0x28, 0x1B, 0xF6, \ + 0xB3, 0xA7, 0x39, 0xC1, 0x22, 0x61, 0x16, 0x82, \ + 0x0A, 0xE8, 0xDB, 0x58, 0x47, 0xA6, 0x7C, 0xBE, \ + 0xF9, 0xC9, 0x09, 0x1B, 0x46, 0x2D, 0x53, 0x8C, \ + 0xD7, 0x2B, 0x03, 0x74, 0x6A, 0xE7, 0x7F, 0x5E, \ + 0x62, 0x29, 0x2C, 0x31, 0x15, 0x62, 0xA8, 0x46, \ + 0x50, 0x5D, 0xC8, 0x2D, 0xB8, 0x54, 0x33, 0x8A, \ + 0xE4, 0x9F, 0x52, 0x35, 0xC9, 0x5B, 0x91, 0x17, \ + 0x8C, 0xCF, 0x2D, 0xD5, 0xCA, 0xCE, 0xF4, 0x03, \ + 0xEC, 0x9D, 0x18, 0x10, 0xC6, 0x27, 0x2B, 0x04, \ + 0x5B, 0x3B, 0x71, 0xF9, 0xDC, 0x6B, 0x80, 0xD6, \ + 0x3F, 0xDD, 0x4A, 0x8E, 0x9A, 0xDB, 0x1E, 0x69, \ + 0x62, 0xA6, 0x95, 0x26, 0xD4, 0x31, 0x61, 0xC1, \ + 0xA4, 0x1D, 0x57, 0x0D, 0x79, 0x38, 0xDA, 0xD4, \ + 0xA4, 0x0E, 0x32, 0x9C, 0xD0, 0xE4, 0x0E, 0x65, \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } + +#define MBEDTLS_DHM_RFC7919_FFDHE6144_G_BIN { 0x02 } + +#define MBEDTLS_DHM_RFC7919_FFDHE8192_P_BIN { \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ + 0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, \ + 0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, \ + 0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, \ + 0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, \ + 0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, \ + 0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, \ + 0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, \ + 0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, \ + 0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, \ + 0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, \ + 0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, \ + 0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, \ + 0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, \ + 0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, \ + 0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, \ + 0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, \ + 0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, \ + 0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, \ + 0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, \ + 0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, \ + 0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, \ + 0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, \ + 0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, \ + 0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, \ + 0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, \ + 0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, \ + 0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, \ + 0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, \ + 0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, \ + 0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC, \ + 0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B, \ + 0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38, \ + 0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07, \ + 0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE, \ + 0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C, \ + 0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70, \ + 0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44, \ + 0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3, \ + 0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF, \ + 0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E, \ + 0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D, \ + 0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA, \ + 0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E, \ + 0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF, \ + 0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C, \ + 0x25, 0xE4, 0x1D, 0x2B, 0x66, 0x9E, 0x1E, 0xF1, \ + 0x6E, 0x6F, 0x52, 0xC3, 0x16, 0x4D, 0xF4, 0xFB, \ + 0x79, 0x30, 0xE9, 0xE4, 0xE5, 0x88, 0x57, 0xB6, \ + 0xAC, 0x7D, 0x5F, 0x42, 0xD6, 0x9F, 0x6D, 0x18, \ + 0x77, 0x63, 0xCF, 0x1D, 0x55, 0x03, 0x40, 0x04, \ + 0x87, 0xF5, 0x5B, 0xA5, 0x7E, 0x31, 0xCC, 0x7A, \ + 0x71, 0x35, 0xC8, 0x86, 0xEF, 0xB4, 0x31, 0x8A, \ + 0xED, 0x6A, 0x1E, 0x01, 0x2D, 0x9E, 0x68, 0x32, \ + 0xA9, 0x07, 0x60, 0x0A, 0x91, 0x81, 0x30, 0xC4, \ + 0x6D, 0xC7, 0x78, 0xF9, 0x71, 0xAD, 0x00, 0x38, \ + 0x09, 0x29, 0x99, 0xA3, 0x33, 0xCB, 0x8B, 0x7A, \ + 0x1A, 0x1D, 0xB9, 0x3D, 0x71, 0x40, 0x00, 0x3C, \ + 0x2A, 0x4E, 0xCE, 0xA9, 0xF9, 0x8D, 0x0A, 0xCC, \ + 0x0A, 0x82, 0x91, 0xCD, 0xCE, 0xC9, 0x7D, 0xCF, \ + 0x8E, 0xC9, 0xB5, 0x5A, 0x7F, 0x88, 0xA4, 0x6B, \ + 0x4D, 0xB5, 0xA8, 0x51, 0xF4, 0x41, 0x82, 0xE1, \ + 0xC6, 0x8A, 0x00, 0x7E, 0x5E, 0x0D, 0xD9, 0x02, \ + 0x0B, 0xFD, 0x64, 0xB6, 0x45, 0x03, 0x6C, 0x7A, \ + 0x4E, 0x67, 0x7D, 0x2C, 0x38, 0x53, 0x2A, 0x3A, \ + 0x23, 0xBA, 0x44, 0x42, 0xCA, 0xF5, 0x3E, 0xA6, \ + 0x3B, 0xB4, 0x54, 0x32, 0x9B, 0x76, 0x24, 0xC8, \ + 0x91, 0x7B, 0xDD, 0x64, 0xB1, 0xC0, 0xFD, 0x4C, \ + 0xB3, 0x8E, 0x8C, 0x33, 0x4C, 0x70, 0x1C, 0x3A, \ + 0xCD, 0xAD, 0x06, 0x57, 0xFC, 0xCF, 0xEC, 0x71, \ + 0x9B, 0x1F, 0x5C, 0x3E, 0x4E, 0x46, 0x04, 0x1F, \ + 0x38, 0x81, 0x47, 0xFB, 0x4C, 0xFD, 0xB4, 0x77, \ + 0xA5, 0x24, 0x71, 0xF7, 0xA9, 0xA9, 0x69, 0x10, \ + 0xB8, 0x55, 0x32, 0x2E, 0xDB, 0x63, 0x40, 0xD8, \ + 0xA0, 0x0E, 0xF0, 0x92, 0x35, 0x05, 0x11, 0xE3, \ + 0x0A, 0xBE, 0xC1, 0xFF, 0xF9, 0xE3, 0xA2, 0x6E, \ + 0x7F, 0xB2, 0x9F, 0x8C, 0x18, 0x30, 0x23, 0xC3, \ + 0x58, 0x7E, 0x38, 0xDA, 0x00, 0x77, 0xD9, 0xB4, \ + 0x76, 0x3E, 0x4E, 0x4B, 0x94, 0xB2, 0xBB, 0xC1, \ + 0x94, 0xC6, 0x65, 0x1E, 0x77, 0xCA, 0xF9, 0x92, \ + 0xEE, 0xAA, 0xC0, 0x23, 0x2A, 0x28, 0x1B, 0xF6, \ + 0xB3, 0xA7, 0x39, 0xC1, 0x22, 0x61, 0x16, 0x82, \ + 0x0A, 0xE8, 0xDB, 0x58, 0x47, 0xA6, 0x7C, 0xBE, \ + 0xF9, 0xC9, 0x09, 0x1B, 0x46, 0x2D, 0x53, 0x8C, \ + 0xD7, 0x2B, 0x03, 0x74, 0x6A, 0xE7, 0x7F, 0x5E, \ + 0x62, 0x29, 0x2C, 0x31, 0x15, 0x62, 0xA8, 0x46, \ + 0x50, 0x5D, 0xC8, 0x2D, 0xB8, 0x54, 0x33, 0x8A, \ + 0xE4, 0x9F, 0x52, 0x35, 0xC9, 0x5B, 0x91, 0x17, \ + 0x8C, 0xCF, 0x2D, 0xD5, 0xCA, 0xCE, 0xF4, 0x03, \ + 0xEC, 0x9D, 0x18, 0x10, 0xC6, 0x27, 0x2B, 0x04, \ + 0x5B, 0x3B, 0x71, 0xF9, 0xDC, 0x6B, 0x80, 0xD6, \ + 0x3F, 0xDD, 0x4A, 0x8E, 0x9A, 0xDB, 0x1E, 0x69, \ + 0x62, 0xA6, 0x95, 0x26, 0xD4, 0x31, 0x61, 0xC1, \ + 0xA4, 0x1D, 0x57, 0x0D, 0x79, 0x38, 0xDA, 0xD4, \ + 0xA4, 0x0E, 0x32, 0x9C, 0xCF, 0xF4, 0x6A, 0xAA, \ + 0x36, 0xAD, 0x00, 0x4C, 0xF6, 0x00, 0xC8, 0x38, \ + 0x1E, 0x42, 0x5A, 0x31, 0xD9, 0x51, 0xAE, 0x64, \ + 0xFD, 0xB2, 0x3F, 0xCE, 0xC9, 0x50, 0x9D, 0x43, \ + 0x68, 0x7F, 0xEB, 0x69, 0xED, 0xD1, 0xCC, 0x5E, \ + 0x0B, 0x8C, 0xC3, 0xBD, 0xF6, 0x4B, 0x10, 0xEF, \ + 0x86, 0xB6, 0x31, 0x42, 0xA3, 0xAB, 0x88, 0x29, \ + 0x55, 0x5B, 0x2F, 0x74, 0x7C, 0x93, 0x26, 0x65, \ + 0xCB, 0x2C, 0x0F, 0x1C, 0xC0, 0x1B, 0xD7, 0x02, \ + 0x29, 0x38, 0x88, 0x39, 0xD2, 0xAF, 0x05, 0xE4, \ + 0x54, 0x50, 0x4A, 0xC7, 0x8B, 0x75, 0x82, 0x82, \ + 0x28, 0x46, 0xC0, 0xBA, 0x35, 0xC3, 0x5F, 0x5C, \ + 0x59, 0x16, 0x0C, 0xC0, 0x46, 0xFD, 0x82, 0x51, \ + 0x54, 0x1F, 0xC6, 0x8C, 0x9C, 0x86, 0xB0, 0x22, \ + 0xBB, 0x70, 0x99, 0x87, 0x6A, 0x46, 0x0E, 0x74, \ + 0x51, 0xA8, 0xA9, 0x31, 0x09, 0x70, 0x3F, 0xEE, \ + 0x1C, 0x21, 0x7E, 0x6C, 0x38, 0x26, 0xE5, 0x2C, \ + 0x51, 0xAA, 0x69, 0x1E, 0x0E, 0x42, 0x3C, 0xFC, \ + 0x99, 0xE9, 0xE3, 0x16, 0x50, 0xC1, 0x21, 0x7B, \ + 0x62, 0x48, 0x16, 0xCD, 0xAD, 0x9A, 0x95, 0xF9, \ + 0xD5, 0xB8, 0x01, 0x94, 0x88, 0xD9, 0xC0, 0xA0, \ + 0xA1, 0xFE, 0x30, 0x75, 0xA5, 0x77, 0xE2, 0x31, \ + 0x83, 0xF8, 0x1D, 0x4A, 0x3F, 0x2F, 0xA4, 0x57, \ + 0x1E, 0xFC, 0x8C, 0xE0, 0xBA, 0x8A, 0x4F, 0xE8, \ + 0xB6, 0x85, 0x5D, 0xFE, 0x72, 0xB0, 0xA6, 0x6E, \ + 0xDE, 0xD2, 0xFB, 0xAB, 0xFB, 0xE5, 0x8A, 0x30, \ + 0xFA, 0xFA, 0xBE, 0x1C, 0x5D, 0x71, 0xA8, 0x7E, \ + 0x2F, 0x74, 0x1E, 0xF8, 0xC1, 0xFE, 0x86, 0xFE, \ + 0xA6, 0xBB, 0xFD, 0xE5, 0x30, 0x67, 0x7F, 0x0D, \ + 0x97, 0xD1, 0x1D, 0x49, 0xF7, 0xA8, 0x44, 0x3D, \ + 0x08, 0x22, 0xE5, 0x06, 0xA9, 0xF4, 0x61, 0x4E, \ + 0x01, 0x1E, 0x2A, 0x94, 0x83, 0x8F, 0xF8, 0x8C, \ + 0xD6, 0x8C, 0x8B, 0xB7, 0xC5, 0xC6, 0x42, 0x4C, \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } + +#define MBEDTLS_DHM_RFC7919_FFDHE8192_G_BIN { 0x02 } + +#endif /* dhm.h */ diff --git a/port/mbedtls/removed/mbedtls/ecdh.h b/port/mbedtls/removed/mbedtls/ecdh.h new file mode 100644 index 0000000000..5f448826a3 --- /dev/null +++ b/port/mbedtls/removed/mbedtls/ecdh.h @@ -0,0 +1,500 @@ +/** + * \file ecdh.h + * + * \brief This file contains ECDH definitions and functions. + * + * The Elliptic Curve Diffie-Hellman (ECDH) protocol is an anonymous + * key agreement protocol allowing two parties to establish a shared + * secret over an insecure channel. Each party must have an + * elliptic-curve public–private key pair. + * + * For more information, see NIST SP 800-56A Rev. 2: Recommendation for + * Pair-Wise Key Establishment Schemes Using Discrete Logarithm + * Cryptography. + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#ifndef TF_PSA_CRYPTO_MBEDTLS_PRIVATE_ECDH_H +#define TF_PSA_CRYPTO_MBEDTLS_PRIVATE_ECDH_H +#include "mbedtls/private_access.h" + +#include "tf-psa-crypto/build_info.h" + +#include "mbedtls/private/ecp.h" + +/* + * Mbed TLS supports two formats for ECDH contexts (#mbedtls_ecdh_context + * defined in `ecdh.h`). For most applications, the choice of format makes + * no difference, since all library functions can work with either format, + * except that the new format is incompatible with MBEDTLS_ECP_RESTARTABLE. + + * The new format used when this option is disabled is smaller + * (56 bytes on a 32-bit platform). In future versions of the library, it + * will support alternative implementations of ECDH operations. + * The new format is incompatible with applications that access + * context fields directly and with restartable ECP operations. + */ + +#if defined(MBEDTLS_ECP_RESTARTABLE) +#define MBEDTLS_ECDH_LEGACY_CONTEXT +#else +#undef MBEDTLS_ECDH_LEGACY_CONTEXT +#endif + +#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) +#undef MBEDTLS_ECDH_LEGACY_CONTEXT +#include "tf-psa-crypto/private/everest/x25519.h" +#include "tf-psa-crypto/private/everest/everest.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS) +/** + * Defines the source of the imported EC key. + */ +typedef enum { + MBEDTLS_ECDH_OURS, /**< Our key. */ + MBEDTLS_ECDH_THEIRS, /**< The key of the peer. */ +} mbedtls_ecdh_side; +#endif /* MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS */ + +#if !defined(MBEDTLS_ECDH_LEGACY_CONTEXT) +/** + * Defines the ECDH implementation used. + * + * Later versions of the library may add new variants, therefore users should + * not make any assumptions about them. + */ +typedef enum { + MBEDTLS_ECDH_VARIANT_NONE = 0, /*!< Implementation not defined. */ + MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0,/*!< The default Mbed TLS implementation */ +#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) + MBEDTLS_ECDH_VARIANT_EVEREST /*!< Everest implementation */ +#endif +} mbedtls_ecdh_variant; + +/** + * The context used by the default ECDH implementation. + * + * Later versions might change the structure of this context, therefore users + * should not make any assumptions about the structure of + * mbedtls_ecdh_context_mbed. + */ +typedef struct mbedtls_ecdh_context_mbed { + mbedtls_ecp_group MBEDTLS_PRIVATE(grp); /*!< The elliptic curve used. */ + mbedtls_mpi MBEDTLS_PRIVATE(d); /*!< The private key. */ + mbedtls_ecp_point MBEDTLS_PRIVATE(Q); /*!< The public key. */ + mbedtls_ecp_point MBEDTLS_PRIVATE(Qp); /*!< The value of the public key of the peer. */ + mbedtls_mpi MBEDTLS_PRIVATE(z); /*!< The shared secret. */ +#if defined(MBEDTLS_ECP_RESTARTABLE) + mbedtls_ecp_restart_ctx MBEDTLS_PRIVATE(rs); /*!< The restart context for EC computations. */ +#endif +} mbedtls_ecdh_context_mbed; +#endif + +#if defined(MBEDTLS_ECP_RESTARTABLE) +#define MBEDTLS_ECDH_CONTEXT_MBED_INIT { MBEDTLS_ECP_GROUP_INIT, MBEDTLS_MPI_INIT, \ + MBEDTLS_ECP_POINT_INIT, \ + MBEDTLS_ECP_POINT_INIT, MBEDTLS_MPI_INIT, \ + MBEDTLS_ECP_RESTART_INIT } +#else +#define MBEDTLS_ECDH_CONTEXT_MBED_INIT { MBEDTLS_ECP_GROUP_INIT, MBEDTLS_MPI_INIT, \ + MBEDTLS_ECP_POINT_INIT, \ + MBEDTLS_ECP_POINT_INIT, MBEDTLS_MPI_INIT } +#endif + +/** + * + * \warning Performing multiple operations concurrently on the same + * ECDSA context is not supported; objects of this type + * should not be shared between multiple threads. + * \brief The ECDH context structure. + */ +typedef struct mbedtls_ecdh_context { +#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) + mbedtls_ecp_group MBEDTLS_PRIVATE(grp); /*!< The elliptic curve used. */ + mbedtls_mpi MBEDTLS_PRIVATE(d); /*!< The private key. */ + mbedtls_ecp_point MBEDTLS_PRIVATE(Q); /*!< The public key. */ + mbedtls_ecp_point MBEDTLS_PRIVATE(Qp); /*!< The value of the public key of the peer. */ + mbedtls_mpi MBEDTLS_PRIVATE(z); /*!< The shared secret. */ + int MBEDTLS_PRIVATE(point_format); /*!< The format of point export in TLS messages. */ + mbedtls_ecp_point MBEDTLS_PRIVATE(Vi); /*!< The blinding value. */ + mbedtls_ecp_point MBEDTLS_PRIVATE(Vf); /*!< The unblinding value. */ + mbedtls_mpi MBEDTLS_PRIVATE(_d); /*!< The previous \p d. */ +#if defined(MBEDTLS_ECP_RESTARTABLE) + int MBEDTLS_PRIVATE(restart_enabled); /*!< The flag for restartable mode. */ + mbedtls_ecp_restart_ctx MBEDTLS_PRIVATE(rs); /*!< The restart context for EC computations. */ +#endif /* MBEDTLS_ECP_RESTARTABLE */ +#else + uint8_t MBEDTLS_PRIVATE(point_format); /*!< The format of point export in TLS messages + as defined in RFC 4492. */ + mbedtls_ecp_group_id MBEDTLS_PRIVATE(grp_id);/*!< The elliptic curve used. */ + mbedtls_ecdh_variant MBEDTLS_PRIVATE(var); /*!< The ECDH implementation/structure used. */ + union { + mbedtls_ecdh_context_mbed MBEDTLS_PRIVATE(mbed_ecdh); +#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) + mbedtls_ecdh_context_everest MBEDTLS_PRIVATE(everest_ecdh); +#endif + } MBEDTLS_PRIVATE(ctx); /*!< Implementation-specific context. The + context in use is specified by the \c var + field. */ +#if defined(MBEDTLS_ECP_RESTARTABLE) + uint8_t MBEDTLS_PRIVATE(restart_enabled); /*!< The flag for restartable mode. Functions of + an alternative implementation not supporting + restartable mode must return + MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED error + if this flag is set. */ +#endif /* MBEDTLS_ECP_RESTARTABLE */ +#endif /* MBEDTLS_ECDH_LEGACY_CONTEXT */ +} +mbedtls_ecdh_context; + +#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) +#if defined(MBEDTLS_ECP_RESTARTABLE) +#define MBEDTLS_ECDH_CONTEXT_INIT { MBEDTLS_ECP_GROUP_INIT, MBEDTLS_MPI_INIT, \ + MBEDTLS_ECP_POINT_INIT, \ + MBEDTLS_ECP_POINT_INIT, MBEDTLS_MPI_INIT, \ + MBEDTLS_ECP_PF_UNCOMPRESSED, \ + MBEDTLS_ECP_POINT_INIT, MBEDTLS_ECP_POINT_INIT, \ + MBEDTLS_MPI_INIT, 0, \ + MBEDTLS_ECP_RESTART_INIT } +#else +#define MBEDTLS_ECDH_CONTEXT_INIT { MBEDTLS_ECP_GROUP_INIT, MBEDTLS_MPI_INIT, \ + MBEDTLS_ECP_POINT_INIT, \ + MBEDTLS_ECP_POINT_INIT, MBEDTLS_MPI_INIT, \ + MBEDTLS_ECP_PF_UNCOMPRESSED, \ + MBEDTLS_ECP_POINT_INIT, MBEDTLS_ECP_POINT_INIT, \ + MBEDTLS_MPI_INIT } +#endif /* MBEDTLS_ECP_RESTARTABLE */ +#else +#if defined(MBEDTLS_ECP_RESTARTABLE) +#define MBEDTLS_ECDH_CONTEXT_INIT { MBEDTLS_ECP_PF_UNCOMPRESSED, MBEDTLS_ECP_DP_NONE, \ + MBEDTLS_ECDH_VARIANT_NONE, \ + { MBEDTLS_ECDH_CONTEXT_MBED_INIT }, 0 } +#else +#define MBEDTLS_ECDH_CONTEXT_INIT { MBEDTLS_ECP_PF_UNCOMPRESSED, MBEDTLS_ECP_DP_NONE, \ + MBEDTLS_ECDH_VARIANT_NONE, \ + { MBEDTLS_ECDH_CONTEXT_MBED_INIT } } +#endif /* MBEDTLS_ECP_RESTARTABLE */ +#endif /* MBEDTLS_ECDH_LEGACY_CONTEXT */ + +#if defined(MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS) +/** + * \brief Return the ECP group for provided context. + * + * \note To access group specific fields, users should use + * `mbedtls_ecp_curve_info_from_grp_id` or + * `mbedtls_ecp_group_load` on the extracted `group_id`. + * + * \param ctx The ECDH context to parse. This must not be \c NULL. + * + * \return The \c mbedtls_ecp_group_id of the context. + */ +mbedtls_ecp_group_id mbedtls_ecdh_get_grp_id(mbedtls_ecdh_context *ctx); + +/** + * \brief Check whether a given group can be used for ECDH. + * + * \param gid The ECP group ID to check. + * + * \return \c 1 if the group can be used, \c 0 otherwise + */ +int mbedtls_ecdh_can_do(mbedtls_ecp_group_id gid); + +/** + * \brief This function generates an ECDH keypair on an elliptic + * curve. + * + * This function performs the first of two core computations + * implemented during the ECDH key exchange. The second core + * computation is performed by mbedtls_ecdh_compute_shared(). + * + * \see ecp.h + * + * \param grp The ECP group to use. This must be initialized and have + * domain parameters loaded, for example through + * mbedtls_ecp_load() or mbedtls_ecp_tls_read_group(). + * \param d The destination MPI (private key). + * This must be initialized. + * \param Q The destination point (public key). + * This must be initialized. + * \param f_rng The RNG function to use. This must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may be + * \c NULL in case \p f_rng doesn't need a context argument. + * + * \return \c 0 on success. + * \return Another \c MBEDTLS_ERR_ECP_XXX or + * \c MBEDTLS_MPI_XXX error code on failure. + */ +int mbedtls_ecdh_gen_public(mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng); + +/** + * \brief This function computes the shared secret. + * + * This function performs the second of two core computations + * implemented during the ECDH key exchange. The first core + * computation is performed by mbedtls_ecdh_gen_public(). + * + * \see ecp.h + * + * \note If \p f_rng is not NULL, it is used to implement + * countermeasures against side-channel attacks. + * For more information, see mbedtls_ecp_mul(). + * + * \param grp The ECP group to use. This must be initialized and have + * domain parameters loaded, for example through + * mbedtls_ecp_load() or mbedtls_ecp_tls_read_group(). + * \param z The destination MPI (shared secret). + * This must be initialized. + * \param Q The public key from another party. + * This must be initialized. + * \param d Our secret exponent (private key). + * This must be initialized. + * \param f_rng The RNG function to use. This must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may be + * \c NULL if \p f_rng is \c NULL or doesn't need a + * context argument. + * + * \return \c 0 on success. + * \return Another \c MBEDTLS_ERR_ECP_XXX or + * \c MBEDTLS_MPI_XXX error code on failure. + */ +int mbedtls_ecdh_compute_shared(mbedtls_ecp_group *grp, mbedtls_mpi *z, + const mbedtls_ecp_point *Q, const mbedtls_mpi *d, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng); + +/** + * \brief This function initializes an ECDH context. + * + * \param ctx The ECDH context to initialize. This must not be \c NULL. + */ +void mbedtls_ecdh_init(mbedtls_ecdh_context *ctx); + +/** + * \brief This function sets up the ECDH context with the information + * given. + * + * This function should be called after mbedtls_ecdh_init() but + * before mbedtls_ecdh_make_params(). There is no need to call + * this function before mbedtls_ecdh_read_params(). + * + * This is the first function used by a TLS server for ECDHE + * ciphersuites. + * + * \param ctx The ECDH context to set up. This must be initialized. + * \param grp_id The group id of the group to set up the context for. + * + * \return \c 0 on success. + */ +int mbedtls_ecdh_setup(mbedtls_ecdh_context *ctx, + mbedtls_ecp_group_id grp_id); + +/** + * \brief This function frees a context. + * + * \param ctx The context to free. This may be \c NULL, in which + * case this function does nothing. If it is not \c NULL, + * it must point to an initialized ECDH context. + */ +void mbedtls_ecdh_free(mbedtls_ecdh_context *ctx); + +/** + * \brief This function generates an EC key pair and exports its + * in the format used in a TLS ServerKeyExchange handshake + * message. + * + * This is the second function used by a TLS server for ECDHE + * ciphersuites. (It is called after mbedtls_ecdh_setup().) + * + * \see ecp.h + * + * \param ctx The ECDH context to use. This must be initialized + * and bound to a group, for example via mbedtls_ecdh_setup(). + * \param olen The address at which to store the number of Bytes written. + * \param buf The destination buffer. This must be a writable buffer of + * length \p blen Bytes. + * \param blen The length of the destination buffer \p buf in Bytes. + * \param f_rng The RNG function to use. This must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may be + * \c NULL in case \p f_rng doesn't need a context argument. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of + * operations was reached: see \c mbedtls_ecp_set_max_ops(). + * \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure. + */ +int mbedtls_ecdh_make_params(mbedtls_ecdh_context *ctx, size_t *olen, + unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng); + +/** + * \brief This function parses the ECDHE parameters in a + * TLS ServerKeyExchange handshake message. + * + * \note In a TLS handshake, this is the how the client + * sets up its ECDHE context from the server's public + * ECDHE key material. + * + * \see ecp.h + * + * \param ctx The ECDHE context to use. This must be initialized. + * \param buf On input, \c *buf must be the start of the input buffer. + * On output, \c *buf is updated to point to the end of the + * data that has been read. On success, this is the first byte + * past the end of the ServerKeyExchange parameters. + * On error, this is the point at which an error has been + * detected, which is usually not useful except to debug + * failures. + * \param end The end of the input buffer. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_ECP_XXX error code on failure. + * + */ +int mbedtls_ecdh_read_params(mbedtls_ecdh_context *ctx, + const unsigned char **buf, + const unsigned char *end); + +/** + * \brief This function sets up an ECDH context from an EC key. + * + * It is used by clients and servers in place of the + * ServerKeyExchange for static ECDH, and imports ECDH + * parameters from the EC key information of a certificate. + * + * \see ecp.h + * + * \param ctx The ECDH context to set up. This must be initialized. + * \param key The EC key to use. This must be initialized. + * \param side Defines the source of the key. Possible values are: + * - #MBEDTLS_ECDH_OURS: The key is ours. + * - #MBEDTLS_ECDH_THEIRS: The key is that of the peer. + * + * \return \c 0 on success. + * \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure. + * + */ +int mbedtls_ecdh_get_params(mbedtls_ecdh_context *ctx, + const mbedtls_ecp_keypair *key, + mbedtls_ecdh_side side); + +/** + * \brief This function generates a public key and exports it + * as a TLS ClientKeyExchange payload. + * + * This is the second function used by a TLS client for ECDH(E) + * ciphersuites. + * + * \see ecp.h + * + * \param ctx The ECDH context to use. This must be initialized + * and bound to a group, the latter usually by + * mbedtls_ecdh_read_params(). + * \param olen The address at which to store the number of Bytes written. + * This must not be \c NULL. + * \param buf The destination buffer. This must be a writable buffer + * of length \p blen Bytes. + * \param blen The size of the destination buffer \p buf in Bytes. + * \param f_rng The RNG function to use. This must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may be + * \c NULL in case \p f_rng doesn't need a context argument. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of + * operations was reached: see \c mbedtls_ecp_set_max_ops(). + * \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure. + */ +int mbedtls_ecdh_make_public(mbedtls_ecdh_context *ctx, size_t *olen, + unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng); + +/** + * \brief This function parses and processes the ECDHE payload of a + * TLS ClientKeyExchange message. + * + * This is the third function used by a TLS server for ECDH(E) + * ciphersuites. (It is called after mbedtls_ecdh_setup() and + * mbedtls_ecdh_make_params().) + * + * \see ecp.h + * + * \param ctx The ECDH context to use. This must be initialized + * and bound to a group, for example via mbedtls_ecdh_setup(). + * \param buf The pointer to the ClientKeyExchange payload. This must + * be a readable buffer of length \p blen Bytes. + * \param blen The length of the input buffer \p buf in Bytes. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_ECP_XXX error code on failure. + */ +int mbedtls_ecdh_read_public(mbedtls_ecdh_context *ctx, + const unsigned char *buf, size_t blen); + +/** + * \brief This function derives and exports the shared secret. + * + * This is the last function used by both TLS client + * and servers. + * + * \note If \p f_rng is not NULL, it is used to implement + * countermeasures against side-channel attacks. + * For more information, see mbedtls_ecp_mul(). + * + * \see ecp.h + + * \param ctx The ECDH context to use. This must be initialized + * and have its own private key generated and the peer's + * public key imported. + * \param olen The address at which to store the total number of + * Bytes written on success. This must not be \c NULL. + * \param buf The buffer to write the generated shared key to. This + * must be a writable buffer of size \p blen Bytes. + * \param blen The length of the destination buffer \p buf in Bytes. + * \param f_rng The RNG function to use. This must not be \c NULL. + * \param p_rng The RNG context. This may be \c NULL if \p f_rng + * doesn't need a context argument. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of + * operations was reached: see \c mbedtls_ecp_set_max_ops(). + * \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure. + */ +int mbedtls_ecdh_calc_secret(mbedtls_ecdh_context *ctx, size_t *olen, + unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng); + +#if defined(MBEDTLS_ECP_RESTARTABLE) +/** + * \brief This function enables restartable EC computations for this + * context. (Default: disabled.) + * + * \see \c mbedtls_ecp_set_max_ops() + * + * \note It is not possible to safely disable restartable + * computations once enabled, except by free-ing the context, + * which cancels possible in-progress operations. + * + * \param ctx The ECDH context to use. This must be initialized. + */ +void mbedtls_ecdh_enable_restart(mbedtls_ecdh_context *ctx); +#endif /* MBEDTLS_ECP_RESTARTABLE */ + +#endif /* MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS */ + +#ifdef __cplusplus +} +#endif + +#endif /* TF_PSA_CRYPTO_MBEDTLS_PRIVATE_ECDH_H */ diff --git a/src/crypto/crypto_mbedtls_alt.c b/src/crypto/crypto_mbedtls_alt.c index 03a321dc07..8f048f3732 100644 --- a/src/crypto/crypto_mbedtls_alt.c +++ b/src/crypto/crypto_mbedtls_alt.c @@ -13,16 +13,11 @@ #include /* mbedtls_platform_zeroize() */ #include #include -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_MBEDTLS_PSA +#include + +#include +#include #include "supp_psa_api.h" -#endif #ifndef MBEDTLS_PRIVATE #define MBEDTLS_PRIVATE(x) x @@ -118,7 +113,7 @@ #endif /* dh5_init_fixed() */ #endif /* crypto_dh_*() */ -#if defined(MBEDTLS_ECDH_C) || defined(CONFIG_PSA_WANT_ALG_ECDH) +#if defined(CONFIG_PSA_WANT_ALG_ECDH) #define CRYPTO_MBEDTLS_CRYPTO_ECDH #endif /* crypto_ecdh_*() */ @@ -151,120 +146,33 @@ #endif /* crypto_rsa_*() */ - - -#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) -#include -/* Setting ctr_drbg_init_state to 1 to allow unload_crypto to run */ -static int ctr_drbg_init_state = 1; -int (*hostap_rng_fn)(void*, unsigned char*, size_t) = mbedtls_psa_get_random; -#else -#include -#include -static int ctr_drbg_init_state; -static mbedtls_ctr_drbg_context ctr_drbg; -static mbedtls_entropy_context entropy; -int(*hostap_rng_fn)(void*, unsigned char*, size_t) = mbedtls_ctr_drbg_random; -#endif - #ifdef CRYPTO_MBEDTLS_CRYPTO_BIGNUM #include static mbedtls_mpi mpi_sw_A; #endif -#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) -static int wm_wrap_entropy_poll(void *data, unsigned char *output, size_t len, size_t *olen) -{ - ((void)data); - os_get_random(output, len); - *olen = len; - return 0; -} - -__attribute_cold__ __attribute_noinline__ static mbedtls_ctr_drbg_context *ctr_drbg_init(void) -{ - const unsigned char *custom_name = (const unsigned char *)"WPA_SUPPLICANT/HOSTAPD"; - size_t custom_name_len = os_strlen((const char *)custom_name); - - mbedtls_ctr_drbg_init(&ctr_drbg); - mbedtls_entropy_init(&entropy); - - mbedtls_entropy_add_source(&entropy, wm_wrap_entropy_poll, NULL, ENTROPY_MIN_PLATFORM, - MBEDTLS_ENTROPY_SOURCE_STRONG); - - if (mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, custom_name, custom_name_len)) - { - wpa_printf(MSG_ERROR, "Init of random number generator failed"); - /* XXX: abort? */ - } - else - ctr_drbg_init_state = 1; - - return &ctr_drbg; -} -#endif - __attribute_cold__ void crypto_unload(void) { - if (ctr_drbg_init_state) - { -#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) - mbedtls_ctr_drbg_free(&ctr_drbg); - mbedtls_entropy_free(&entropy); -#endif -#ifdef CRYPTO_MBEDTLS_CRYPTO_BIGNUM - mbedtls_mpi_free(&mpi_sw_A); -#endif - ctr_drbg_init_state = 0; - } + /* Nothing to do */ } -#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) -/* init ctr_drbg on first use - * crypto_global_init() and crypto_global_deinit() are not available here - * (available only when CONFIG_TLS=internal, which is not CONFIG_TLS=mbedtls) */ -mbedtls_ctr_drbg_context *crypto_mbedtls_ctr_drbg(void); /*(not in header)*/ -inline mbedtls_ctr_drbg_context *crypto_mbedtls_ctr_drbg(void) +int hostap_rng_fn(void* ctx, unsigned char* buf, size_t buf_size) { - return ctr_drbg_init_state ? &ctr_drbg : ctr_drbg_init(); + if (psa_generate_random(buf, buf_size) != PSA_SUCCESS) { + return -1; + } + return 0; } -#endif void *hostap_rng_ctx(void) { -#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) - return MBEDTLS_PSA_RANDOM_STATE; -#else - return (mbedtls_ctr_drbg_context *) crypto_mbedtls_ctr_drbg(); -#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ + return NULL; } -/* tradeoff: slightly smaller code size here at cost of slight increase - * in instructions and function calls at runtime versus the expanded - * per-message-digest code that follows in #else (~0.5 kib .text larger) */ __attribute_noinline__ static int md_vector( size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac, mbedtls_md_type_t md_type) { -#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_MBEDTLS_PSA return md_vector_psa(num_elem, addr, len, mac, md_type); -#else - if (TEST_FAIL()) - return -1; - - mbedtls_md_context_t ctx; - mbedtls_md_init(&ctx); - if (mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(md_type), 0) != 0) - { - mbedtls_md_free(&ctx); - return -1; - } - mbedtls_md_starts(&ctx); - for (size_t i = 0; i < num_elem; ++i) - mbedtls_md_update(&ctx, addr[i], len[i]); - mbedtls_md_finish(&ctx, mac); - mbedtls_md_free(&ctx); - return 0; -#endif } int sha512_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) @@ -282,14 +190,14 @@ int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_SHA256); } -#if defined(MBEDTLS_SHA1_C) || defined(CONFIG_PSA_WANT_ALG_SHA_1) +#if defined(CONFIG_PSA_WANT_ALG_SHA_1) int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) { return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_SHA1); } #endif -#if defined(MBEDTLS_MD5_C) || defined(CONFIG_PSA_WANT_ALG_MD5) +#if defined(CONFIG_PSA_WANT_ALG_MD5) int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) { return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_MD5); @@ -350,7 +258,7 @@ struct crypto_hash *crypto_hash_init(enum crypto_hash_alg alg, const u8 *key, si os_free(ctx); return NULL; } - ret = mbedtls_md_setup(&ctx->ctx, md_info, 1); + ret = mbedtls_md_setup(&ctx->ctx, md_info, 0); if (ret != 0) { os_free(ctx); @@ -398,26 +306,7 @@ __attribute_noinline__ static int hmac_vector(const u8 *key, u8 *mac, mbedtls_md_type_t md_type) { -#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_MBEDTLS_PSA return hmac_vector_psa(key, key_len, num_elem, addr, len, mac, md_type); -#else - if (TEST_FAIL()) - return -1; - - mbedtls_md_context_t ctx; - mbedtls_md_init(&ctx); - if (mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(md_type), 1) != 0) - { - mbedtls_md_free(&ctx); - return -1; - } - mbedtls_md_hmac_starts(&ctx, key, key_len); - for (size_t i = 0; i < num_elem; ++i) - mbedtls_md_hmac_update(&ctx, addr[i], len[i]); - mbedtls_md_hmac_finish(&ctx, mac); - mbedtls_md_free(&ctx); - return 0; -#endif } int hmac_sha512_vector(const u8 *key, size_t key_len, size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) @@ -450,7 +339,7 @@ int hmac_sha256(const u8 *key, size_t key_len, const u8 *data, size_t data_len, return hmac_vector(key, key_len, 1, &data, &data_len, mac, MBEDTLS_MD_SHA256); } -#if defined(MBEDTLS_SHA1_C) || defined(CONFIG_PSA_WANT_ALG_SHA_1) +#if defined(CONFIG_PSA_WANT_ALG_SHA_1) int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) { return hmac_vector(key, key_len, num_elem, addr, len, mac, MBEDTLS_MD_SHA1); @@ -462,7 +351,7 @@ int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len, u8 } #endif -#if defined(MBEDTLS_MD5_C) || defined(CONFIG_PSA_WANT_ALG_MD5) +#if defined(CONFIG_PSA_WANT_ALG_MD5) int hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) { return hmac_vector(key, key_len, num_elem, addr, len, mac, MBEDTLS_MD_MD5); @@ -474,9 +363,22 @@ int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len, u8 } #endif -#ifdef MBEDTLS_HKDF_C -#include +#if defined(PSA_WANT_ALG_HKDF) +#include +/* Perform "_op_" PSA API call and check if it succeeded. If not return + * "_ret_fail_". + * Note that operations using "psa_status" can be specified as second argument + * like "do_something(psa_status)". +*/ +#define PSA_CHECK(_op_, _ret_fail_) \ + do { \ + psa_status_t psa_status; \ + psa_status = _op_; \ + if (psa_status != PSA_SUCCESS) { \ + return _ret_fail_; \ + } \ + } while(0) /* sha256-kdf.c sha384-kdf.c sha512-kdf.c */ /* HMAC-SHA256 KDF (RFC 5295) and HKDF-Expand(SHA256) (RFC 5869) */ @@ -495,8 +397,19 @@ __attribute_noinline__ static int hmac_kdf_expand(const u8 *prk, return -1; const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_type); - if (label == NULL) /* RFC 5869 HKDF-Expand when (label == NULL) */ - return mbedtls_hkdf_expand(md_info, prk, prk_len, info, info_len, okm, okm_len) ? -1 : 0; + /* RFC 5869 HKDF-Expand when (label == NULL) */ + if (label == NULL) { + psa_key_derivation_operation_t psa_op = PSA_KEY_DERIVATION_OPERATION_INIT; + psa_algorithm_t psa_hash_alg = mbedtls_md_psa_alg_from_type(md_type); + + PSA_CHECK(psa_key_derivation_setup(&psa_op, PSA_ALG_HKDF_EXPAND(psa_hash_alg)), -1); + PSA_CHECK(psa_key_derivation_input_bytes(&psa_op, PSA_KEY_DERIVATION_INPUT_SECRET, + prk, prk_len), -1); + PSA_CHECK(psa_key_derivation_input_bytes(&psa_op, PSA_KEY_DERIVATION_INPUT_INFO, + info, info_len), -1); + PSA_CHECK(psa_key_derivation_output_bytes(&psa_op, okm, okm_len), -1); + PSA_CHECK(psa_key_derivation_abort(&psa_op), -1); + } const size_t mac_len = mbedtls_md_get_size(md_info); /* okm_len must not exceed 255 times hash len (RFC 5869 Section 2.3) */ @@ -505,12 +418,17 @@ __attribute_noinline__ static int hmac_kdf_expand(const u8 *prk, mbedtls_md_context_t ctx; mbedtls_md_init(&ctx); - if (mbedtls_md_setup(&ctx, md_info, 1) != 0) - { + if (mbedtls_md_setup(&ctx, md_info, 0) != 0) { + return -1; + } + if (mbedtls_md_hmac_setup(&ctx, md_info) != 0) { + mbedtls_md_free(&ctx); + return -1; + } + if (mbedtls_md_hmac_starts(&ctx, prk, prk_len) != 0) { mbedtls_md_free(&ctx); return -1; } - mbedtls_md_hmac_starts(&ctx, prk, prk_len); u8 iter = 1; const u8 *addr[4] = {okm, (const u8 *)label, info, &iter}; @@ -558,88 +476,137 @@ int hmac_sha256_kdf( { return hmac_kdf_expand(secret, secret_len, label, seed, seed_len, out, outlen, MBEDTLS_MD_SHA256); } -#endif /* MBEDTLS_HKDF_C */ +#endif /* PSA_WANT_ALG_HKDF */ /* sha256-prf.c sha384-prf.c sha512-prf.c */ /* hmac_prf_bits - IEEE Std 802.11ac-2013, 11.6.1.7.2 Key derivation function */ -__attribute_noinline__ static int hmac_prf_bits(const u8 *key, +__attribute_noinline__ static int hmac_prf_bits(const uint8_t *key, size_t key_len, const char *label, - const u8 *data, + const uint8_t *data, size_t data_len, - u8 *buf, + uint8_t *buf, size_t buf_len_bits, - mbedtls_md_type_t md_type) -{ + psa_algorithm_t alg) +{ + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id = PSA_KEY_ID_NULL; + psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; + psa_algorithm_t hash_alg = PSA_ALG_HMAC_GET_HASH(alg); + size_t mac_len = PSA_HASH_LENGTH(hash_alg); + size_t buf_len = (buf_len_bits + 7) / 8; + u16 ctr; + u16 n_le = host_to_le16(buf_len_bits); + const u8 *const addr[] = {(u8 *)&ctr, (u8 *)label, data, (u8 *)&n_le}; + const size_t len[] = {2, os_strlen(label), data_len, 2}; + if (TEST_FAIL()) return -1; - mbedtls_md_context_t ctx; - mbedtls_md_init(&ctx); - const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_type); - if (mbedtls_md_setup(&ctx, md_info, 1) != 0) - { - mbedtls_md_free(&ctx); + /* Import HMAC key into PSA */ + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH); + psa_set_key_algorithm(&attributes, alg); + psa_set_key_type(&attributes, PSA_KEY_TYPE_HMAC); + psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE); + status = psa_import_key(&attributes, key, key_len, &key_id); + if (status != PSA_SUCCESS) { return -1; } - mbedtls_md_hmac_starts(&ctx, key, key_len); - u16 ctr, n_le = host_to_le16(buf_len_bits); - const u8 *const addr[] = {(u8 *)&ctr, (u8 *)label, data, (u8 *)&n_le}; - const size_t len[] = {2, os_strlen(label), data_len, 2}; - const size_t mac_len = mbedtls_md_get_size(md_info); - size_t buf_len = (buf_len_bits + 7) / 8; - for (ctr = 1; buf_len >= mac_len; buf_len -= mac_len, ++ctr) - { + /* Generate output in mac_len chunks */ + for (ctr = 1; buf_len >= mac_len; buf_len -= mac_len, ++ctr) { #if __BYTE_ORDER == __BIG_ENDIAN ctr = host_to_le16(ctr); #endif - for (size_t i = 0; i < ARRAY_SIZE(addr); ++i) - mbedtls_md_hmac_update(&ctx, addr[i], len[i]); - mbedtls_md_hmac_finish(&ctx, buf); - mbedtls_md_hmac_reset(&ctx); + status = psa_mac_sign_setup(&operation, key_id, alg); + if (status != PSA_SUCCESS) { + goto cleanup; + } + + /* Update MAC with all input chunks: counter || label || data || length */ + for (size_t i = 0; i < ARRAY_SIZE(addr); ++i) { + status = psa_mac_update(&operation, addr[i], len[i]); + if (status != PSA_SUCCESS) { + psa_mac_abort(&operation); + goto cleanup; + } + } + + /* Finalize MAC and write to output buffer */ + size_t mac_output_len; + status = psa_mac_sign_finish(&operation, buf, mac_len, &mac_output_len); + if (status != PSA_SUCCESS) { + psa_mac_abort(&operation); + goto cleanup; + } + buf += mac_len; #if __BYTE_ORDER == __BIG_ENDIAN ctr = le_to_host16(ctr); #endif } - if (buf_len) - { - u8 hash[MBEDTLS_MD_MAX_SIZE]; + /* Handle remaining bytes (less than one full MAC length) */ + if (buf_len) { + u8 hash[PSA_MAC_MAX_SIZE]; + size_t mac_output_len; + #if __BYTE_ORDER == __BIG_ENDIAN ctr = host_to_le16(ctr); #endif - for (size_t i = 0; i < ARRAY_SIZE(addr); ++i) - mbedtls_md_hmac_update(&ctx, addr[i], len[i]); - mbedtls_md_hmac_finish(&ctx, hash); + status = psa_mac_sign_setup(&operation, key_id, alg); + if (status != PSA_SUCCESS) { + goto cleanup; + } + + for (size_t i = 0; i < ARRAY_SIZE(addr); ++i) { + status = psa_mac_update(&operation, addr[i], len[i]); + if (status != PSA_SUCCESS) { + psa_mac_abort(&operation); + goto cleanup; + } + } + + status = psa_mac_sign_finish(&operation, hash, sizeof(hash), &mac_output_len); + if (status != PSA_SUCCESS) { + psa_mac_abort(&operation); + goto cleanup; + } + os_memcpy(buf, hash, buf_len); buf += buf_len; - forced_memzero(hash, mac_len); + forced_memzero(hash, mac_output_len); } - /* Mask out unused bits in last octet if it does not use all the bits */ - if ((buf_len_bits &= 0x7)) + /* Mask out unused bits in last octet if needed */ + if ((buf_len_bits &= 0x7)) { buf[-1] &= (u8)(0xff << (8 - buf_len_bits)); + } - mbedtls_md_free(&ctx); + psa_destroy_key(key_id); return 0; + +cleanup: + if (key_id != PSA_KEY_ID_NULL) { + psa_destroy_key(key_id); + } + return -1; } int sha512_prf( const u8 *key, size_t key_len, const char *label, const u8 *data, size_t data_len, u8 *buf, size_t buf_len) { - return hmac_prf_bits(key, key_len, label, data, data_len, buf, buf_len * 8, MBEDTLS_MD_SHA512); + return hmac_prf_bits(key, key_len, label, data, data_len, buf, buf_len * 8, PSA_ALG_HMAC(PSA_ALG_SHA_512)); } int sha384_prf( const u8 *key, size_t key_len, const char *label, const u8 *data, size_t data_len, u8 *buf, size_t buf_len) { - return hmac_prf_bits(key, key_len, label, data, data_len, buf, buf_len * 8, MBEDTLS_MD_SHA384); + return hmac_prf_bits(key, key_len, label, data, data_len, buf, buf_len * 8, PSA_ALG_HMAC(PSA_ALG_SHA_384)); } -#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_MBEDTLS_PSA /** * Based on Supplicant internal implementaion of SHA-256. This API * uses PSA APIs instead of Supplicant internal implementation or @@ -682,25 +649,20 @@ static int hmac_prf256(const u8 *key, return 0; } -#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_MBEDTLS_PSA */ int sha256_prf( const u8 *key, size_t key_len, const char *label, const u8 *data, size_t data_len, u8 *buf, size_t buf_len) { -#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_MBEDTLS_PSA return hmac_prf256(key, key_len, label, data, data_len, buf, buf_len * 8, MBEDTLS_MD_SHA256); -#else - return hmac_prf_bits(key, key_len, label, data, data_len, buf, buf_len * 8, MBEDTLS_MD_SHA256); -#endif } int sha256_prf_bits( const u8 *key, size_t key_len, const char *label, const u8 *data, size_t data_len, u8 *buf, size_t buf_len_bits) { - return hmac_prf_bits(key, key_len, label, data, data_len, buf, buf_len_bits, MBEDTLS_MD_SHA256); + return hmac_prf_bits(key, key_len, label, data, data_len, buf, buf_len_bits, PSA_ALG_HMAC(PSA_ALG_SHA_256)); } -#if defined(MBEDTLS_SHA1_C) || defined(CONFIG_PSA_WANT_ALG_SHA_1) +#if defined(CONFIG_PSA_WANT_ALG_SHA_1) /* sha1-prf.c */ @@ -773,9 +735,8 @@ int sha1_t_prf( } #endif /* CRYPTO_MBEDTLS_SHA1_T_PRF */ -#endif /* MBEDTLS_SHA1_C || CONFIG_PSA_WANT_ALG_SHA_1 */ +#endif /* CONFIG_PSA_WANT_ALG_SHA_1 */ -#ifdef MBEDTLS_DES_C #include int des_encrypt(const u8 *clear, const u8 *key, u8 *cypher) { @@ -798,23 +759,15 @@ int des_encrypt(const u8 *clear, const u8 *key, u8 *cypher) mbedtls_des_free(&des); return ret; } -#endif #ifdef CRYPTO_MBEDTLS_PBKDF2_SHA1 /* sha1-pbkdf2.c */ #include int pbkdf2_sha1(const char *passphrase, const u8 *ssid, size_t ssid_len, int iterations, u8 *buf, size_t buflen) { -#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_MBEDTLS_PSA return pbkdf2_sha1_psa(MBEDTLS_MD_SHA1, (const u8 *)passphrase, os_strlen(passphrase), ssid, ssid_len, iterations, 32, buf) ? -1: 0; -#else - return mbedtls_pkcs5_pbkdf2_hmac_ext(MBEDTLS_MD_SHA1, (const u8 *)passphrase, os_strlen(passphrase), ssid, ssid_len, - iterations, 32, buf) ? - -1 : - 0; -#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_MBEDTLS_PSA */ } #endif @@ -823,6 +776,7 @@ int pbkdf2_sha1(const char *passphrase, const u8 *ssid, size_t ssid_len, int ite #ifdef MBEDTLS_NIST_KW_C #include +#include /* aes-wrap.c */ int aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain, u8 *cipher) @@ -830,15 +784,26 @@ int aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain, u8 *cipher) if (TEST_FAIL()) return -1; - mbedtls_nist_kw_context ctx; - mbedtls_nist_kw_init(&ctx); + psa_key_id_t key_id = PSA_KEY_ID_NULL; + psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; size_t olen; - int ret = mbedtls_nist_kw_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, kek, kek_len * 8, 1) || - mbedtls_nist_kw_wrap(&ctx, MBEDTLS_KW_MODE_KW, plain, n * 8, cipher, &olen, (n + 1) * 8) ? - -1 : - 0; - mbedtls_nist_kw_free(&ctx); - return ret; + psa_status_t status; + int ret; + + psa_set_key_type(&key_attr, PSA_KEY_TYPE_AES); + psa_set_key_algorithm(&key_attr, PSA_ALG_ECB_NO_PADDING); + psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); + status = psa_import_key(&key_attr, kek, kek_len, &key_id); + if (status != PSA_SUCCESS) { + return -1; + } + + ret = mbedtls_nist_kw_wrap(key_id, MBEDTLS_KW_MODE_KW, plain, n * 8, cipher, (n + 1) * 8, &olen); + + psa_reset_key_attributes(&key_attr); + psa_destroy_key(key_id); + + return (ret != 0) ? -1 : 0; } /* aes-unwrap.c */ @@ -847,19 +812,30 @@ int aes_unwrap(const u8 *kek, size_t kek_len, int n, const u8 *cipher, u8 *plain if (TEST_FAIL()) return -1; - mbedtls_nist_kw_context ctx; - mbedtls_nist_kw_init(&ctx); + psa_key_id_t key_id = PSA_KEY_ID_NULL; + psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; size_t olen; - int ret = mbedtls_nist_kw_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, kek, kek_len * 8, 0) || - mbedtls_nist_kw_unwrap(&ctx, MBEDTLS_KW_MODE_KW, cipher, (n + 1) * 8, plain, &olen, n * 8) ? - -1 : - 0; - mbedtls_nist_kw_free(&ctx); - return ret; + psa_status_t status; + int ret; + + psa_set_key_type(&key_attr, PSA_KEY_TYPE_AES); + psa_set_key_algorithm(&key_attr, PSA_ALG_ECB_NO_PADDING); + psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); + status = psa_import_key(&key_attr, kek, kek_len, &key_id); + if (status != PSA_SUCCESS) { + return -1; + } + + ret = mbedtls_nist_kw_unwrap(key_id, MBEDTLS_KW_MODE_KW, cipher, (n + 1) * 8, plain, n * 8, &olen); + + psa_reset_key_attributes(&key_attr); + psa_destroy_key(key_id); + + return (ret != 0) ? -1 : 0; } #endif /* MBEDTLS_NIST_KW_C */ -#if defined(MBEDTLS_CMAC_C) || defined(CONFIG_PSA_WANT_ALG_CMAC) +#if defined(CONFIG_PSA_WANT_ALG_CMAC) /* aes-omac1.c */ @@ -867,46 +843,7 @@ int aes_unwrap(const u8 *kek, size_t kek_len, int n, const u8 *cipher, u8 *plain int omac1_aes_vector(const u8 *key, size_t key_len, size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) { -#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_MBEDTLS_PSA return omac1_aes_vector_psa(key, key_len, num_elem, addr, len, mac); -#else - if (TEST_FAIL()) - return -1; - - mbedtls_cipher_type_t cipher_type; - switch (key_len) - { - case 16: - cipher_type = MBEDTLS_CIPHER_AES_128_ECB; - break; - case 24: - cipher_type = MBEDTLS_CIPHER_AES_192_ECB; - break; - case 32: - cipher_type = MBEDTLS_CIPHER_AES_256_ECB; - break; - default: - return -1; - } - const mbedtls_cipher_info_t *cipher_info; - cipher_info = mbedtls_cipher_info_from_type(cipher_type); - if (cipher_info == NULL) - return -1; - - mbedtls_cipher_context_t ctx; - mbedtls_cipher_init(&ctx); - int ret = -1; - if (mbedtls_cipher_setup(&ctx, cipher_info) == 0 && mbedtls_cipher_cmac_starts(&ctx, key, key_len * 8) == 0) - { - ret = 0; - for (size_t i = 0; i < num_elem && ret == 0; ++i) - ret = mbedtls_cipher_cmac_update(&ctx, addr[i], len[i]); - } - if (ret == 0) - ret = mbedtls_cipher_cmac_finish(&ctx, mac); - mbedtls_cipher_free(&ctx); - return ret ? -1 : 0; -#endif } int omac1_aes_128_vector(const u8 *key, size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) @@ -932,9 +869,9 @@ int omac1_aes_256(const u8 *key, const u8 *data, size_t data_len, u8 *mac) #define MBEDTLS_AES_BLOCK_SIZE 16 #endif -#endif /* MBEDTLS_CMAC_C */ +#endif /* CONFIG_PSA_WANT_ALG_CMAC */ -#if defined(MBEDTLS_AES_C) || defined(CONFIG_PSA_WANT_KEY_TYPE_AES) +#if defined(CONFIG_PSA_WANT_KEY_TYPE_AES) /* These interfaces can be inefficient when used in loops, as the overhead of * initialization each call is large for each block input (e.g. 16 bytes) */ @@ -942,45 +879,13 @@ int omac1_aes_256(const u8 *key, const u8 *data, size_t data_len, u8 *mac) /* aes-encblock.c */ int aes_128_encrypt_block(const u8 *key, const u8 *in, u8 *out) { -#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_MBEDTLS_PSA return aes_128_encrypt_block_psa(key, in, out); -#else - if (TEST_FAIL()) - return -1; - - mbedtls_aes_context aes; - mbedtls_aes_init(&aes); - int ret = - mbedtls_aes_setkey_enc(&aes, key, 128) || mbedtls_aes_crypt_ecb(&aes, MBEDTLS_AES_ENCRYPT, in, out) ? -1 : 0; - mbedtls_aes_free(&aes); - return ret; -#endif } /* aes-ctr.c */ int aes_ctr_encrypt(const u8 *key, size_t key_len, const u8 *nonce, u8 *data, size_t data_len) { -#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_MBEDTLS_PSA return aes_ctr_encrypt_psa(key, key_len, nonce, data, data_len); -#else - if (TEST_FAIL()) - return -1; - - unsigned char counter[MBEDTLS_AES_BLOCK_SIZE]; - unsigned char stream_block[MBEDTLS_AES_BLOCK_SIZE]; - os_memcpy(counter, nonce, MBEDTLS_AES_BLOCK_SIZE); /*(must be writable)*/ - - mbedtls_aes_context ctx; - mbedtls_aes_init(&ctx); - size_t nc_off = 0; - int ret = mbedtls_aes_setkey_enc(&ctx, key, key_len * 8) || - mbedtls_aes_crypt_ctr(&ctx, data_len, &nc_off, counter, stream_block, data, data) ? - -1 : - 0; - forced_memzero(stream_block, sizeof(stream_block)); - mbedtls_aes_free(&ctx); - return ret; -#endif } int aes_128_ctr_encrypt(const u8 *key, const u8 *nonce, u8 *data, size_t data_len) @@ -988,26 +893,16 @@ int aes_128_ctr_encrypt(const u8 *key, const u8 *nonce, u8 *data, size_t data_le return aes_ctr_encrypt(key, 16, nonce, data, data_len); } +#define HOSTAP_AES_ENCRYPT 0 +#define HOSTAP_AES_DECRYPT 1 + /* aes-cbc.c */ static int aes_128_cbc_oper(const u8 *key, const u8 *iv, u8 *data, size_t data_len, int mode) { -#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_MBEDTLS_PSA - if (mode == MBEDTLS_AES_ENCRYPT) + if (mode == HOSTAP_AES_ENCRYPT) return aes_128_cbc_encrypt_psa(key, iv, data, data_len); else return aes_128_cbc_decrypt_psa(key, iv, data, data_len); -#else - unsigned char ivec[MBEDTLS_AES_BLOCK_SIZE]; - os_memcpy(ivec, iv, MBEDTLS_AES_BLOCK_SIZE); /*(must be writable)*/ - - mbedtls_aes_context ctx; - mbedtls_aes_init(&ctx); - int ret = (mode == MBEDTLS_AES_ENCRYPT ? mbedtls_aes_setkey_enc(&ctx, key, 128) : - mbedtls_aes_setkey_dec(&ctx, key, 128)) || - mbedtls_aes_crypt_cbc(&ctx, mode, data_len, ivec, data, data); - mbedtls_aes_free(&ctx); - return ret ? -1 : 0; -#endif } int aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) @@ -1015,7 +910,7 @@ int aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) if (TEST_FAIL()) return -1; - return aes_128_cbc_oper(key, iv, data, data_len, MBEDTLS_AES_ENCRYPT); + return aes_128_cbc_oper(key, iv, data, data_len, HOSTAP_AES_ENCRYPT); } int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) @@ -1023,9 +918,9 @@ int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) if (TEST_FAIL()) return -1; - return aes_128_cbc_oper(key, iv, data, data_len, MBEDTLS_AES_DECRYPT); + return aes_128_cbc_oper(key, iv, data, data_len, HOSTAP_AES_DECRYPT); } -#endif +#endif /* CONFIG_PSA_WANT_KEY_TYPE_AES */ /* * Much of the following is documented in crypto.h as for CONFIG_TLS=internal @@ -1055,7 +950,7 @@ struct crypto_cipher *crypto_cipher_init(enum crypto_cipher_alg alg, const u8 *i size_t iv_len; switch (alg) { -#ifdef MBEDTLS_AES_C +#ifdef PSA_WANT_KEY_TYPE_AES case CRYPTO_CIPHER_ALG_AES: if (key_len == 16) cipher_type = MBEDTLS_CIPHER_AES_128_CTR; @@ -1065,12 +960,6 @@ struct crypto_cipher *crypto_cipher_init(enum crypto_cipher_alg alg, const u8 *i cipher_type = MBEDTLS_CIPHER_AES_256_CTR; iv_len = 16; break; -#endif -#ifdef MBEDTLS_DES_C - case CRYPTO_CIPHER_ALG_3DES: - cipher_type = MBEDTLS_CIPHER_DES_EDE3_CBC; - iv_len = 8; - break; #endif default: return NULL; @@ -1728,247 +1617,381 @@ static int crypto_mbedtls_ike_id_from_ecp_group_id(mbedtls_ecp_group_id grp_id) #include #include -mbedtls_ecp_keypair *mbedtls_pk_ec(const mbedtls_pk_context pk); +/* tf-psa-crypto internal functions */ +psa_ecc_family_t mbedtls_ecc_group_to_psa(mbedtls_ecp_group_id grpid, size_t *bits); +mbedtls_ecp_group_id mbedtls_ecc_group_from_psa(psa_ecc_family_t family, size_t bits); -static int crypto_mbedtls_keypair_gen(int group, mbedtls_pk_context *pk) +static int crypto_mbedtls_keypair_gen(int group, psa_key_id_t *key_id, psa_ecc_family_t *ec_family) { mbedtls_ecp_group_id grp_id = crypto_mbedtls_ecp_group_id_from_ike_id(group); - if (grp_id == MBEDTLS_ECP_DP_NONE) + size_t key_bits; + psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; + + *key_id = PSA_KEY_ID_NULL; + + *ec_family = mbedtls_ecc_group_to_psa(grp_id, (size_t *) &key_bits); + if (*ec_family == 0) { return -1; - const mbedtls_pk_info_t *pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY); - if (pk_info == NULL) + } + + psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_KEY_PAIR(*ec_family)); + psa_set_key_bits(&key_attr, key_bits); + psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_DERIVE | + PSA_KEY_USAGE_COPY | + PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH); + psa_set_key_algorithm(&key_attr, PSA_ALG_ECDH); +#if defined(MBEDTLS_PSA_CRYPTO_C) + psa_set_key_enrollment_algorithm(&key_attr, PSA_ALG_ECDSA(PSA_ALG_ANY_HASH)); +#endif + if (psa_generate_key(&key_attr, key_id) != PSA_SUCCESS) { return -1; - return mbedtls_pk_setup(pk, pk_info) || - mbedtls_ecp_gen_key(grp_id, (mbedtls_ecp_keypair *)mbedtls_pk_ec(*pk), - hostap_rng_fn, hostap_rng_ctx()) ? - -1 : - 0; + } + + return 0; } #endif #ifdef CRYPTO_MBEDTLS_CRYPTO_ECDH -#include #include #include #include -/* wrap mbedtls_ecdh_context for more future-proof direct access to components - * (mbedtls_ecdh_context internal implementation may change between releases) - * - * If mbedtls_pk_context -- specifically underlying mbedtls_ecp_keypair -- - * lifetime were guaranteed to be longer than that of mbedtls_ecdh_context, - * then mbedtls_pk_context or mbedtls_ecp_keypair could be stored in crypto_ecdh - * (or crypto_ec_key could be stored in crypto_ecdh, and crypto_ec_key could - * wrap mbedtls_ecp_keypair and components, to avoid MBEDTLS_PRIVATE access) */ -struct crypto_ecdh -{ - mbedtls_ecdh_context ctx; - mbedtls_ecp_group grp; - mbedtls_ecp_point Q; +struct crypto_ecdh { + mbedtls_pk_context our_key; + uint8_t peer_key[PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS)]; + uint8_t shared_secret[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)]; }; -struct crypto_ec -{ +/* + * Following map is being used: + * struct crypto_ec_key --> mbedtls_pk_context + */ + +struct crypto_ec { mbedtls_ecp_group group; }; struct crypto_ecdh *crypto_ecdh_init(int group) { - mbedtls_pk_context pk; - mbedtls_pk_init(&pk); - struct crypto_ecdh *ecdh = - crypto_mbedtls_keypair_gen(group, &pk) == 0 ? crypto_ecdh_init2(group, (struct crypto_ec_key *)&pk) : NULL; - mbedtls_pk_free(&pk); - return ecdh; -} + struct crypto_ecdh *ecdh = NULL; + psa_key_id_t key_id; + int ret; + psa_ecc_family_t ec_family; -struct crypto_ecdh *crypto_ecdh_init2(int group, struct crypto_ec_key *own_key) -{ - mbedtls_ecp_group_id grp_id = crypto_mbedtls_ecp_group_id_from_ike_id(group); - if (grp_id == MBEDTLS_ECP_DP_NONE) + if (crypto_mbedtls_keypair_gen(group, &key_id, &ec_family) != 0) { return NULL; - mbedtls_ecp_keypair *ecp_kp = (mbedtls_ecp_keypair *)mbedtls_pk_ec(*(mbedtls_pk_context *)own_key); - struct crypto_ecdh *ecdh = os_malloc(sizeof(*ecdh)); - if (ecdh == NULL) + } + + ecdh = os_calloc(1, sizeof(struct crypto_ecdh)); + if (ecdh == NULL) { + psa_destroy_key(key_id); return NULL; - mbedtls_ecdh_init(&ecdh->ctx); - mbedtls_ecp_group_init(&ecdh->grp); - mbedtls_ecp_point_init(&ecdh->Q); - if (mbedtls_ecdh_setup(&ecdh->ctx, grp_id) == 0 && - mbedtls_ecdh_get_params(&ecdh->ctx, ecp_kp, MBEDTLS_ECDH_OURS) == 0) - { - /* copy grp and Q for later use - * (retrieving this info later is more convoluted - * even if mbedtls_ecdh_make_public() is considered)*/ - mbedtls_mpi d; - mbedtls_mpi_init(&d); - if (mbedtls_ecp_export(ecp_kp, &ecdh->grp, &d, &ecdh->Q) == 0) - { - mbedtls_mpi_free(&d); - return ecdh; - } - mbedtls_mpi_free(&d); } - mbedtls_ecp_point_free(&ecdh->Q); - mbedtls_ecp_group_free(&ecdh->grp); - mbedtls_ecdh_free(&ecdh->ctx); - os_free(ecdh); - return NULL; + mbedtls_pk_init(&ecdh->our_key); + ret = mbedtls_pk_wrap_psa(&ecdh->our_key, key_id); + if (ret != 0) { + mbedtls_pk_free(&ecdh->our_key); + psa_destroy_key(key_id); + os_free(ecdh); + return NULL; + } +#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) + ecdh->our_key.MBEDTLS_PRIVATE(ec_family) = ec_family; +#endif + return ecdh; } -struct wpabuf *crypto_ecdh_get_pubkey(struct crypto_ecdh *ecdh, int inc_y) +struct crypto_ecdh *crypto_ecdh_init2(int group, struct crypto_ec_key *own_key) { - mbedtls_ecp_group *grp = &ecdh->grp; - size_t len = CRYPTO_EC_plen(grp); -#ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED - /* len */ -#endif -#ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED - if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) - len = inc_y ? len * 2 + 1 : len + 1; -#endif - struct wpabuf *buf = wpabuf_alloc(len); - if (buf == NULL) + struct crypto_ecdh *ecdh = NULL; + mbedtls_pk_context *pk = (mbedtls_pk_context *) own_key; + psa_key_id_t orig_key_id; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_status_t status; + psa_key_id_t new_key_id; + int ret; + + if (pk == NULL) { return NULL; - inc_y = inc_y ? MBEDTLS_ECP_PF_UNCOMPRESSED : MBEDTLS_ECP_PF_COMPRESSED; - if (mbedtls_ecp_point_write_binary(grp, &ecdh->Q, inc_y, &len, wpabuf_mhead_u8(buf), len) == 0) - { - wpabuf_put(buf, len); - return buf; } - wpabuf_free(buf); - return NULL; -} + /* Get the original PSA key ID from the pk context */ + orig_key_id = pk->MBEDTLS_PRIVATE(priv_id); + if (mbedtls_svc_key_id_is_null(orig_key_id)) { + return NULL; + } -#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) -static int crypto_mbedtls_short_weierstrass_derive_y(mbedtls_ecp_group *grp, mbedtls_mpi *bn, int parity_bit) -{ - /* y^2 = x^3 + ax + b - * sqrt(w) = w^((p+1)/4) mod p (for prime p where p = 3 mod 4) */ - mbedtls_mpi *cy2 = - (mbedtls_mpi *)crypto_ec_point_compute_y_sqr((struct crypto_ec *)grp, (const struct crypto_bignum *)bn); /*x*/ - if (cy2 == NULL) - return -1; + /* Allocate ECDH structure */ + ecdh = os_calloc(1, sizeof(struct crypto_ecdh)); + if (ecdh == NULL) { + return NULL; + } - /*mbedtls_mpi_free(bn);*/ - /*(reuse bn to store result (y))*/ + status = psa_get_key_attributes(orig_key_id, &attributes); + if (status != PSA_SUCCESS) { + return NULL; + } + psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE); - mbedtls_mpi exp; - mbedtls_mpi_init(&exp); - int ret = mbedtls_mpi_get_bit(&grp->P, 0) != 1 /*(p = 3 mod 4)*/ - || mbedtls_mpi_get_bit(&grp->P, 1) != 1 /*(p = 3 mod 4)*/ - || mbedtls_mpi_add_int(&exp, &grp->P, 1) || mbedtls_mpi_shift_r(&exp, 2) || - mbedtls_mpi_exp_mod(bn, cy2, &exp, &grp->P, NULL) || - (mbedtls_mpi_get_bit(bn, 0) != parity_bit && mbedtls_mpi_sub_mpi(bn, &grp->P, bn)); - mbedtls_mpi_free(&exp); - mbedtls_mpi_free(cy2); - os_free(cy2); - return ret; -} -#endif + /* Copy the PSA key using psa_copy_key() */ + status = psa_copy_key(orig_key_id, &attributes, &new_key_id); + psa_reset_key_attributes(&attributes); -struct wpabuf *crypto_ecdh_set_peerkey(struct crypto_ecdh *ecdh, int inc_y, const u8 *key, size_t len) -{ - if (len == 0) /*(invalid peer key)*/ + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: Failed to copy key: %d", + __FUNCTION__, (int)status); + os_free(ecdh); return NULL; + } -#if defined (MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) || defined (MBEDTLS_ECP_MONTGOMERY_ENABLED) - mbedtls_ecp_group *grp = &ecdh->grp; -#endif + /* Initialize the new pk context */ + mbedtls_pk_init(&ecdh->our_key); -#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) - if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) - { - /* add header for mbedtls_ecdh_read_public() */ - u8 buf[256]; - if (sizeof(buf) - 1 < len) - return NULL; - buf[0] = (u8)(len); - os_memcpy(buf + 1, key, len); + /* Wrap the new PSA key with pk context */ + ret = mbedtls_pk_wrap_psa(&ecdh->our_key, new_key_id); + if (ret != 0) { + wpa_printf(MSG_ERROR, "%s: Failed to wrap PSA key: %d", + __FUNCTION__, ret); + mbedtls_pk_free(&ecdh->our_key); + psa_destroy_key(new_key_id); + os_free(ecdh); + return NULL; + } - if (inc_y) - { - if (!(len & 1)) - { /*(dpp code/tests does not include tag?!?)*/ - if (sizeof(buf) - 2 < len) - return NULL; - buf[0] = (u8)(1 + len); - buf[1] = 0x04; - os_memcpy(buf + 2, key, len); - } - len >>= 1; /*(repurpose len to prime_len)*/ - } - else if (key[0] == 0x02 || key[0] == 0x03) - { /* (inc_y == 0) */ - if(len == 0) - return NULL; - --len; /*(repurpose len to prime_len)*/ + /* Copy public key raw data if available */ + if (pk->MBEDTLS_PRIVATE(pub_raw_len) > 0 ) { + os_memcpy(ecdh->our_key.MBEDTLS_PRIVATE(pub_raw), + pk->MBEDTLS_PRIVATE(pub_raw), + pk->MBEDTLS_PRIVATE(pub_raw_len)); + ecdh->our_key.MBEDTLS_PRIVATE(pub_raw_len) = pk->MBEDTLS_PRIVATE(pub_raw_len); + } - /* mbedtls_ecp_point_read_binary() does not currently support - * MBEDTLS_ECP_PF_COMPRESSED format (buf[1] = 0x02 or 0x03) - * (returns MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE) */ + /* Copy other key attributes */ + ecdh->our_key.MBEDTLS_PRIVATE(bits) = pk->MBEDTLS_PRIVATE(bits); + ecdh->our_key.MBEDTLS_PRIVATE(psa_type) = pk->MBEDTLS_PRIVATE(psa_type); - /* derive y, amend buf[] with y for UNCOMPRESSED format */ - if (sizeof(buf) - 2 < len * 2 || len == 0) - return NULL; - buf[0] = (u8)(1 + len * 2); - buf[1] = 0x04; - mbedtls_mpi bn; - mbedtls_mpi_init(&bn); - int ret = mbedtls_mpi_read_binary(&bn, key + 1, len) || - crypto_mbedtls_short_weierstrass_derive_y(grp, &bn, key[0] & 1) || - mbedtls_mpi_write_binary(&bn, buf + 2 + len, len); - mbedtls_mpi_free(&bn); - if (ret != 0) - return NULL; +#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) + ecdh->our_key.MBEDTLS_PRIVATE(ec_family) = pk->MBEDTLS_PRIVATE(ec_family); +#endif + + return ecdh; +} + +struct wpabuf *crypto_ecdh_get_pubkey(struct crypto_ecdh *ecdh, int inc_y) +{ + psa_status_t status; + uint8_t pubkey_buf[PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(256)]; + size_t pubkey_len = 0; + size_t prime_len = 0; + struct wpabuf *buf; + + /* Export PSA public key (always in format: 0x04 + X + Y) */ + status = psa_export_public_key(ecdh->our_key.MBEDTLS_PRIVATE(priv_id), pubkey_buf, + sizeof(pubkey_buf), &pubkey_len); + if (status != PSA_SUCCESS) { + return NULL; + } + + prime_len = (pubkey_len - 1) / 2; + + if (inc_y) { + /* Uncompressed: copy entire key */ + buf = wpabuf_alloc_copy(pubkey_buf, pubkey_len); + } else { + /* Compressed: convert format */ + buf = wpabuf_alloc(1 + prime_len); + if (buf) { + uint8_t y_is_odd = pubkey_buf[pubkey_len - 1] & 0x01; + wpabuf_put_u8(buf, y_is_odd ? 0x03 : 0x02); + wpabuf_put_data(buf, pubkey_buf + 1, prime_len); } + } - if (key[0] == 0) /*(repurpose len to prime_len)*/ - len = CRYPTO_EC_plen(grp); + return buf; +} - if (mbedtls_ecdh_read_public(&ecdh->ctx, buf, buf[0] + 1)) - return NULL; +struct wpabuf *crypto_ecdh_set_peerkey(struct crypto_ecdh *ecdh, int inc_y, const u8 *key, size_t len) +{ + struct wpabuf *buf = NULL; + psa_status_t status; + size_t olen = 0; + u8 *peer_key_buf = NULL; + size_t peer_key_len = 0; + bool need_free = false; + size_t key_bits, prime_len; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + + if (len == 0) { + return NULL; } -#endif -#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) - if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) - { - if (mbedtls_ecdh_read_public(&ecdh->ctx, key, len)) + + /* Get curve information from our key */ + status = psa_get_key_attributes(ecdh->our_key.MBEDTLS_PRIVATE(priv_id), &attributes); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: Failed to get key attributes", __FUNCTION__); + return NULL; + } + key_bits = psa_get_key_bits(&attributes); + psa_reset_key_attributes(&attributes); + prime_len = PSA_BITS_TO_BYTES(key_bits); + /* Process the peer's public key based on format */ + if (inc_y) { + /* Uncompressed format: should contain X + Y coordinates */ + if (key[0] == 0x04) { + /* Already in standard uncompressed format: 0x04 + X + Y */ + peer_key_buf = (u8 *)key; + peer_key_len = len; + } else if (len == 2 * prime_len) { + /* Raw X + Y coordinates without prefix (some DPP implementations) + * Need to add 0x04 prefix */ + peer_key_len = 1 + len; + peer_key_buf = os_malloc(peer_key_len); + if (!peer_key_buf) { + return NULL; + } + peer_key_buf[0] = 0x04; + os_memcpy(peer_key_buf + 1, key, len); + need_free = true; + } else { + wpa_printf(MSG_ERROR, "%s: Invalid uncompressed key length %zu", __FUNCTION__, len); + return NULL; + } + } else { + mbedtls_ecp_group_id grp_id; + size_t written_len = 0; + + /* Compressed format: 0x02/0x03 + X coordinate only */ + if (key[0] == 0x02 || key[0] == 0x03) { + /* Compressed format with prefix */ + if (len != 1 + prime_len) { + wpa_printf(MSG_ERROR, "%s: Invalid compressed key length %zu", __FUNCTION__, len); + return NULL; + } + + peer_key_len = 1 + 2 * prime_len; + peer_key_buf = os_malloc(peer_key_len); + if (!peer_key_buf) { + wpa_printf(MSG_ERROR, "%s: Memory allocation failed", __FUNCTION__); + return NULL; + } + need_free = true; + peer_key_buf[0] = 0x04; + + /* Copy X coordinate */ + os_memcpy(peer_key_buf + 1, key + 1, prime_len); + + mbedtls_ecp_group grp; + mbedtls_ecp_point point; + mbedtls_ecp_group_init(&grp); + mbedtls_ecp_point_init(&point); + + /* Load the curve group */ + grp_id = (key_bits == 256) ? MBEDTLS_ECP_DP_SECP256R1 : + (key_bits == 384) ? MBEDTLS_ECP_DP_SECP384R1 : + (key_bits == 521) ? MBEDTLS_ECP_DP_SECP521R1 : + MBEDTLS_ECP_DP_NONE; + + if (grp_id == MBEDTLS_ECP_DP_NONE) { + wpa_printf(MSG_ERROR, "%s: Unsupported curve size %zu bits", __FUNCTION__, key_bits); + os_free(peer_key_buf); + return NULL; + } + + status = mbedtls_ecp_group_load(&grp, grp_id); + if (status != 0) { + wpa_printf(MSG_ERROR, "%s: Failed to load curve group: %d", __FUNCTION__, status); + mbedtls_ecp_point_free(&point); + mbedtls_ecp_group_free(&grp); + os_free(peer_key_buf); + return NULL; + } + + /* Read the compressed point and decompress it */ + status = mbedtls_ecp_point_read_binary(&grp, &point, key, len); + if (status != 0) { + wpa_printf(MSG_ERROR, "%s: Failed to read compressed point: %d", __FUNCTION__, status); + mbedtls_ecp_point_free(&point); + mbedtls_ecp_group_free(&grp); + os_free(peer_key_buf); + return NULL; + } + + /* Write the uncompressed point */ + status = mbedtls_ecp_point_write_binary(&grp, &point, + MBEDTLS_ECP_PF_UNCOMPRESSED, + &written_len, + peer_key_buf, + peer_key_len); + + mbedtls_ecp_point_free(&point); + mbedtls_ecp_group_free(&grp); + if (status != 0) { + wpa_printf(MSG_ERROR, "%s: Failed to write uncompressed point: %d", __FUNCTION__, status); + os_free(peer_key_buf); + return NULL; + } + + peer_key_len = written_len; + } else { + wpa_printf(MSG_ERROR, "%s: Invalid compressed key format", __FUNCTION__); return NULL; + } } -#endif - struct wpabuf *buf = wpabuf_alloc(len); - if (buf == NULL) + buf = wpabuf_alloc(prime_len); + if (!buf) { + wpa_printf(MSG_ERROR, "%s: Failed to allocate output buffer", __FUNCTION__); + if (need_free) + os_free(peer_key_buf); return NULL; + } - if (mbedtls_ecdh_calc_secret(&ecdh->ctx, &len, wpabuf_mhead(buf), len, hostap_rng_fn, hostap_rng_ctx()) == 0) - { - wpabuf_put(buf, len); - return buf; + /* Perform ECDH key agreement using PSA API */ + status = psa_raw_key_agreement( + PSA_ALG_ECDH, + ecdh->our_key.MBEDTLS_PRIVATE(priv_id), + peer_key_buf, + peer_key_len, + wpabuf_mhead_u8(buf), + wpabuf_size(buf), + &olen + ); + + if (need_free) { + os_free(peer_key_buf); } - wpabuf_clear_free(buf); - return NULL; + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_raw_key_agreement failed: %d", __FUNCTION__, status); + wpabuf_free(buf); + return NULL; + } + + wpabuf_put(buf, olen); + return buf; } void crypto_ecdh_deinit(struct crypto_ecdh *ecdh) { - if (ecdh == NULL) - return; - mbedtls_ecp_point_free(&ecdh->Q); - mbedtls_ecp_group_free(&ecdh->grp); - mbedtls_ecdh_free(&ecdh->ctx); - os_free(ecdh); + psa_key_id_t key_id; + mbedtls_pk_context *pk; + + if (NULL != ecdh) + { + pk = (mbedtls_pk_context *) &ecdh->our_key; + key_id = pk->MBEDTLS_PRIVATE(priv_id); + mbedtls_pk_free(&ecdh->our_key); + psa_destroy_key(key_id); + os_free(ecdh); + } } size_t crypto_ecdh_prime_len(struct crypto_ecdh *ecdh) { - return CRYPTO_EC_plen(&ecdh->grp); + return mbedtls_pk_get_bitlen(&ecdh->our_key); } #endif /* CRYPTO_MBEDTLS_CRYPTO_ECDH */ @@ -2353,431 +2376,518 @@ void crypto_ec_point_debug_print(const struct crypto_ec *e, const struct crypto_ #else void crypto_ec_point_debug_print(const struct crypto_ec *e, const struct crypto_ec_point *p, const char *title) { - // Fixing linking error undefined reference to `crypto_ec_point_debug_print' + // Fixing linking error undefined reference to `crypto_ec_point_debug_print' } #endif +#include +#include + struct crypto_ec_key *crypto_ec_key_parse_priv(const u8 *der, size_t der_len) { - mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx)); - if (ctx == NULL) + mbedtls_pk_context *pk; + uint8_t key[PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS)] = { 0 }; + size_t key_len; + psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; + psa_key_type_t key_type; + psa_key_bits_t key_bits; + psa_key_id_t key_id = PSA_KEY_ID_NULL; + psa_ecc_family_t ec_family; + + pk = os_calloc(1, sizeof(mbedtls_pk_context)); + if (pk == NULL) return NULL; - mbedtls_pk_init(ctx); - if (mbedtls_pk_parse_key(ctx, der, der_len, NULL, 0, hostap_rng_fn, hostap_rng_ctx()) == 0) - return (struct crypto_ec_key *)ctx; - - mbedtls_pk_free(ctx); - os_free(ctx); - return NULL; -} -#include -#include -static int crypto_mbedtls_pk_parse_subpubkey_compressed(mbedtls_pk_context *ctx, const u8 *der, size_t der_len) -{ - /* The following is modified from: - * mbedtls/library/pkparse.c:mbedtls_pk_parse_subpubkey() - * mbedtls/library/pkparse.c:pk_get_pk_alg() - * mbedtls/library/pkparse.c:pk_use_ecparams() - */ - mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE; - const mbedtls_pk_info_t *pk_info; - int ret; - size_t len; - const unsigned char *end = der + der_len; - unsigned char *p; - *(const unsigned char **)&p = der; - - if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) - { - return (MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret)); + mbedtls_pk_init(pk); + if (mbedtls_pk_parse_key(pk, der, der_len, NULL, 0) != 0) { + mbedtls_pk_free(pk); + os_free(pk); + return NULL; } +#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) + ec_family = pk->MBEDTLS_PRIVATE(ec_family); +#endif + /* By deafult "mbedlts_pk_parse_key()" assigns ECDSA(ANY_HASH) algorithm to the imported + * PSA key. We need to change that to ECDH. */ - end = p + len; - - /* - if( ( ret = pk_get_pk_alg( &p, end, &pk_alg, &alg_params ) ) != 0 ) - return( ret ); - */ - mbedtls_asn1_buf alg_oid, params; - memset(¶ms, 0, sizeof(mbedtls_asn1_buf)); - if ((ret = mbedtls_asn1_get_alg(&p, end, &alg_oid, ¶ms)) != 0) - return (MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_ALG, ret)); - if (mbedtls_oid_get_pk_alg(&alg_oid, &pk_alg) != 0) - return (MBEDTLS_ERR_PK_UNKNOWN_PK_ALG); - - if ((ret = mbedtls_asn1_get_bitstring_null(&p, end, &len)) != 0) - return (MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_PUBKEY, ret)); - - if (p + len != end) - return (MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_PUBKEY, MBEDTLS_ERR_ASN1_LENGTH_MISMATCH)); + if (psa_get_key_attributes(pk->MBEDTLS_PRIVATE(priv_id), &key_attr) != PSA_SUCCESS) { + mbedtls_pk_free(pk); + os_free(pk); + return NULL; + } + if (psa_export_key(pk->MBEDTLS_PRIVATE(priv_id), key, sizeof(key), &key_len) != PSA_SUCCESS) { + mbedtls_pk_free(pk); + os_free(pk); + return NULL; + } + /* Free the PK context to re-use it below */ + mbedtls_pk_free(pk); + /* Copy key attributes (key type and bits) and set key algorithm and usage. */ + key_type = psa_get_key_type(&key_attr); + key_bits = psa_get_key_bits(&key_attr); + psa_reset_key_attributes(&key_attr); + key_attr = psa_key_attributes_init(); + psa_set_key_type(&key_attr, key_type); + psa_set_key_bits(&key_attr, key_bits); + psa_set_key_algorithm(&key_attr, PSA_ALG_ECDH); +#if defined(MBEDTLS_PSA_CRYPTO_C) + psa_set_key_enrollment_algorithm(&key_attr, PSA_ALG_ECDSA(PSA_ALG_ANY_HASH)); +#endif + psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_DERIVE + | PSA_KEY_USAGE_COPY); + psa_set_key_lifetime(&key_attr, PSA_KEY_LIFETIME_VOLATILE); + if (psa_import_key(&key_attr, key, key_len, &key_id) != PSA_SUCCESS) { + os_free(pk); + return NULL; + } - if ((pk_info = mbedtls_pk_info_from_type(pk_alg)) == NULL) - return (MBEDTLS_ERR_PK_UNKNOWN_PK_ALG); + mbedtls_pk_init(pk); - if ((ret = mbedtls_pk_setup(ctx, pk_info)) != 0) - return (ret); + if (mbedtls_pk_wrap_psa(pk, key_id) != 0) { + mbedtls_pk_free(pk); + psa_destroy_key(key_id); + os_free(pk); + return NULL; + } +#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) + pk->MBEDTLS_PRIVATE(ec_family) = ec_family; +#endif + return (struct crypto_ec_key *) pk; +} - /* assume mbedtls_pk_parse_subpubkey(&der, der+der_len, ctx) - * has already run with ctx initialized up to pk_get_ecpubkey(), - * and pk_get_ecpubkey() has returned MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE - * - * mbedtls mbedtls_ecp_point_read_binary() - * does not handle point in COMPRESSED format - * - * (validate assumption that algorithm is EC) */ - mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*ctx); - if (ecp_kp == NULL) - return (MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE); - mbedtls_ecp_group *ecp_kp_grp = &ecp_kp->MBEDTLS_PRIVATE(grp); - mbedtls_ecp_point *ecp_kp_Q = &ecp_kp->MBEDTLS_PRIVATE(Q); - mbedtls_ecp_group_id grp_id; +struct crypto_ec_key * crypto_ec_key_set_priv(int group, const u8 *raw, size_t raw_len) +{ + mbedtls_pk_context *pk; + psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id = PSA_KEY_ID_NULL; + psa_ecc_family_t ec_family; + size_t key_bits; + mbedtls_ecp_group_id ecp_group_id; + int ret; - /* mbedtls/library/pkparse.c:pk_use_ecparams() */ + ecp_group_id = crypto_mbedtls_ecp_group_id_from_ike_id(group); + ec_family = mbedtls_ecc_group_to_psa(ecp_group_id, (size_t *) &key_bits); + if (ec_family == 0) { + return NULL; + } - if (params.tag == MBEDTLS_ASN1_OID) - { - if (mbedtls_oid_get_ec_grp(¶ms, &grp_id) != 0) - return (MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE); + psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_KEY_PAIR(ec_family)); + psa_set_key_bits(&key_attr, key_bits); + psa_set_key_algorithm(&key_attr, PSA_ALG_ECDH); +#if defined(MBEDTLS_PSA_CRYPTO_C) + psa_set_key_enrollment_algorithm(&key_attr, PSA_ALG_ECDSA(PSA_ALG_ANY_HASH)); +#endif + psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_DERIVE + | PSA_KEY_USAGE_COPY); + if (psa_import_key(&key_attr, raw, raw_len, &key_id) != PSA_SUCCESS) { + return NULL; } - else - { - return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT); + + pk = os_calloc(1, sizeof(mbedtls_pk_context)); + if (pk == NULL) { + psa_destroy_key(key_id); + return NULL; } - /* - * grp may already be initialized; if so, make sure IDs match - */ - if (ecp_kp_grp->id != MBEDTLS_ECP_DP_NONE && ecp_kp_grp->id != grp_id) - return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT); - - if ((ret = mbedtls_ecp_group_load(ecp_kp_grp, grp_id)) != 0) - return (ret); - - /* (validate assumption that EC point is in COMPRESSED format) */ - len = CRYPTO_EC_plen(ecp_kp_grp); - if (mbedtls_ecp_get_type(ecp_kp_grp) != MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS || (end - p) != 1 + len || - (*p != 0x02 && *p != 0x03)) - return (MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE); - - /* Instead of calling mbedtls/library/pkparse.c:pk_get_ecpubkey() to call - * mbedtls_ecp_point_read_binary(), manually parse point into ecp_kp_Q */ - mbedtls_mpi *X = &ecp_kp_Q->MBEDTLS_PRIVATE(X); - mbedtls_mpi *Y = &ecp_kp_Q->MBEDTLS_PRIVATE(Y); - mbedtls_mpi *Z = &ecp_kp_Q->MBEDTLS_PRIVATE(Z); - ret = mbedtls_mpi_lset(Z, 1); - if (ret != 0) - return (ret); - ret = mbedtls_mpi_read_binary(X, p + 1, len); - if (ret != 0) - return (ret); - /* derive Y - * (similar derivation of Y in crypto_mbedtls.c:crypto_ecdh_set_peerkey())*/ - ret = mbedtls_mpi_copy(Y, X) /*(Y is used as input and output obj below)*/ - || crypto_mbedtls_short_weierstrass_derive_y(ecp_kp_grp, Y, (*p & 1)); - if (ret != 0) - return (ret); + mbedtls_pk_init(pk); + ret = mbedtls_pk_wrap_psa(pk, key_id); + if (ret != 0) { + mbedtls_pk_free(pk); + psa_destroy_key(key_id); + os_free(pk); + return NULL; + } - return mbedtls_ecp_check_pubkey(ecp_kp_grp, ecp_kp_Q); + return (struct crypto_ec_key *) pk; } struct crypto_ec_key *crypto_ec_key_parse_pub(const u8 *der, size_t der_len) { - mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx)); - if (ctx == NULL) + mbedtls_pk_context *pk; + + pk = os_calloc(1, sizeof(mbedtls_pk_context)); + if (pk == NULL) + return NULL; + + mbedtls_pk_init(pk); + if (mbedtls_pk_parse_public_key(pk, der, der_len) != 0) { + mbedtls_pk_free(pk); + os_free(pk); return NULL; - mbedtls_pk_init(ctx); - /*int rc = mbedtls_pk_parse_subpubkey(&der, der+der_len, ctx);*/ - int rc = mbedtls_pk_parse_public_key(ctx, der, der_len); - if (rc == 0) - return (struct crypto_ec_key *)ctx; - else if (rc == MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE) - { - /* mbedtls mbedtls_ecp_point_read_binary() - * does not handle point in COMPRESSED format; parse internally */ - rc = crypto_mbedtls_pk_parse_subpubkey_compressed(ctx, der, der_len); - if (rc == 0) - return (struct crypto_ec_key *)ctx; } - mbedtls_pk_free(ctx); - os_free(ctx); - return NULL; + return (struct crypto_ec_key *) pk; } #ifdef CRYPTO_MBEDTLS_CRYPTO_EC_DPP -static struct crypto_ec_key *crypto_ec_key_set_pub_point_for_group(mbedtls_ecp_group_id grp_id, - const mbedtls_ecp_point *pub, - const u8 *buf, - size_t len) +/* Internal to PK. Defined in "pk_wrap.c" */ +extern const mbedtls_pk_info_t mbedtls_eckey_info; + +struct crypto_ec_key *crypto_ec_key_set_pub(int group, const u8 *x, const u8 *y, size_t len) { - const mbedtls_pk_info_t *pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY); - if (pk_info == NULL) - return NULL; - mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx)); - if (ctx == NULL) + mbedtls_pk_context *pk; + mbedtls_ecp_group_id group_id = crypto_mbedtls_ecp_group_id_from_ike_id(group); + uint8_t *raw_key_ptr; + psa_ecc_family_t ec_family; + size_t key_bits; + + ec_family = mbedtls_ecc_group_to_psa(group_id, (size_t *) &key_bits); + if (ec_family == 0) { return NULL; - mbedtls_pk_init(ctx); - if (mbedtls_pk_setup(ctx, pk_info) == 0) - { - /* (Is private key generation necessary for callers?) - * alt: gen key then overwrite Q - * mbedtls_ecp_gen_key(grp_id, ecp_kp, hostap_rng_fn, hostap_rng_ctx()) == 0 - */ - mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*ctx); - mbedtls_ecp_group *ecp_kp_grp = &ecp_kp->MBEDTLS_PRIVATE(grp); - mbedtls_ecp_point *ecp_kp_Q = &ecp_kp->MBEDTLS_PRIVATE(Q); - mbedtls_mpi *ecp_kp_d = &ecp_kp->MBEDTLS_PRIVATE(d); - if (mbedtls_ecp_group_load(ecp_kp_grp, grp_id) == 0 && - (pub ? mbedtls_ecp_copy(ecp_kp_Q, pub) == 0 : - mbedtls_ecp_point_read_binary(ecp_kp_grp, ecp_kp_Q, buf, len) == 0) && - mbedtls_ecp_gen_privkey(ecp_kp_grp, ecp_kp_d, hostap_rng_fn, hostap_rng_ctx()) == 0) - { - return (struct crypto_ec_key *)ctx; - } } - mbedtls_pk_free(ctx); - os_free(ctx); - return NULL; -} - -struct crypto_ec_key *crypto_ec_key_set_pub(int group, const u8 *x, const u8 *y, size_t len) -{ - mbedtls_ecp_group_id grp_id = crypto_mbedtls_ecp_group_id_from_ike_id(group); - if (grp_id == MBEDTLS_ECP_DP_NONE) + /* Ensure data will fit into pk->pub_raw */ + if ((2 * len + 1) > MBEDTLS_PK_MAX_PUBKEY_RAW_LEN) { return NULL; - if (len > MBEDTLS_MPI_MAX_SIZE) + } + + pk = os_calloc(1, sizeof(mbedtls_pk_context)); + if (pk == NULL) { return NULL; - u8 buf[1 + MBEDTLS_MPI_MAX_SIZE * 2]; - buf[0] = 0x04; /* assume x,y for Short Weierstrass */ - os_memcpy(buf + 1, x, len); - os_memcpy(buf + 1 + len, y, len); + } + + raw_key_ptr = pk->MBEDTLS_PRIVATE(pub_raw); + *raw_key_ptr = 0x04; + raw_key_ptr++; + pk->MBEDTLS_PRIVATE(pub_raw_len)++; + memcpy(raw_key_ptr, x, len); + pk->MBEDTLS_PRIVATE(pub_raw_len) += len; + raw_key_ptr += len; + memcpy(raw_key_ptr, y, len); + pk->MBEDTLS_PRIVATE(pub_raw_len) += len; +#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) + pk->MBEDTLS_PRIVATE(ec_family) = ec_family; +#endif + pk->MBEDTLS_PRIVATE(bits) = key_bits; + pk->MBEDTLS_PRIVATE(pk_info) = &mbedtls_eckey_info; - return crypto_ec_key_set_pub_point_for_group(grp_id, NULL, buf, 1 + len * 2); + return (struct crypto_ec_key *) pk; } struct crypto_ec_key *crypto_ec_key_set_pub_point(struct crypto_ec *e, const struct crypto_ec_point *pub) { - mbedtls_ecp_group_id grp_id = ((mbedtls_ecp_group *)e)->id; - mbedtls_ecp_point *p = (mbedtls_ecp_point *)pub; - return crypto_ec_key_set_pub_point_for_group(grp_id, p, NULL, 0); + mbedtls_ecp_group *ecp_group = (mbedtls_ecp_group *) e; + mbedtls_ecp_point *ecp_point = (mbedtls_ecp_point *) pub; + uint8_t key[PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS)] = { 0 }; + uint8_t *x, *y; + size_t key_len, coord_len; + int crypto_group; + + if (mbedtls_ecp_point_write_binary(ecp_group, ecp_point, MBEDTLS_ECP_PF_UNCOMPRESSED, + &key_len, key, sizeof(key)) != 0) { + return NULL; + } + + coord_len = (key_len - 1) / 2; + crypto_group = crypto_mbedtls_ike_id_from_ecp_group_id(ecp_group->id); + x = &key[1]; + y = x + coord_len; + + return crypto_ec_key_set_pub(crypto_group, x, y, coord_len); } struct crypto_ec_key *crypto_ec_key_gen(int group) { - mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx)); - if (ctx == NULL) + psa_key_id_t key_id = PSA_KEY_ID_NULL; + mbedtls_pk_context *pk; + int ret; + psa_ecc_family_t ec_family; + + if (crypto_mbedtls_keypair_gen(group, &key_id, &ec_family) != 0) { return NULL; - mbedtls_pk_init(ctx); - if (crypto_mbedtls_keypair_gen(group, ctx) == 0) - return (struct crypto_ec_key *)ctx; - mbedtls_pk_free(ctx); - os_free(ctx); - return NULL; + } + + pk = os_malloc(sizeof(mbedtls_pk_context)); + if (pk == NULL) { + psa_destroy_key(key_id); + return NULL; + } + + mbedtls_pk_init(pk); + ret = mbedtls_pk_wrap_psa(pk, key_id); + if (ret != 0) { + mbedtls_pk_free(pk); + psa_destroy_key(key_id); + os_free(pk); + return NULL; + } +#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) + pk->MBEDTLS_PRIVATE(ec_family)= ec_family; +#endif + return (struct crypto_ec_key *) pk; } #endif /* CRYPTO_MBEDTLS_CRYPTO_EC_DPP */ void crypto_ec_key_deinit(struct crypto_ec_key *key) { - mbedtls_pk_free((mbedtls_pk_context *)key); - os_free(key); + mbedtls_pk_context *pk = (mbedtls_pk_context *) key; + psa_key_id_t key_id; + + if (NULL != key) + { + key_id = pk->MBEDTLS_PRIVATE(priv_id); + mbedtls_pk_free(pk); + psa_destroy_key(key_id); + os_free(key); + } } +/* Internal - from pkwrite.h */ +#define MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES \ + (29 + PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS)) + struct wpabuf *crypto_ec_key_get_subject_public_key(struct crypto_ec_key *key) { - /* (similar to crypto_ec_key_get_pubkey_point(), - * but compressed point format and ASN.1 DER wrapping)*/ -#ifndef MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES /*(mbedtls/library/pkwrite.h)*/ -#define MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES (30 + 2 * MBEDTLS_ECP_MAX_BYTES) -#endif - unsigned char buf[MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES]; - int len = mbedtls_pk_write_pubkey_der((mbedtls_pk_context *)key, buf, sizeof(buf)); - if (len < 0) - return NULL; - /* Note: data is written at the end of the buffer! Use the - * return value to determine where you should start - * using the buffer */ - unsigned char *p = buf + sizeof(buf) - len; + mbedtls_pk_context *pk = (mbedtls_pk_context *)key; + struct wpabuf *tmp = NULL; /* holds the original DER from mbedtls_pk_write_pubkey_der() */ + struct wpabuf *out = NULL; /* final DER with compressed point (or original if not applicable) */ + int der_len; + + tmp = wpabuf_alloc(MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES); + if (!tmp) + return NULL; + + der_len = mbedtls_pk_write_pubkey_der(pk, + wpabuf_mhead(tmp), + wpabuf_size(tmp)); + if (der_len < 0) { + wpabuf_free(tmp); + return NULL; + } + + /* Effective DER lies at the end of the allocated buffer */ + uint8_t *der = wpabuf_mhead_u8(tmp) + wpabuf_size(tmp) - der_len; + uint8_t *end = der + der_len; + /* Parse SPKI: SEQUENCE -> AlgorithmIdentifier(TLV) -> BIT STRING(content) */ + unsigned char *p = der; + size_t seq_len, alg_len, bit_len; + + /* SEQUENCE (SubjectPublicKeyInfo) */ + if (mbedtls_asn1_get_tag(&p, end, &seq_len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) { + goto fail; + } + /* AlgorithmIdentifier (remember full TLV region to copy verbatim later) */ + const uint8_t *alg_tlv_start = p; + if (mbedtls_asn1_get_tag(&p, end, &alg_len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) { + goto fail; + } + const uint8_t *alg_content = p; + p += alg_len; + /* Total bytes of the AlgId TLV (tag + len + contents) */ + size_t alg_tlv_total = (size_t)(alg_content - alg_tlv_start) + alg_len; + + /* subjectPublicKey (BIT STRING) – we only change its contents if uncompressed EC point is present */ + if (mbedtls_asn1_get_tag(&p, end, &bit_len, MBEDTLS_ASN1_BIT_STRING)) { + goto fail; + } + const uint8_t *bit = p; + + /* Expect: 0x00 | 0x04 | X | Y (uncompressed ECPoint) + * If not matching, just return the original DER unchanged. + */ + if (bit_len < 2 || bit[0] != 0x00) { + out = wpabuf_alloc_copy(der, (size_t)der_len); + goto done; + } + if (bit[1] != 0x04) { + /* Already compressed (0x02/0x03) or some other format – keep as-is */ + out = wpabuf_alloc_copy(der, (size_t)der_len); + goto done; + } -#ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED - mbedtls_ecp_keypair *ecp_kp = (mbedtls_ecp_keypair *)mbedtls_pk_ec(*(mbedtls_pk_context *)key); - if (ecp_kp == NULL) - return NULL; - mbedtls_ecp_group *grp = &ecp_kp->MBEDTLS_PRIVATE(grp); - /* Note: sae_pk.c expects pubkey point in compressed format, - * but mbedtls_pk_write_pubkey_der() writes uncompressed format. - * Manually translate format and update lengths in DER format */ - if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) + /* Compute compressed point: 0x02/0x03 || X + * - point_len = len of (0x04 || X || Y), NOT including the initial 'unused bits' byte + * - coord_len = |X| = |Y| + */ + size_t point_len = bit_len - 1; /* drop unused-bits byte */ + if (point_len < 1 || ((point_len - 1) % 2) != 0) { + /* Not in the expected SEC1 uncompressed format – keep as-is */ + out = wpabuf_alloc_copy(der, (size_t)der_len); + goto done; + } + + size_t coord_len = (point_len - 1) / 2; + const uint8_t *X = bit + 2; /* 0x00, 0x04, then X */ + const uint8_t *Y = X + coord_len; + /* Choose 0x02 (even Y) or 0x03 (odd Y) by the least significant bit of Y */ + uint8_t comp_tag = (Y[coord_len - 1] & 1) ? 0x03 : 0x02; + + /* New BIT STRING content size: 0x00 | 0x02/0x03 | X */ + size_t new_bit_len = 1 + 1 + coord_len; + + /* Rebuild a fresh SPKI with the compressed point using backward ASN.1 writer */ + uint8_t newbuf[MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES]; + uint8_t *w = newbuf + sizeof(newbuf); + size_t total = 0; + + /* BIT STRING content (compressed) */ + w -= new_bit_len; + w[0] = 0x00; /* number of unused bits */ + w[1] = comp_tag; /* 0x02 or 0x03 */ + memcpy(w + 2, X, coord_len); + total += new_bit_len; + + /* BIT STRING TL */ { - unsigned char *end = buf + sizeof(buf); - size_t n; - /* SubjectPublicKeyInfo SEQUENCE */ - mbedtls_asn1_get_tag(&p, end, &n, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); - /* algorithm AlgorithmIdentifier */ - unsigned char *a = p; - size_t alen; - int ret; - mbedtls_asn1_get_tag(&p, end, &alen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); - p += alen; - alen = (size_t)(p - a); - /* subjectPublicKey BIT STRING */ - mbedtls_asn1_get_tag(&p, end, &n, MBEDTLS_ASN1_BIT_STRING); - /* rewrite into compressed point format and rebuild ASN.1 */ - p[1] = (buf[sizeof(buf) - 1] & 1) ? 0x03 : 0x02; - n = 1 + 1 + (n - 2) / 2; - len = mbedtls_asn1_write_len(&p, buf, n) + (int)n; - len += mbedtls_asn1_write_tag(&p, buf, MBEDTLS_ASN1_BIT_STRING); - os_memmove(p - alen, a, alen); - len += alen; - p -= alen; - if ((ret = mbedtls_asn1_write_len(&p, buf, (size_t)len)) < 0) - { - return NULL; - } - len += ret; - if ((ret = mbedtls_asn1_write_tag(&p, buf, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) < 0) - { - return NULL; - } - len += ret; + int t = mbedtls_asn1_write_len(&w, newbuf, new_bit_len); + if (t < 0) + goto fail; + + total += (size_t)t; + t = mbedtls_asn1_write_tag(&w, newbuf, MBEDTLS_ASN1_BIT_STRING); + if (t < 0) + goto fail; + + total += (size_t)t; } -#endif - return wpabuf_alloc_copy(p, (size_t)len); + + /* Copy AlgorithmIdentifier TLV as-is */ + w -= alg_tlv_total; + memcpy(w, alg_tlv_start, alg_tlv_total); + total += alg_tlv_total; + + /* Wrap everything in the outer SEQUENCE (SPKI) */ + int t = mbedtls_asn1_write_len(&w, newbuf, total); + if (t < 0) + goto fail; + + total += (size_t)t; + + t = mbedtls_asn1_write_tag(&w, newbuf, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); + if (t < 0) + goto fail; + + total += (size_t)t; + + out = wpabuf_alloc_copy(w, total); +done: + wpabuf_free(tmp); + return out; + +fail: + wpabuf_free(tmp); + return NULL; } #ifdef CRYPTO_MBEDTLS_CRYPTO_EC_DPP + +/* Internal - from pkwrite.h */ +#define MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES \ + (8 + PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS) + \ + 16 + 4 + PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS)) + struct wpabuf *crypto_ec_key_get_ecprivate_key(struct crypto_ec_key *key, bool include_pub) { -#ifndef MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES /*(mbedtls/library/pkwrite.h)*/ -#define MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES (29 + 3 * MBEDTLS_ECP_MAX_BYTES) -#endif - unsigned char priv[MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES]; - int privlen = mbedtls_pk_write_key_der((mbedtls_pk_context *)key, priv, sizeof(priv)); - if (privlen < 0) + mbedtls_pk_context *pk = (mbedtls_pk_context *) key; + struct wpabuf *buf, *buf2; + uint8_t *p; + int ret; + + buf = wpabuf_alloc(MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES); + if (buf == NULL) { return NULL; + } - struct wpabuf *wbuf; + /* The buffer is written starting from the end! "ret" is the amount of data written. */ + ret = mbedtls_pk_write_key_der(pk, wpabuf_mhead(buf), wpabuf_size(buf)); + if (ret < 0) { + wpabuf_free(buf); + return NULL; + } - /* Note: data is written at the end of the buffer! Use the - * return value to determine where you should start - * using the buffer */ - /* mbedtls_pk_write_key_der() includes publicKey in DER */ - if (include_pub) - wbuf = wpabuf_alloc_copy(priv + sizeof(priv) - privlen, privlen); - else - { - /* calculate publicKey offset and skip from end of buffer */ - unsigned char *p = priv + sizeof(priv) - privlen; - unsigned char *end = priv + sizeof(priv); - size_t len; - int ret; - /* ECPrivateKey SEQUENCE */ - mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); - /* version INTEGER */ - unsigned char *v = p; - mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_INTEGER); - p += len; - /* privateKey OCTET STRING */ - mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING); - p += len; - /* parameters ECParameters */ - mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED); - p += len; + p = wpabuf_mhead_u8(buf) + wpabuf_size(buf) - ret; - /* write new SEQUENCE header (we know that it fits in priv[]) */ - len = (size_t)(p - v); - p = v; - if ((ret = mbedtls_asn1_write_len(&p, priv, len)) < 0) - { - return NULL; - } - len += ret; - if ((ret = mbedtls_asn1_write_tag(&p, priv, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) < 0) - { - return NULL; - } - len += ret; - wbuf = wpabuf_alloc_copy(p, len); - } + buf2 = wpabuf_alloc_copy(p, ret); + wpabuf_free(buf); - forced_memzero(priv, sizeof(priv)); - return wbuf; + return buf2; } struct wpabuf *crypto_ec_key_get_pubkey_point(struct crypto_ec_key *key, int prefix) { - /*(similarities to crypto_ecdh_get_pubkey(), but different struct)*/ - mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key); - if (ecp_kp == NULL) - return NULL; - mbedtls_ecp_group *grp = &ecp_kp->MBEDTLS_PRIVATE(grp); - size_t len = CRYPTO_EC_plen(grp); -#ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED - /* len */ -#endif -#ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED - if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) - len = len * 2 + 1; -#endif - struct wpabuf *buf = wpabuf_alloc(len); - if (buf == NULL) + mbedtls_pk_context *pk = (mbedtls_pk_context *) key; + uint8_t *key_ptr = pk->MBEDTLS_PRIVATE(pub_raw); + size_t key_len = pk->MBEDTLS_PRIVATE(pub_raw_len); + struct wpabuf *buf; + + if (prefix) { + buf = wpabuf_alloc_copy(key_ptr, key_len); + } else { + buf = wpabuf_alloc_copy(key_ptr + 1, key_len - 1); + } + if (buf == NULL) { return NULL; - mbedtls_ecp_point *ecp_kp_Q = &ecp_kp->MBEDTLS_PRIVATE(Q); - if (mbedtls_ecp_point_write_binary(grp, ecp_kp_Q, MBEDTLS_ECP_PF_UNCOMPRESSED, &len, wpabuf_mhead_u8(buf), len) == - 0) - { - if (!prefix) /* Remove 0x04 prefix if requested */ - os_memmove(wpabuf_mhead(buf), ((u8 *)wpabuf_mhead(buf) + 1), --len); - wpabuf_put(buf, len); - return buf; } - wpabuf_free(buf); - return NULL; + return buf; } struct crypto_ec_point *crypto_ec_key_get_public_key(struct crypto_ec_key *key) { - mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key); - if (ecp_kp == NULL) + mbedtls_pk_context *pk = (mbedtls_pk_context *) key; + uint8_t *key_ptr = pk->MBEDTLS_PRIVATE(pub_raw); + size_t key_len = pk->MBEDTLS_PRIVATE(pub_raw_len); + mbedtls_ecp_point *ecp_point; + mbedtls_ecp_group ecp_group; + mbedtls_ecp_group_id ecp_group_id; + int ret; + + ecp_group_id = mbedtls_ecc_group_from_psa(pk->MBEDTLS_PRIVATE(ec_family), + pk->MBEDTLS_PRIVATE(bits)); + if (ecp_group_id == 0) { return NULL; - mbedtls_ecp_point *p = os_malloc(sizeof(*p)); - if (p != NULL) - { - /*(mbedtls_ecp_export() uses &ecp_kp->MBEDTLS_PRIVATE(grp))*/ - mbedtls_ecp_point_init(p); - mbedtls_ecp_point *ecp_kp_Q = &ecp_kp->MBEDTLS_PRIVATE(Q); - if (mbedtls_ecp_copy(p, ecp_kp_Q)) - { - mbedtls_ecp_point_free(p); - os_free(p); - p = NULL; - } } - return (struct crypto_ec_point *)p; + + ecp_point = os_malloc(sizeof(mbedtls_ecp_point)); + if (ecp_point == NULL) { + return NULL; + } + + mbedtls_ecp_point_init(ecp_point); + mbedtls_ecp_group_init(&ecp_group); + if (mbedtls_ecp_group_load(&ecp_group, ecp_group_id) != 0) { + os_free(ecp_point); + return NULL; + } + ret = mbedtls_ecp_point_read_binary(&ecp_group, ecp_point, key_ptr, key_len); + mbedtls_ecp_group_free(&ecp_group); + if (ret != 0) { + os_free(ecp_point); + return NULL; + } + + return (struct crypto_ec_point *) ecp_point; } struct crypto_bignum *crypto_ec_key_get_private_key(struct crypto_ec_key *key) { - mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key); - if (ecp_kp == NULL) + mbedtls_pk_context *pk = (mbedtls_pk_context *) key; + uint8_t priv_key[PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS)] = { 0 }; + size_t priv_key_len; + mbedtls_mpi *mpi; + + mpi = os_malloc(sizeof(mbedtls_mpi)); + if (mpi == NULL) { return NULL; - mbedtls_mpi *bn = os_malloc(sizeof(*bn)); - if (bn) - { - /*(mbedtls_ecp_export() uses &ecp_kp->MBEDTLS_PRIVATE(grp))*/ - mbedtls_mpi_init(bn); - mbedtls_mpi *ecp_kp_d = &ecp_kp->MBEDTLS_PRIVATE(d); - if (mbedtls_mpi_copy(bn, ecp_kp_d)) - { - mbedtls_mpi_free(bn); - os_free(bn); - bn = NULL; - } } - return (struct crypto_bignum *)bn; + + mbedtls_mpi_init(mpi); + if (psa_export_key(pk->MBEDTLS_PRIVATE(priv_id), priv_key, sizeof(priv_key), &priv_key_len) != PSA_SUCCESS) { + os_free(mpi); + return NULL; + } + + if (mbedtls_mpi_read_binary(mpi, priv_key, priv_key_len) != 0) { + memset(priv_key, 0, sizeof(priv_key)); + os_free(mpi); + return NULL; + } + + return (struct crypto_bignum *) mpi; } #endif /* CRYPTO_MBEDTLS_CRYPTO_EC_DPP */ @@ -2804,93 +2914,65 @@ static mbedtls_md_type_t crypto_ec_key_sign_md(size_t len) struct wpabuf *crypto_ec_key_sign(struct crypto_ec_key *key, const u8 *data, size_t len) { -#ifndef MBEDTLS_PK_SIGNATURE_MAX_SIZE /*(defined since mbedtls 2.20.0)*/ -#if MBEDTLS_ECDSA_MAX_LEN > MBEDTLS_MPI_MAX_SIZE -#define MBEDTLS_PK_SIGNATURE_MAX_SIZE MBEDTLS_ECDSA_MAX_LEN -#else -#define MBEDTLS_PK_SIGNATURE_MAX_SIZE MBEDTLS_MPI_MAX_SIZE -#endif -#endif - size_t sig_len = MBEDTLS_PK_SIGNATURE_MAX_SIZE; - struct wpabuf *buf = wpabuf_alloc(sig_len); - if (buf == NULL) + mbedtls_pk_context *pk = (mbedtls_pk_context *) key; + mbedtls_md_type_t md_alg = crypto_ec_key_sign_md(len); + uint8_t sig[MBEDTLS_PK_SIGNATURE_MAX_SIZE]; + struct wpabuf *buf; + size_t sig_len; + + if (mbedtls_pk_sign(pk, md_alg, data, len, sig, sizeof(sig), &sig_len) != 0) { return NULL; - if (mbedtls_pk_sign((mbedtls_pk_context *)key, crypto_ec_key_sign_md(len), data, len, wpabuf_mhead_u8(buf), - sig_len, - &sig_len, hostap_rng_fn, hostap_rng_ctx()) == 0) - { - wpabuf_put(buf, sig_len); - return buf; } - wpabuf_free(buf); - return NULL; + buf = wpabuf_alloc_copy(sig, sig_len); + if (buf == NULL) { + return NULL; + } + + return buf; } #ifdef CRYPTO_MBEDTLS_CRYPTO_EC_DPP struct wpabuf *crypto_ec_key_sign_r_s(struct crypto_ec_key *key, const u8 *data, size_t len) { - mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key); - if (ecp_kp == NULL) - return NULL; + mbedtls_pk_context *pk = (mbedtls_pk_context *) key; + mbedtls_md_type_t md_alg = crypto_ec_key_sign_md(len); + uint8_t sig[MBEDTLS_PK_SIGNATURE_MAX_SIZE]; + uint8_t sig_raw[MBEDTLS_PK_SIGNATURE_MAX_SIZE]; + size_t sig_len, sig_raw_len; + size_t bits; + struct wpabuf *buf; - size_t sig_len = MBEDTLS_ECDSA_MAX_LEN; - u8 buf[MBEDTLS_ECDSA_MAX_LEN]; - if (mbedtls_ecdsa_write_signature(ecp_kp, crypto_ec_key_sign_md(len), data, len, buf, - sig_len, - &sig_len, hostap_rng_fn, hostap_rng_ctx())) - { + if (mbedtls_pk_sign(pk, md_alg, data, len, sig, sizeof(sig), &sig_len) != 0) { return NULL; } - /*(mbedtls_ecdsa_write_signature() writes signature in ASN.1)*/ - /* parse ASN.1 to get r and s and lengths */ - u8 *p = buf, *r, *s; - u8 *end = p + sig_len; - size_t rlen, slen; - mbedtls_asn1_get_tag(&p, end, &rlen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); - mbedtls_asn1_get_tag(&p, end, &rlen, MBEDTLS_ASN1_INTEGER); - r = p; - p += rlen; - mbedtls_asn1_get_tag(&p, end, &slen, MBEDTLS_ASN1_INTEGER); - s = p; - - /* write raw r and s into out - * (including removal of leading 0 if added for ASN.1 integer) - * note: DPP caller expects raw r, s each padded to prime len */ - mbedtls_ecp_group *ecp_kp_grp = &ecp_kp->MBEDTLS_PRIVATE(grp); - size_t plen = CRYPTO_EC_plen(ecp_kp_grp); - if (rlen > plen) - { - r += (rlen - plen); - rlen = plen; - } - if (slen > plen) - { - s += (slen - plen); - slen = plen; + bits = mbedtls_pk_get_bitlen(pk); + if (mbedtls_ecdsa_der_to_raw(bits, sig, sig_len, sig_raw, sizeof(sig_raw), &sig_raw_len) != 0) { + return NULL; } - struct wpabuf *out = wpabuf_alloc(plen * 2); - if (out) - { - wpabuf_put(out, plen * 2); - p = wpabuf_mhead_u8(out); - os_memset(p, 0, plen * 2); - os_memcpy(p + plen * 1 - rlen, r, rlen); - os_memcpy(p + plen * 2 - slen, s, slen); + + buf = wpabuf_alloc_copy(sig_raw, sig_raw_len); + if (buf == NULL) { + return NULL; } - return out; + + return buf; } #endif /* CRYPTO_MBEDTLS_CRYPTO_EC_DPP */ -int crypto_ec_key_verify_signature(struct crypto_ec_key *key, const u8 *data, size_t len, const u8 *sig, size_t sig_len) +int crypto_ec_key_verify_signature(struct crypto_ec_key *key, const u8 *data, size_t len, + const u8 *sig, size_t sig_len) { - switch (mbedtls_pk_verify((mbedtls_pk_context *)key, crypto_ec_key_sign_md(len), data, len, sig, sig_len)) - { + mbedtls_pk_context *pk = (mbedtls_pk_context *) key; + mbedtls_md_type_t md_alg = crypto_ec_key_sign_md(len); + int ret; + + ret = mbedtls_pk_verify(pk, md_alg, data, len, sig, sig_len); + switch (ret) { case 0: - /*case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:*/ /* XXX: allow? */ return 1; - case MBEDTLS_ERR_ECP_VERIFY_FAILED: + case PSA_ERROR_INVALID_SIGNATURE: return 0; default: return -1; @@ -2898,55 +2980,55 @@ int crypto_ec_key_verify_signature(struct crypto_ec_key *key, const u8 *data, si } #ifdef CRYPTO_MBEDTLS_CRYPTO_EC_DPP -int crypto_ec_key_verify_signature_r_s( - struct crypto_ec_key *key, const u8 *data, size_t len, const u8 *r, size_t r_len, const u8 *s, size_t s_len) +int crypto_ec_key_verify_signature_r_s(struct crypto_ec_key *key, const u8 *data, size_t len, + const u8 *r, size_t r_len, const u8 *s, size_t s_len) { - /* reimplement mbedtls_ecdsa_read_signature() without encoding r and s - * into ASN.1 just for mbedtls_ecdsa_read_signature() to decode ASN.1 */ - mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key); - if (ecp_kp == NULL) + mbedtls_pk_context *pk = (mbedtls_pk_context *) key; + uint8_t sig[MBEDTLS_PK_SIGNATURE_MAX_SIZE] = { 0 }; + uint8_t sig_raw[MBEDTLS_PK_SIGNATURE_MAX_SIZE] = { 0 }; + size_t bits, sig_raw_len, sig_len; + + memcpy(sig_raw, r, r_len); + memcpy(sig_raw + r_len, s, s_len); + sig_raw_len = r_len + s_len; + + bits = mbedtls_pk_get_bitlen(pk); + if (mbedtls_ecdsa_raw_to_der(bits, sig_raw, sig_raw_len, sig, sizeof(sig), &sig_len) != 0) { return -1; - mbedtls_ecp_group *ecp_kp_grp = &ecp_kp->MBEDTLS_PRIVATE(grp); - mbedtls_ecp_point *ecp_kp_Q = &ecp_kp->MBEDTLS_PRIVATE(Q); - - mbedtls_mpi mpi_r; - mbedtls_mpi mpi_s; - mbedtls_mpi_init(&mpi_r); - mbedtls_mpi_init(&mpi_s); - int ret = mbedtls_mpi_read_binary(&mpi_r, r, r_len) || mbedtls_mpi_read_binary(&mpi_s, s, s_len) ? -1 : 0; - if (ret == 0) - { - ret = mbedtls_ecdsa_verify(ecp_kp_grp, data, len, ecp_kp_Q, &mpi_r, &mpi_s); - ret = ret ? ret == MBEDTLS_ERR_ECP_BAD_INPUT_DATA ? 0 : -1 : 1; } - mbedtls_mpi_free(&mpi_r); - mbedtls_mpi_free(&mpi_s); - return ret; + + return crypto_ec_key_verify_signature(key, data, len, sig, sig_len); } #endif /* CRYPTO_MBEDTLS_CRYPTO_EC_DPP */ int crypto_ec_key_group(struct crypto_ec_key *key) { - mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key); - if (ecp_kp == NULL) - return -1; - mbedtls_ecp_group *ecp_group = &ecp_kp->MBEDTLS_PRIVATE(grp); - return crypto_mbedtls_ike_id_from_ecp_group_id(ecp_group->id); + mbedtls_pk_context *pk = (mbedtls_pk_context *) key; + mbedtls_ecp_group_id ecp_group_id; + + ecp_group_id = mbedtls_ecc_group_from_psa(pk->MBEDTLS_PRIVATE(ec_family), + pk->MBEDTLS_PRIVATE(bits)); + return crypto_mbedtls_ike_id_from_ecp_group_id(ecp_group_id); } #ifdef CRYPTO_MBEDTLS_CRYPTO_EC_DPP int crypto_ec_key_cmp(struct crypto_ec_key *key1, struct crypto_ec_key *key2) { - mbedtls_ecp_keypair *ecp_kp1 = mbedtls_pk_ec(*(mbedtls_pk_context *)key1); - mbedtls_ecp_keypair *ecp_kp2 = mbedtls_pk_ec(*(mbedtls_pk_context *)key2); - if (ecp_kp1 == NULL || ecp_kp2 == NULL) + mbedtls_pk_context *pk1 = (mbedtls_pk_context *) key1; + mbedtls_pk_context *pk2 = (mbedtls_pk_context *) key2; + + if (pk1->MBEDTLS_PRIVATE(pub_raw_len) != pk2->MBEDTLS_PRIVATE(pub_raw_len)) { return -1; - mbedtls_ecp_group *ecp_kp1_grp = &ecp_kp1->MBEDTLS_PRIVATE(grp); - mbedtls_ecp_group *ecp_kp2_grp = &ecp_kp2->MBEDTLS_PRIVATE(grp); - mbedtls_ecp_point *ecp_kp1_Q = &ecp_kp1->MBEDTLS_PRIVATE(Q); - mbedtls_ecp_point *ecp_kp2_Q = &ecp_kp2->MBEDTLS_PRIVATE(Q); - return ecp_kp1_grp->id != ecp_kp2_grp->id || mbedtls_ecp_point_cmp(ecp_kp1_Q, ecp_kp2_Q) ? -1 : 0; + } + + if (memcmp(pk1->MBEDTLS_PRIVATE(pub_raw), + pk2->MBEDTLS_PRIVATE(pub_raw), + pk1->MBEDTLS_PRIVATE(pub_raw_len)) != 0) { + return -1; + } + + return 0; } void crypto_ec_key_debug_print(const struct crypto_ec_key *key, const char *title) @@ -3011,19 +3093,19 @@ struct crypto_csr *crypto_csr_verify(const struct wpabuf *req) void crypto_csr_deinit(struct crypto_csr *csr) { - if ((uintptr_t)csr & 1uL) - { + if ((uintptr_t)csr & 1uL) { csr = (struct crypto_csr *)((uintptr_t)csr & ~1uL); - mbedtls_x509_csr_free((mbedtls_x509_csr *)csr); } - else - mbedtls_x509write_csr_free((mbedtls_x509write_csr *)csr); + + mbedtls_x509_csr *csr_ctx = (mbedtls_x509_csr *) csr; + mbedtls_x509_csr_free(csr_ctx); os_free(csr); } int crypto_csr_set_ec_public_key(struct crypto_csr *csr, struct crypto_ec_key *key) { - mbedtls_x509write_csr_set_key((mbedtls_x509write_csr *)csr, (mbedtls_pk_context *)key); + mbedtls_x509write_csr_set_key((mbedtls_x509write_csr *) csr, (mbedtls_pk_context *) key); + return 0; } @@ -3204,7 +3286,7 @@ struct wpabuf *crypto_csr_sign(struct crypto_csr *csr, struct crypto_ec_key *key mbedtls_x509write_csr_set_md_alg((mbedtls_x509write_csr *)csr, sig_md); unsigned char buf[4096]; /* XXX: large enough? too large? */ - int len = mbedtls_x509write_csr_der((mbedtls_x509write_csr *)csr, buf, sizeof(buf), hostap_rng_fn, hostap_rng_ctx()); + int len = mbedtls_x509write_csr_der((mbedtls_x509write_csr *)csr, buf, sizeof(buf)); if (len < 0) return NULL; /* Note: data is written at the end of the buffer! Use the diff --git a/src/crypto/crypto_module_tests.c b/src/crypto/crypto_module_tests.c index ffeddbaddf..c92c15d574 100644 --- a/src/crypto/crypto_module_tests.c +++ b/src/crypto/crypto_module_tests.c @@ -19,6 +19,7 @@ #include "crypto/sha256.h" #include "crypto/sha384.h" +#define CONFIG_FIPS static int test_siv(void) { diff --git a/src/crypto/tls_mbedtls_alt.c b/src/crypto/tls_mbedtls_alt.c index a478e2d255..47af15b4a7 100644 --- a/src/crypto/tls_mbedtls_alt.c +++ b/src/crypto/tls_mbedtls_alt.c @@ -47,8 +47,8 @@ #ifndef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_NONE +#include #include -#include #include #include #include @@ -58,10 +58,7 @@ #include #include #include -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) -#include <../library/ssl_misc.h> -#include <../library/ssl_tls13_keys.h> -#endif +#include extern int (*hostap_rng_fn)(void*, unsigned char*, size_t); extern void* hostap_rng_ctx(void); @@ -163,7 +160,6 @@ struct tls_global { struct tls_conf *tls_conf; char *ocsp_stapling_response; - mbedtls_ctr_drbg_context *ctr_drbg; /*(see crypto_mbedtls.c)*/ #ifdef MBEDTLS_SSL_SESSION_TICKETS mbedtls_ssl_ticket_context ticket_ctx; #endif @@ -327,7 +323,6 @@ struct tls_conf *tls_conf_init(void *tls_ctx) tls_conf->refcnt = 1; mbedtls_ssl_config_init(&tls_conf->conf); - mbedtls_ssl_conf_rng(&tls_conf->conf, hostap_rng_fn, hostap_rng_ctx()); mbedtls_x509_crt_init(&tls_conf->ca_cert); mbedtls_x509_crt_init(&tls_conf->client_cert); mbedtls_pk_init(&tls_conf->private_key); @@ -365,10 +360,6 @@ struct tls_conf *tls_conf_deinit(struct tls_conf *tls_conf) return NULL; } -#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) -mbedtls_ctr_drbg_context *crypto_mbedtls_ctr_drbg(void); /*(not in header)*/ -#endif - __attribute_cold__ void *tls_init(const struct tls_config *conf) { /* RFE: review struct tls_config *conf (different from tls_conf) */ @@ -376,13 +367,14 @@ __attribute_cold__ void *tls_init(const struct tls_config *conf) if (++tls_ctx_global.refcnt > 1) return &tls_ctx_global; -#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) - tls_ctx_global.ctr_drbg = crypto_mbedtls_ctr_drbg(); -#endif #ifdef MBEDTLS_SSL_SESSION_TICKETS mbedtls_ssl_ticket_init(&tls_ctx_global.ticket_ctx); - mbedtls_ssl_ticket_setup(&tls_ctx_global.ticket_ctx, hostap_rng_fn, hostap_rng_ctx(), - MBEDTLS_CIPHER_AES_256_GCM, 43200); /* ticket timeout: 12 hours */ + if (mbedtls_ssl_ticket_setup(&tls_ctx_global.ticket_ctx, PSA_ALG_GCM, PSA_KEY_TYPE_AES, 256, + 43200) != 0) /* ticket timeout: 12 hours */ + { + wpa_printf(MSG_ERROR, "Failed to setup SSL ticket context"); + return NULL; + } #endif /* copy struct for future use */ tls_ctx_global.init_conf = *conf; @@ -846,129 +838,62 @@ static const int suite_AES_256_ephemeral[] = { /* All AES-256 ephemeral suites */ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, - MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM, - MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM, MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, - MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, - MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA, MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, - MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8}; +}; /* data copied from lighttpd src/mod_mbedtls.c (BSD-3-Clause) */ static const int suite_AES_128_ephemeral[] = { /* All AES-128 ephemeral suites */ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, - MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM, - MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM, MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, - MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, - MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA, MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, - MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8}; +}; /* data copied from lighttpd src/mod_mbedtls.c (BSD-3-Clause) */ /* HIGH cipher list (mapped from openssl list to mbedtls) */ static const int suite_HIGH[] = {MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, - MBEDTLS_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, - MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM, - MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM, MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, - MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, - MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA, MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, - MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8, MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384, - MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256, - MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384, MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384, - MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384, MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, - MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM, - MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM, MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, - MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, - MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA, MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, - MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8, MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, - MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, - MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256, MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256, - MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256, MBEDTLS_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256, - MBEDTLS_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256, - MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, - MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM, MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, - MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, - MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA, MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, - MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, - MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM_8, - MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384, - MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256, - MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM, MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, - MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, - MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA, - MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, - MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM_8, - MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256, - MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384, - MBEDTLS_TLS_RSA_WITH_AES_256_CCM, - MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256, - MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA, - MBEDTLS_TLS_RSA_WITH_AES_256_CCM_8, - MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256, - MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, - MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384, - MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256, - MBEDTLS_TLS_RSA_WITH_AES_128_CCM, - MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256, - MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA, - MBEDTLS_TLS_RSA_WITH_AES_128_CCM_8, - MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256, - MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, - MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256, - MBEDTLS_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256, - MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384, - MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, - MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA, - MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384, - MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384, - MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256, - MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256, - MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA, - MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256, - MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256, MBEDTLS_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256, MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384, MBEDTLS_TLS_PSK_WITH_AES_256_CCM, @@ -1483,7 +1408,7 @@ static int tls_mbedtls_set_certs(struct tls_conf *tls_conf, const struct tls_con } const char *pwd = params->private_key_passwd; ret = mbedtls_pk_parse_key(&tls_conf->private_key, data, len, (const unsigned char *)pwd, - pwd ? os_strlen(pwd) : 0, hostap_rng_fn, hostap_rng_ctx()); + pwd ? os_strlen(pwd) : 0); if (params->private_key) { forced_memzero(data, len); @@ -1517,7 +1442,7 @@ static const mbedtls_x509_crt_profile tls_mbedtls_crt_profile_suiteb128 = { /* Only SHA-256 and 384 */ MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA256) | MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA384), /* Only ECDSA */ - MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_ECDSA) | MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_ECKEY), + MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_SIGALG_ECDSA), #if defined(MBEDTLS_ECP_C) /* Only NIST P-256 and P-384 */ MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP256R1) | MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP384R1), @@ -1534,7 +1459,7 @@ static const mbedtls_x509_crt_profile tls_mbedtls_crt_profile_suiteb192 = { /* Only SHA-384 */ MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA384), /* Only ECDSA */ - MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_ECDSA) | MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_ECKEY), + MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_SIGALG_ECDSA), #if defined(MBEDTLS_ECP_C) /* Only NIST P-384 */ MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP384R1), @@ -2091,15 +2016,23 @@ struct wpabuf *tls_connection_handshake(void *tls_ctx, mbedtls_ssl_set_hostname(&conn->ssl, NULL); } -#if MBEDTLS_VERSION_NUMBER >= 0x03020000 /* mbedtls 3.2.0 */ +#if defined(MBEDTLS_SSL_PROTO_TLS1_3) if (conn->ssl.MBEDTLS_PRIVATE(state) == MBEDTLS_SSL_HANDSHAKE_OVER && conn->ssl.MBEDTLS_PRIVATE(tls_version) == MBEDTLS_SSL_VERSION_TLS1_3) { int res = 0; *appl_data = wpabuf_alloc(wpabuf_len(in_data)); +retry: res = mbedtls_ssl_read(&conn->ssl, wpabuf_mhead(*appl_data), wpabuf_size(*appl_data)); if (res < 0) { +#if defined(MBEDTLS_SSL_SESSION_TICKETS) + if (MBEDTLS_ERR_SSL_WANT_READ == res || + MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET == res) + { + goto retry; + } +#endif wpa_printf(MSG_DEBUG, "%s failed: 0x%x", __func__, res); ret = -1; } @@ -2107,16 +2040,8 @@ struct wpabuf *tls_connection_handshake(void *tls_ctx, wpabuf_put(*appl_data, res); } else - ret = mbedtls_ssl_handshake(&conn->ssl); -#else - int ret = 0; - while (conn->ssl.MBEDTLS_PRIVATE(state) != MBEDTLS_SSL_HANDSHAKE_OVER) - { - ret = mbedtls_ssl_handshake_step(&conn->ssl); - if (ret != 0) - break; - } #endif + ret = mbedtls_ssl_handshake(&conn->ssl); #ifdef TLS_MBEDTLS_SESSION_TICKETS mbedtls_ssl_conf_session_tickets_cb(&conn->tls_conf->conf, tls_mbedtls_ssl_ticket_write, @@ -2375,8 +2300,7 @@ int tls_get_library_version(char *buf, size_t buf_len) #ifndef MBEDTLS_VERSION_C const char *const ver = "n/a"; #else - char ver[9]; - mbedtls_version_get_string(ver); + const char *ver = mbedtls_version_get_string(); #endif return os_snprintf(buf, buf_len, "mbed TLS build=" MBEDTLS_VERSION_STRING " run=%s", ver); } @@ -3020,8 +2944,8 @@ static int tls_mbedtls_verify_cb(void *arg, mbedtls_x509_crt *crt, int depth, ui if (tls_conf->flags & TLS_CONN_SUITEB) { /* check RSA modulus size (public key bitlen) */ - const mbedtls_pk_type_t pk_alg = mbedtls_pk_get_type(&crt->pk); - if ((pk_alg == MBEDTLS_PK_RSA || pk_alg == MBEDTLS_PK_RSASSA_PSS) + const psa_key_type_t key_type = mbedtls_pk_get_key_type(&crt->pk); + if (PSA_KEY_TYPE_IS_RSA(key_type) #ifdef CONFIG_SUITEB192 && mbedtls_pk_get_bitlen(&crt->pk) < 3072 #else