Merge remote-tracking branch 'origin/development' into sha3-updated
diff --git a/library/.gitignore b/library/.gitignore
index 18cd305..b4dc918 100644
--- a/library/.gitignore
+++ b/library/.gitignore
@@ -1,4 +1,3 @@
-*.o
libmbed*
*.sln
*.vcxproj
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index b60728c..8e70c46 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -42,7 +42,6 @@
entropy_poll.c
error.c
gcm.c
- hash_info.c
hkdf.c
hmac_drbg.c
lmots.c
@@ -69,6 +68,7 @@
psa_crypto_client.c
psa_crypto_driver_wrappers.c
psa_crypto_ecp.c
+ psa_crypto_ffdh.c
psa_crypto_hash.c
psa_crypto_mac.c
psa_crypto_pake.c
diff --git a/library/Makefile b/library/Makefile
index 4e02bcd..fafcdda 100644
--- a/library/Makefile
+++ b/library/Makefile
@@ -107,7 +107,6 @@
entropy_poll.o \
error.o \
gcm.o \
- hash_info.o \
hkdf.o \
hmac_drbg.o \
lmots.o \
@@ -134,6 +133,7 @@
psa_crypto_client.o \
psa_crypto_driver_wrappers.o \
psa_crypto_ecp.o \
+ psa_crypto_ffdh.o \
psa_crypto_hash.o \
psa_crypto_mac.o \
psa_crypto_pake.o \
diff --git a/library/base64.c b/library/base64.c
index 4170610..3eb9e7c 100644
--- a/library/base64.c
+++ b/library/base64.c
@@ -17,6 +17,8 @@
* limitations under the License.
*/
+#include <limits.h>
+
#include "common.h"
#if defined(MBEDTLS_BASE64_C)
@@ -31,8 +33,6 @@
#include "mbedtls/platform.h"
#endif /* MBEDTLS_SELF_TEST */
-#define BASE64_SIZE_T_MAX ((size_t) -1) /* SIZE_T_MAX is not standard */
-
/*
* Encode a buffer into base64 format
*/
@@ -50,8 +50,8 @@
n = slen / 3 + (slen % 3 != 0);
- if (n > (BASE64_SIZE_T_MAX - 1) / 4) {
- *olen = BASE64_SIZE_T_MAX;
+ if (n > (SIZE_MAX - 1) / 4) {
+ *olen = SIZE_MAX;
return MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL;
}
diff --git a/library/bignum.c b/library/bignum.c
index 2421c1a..36effaf 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -54,8 +54,6 @@
#define MPI_VALIDATE(cond) \
MBEDTLS_INTERNAL_VALIDATE(cond)
-#define MPI_SIZE_T_MAX ((size_t) -1) /* SIZE_T_MAX is not standard */
-
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_mpi_zeroize(mbedtls_mpi_uint *v, size_t n)
{
@@ -416,7 +414,7 @@
slen = strlen(s);
if (radix == 16) {
- if (slen > MPI_SIZE_T_MAX >> 2) {
+ if (slen > SIZE_MAX >> 2) {
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
}
@@ -750,13 +748,9 @@
int mbedtls_mpi_shift_l(mbedtls_mpi *X, size_t count)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- size_t i, v0, t1;
- mbedtls_mpi_uint r0 = 0, r1;
+ size_t i;
MPI_VALIDATE_RET(X != NULL);
- v0 = count / (biL);
- t1 = count & (biL - 1);
-
i = mbedtls_mpi_bitlen(X) + count;
if (X->n * biL < i) {
@@ -765,31 +759,7 @@
ret = 0;
- /*
- * shift by count / limb_size
- */
- if (v0 > 0) {
- for (i = X->n; i > v0; i--) {
- X->p[i - 1] = X->p[i - v0 - 1];
- }
-
- for (; i > 0; i--) {
- X->p[i - 1] = 0;
- }
- }
-
- /*
- * shift by count % limb_size
- */
- if (t1 > 0) {
- for (i = v0; i < X->n; i++) {
- r1 = X->p[i] >> (biL - t1);
- X->p[i] <<= t1;
- X->p[i] |= r0;
- r0 = r1;
- }
- }
-
+ mbedtls_mpi_core_shift_l(X->p, X->n, count);
cleanup:
return ret;
diff --git a/library/bignum_core.c b/library/bignum_core.c
index b0ffa37..de57cfc 100644
--- a/library/bignum_core.c
+++ b/library/bignum_core.c
@@ -366,6 +366,41 @@
}
}
+void mbedtls_mpi_core_shift_l(mbedtls_mpi_uint *X, size_t limbs,
+ size_t count)
+{
+ size_t i, v0, v1;
+ mbedtls_mpi_uint r0 = 0, r1;
+
+ v0 = count / (biL);
+ v1 = count & (biL - 1);
+
+ /*
+ * shift by count / limb_size
+ */
+ if (v0 > 0) {
+ for (i = limbs; i > v0; i--) {
+ X[i - 1] = X[i - v0 - 1];
+ }
+
+ for (; i > 0; i--) {
+ X[i - 1] = 0;
+ }
+ }
+
+ /*
+ * shift by count % limb_size
+ */
+ if (v1 > 0) {
+ for (i = v0; i < limbs; i++) {
+ r1 = X[i] >> (biL - v1);
+ X[i] <<= v1;
+ X[i] |= r0;
+ r0 = r1;
+ }
+ }
+}
+
mbedtls_mpi_uint mbedtls_mpi_core_add(mbedtls_mpi_uint *X,
const mbedtls_mpi_uint *A,
const mbedtls_mpi_uint *B,
diff --git a/library/bignum_core.h b/library/bignum_core.h
index 158d2b3..21a5a11 100644
--- a/library/bignum_core.h
+++ b/library/bignum_core.h
@@ -281,7 +281,7 @@
unsigned char *output,
size_t output_length);
-/** \brief Shift an MPI right in place by a number of bits.
+/** \brief Shift an MPI in-place right by a number of bits.
*
* Shifting by more bits than there are bit positions
* in \p X is valid and results in setting \p X to 0.
@@ -297,6 +297,21 @@
size_t count);
/**
+ * \brief Shift an MPI in-place left by a number of bits.
+ *
+ * Shifting by more bits than there are bit positions
+ * in \p X will produce an unspecified result.
+ *
+ * This function's execution time depends on the value
+ * of \p count (and of course \p limbs).
+ * \param[in,out] X The number to shift.
+ * \param limbs The number of limbs of \p X. This must be at least 1.
+ * \param count The number of bits to shift by.
+ */
+void mbedtls_mpi_core_shift_l(mbedtls_mpi_uint *X, size_t limbs,
+ size_t count);
+
+/**
* \brief Add two fixed-size large unsigned integers, returning the carry.
*
* Calculates `A + B` where `A` and `B` have the same size.
diff --git a/library/debug.c b/library/debug.c
index 3969616..0f02929 100644
--- a/library/debug.c
+++ b/library/debug.c
@@ -30,6 +30,7 @@
#include <stdio.h>
#include <string.h>
+/* DEBUG_BUF_SIZE must be at least 2 */
#define DEBUG_BUF_SIZE 512
static int debug_threshold = 0;
@@ -69,6 +70,8 @@
char str[DEBUG_BUF_SIZE];
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ MBEDTLS_STATIC_ASSERT(DEBUG_BUF_SIZE >= 2, "DEBUG_BUF_SIZE too small");
+
if (NULL == ssl ||
NULL == ssl->conf ||
NULL == ssl->conf->f_dbg ||
@@ -80,10 +83,15 @@
ret = mbedtls_vsnprintf(str, DEBUG_BUF_SIZE, format, argp);
va_end(argp);
- if (ret >= 0 && ret < DEBUG_BUF_SIZE - 1) {
- str[ret] = '\n';
- str[ret + 1] = '\0';
+ if (ret < 0) {
+ ret = 0;
+ } else {
+ if (ret >= DEBUG_BUF_SIZE - 1) {
+ ret = DEBUG_BUF_SIZE - 2;
+ }
}
+ str[ret] = '\n';
+ str[ret + 1] = '\0';
debug_send_line(ssl, level, file, line, str);
}
@@ -195,6 +203,52 @@
#endif /* MBEDTLS_ECP_LIGHT */
#if defined(MBEDTLS_BIGNUM_C)
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+void mbedtls_debug_print_psa_ec(const mbedtls_ssl_context *ssl, int level,
+ const char *file, int line,
+ const char *text, const mbedtls_pk_context *pk)
+{
+ char str[DEBUG_BUF_SIZE];
+ mbedtls_mpi mpi;
+ const uint8_t *mpi_start;
+ size_t mpi_len;
+ int ret;
+
+ if (NULL == ssl ||
+ NULL == ssl->conf ||
+ NULL == ssl->conf->f_dbg ||
+ level > debug_threshold) {
+ return;
+ }
+
+ /* For the description of pk->pk_raw content please refer to the description
+ * psa_export_public_key() function. */
+ mpi_len = (pk->pub_raw_len - 1)/2;
+
+ /* X coordinate */
+ mbedtls_mpi_init(&mpi);
+ mpi_start = pk->pub_raw + 1;
+ ret = mbedtls_mpi_read_binary(&mpi, mpi_start, mpi_len);
+ if (ret != 0) {
+ return;
+ }
+ mbedtls_snprintf(str, sizeof(str), "%s(X)", text);
+ mbedtls_debug_print_mpi(ssl, level, file, line, str, &mpi);
+ mbedtls_mpi_free(&mpi);
+
+ /* Y coordinate */
+ mbedtls_mpi_init(&mpi);
+ mpi_start = mpi_start + mpi_len;
+ ret = mbedtls_mpi_read_binary(&mpi, mpi_start, mpi_len);
+ if (ret != 0) {
+ return;
+ }
+ mbedtls_snprintf(str, sizeof(str), "%s(Y)", text);
+ mbedtls_debug_print_mpi(ssl, level, file, line, str, &mpi);
+ mbedtls_mpi_free(&mpi);
+}
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
+
void mbedtls_debug_print_mpi(const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const char *text, const mbedtls_mpi *X)
@@ -278,6 +332,11 @@
mbedtls_debug_print_ecp(ssl, level, file, line, name, items[i].value);
} else
#endif
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+ if (items[i].type == MBEDTLS_PK_DEBUG_PSA_EC) {
+ mbedtls_debug_print_psa_ec(ssl, level, file, line, name, items[i].value);
+ } else
+#endif
{ debug_send_line(ssl, level, file, line,
"should not happen\n"); }
}
diff --git a/library/ecjpake.c b/library/ecjpake.c
index 7d452bc..19ad2c6 100644
--- a/library/ecjpake.c
+++ b/library/ecjpake.c
@@ -30,8 +30,6 @@
#include "mbedtls/platform_util.h"
#include "mbedtls/error.h"
-#include "hash_info.h"
-
#include <string.h>
#if !defined(MBEDTLS_ECJPAKE_ALT)
@@ -217,7 +215,7 @@
unsigned char *p = buf;
const unsigned char *end = buf + sizeof(buf);
const size_t id_len = strlen(id);
- unsigned char hash[MBEDTLS_HASH_MAX_SIZE];
+ unsigned char hash[MBEDTLS_MD_MAX_SIZE];
/* Write things to temporary buffer */
MBEDTLS_MPI_CHK(ecjpake_write_len_point(&p, end, grp, pf, G));
@@ -244,7 +242,7 @@
/* Turn it into an integer mod n */
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(h, hash,
- mbedtls_hash_info_get_size(md_type)));
+ mbedtls_md_get_size_from_type(md_type)));
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(h, h, &grp->N));
cleanup:
@@ -780,7 +778,7 @@
unsigned char kx[MBEDTLS_ECP_MAX_BYTES];
size_t x_bytes;
- *olen = mbedtls_hash_info_get_size(ctx->md_type);
+ *olen = mbedtls_md_get_size_from_type(ctx->md_type);
if (len < *olen) {
return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
}
diff --git a/library/ecp_curves.c b/library/ecp_curves.c
index f0a3e6e..57ce39a 100644
--- a/library/ecp_curves.c
+++ b/library/ecp_curves.c
@@ -22,9 +22,12 @@
#if defined(MBEDTLS_ECP_LIGHT)
#include "mbedtls/ecp.h"
+#include "mbedtls/platform.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/error.h"
+#include "mbedtls/platform.h"
+
#include "bn_mul.h"
#include "bignum_core.h"
#include "ecp_invasive.h"
@@ -4602,26 +4605,28 @@
/* Additional forward declarations */
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
static int ecp_mod_p255(mbedtls_mpi *);
+MBEDTLS_STATIC_TESTABLE
+int mbedtls_ecp_mod_p255_raw(mbedtls_mpi_uint *X, size_t X_limbs);
#endif
#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
static int ecp_mod_p448(mbedtls_mpi *);
MBEDTLS_STATIC_TESTABLE
-int mbedtls_ecp_mod_p448(mbedtls_mpi *);
+int mbedtls_ecp_mod_p448(mbedtls_mpi_uint *, size_t);
#endif
#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
static int ecp_mod_p192k1(mbedtls_mpi *);
MBEDTLS_STATIC_TESTABLE
-int mbedtls_ecp_mod_p192k1(mbedtls_mpi *);
+int mbedtls_ecp_mod_p192k1_raw(mbedtls_mpi_uint *X, size_t X_limbs);
#endif
#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
static int ecp_mod_p224k1(mbedtls_mpi *);
MBEDTLS_STATIC_TESTABLE
-int mbedtls_ecp_mod_p224k1(mbedtls_mpi *);
+int mbedtls_ecp_mod_p224k1_raw(mbedtls_mpi_uint *X, size_t X_limbs);
#endif
#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
static int ecp_mod_p256k1(mbedtls_mpi *);
MBEDTLS_STATIC_TESTABLE
-int mbedtls_ecp_mod_p256k1(mbedtls_mpi *);
+int mbedtls_ecp_mod_p256k1_raw(mbedtls_mpi_uint *X, size_t X_limbs);
#endif
#if defined(ECP_LOAD_GROUP)
@@ -5415,27 +5420,57 @@
*/
static int ecp_mod_p255(mbedtls_mpi *N)
{
- mbedtls_mpi_uint Mp[P255_WIDTH];
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t expected_width = 2 * P255_WIDTH;
+ MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width));
+ ret = mbedtls_ecp_mod_p255_raw(N->p, expected_width);
+cleanup:
+ return ret;
+}
- /* Helper references for top part of N */
- mbedtls_mpi_uint * const NT_p = N->p + P255_WIDTH;
- const size_t NT_n = N->n - P255_WIDTH;
- if (N->n <= P255_WIDTH) {
- return 0;
- }
- if (NT_n > P255_WIDTH) {
+MBEDTLS_STATIC_TESTABLE
+int mbedtls_ecp_mod_p255_raw(mbedtls_mpi_uint *X, size_t X_Limbs)
+{
+
+ if (X_Limbs != 2 * P255_WIDTH) {
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
}
- /* Split N as N + 2^256 M */
- memcpy(Mp, NT_p, sizeof(mbedtls_mpi_uint) * NT_n);
- memset(NT_p, 0, sizeof(mbedtls_mpi_uint) * NT_n);
+ mbedtls_mpi_uint *carry = mbedtls_calloc(P255_WIDTH, ciL);
+ if (carry == NULL) {
+ return MBEDTLS_ERR_ECP_ALLOC_FAILED;
+ }
- /* N = A0 + 38 * A1 */
- mbedtls_mpi_core_mla(N->p, P255_WIDTH + 1,
- Mp, NT_n,
- 38);
+ /* Step 1: Reduction to P255_WIDTH limbs */
+ if (X_Limbs > P255_WIDTH) {
+ /* Helper references for top part of X */
+ mbedtls_mpi_uint * const A1 = X + P255_WIDTH;
+ const size_t A1_limbs = X_Limbs - P255_WIDTH;
+ /* X = A0 + 38 * A1, capture carry out */
+ *carry = mbedtls_mpi_core_mla(X, P255_WIDTH, A1, A1_limbs, 38);
+ /* Clear top part */
+ memset(A1, 0, sizeof(mbedtls_mpi_uint) * A1_limbs);
+ }
+
+ /* Step 2: Reduce to <2p
+ * Split as A0 + 2^255*c, with c a scalar, and compute A0 + 19*c */
+ *carry <<= 1;
+ *carry += (X[P255_WIDTH - 1] >> (biL - 1));
+ *carry *= 19;
+
+ /* Clear top bit */
+ X[P255_WIDTH - 1] <<= 1; X[P255_WIDTH - 1] >>= 1;
+ /* Since the top bit for X has been cleared 0 + 0 + Carry
+ * will not overflow.
+ *
+ * Furthermore for 2p = 2^256-38. When a carry propagation on the highest
+ * limb occurs, X > 2^255 and all the remaining bits on the limb are zero.
+ * - If X < 2^255 ==> X < 2p
+ * - If X > 2^255 ==> X < 2^256 - 2^255 < 2p */
+ (void) mbedtls_mpi_core_add(X, X, carry, P255_WIDTH);
+
+ mbedtls_free(carry);
return 0;
}
#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
@@ -5453,71 +5488,108 @@
static int ecp_mod_p448(mbedtls_mpi *N)
{
- return mbedtls_ecp_mod_p448(N);
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t expected_width = 2 * ((448 + biL - 1) / biL);
+
+ /* This is required as some tests and use cases do not pass in a Bignum of
+ * the correct size, and expect the growth to be done automatically, which
+ * will no longer happen. */
+ MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width));
+
+ ret = mbedtls_ecp_mod_p448(N->p, N->n);
+
+cleanup:
+ return ret;
}
/*
* Fast quasi-reduction modulo p448 = 2^448 - 2^224 - 1
- * Write N as A0 + 2^448 A1 and A1 as B0 + 2^224 B1, and return
- * A0 + A1 + B1 + (B0 + B1) * 2^224. This is different to the reference
- * implementation of Curve448, which uses its own special 56-bit limbs rather
- * than a generic bignum library. We could squeeze some extra speed out on
- * 32-bit machines by splitting N up into 32-bit limbs and doing the
- * arithmetic using the limbs directly as we do for the NIST primes above,
- * but for 64-bit targets it should use half the number of operations if we do
- * the reduction with 224-bit limbs, since mpi_add_mpi will then use 64-bit adds.
+ * Write X as A0 + 2^448 A1 and A1 as B0 + 2^224 B1, and return A0 + A1 + B1 +
+ * (B0 + B1) * 2^224. This is different to the reference implementation of
+ * Curve448, which uses its own special 56-bit limbs rather than a generic
+ * bignum library. We could squeeze some extra speed out on 32-bit machines by
+ * splitting N up into 32-bit limbs and doing the arithmetic using the limbs
+ * directly as we do for the NIST primes above, but for 64-bit targets it should
+ * use half the number of operations if we do the reduction with 224-bit limbs,
+ * since mpi_core_add will then use 64-bit adds.
*/
MBEDTLS_STATIC_TESTABLE
-int mbedtls_ecp_mod_p448(mbedtls_mpi *N)
+int mbedtls_ecp_mod_p448(mbedtls_mpi_uint *X, size_t X_limbs)
{
- int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t i;
- mbedtls_mpi M, Q;
- mbedtls_mpi_uint Mp[P448_WIDTH + 1], Qp[P448_WIDTH];
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- if (N->n <= P448_WIDTH) {
+ if (X_limbs <= P448_WIDTH) {
return 0;
}
- /* M = A1 */
- M.s = 1;
- M.n = N->n - (P448_WIDTH);
- if (M.n > P448_WIDTH) {
- /* Shouldn't be called with N larger than 2^896! */
+ size_t M_limbs = X_limbs - (P448_WIDTH);
+ const size_t Q_limbs = M_limbs;
+
+ if (M_limbs > P448_WIDTH) {
+ /* Shouldn't be called with X larger than 2^896! */
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
}
- M.p = Mp;
- memset(Mp, 0, sizeof(Mp));
- memcpy(Mp, N->p + P448_WIDTH, M.n * sizeof(mbedtls_mpi_uint));
- /* N = A0 */
- for (i = P448_WIDTH; i < N->n; i++) {
- N->p[i] = 0;
+ /* Extra limb for carry below. */
+ M_limbs++;
+
+ mbedtls_mpi_uint *M = mbedtls_calloc(M_limbs, ciL);
+
+ if (M == NULL) {
+ return MBEDTLS_ERR_ECP_ALLOC_FAILED;
}
- /* N += A1 */
- MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(N, N, &M));
+ mbedtls_mpi_uint *Q = mbedtls_calloc(Q_limbs, ciL);
- /* Q = B1, N += B1 */
- Q = M;
- Q.p = Qp;
- memcpy(Qp, Mp, sizeof(Qp));
- MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&Q, 224));
- MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(N, N, &Q));
+ if (Q == NULL) {
+ ret = MBEDTLS_ERR_ECP_ALLOC_FAILED;
+ goto cleanup;
+ }
- /* M = (B0 + B1) * 2^224, N += M */
+ /* M = A1 */
+ memset(M, 0, (M_limbs * ciL));
+
+ /* Do not copy into the overflow limb, as this would read past the end of
+ * X. */
+ memcpy(M, X + P448_WIDTH, ((M_limbs - 1) * ciL));
+
+ /* X = A0 */
+ for (i = P448_WIDTH; i < X_limbs; i++) {
+ X[i] = 0;
+ }
+
+ /* X += A1 - Carry here dealt with by oversize M and X. */
+ (void) mbedtls_mpi_core_add(X, X, M, M_limbs);
+
+ /* Q = B1, X += B1 */
+ memcpy(Q, M, (Q_limbs * ciL));
+
+ mbedtls_mpi_core_shift_r(Q, Q_limbs, 224);
+
+ /* No carry here - only max 224 bits */
+ (void) mbedtls_mpi_core_add(X, X, Q, Q_limbs);
+
+ /* M = (B0 + B1) * 2^224, X += M */
if (sizeof(mbedtls_mpi_uint) > 4) {
- Mp[P224_WIDTH_MIN] &= ((mbedtls_mpi_uint)-1) >> (P224_UNUSED_BITS);
+ M[P224_WIDTH_MIN] &= ((mbedtls_mpi_uint)-1) >> (P224_UNUSED_BITS);
}
- for (i = P224_WIDTH_MAX; i < M.n; ++i) {
- Mp[i] = 0;
+ for (i = P224_WIDTH_MAX; i < M_limbs; ++i) {
+ M[i] = 0;
}
- MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&M, &M, &Q));
- M.n = P448_WIDTH + 1; /* Make room for shifted carry bit from the addition */
- MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&M, 224));
- MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(N, N, &M));
+
+ (void) mbedtls_mpi_core_add(M, M, Q, Q_limbs);
+
+ /* Shifted carry bit from the addition is dealt with by oversize M */
+ mbedtls_mpi_core_shift_l(M, M_limbs, 224);
+ (void) mbedtls_mpi_core_add(X, X, M, M_limbs);
+
+ ret = 0;
cleanup:
+ mbedtls_free(M);
+ mbedtls_free(Q);
+
return ret;
}
#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
@@ -5525,141 +5597,197 @@
#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
+
/*
* Fast quasi-reduction modulo P = 2^s - R,
* with R about 33 bits, used by the Koblitz curves.
*
- * Write N as A0 + 2^224 A1, return A0 + R * A1.
- * Actually do two passes, since R is big.
+ * Write X as A0 + 2^224 A1, return A0 + R * A1.
*/
-#define P_KOBLITZ_MAX (256 / 8 / sizeof(mbedtls_mpi_uint)) // Max limbs in P
#define P_KOBLITZ_R (8 / sizeof(mbedtls_mpi_uint)) // Limbs in R
-static inline int ecp_mod_koblitz(mbedtls_mpi *N, mbedtls_mpi_uint *Rp, size_t p_limbs,
- size_t adjust, size_t shift, mbedtls_mpi_uint mask)
-{
- int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- mbedtls_mpi M, R;
- mbedtls_mpi_uint Mp[P_KOBLITZ_MAX + P_KOBLITZ_R + 1];
- if (N->n < p_limbs) {
- return 0;
+static inline int ecp_mod_koblitz(mbedtls_mpi_uint *X,
+ size_t X_limbs,
+ mbedtls_mpi_uint *R,
+ size_t bits)
+{
+ int ret = 0;
+
+ /* Determine if A1 is aligned to limb bitsize. If not then the used limbs
+ * of P, A0 and A1 must be set accordingly and there is a middle limb
+ * which is shared by A0 and A1 and need to handle accordingly.
+ */
+ size_t shift = bits % biL;
+ size_t adjust = (shift + biL - 1) / biL;
+ size_t P_limbs = bits / biL + adjust;
+
+ mbedtls_mpi_uint *A1 = mbedtls_calloc(P_limbs, ciL);
+ if (A1 == NULL) {
+ return MBEDTLS_ERR_ECP_ALLOC_FAILED;
}
- /* Init R */
- R.s = 1;
- R.p = Rp;
- R.n = P_KOBLITZ_R;
+ /* Create a buffer to store the value of `R * A1` */
+ size_t R_limbs = P_KOBLITZ_R;
+ size_t M_limbs = P_limbs + R_limbs;
+ mbedtls_mpi_uint *M = mbedtls_calloc(M_limbs, ciL);
+ if (M == NULL) {
+ ret = MBEDTLS_ERR_ECP_ALLOC_FAILED;
+ goto cleanup;
+ }
- /* Common setup for M */
- M.s = 1;
- M.p = Mp;
+ mbedtls_mpi_uint mask = 0;
+ if (adjust != 0) {
+ mask = ((mbedtls_mpi_uint) 1 << shift) - 1;
+ }
- for (size_t pass = 0; pass < 2; pass++) {
- /* M = A1 */
- M.n = N->n - (p_limbs - adjust);
- if (M.n > p_limbs + adjust) {
- M.n = p_limbs + adjust;
- }
- memset(Mp, 0, sizeof(Mp));
- memcpy(Mp, N->p + p_limbs - adjust, M.n * sizeof(mbedtls_mpi_uint));
+ /* Two passes are needed to reduce the value of `A0 + R * A1` and then
+ * we need an additional one to reduce the possible overflow during
+ * the addition.
+ */
+ for (size_t pass = 0; pass < 3; pass++) {
+ /* Copy A1 */
+ memcpy(A1, X + P_limbs - adjust, P_limbs * ciL);
+
+ /* Shift A1 to be aligned */
if (shift != 0) {
- MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&M, shift));
+ mbedtls_mpi_core_shift_r(A1, P_limbs, shift);
}
- M.n += R.n; /* Make room for multiplication by R */
- /* N = A0 */
+ /* Zeroize the A1 part of the shared limb */
if (mask != 0) {
- N->p[p_limbs - 1] &= mask;
- }
- for (size_t i = p_limbs; i < N->n; i++) {
- N->p[i] = 0;
+ X[P_limbs - 1] &= mask;
}
- /* N = A0 + R * A1 */
- MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&M, &M, &R));
- MBEDTLS_MPI_CHK(mbedtls_mpi_add_abs(N, N, &M));
+ /* X = A0
+ * Zeroize the A1 part of X to keep only the A0 part.
+ */
+ for (size_t i = P_limbs; i < X_limbs; i++) {
+ X[i] = 0;
+ }
+
+ /* X = A0 + R * A1 */
+ mbedtls_mpi_core_mul(M, A1, P_limbs, R, R_limbs);
+ (void) mbedtls_mpi_core_add(X, X, M, P_limbs + R_limbs);
+
+ /* Carry can not be generated since R is a 33-bit value and stored in
+ * 64 bits. The result value of the multiplication is at most
+ * P length + 33 bits in length and the result value of the addition
+ * is at most P length + 34 bits in length. So the result of the
+ * addition always fits in P length + 64 bits.
+ */
}
cleanup:
+ mbedtls_free(M);
+ mbedtls_free(A1);
+
return ret;
}
+
#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED) ||
MBEDTLS_ECP_DP_SECP224K1_ENABLED) ||
MBEDTLS_ECP_DP_SECP256K1_ENABLED) */
#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
+
/*
* Fast quasi-reduction modulo p192k1 = 2^192 - R,
- * with R = 2^32 + 2^12 + 2^8 + 2^7 + 2^6 + 2^3 + 1 = 0x0100001119
+ * with R = 2^32 + 2^12 + 2^8 + 2^7 + 2^6 + 2^3 + 1 = 0x01000011C9
*/
static int ecp_mod_p192k1(mbedtls_mpi *N)
{
- return mbedtls_ecp_mod_p192k1(N);
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t expected_width = 2 * ((192 + biL - 1) / biL);
+ MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width));
+ ret = mbedtls_ecp_mod_p192k1_raw(N->p, expected_width);
+
+cleanup:
+ return ret;
}
MBEDTLS_STATIC_TESTABLE
-int mbedtls_ecp_mod_p192k1(mbedtls_mpi *N)
+int mbedtls_ecp_mod_p192k1_raw(mbedtls_mpi_uint *X, size_t X_limbs)
{
static mbedtls_mpi_uint Rp[] = {
- MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00,
- 0x00)
+ MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x11, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00)
};
- return ecp_mod_koblitz(N, Rp, 192 / 8 / sizeof(mbedtls_mpi_uint), 0, 0,
- 0);
+ if (X_limbs != 2 * ((192 + biL - 1) / biL)) {
+ return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+ }
+
+ return ecp_mod_koblitz(X, X_limbs, Rp, 192);
}
+
#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
-static int ecp_mod_p224k1(mbedtls_mpi *N)
-{
- return mbedtls_ecp_mod_p224k1(N);
-}
-
/*
* Fast quasi-reduction modulo p224k1 = 2^224 - R,
* with R = 2^32 + 2^12 + 2^11 + 2^9 + 2^7 + 2^4 + 2 + 1 = 0x0100001A93
*/
+static int ecp_mod_p224k1(mbedtls_mpi *N)
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t expected_width = 2 * 224 / biL;
+ MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width));
+ ret = mbedtls_ecp_mod_p224k1_raw(N->p, expected_width);
+
+cleanup:
+ return ret;
+}
+
MBEDTLS_STATIC_TESTABLE
-int mbedtls_ecp_mod_p224k1(mbedtls_mpi *N)
+int mbedtls_ecp_mod_p224k1_raw(mbedtls_mpi_uint *X, size_t X_limbs)
{
static mbedtls_mpi_uint Rp[] = {
- MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x00,
- 0x00)
+ MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x1A, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00)
};
-#if defined(MBEDTLS_HAVE_INT64)
- return ecp_mod_koblitz(N, Rp, 4, 1, 32, 0xFFFFFFFF);
-#else
- return ecp_mod_koblitz(N, Rp, 224 / 8 / sizeof(mbedtls_mpi_uint), 0, 0,
- 0);
-#endif
+ if (X_limbs != 2 * 224 / biL) {
+ return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+ }
+
+ return ecp_mod_koblitz(X, X_limbs, Rp, 224);
}
#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
-static int ecp_mod_p256k1(mbedtls_mpi *N)
-{
- return mbedtls_ecp_mod_p256k1(N);
-}
-
/*
* Fast quasi-reduction modulo p256k1 = 2^256 - R,
* with R = 2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1 = 0x01000003D1
*/
+static int ecp_mod_p256k1(mbedtls_mpi *N)
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t expected_width = 2 * ((256 + biL - 1) / biL);
+ MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width));
+ ret = mbedtls_ecp_mod_p256k1_raw(N->p, expected_width);
+
+cleanup:
+ return ret;
+}
+
MBEDTLS_STATIC_TESTABLE
-int mbedtls_ecp_mod_p256k1(mbedtls_mpi *N)
+int mbedtls_ecp_mod_p256k1_raw(mbedtls_mpi_uint *X, size_t X_limbs)
{
static mbedtls_mpi_uint Rp[] = {
- MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00,
- 0x00)
+ MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0x03, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00)
};
- return ecp_mod_koblitz(N, Rp, 256 / 8 / sizeof(mbedtls_mpi_uint), 0, 0,
- 0);
+
+ if (X_limbs != 2 * ((256 + biL - 1) / biL)) {
+ return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+ }
+
+ return ecp_mod_koblitz(X, X_limbs, Rp, 256);
}
+
#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
#if defined(MBEDTLS_TEST_HOOKS)
diff --git a/library/ecp_invasive.h b/library/ecp_invasive.h
index 68187ac..587b173 100644
--- a/library/ecp_invasive.h
+++ b/library/ecp_invasive.h
@@ -171,32 +171,101 @@
#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
-/*
- * Fast quasi-reduction modulo p192k1 = 2^192 - R,
- * with R = 2^32 + 2^12 + 2^8 + 2^7 + 2^6 + 2^3 + 1 = 0x0100001119
+/** Fast quasi-reduction modulo p192k1 = 2^192 - R,
+ * with R = 2^32 + 2^12 + 2^8 + 2^7 + 2^6 + 2^3 + 1 = 0x01000011C9
+ *
+ * \param[in,out] X The address of the MPI to be converted.
+ * Must have exact limb size that stores a 384-bit MPI
+ * (double the bitlength of the modulus).
+ * Upon return holds the reduced value which is
+ * in range `0 <= X < 2 * N` (where N is the modulus).
+ * The bitlength of the reduced value is the same as
+ * that of the modulus (192 bits).
+ * \param[in] X_limbs The length of \p X in limbs.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X does not have
+ * twice as many limbs as the modulus.
+ * \return #MBEDTLS_ERR_ECP_ALLOC_FAILED if memory allocation failed.
*/
MBEDTLS_STATIC_TESTABLE
-int mbedtls_ecp_mod_p192k1(mbedtls_mpi *N);
+int mbedtls_ecp_mod_p192k1_raw(mbedtls_mpi_uint *X, size_t X_limbs);
#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
+
#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
+/** Fast quasi-reduction modulo p224k1 = 2^224 - R,
+ * with R = 2^32 + 2^12 + 2^11 + 2^9 + 2^7 + 2^4 + 2 + 1 = 0x0100001A93
+ *
+ * \param[in,out] X The address of the MPI to be converted.
+ * Must have exact limb size that stores a 448-bit MPI
+ * (double the bitlength of the modulus).
+ * Upon return holds the reduced value which is
+ * in range `0 <= X < 2 * N` (where N is the modulus).
+ * The bitlength of the reduced value is the same as
+ * that of the modulus (224 bits).
+ * \param[in] X_limbs The length of \p X in limbs.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X does not have
+ * twice as many limbs as the modulus.
+ * \return #MBEDTLS_ERR_ECP_ALLOC_FAILED if memory allocation failed.
+ */
MBEDTLS_STATIC_TESTABLE
-int mbedtls_ecp_mod_p224k1(mbedtls_mpi *N);
+int mbedtls_ecp_mod_p224k1_raw(mbedtls_mpi_uint *X, size_t X_limbs);
#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
+/** Fast quasi-reduction modulo p256k1 = 2^256 - R,
+ * with R = 2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1 = 0x01000003D1
+ *
+ * \param[in,out] X The address of the MPI to be converted.
+ * Must have exact limb size that stores a 512-bit MPI
+ * (double the bitlength of the modulus).
+ * Upon return holds the reduced value which is
+ * in range `0 <= X < 2 * N` (where N is the modulus).
+ * The bitlength of the reduced value is the same as
+ * that of the modulus (256 bits).
+ * \param[in] X_limbs The length of \p X in limbs.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X does not have
+ * twice as many limbs as the modulus.
+ * \return #MBEDTLS_ERR_ECP_ALLOC_FAILED if memory allocation failed.
+ */
MBEDTLS_STATIC_TESTABLE
-int mbedtls_ecp_mod_p256k1(mbedtls_mpi *N);
+int mbedtls_ecp_mod_p256k1_raw(mbedtls_mpi_uint *X, size_t X_limbs);
#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
+#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
+
+/** Fast quasi-reduction modulo p255 = 2^255 - 19
+ *
+ * \param[in,out] X The address of the MPI to be converted.
+ * Must have exact limb size that stores a 510-bit MPI
+ * (double the bitlength of the modulus).
+ * Upon return holds the reduced value which is
+ * in range `0 <= X < 2 * N` (where N is the modulus).
+ * \param[in] X_limbs The length of \p X in limbs.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X does not have
+ * twice as many limbs as the modulus.
+ * \return #MBEDTLS_ERR_ECP_ALLOC_FAILED if memory allocation failed.
+ */
+MBEDTLS_STATIC_TESTABLE
+int mbedtls_ecp_mod_p255_raw(mbedtls_mpi_uint *X, size_t X_limbs);
+
+#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
+
#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
MBEDTLS_STATIC_TESTABLE
-int mbedtls_ecp_mod_p448(mbedtls_mpi *N);
+int mbedtls_ecp_mod_p448(mbedtls_mpi_uint *X, size_t X_limbs);
#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
diff --git a/library/hash_info.c b/library/hash_info.c
deleted file mode 100644
index 37e44c6..0000000
--- a/library/hash_info.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Hash information that's independent from the crypto implementation.
- *
- * (See the corresponding header file for usage notes.)
- */
-/*
- * Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "hash_info.h"
-#include "mbedtls/error.h"
-
-typedef struct {
- psa_algorithm_t psa_alg;
- mbedtls_md_type_t md_type;
- unsigned char size;
- unsigned char block_size;
-} hash_entry;
-
-static const hash_entry hash_table[] = {
-#if defined(MBEDTLS_MD_CAN_MD5)
- { PSA_ALG_MD5, MBEDTLS_MD_MD5, 16, 64 },
-#endif
-#if defined(MBEDTLS_MD_CAN_RIPEMD160)
- { PSA_ALG_RIPEMD160, MBEDTLS_MD_RIPEMD160, 20, 64 },
-#endif
-#if defined(MBEDTLS_MD_CAN_SHA1)
- { PSA_ALG_SHA_1, MBEDTLS_MD_SHA1, 20, 64 },
-#endif
-#if defined(MBEDTLS_MD_CAN_SHA224)
- { PSA_ALG_SHA_224, MBEDTLS_MD_SHA224, 28, 64 },
-#endif
-#if defined(MBEDTLS_MD_CAN_SHA256)
- { PSA_ALG_SHA_256, MBEDTLS_MD_SHA256, 32, 64 },
-#endif
-#if defined(MBEDTLS_MD_CAN_SHA384)
- { PSA_ALG_SHA_384, MBEDTLS_MD_SHA384, 48, 128 },
-#endif
-#if defined(MBEDTLS_MD_CAN_SHA512)
- { PSA_ALG_SHA_512, MBEDTLS_MD_SHA512, 64, 128 },
-#endif
- { PSA_ALG_NONE, MBEDTLS_MD_NONE, 0, 0 },
-};
-
-/* Get size from MD type */
-unsigned char mbedtls_hash_info_get_size(mbedtls_md_type_t md_type)
-{
- const hash_entry *entry = hash_table;
- while (entry->md_type != MBEDTLS_MD_NONE &&
- entry->md_type != md_type) {
- entry++;
- }
-
- return entry->size;
-}
-
-/* Get block size from MD type */
-unsigned char mbedtls_hash_info_get_block_size(mbedtls_md_type_t md_type)
-{
- const hash_entry *entry = hash_table;
- while (entry->md_type != MBEDTLS_MD_NONE &&
- entry->md_type != md_type) {
- entry++;
- }
-
- return entry->block_size;
-}
-
-/* Get PSA from MD */
-psa_algorithm_t mbedtls_hash_info_psa_from_md(mbedtls_md_type_t md_type)
-{
- const hash_entry *entry = hash_table;
- while (entry->md_type != MBEDTLS_MD_NONE &&
- entry->md_type != md_type) {
- entry++;
- }
-
- return entry->psa_alg;
-}
-
-/* Get MD from PSA */
-mbedtls_md_type_t mbedtls_hash_info_md_from_psa(psa_algorithm_t psa_alg)
-{
- const hash_entry *entry = hash_table;
- while (entry->md_type != MBEDTLS_MD_NONE &&
- entry->psa_alg != psa_alg) {
- entry++;
- }
-
- return entry->md_type;
-}
-
-#if !defined(MBEDTLS_DEPRECATED_REMOVED)
-int mbedtls_md_error_from_psa(psa_status_t status)
-{
- switch (status) {
- case PSA_SUCCESS:
- return 0;
- case PSA_ERROR_NOT_SUPPORTED:
- return MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE;
- case PSA_ERROR_INVALID_ARGUMENT:
- return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
- case PSA_ERROR_INSUFFICIENT_MEMORY:
- return MBEDTLS_ERR_MD_ALLOC_FAILED;
- default:
- return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
- }
-}
-#endif /* !MBEDTLS_DEPRECATED_REMOVED */
diff --git a/library/hash_info.h b/library/hash_info.h
deleted file mode 100644
index f984c82..0000000
--- a/library/hash_info.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/**
- * Hash information that's independent from the crypto implementation.
- *
- * This can be used by:
- * - code based on PSA
- * - code based on the legacy API
- * - code based on either of them depending on MBEDTLS_USE_PSA_CRYPTO
- * - code based on either of them depending on what's available
- *
- * Note: this internal module will go away when everything becomes based on
- * PSA Crypto; it is a helper for the transition while hash algorithms are
- * still represented using mbedtls_md_type_t in most places even when PSA is
- * used for the actual crypto computations.
- *
- * Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef MBEDTLS_HASH_INFO_H
-#define MBEDTLS_HASH_INFO_H
-
-#include "common.h"
-
-#include "mbedtls/md.h"
-#include "psa/crypto.h"
-#include "mbedtls/platform_util.h"
-
-/** \def MBEDTLS_HASH_MAX_SIZE
- *
- * Maximum size of a hash based on configuration.
- */
-#if defined(MBEDTLS_MD_C) && ( \
- !defined(MBEDTLS_PSA_CRYPTO_C) || \
- MBEDTLS_MD_MAX_SIZE >= PSA_HASH_MAX_SIZE)
-#define MBEDTLS_HASH_MAX_SIZE MBEDTLS_MD_MAX_SIZE
-#elif defined(MBEDTLS_PSA_CRYPTO_C) && ( \
- !defined(MBEDTLS_MD_C) || \
- PSA_HASH_MAX_SIZE >= MBEDTLS_MD_MAX_SIZE)
-#define MBEDTLS_HASH_MAX_SIZE PSA_HASH_MAX_SIZE
-#endif
-
-/** Get the output length of the given hash type from its MD type.
- *
- * \note To get the output length from the PSA alg, use \c PSA_HASH_LENGTH().
- *
- * \param md_type The hash MD type.
- *
- * \return The output length in bytes, or 0 if not known.
- */
-unsigned char mbedtls_hash_info_get_size(mbedtls_md_type_t md_type);
-
-/** Get the block size of the given hash type from its MD type.
- *
- * \note To get the output length from the PSA alg, use
- * \c PSA_HASH_BLOCK_LENGTH().
- *
- * \param md_type The hash MD type.
- *
- * \return The block size in bytes, or 0 if not known.
- */
-unsigned char mbedtls_hash_info_get_block_size(mbedtls_md_type_t md_type);
-
-/** Get the PSA alg from the MD type.
- *
- * \param md_type The hash MD type.
- *
- * \return The corresponding PSA algorithm identifier,
- * or PSA_ALG_NONE if not known.
- */
-psa_algorithm_t mbedtls_hash_info_psa_from_md(mbedtls_md_type_t md_type);
-
-/** Get the MD type alg from the PSA algorithm identifier.
- *
- * \param psa_alg The PSA hash algorithm.
- *
- * \return The corresponding MD type,
- * or MBEDTLS_MD_NONE if not known.
- */
-mbedtls_md_type_t mbedtls_hash_info_md_from_psa(psa_algorithm_t psa_alg);
-
-#if !defined(MBEDTLS_DEPRECATED_REMOVED)
-/** Convert PSA status to MD error code.
- *
- * \param status PSA status.
- *
- * \return The corresponding MD error code,
- */
-int MBEDTLS_DEPRECATED mbedtls_md_error_from_psa(psa_status_t status);
-#endif /* !MBEDTLS_DEPRECATED_REMOVED */
-#endif /* MBEDTLS_HASH_INFO_H */
diff --git a/library/md.c b/library/md.c
index 993b006..ee7610e 100644
--- a/library/md.c
+++ b/library/md.c
@@ -51,12 +51,15 @@
#include "mbedtls/sha1.h"
#include "mbedtls/sha256.h"
#include "mbedtls/sha512.h"
-#if defined(MBEDTLS_SHA3_C)
#include "mbedtls/sha3.h"
+
+#if defined(MBEDTLS_PSA_CRYPTO_C)
+#include <psa/crypto.h>
+#include "md_psa.h"
+#include "mbedtls/psa_util.h"
#endif
#if defined(MBEDTLS_MD_SOME_PSA)
-#include <psa/crypto.h>
#include "psa_crypto_core.h"
#endif
@@ -68,6 +71,11 @@
#include <stdio.h>
#endif
+/* See comment above MBEDTLS_MD_MAX_SIZE in md.h */
+#if defined(MBEDTLS_PSA_CRYPTO_C) && MBEDTLS_MD_MAX_SIZE < PSA_HASH_MAX_SIZE
+#error "Internal error: MBEDTLS_MD_MAX_SIZE < PSA_HASH_MAX_SIZE"
+#endif
+
#if defined(MBEDTLS_MD_CAN_MD5)
const mbedtls_md_info_t mbedtls_md5_info = {
"MD5",
@@ -131,25 +139,28 @@
};
#endif
-#if defined(MBEDTLS_SHA3_C)
+#if defined(MBEDTLS_MD_CAN_SHA3)
const mbedtls_md_info_t mbedtls_sha3_224_info = {
"SHA3-224",
MBEDTLS_MD_SHA3_224,
28,
144,
};
+
const mbedtls_md_info_t mbedtls_sha3_256_info = {
"SHA3-256",
MBEDTLS_MD_SHA3_256,
32,
136,
};
+
const mbedtls_md_info_t mbedtls_sha3_384_info = {
"SHA3-384",
MBEDTLS_MD_SHA3_384,
48,
104,
};
+
const mbedtls_md_info_t mbedtls_sha3_512_info = {
"SHA3-512",
MBEDTLS_MD_SHA3_512,
@@ -250,20 +261,6 @@
return psa_can_do_hash(alg);
}
-
-static int mbedtls_md_error_from_psa(psa_status_t status)
-{
- switch (status) {
- case PSA_SUCCESS:
- return 0;
- case PSA_ERROR_NOT_SUPPORTED:
- return MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE;
- case PSA_ERROR_INSUFFICIENT_MEMORY:
- return MBEDTLS_ERR_MD_ALLOC_FAILED;
- default:
- return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
- }
-}
#endif /* MBEDTLS_MD_SOME_PSA */
void mbedtls_md_init(mbedtls_md_context_t *ctx)
@@ -432,7 +429,12 @@
int mbedtls_md_setup(mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac)
{
- if (md_info == NULL || ctx == NULL) {
+#if defined(MBEDTLS_MD_C)
+ if (ctx == NULL) {
+ return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
+ }
+#endif
+ if (md_info == NULL) {
return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
}
@@ -519,9 +521,11 @@
int mbedtls_md_starts(mbedtls_md_context_t *ctx)
{
+#if defined(MBEDTLS_MD_C)
if (ctx == NULL || ctx->md_info == NULL) {
return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
}
+#endif
#if defined(MBEDTLS_MD_SOME_PSA)
if (ctx->engine == MBEDTLS_MD_ENGINE_PSA) {
@@ -578,9 +582,11 @@
int mbedtls_md_update(mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen)
{
+#if defined(MBEDTLS_MD_C)
if (ctx == NULL || ctx->md_info == NULL) {
return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
}
+#endif
#if defined(MBEDTLS_MD_SOME_PSA)
if (ctx->engine == MBEDTLS_MD_ENGINE_PSA) {
@@ -632,9 +638,11 @@
int mbedtls_md_finish(mbedtls_md_context_t *ctx, unsigned char *output)
{
+#if defined(MBEDTLS_MD_C)
if (ctx == NULL || ctx->md_info == NULL) {
return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
}
+#endif
#if defined(MBEDTLS_MD_SOME_PSA)
if (ctx->engine == MBEDTLS_MD_ENGINE_PSA) {
@@ -765,6 +773,87 @@
return md_info->type;
}
+#if defined(MBEDTLS_PSA_CRYPTO_C)
+psa_algorithm_t mbedtls_md_psa_alg_from_type(mbedtls_md_type_t md_type)
+{
+ switch (md_type) {
+#if defined(MBEDTLS_MD_CAN_MD5)
+ case MBEDTLS_MD_MD5:
+ return PSA_ALG_MD5;
+#endif
+#if defined(MBEDTLS_MD_CAN_RIPEMD160)
+ case MBEDTLS_MD_RIPEMD160:
+ return PSA_ALG_RIPEMD160;
+#endif
+#if defined(MBEDTLS_MD_CAN_SHA1)
+ case MBEDTLS_MD_SHA1:
+ return PSA_ALG_SHA_1;
+#endif
+#if defined(MBEDTLS_MD_CAN_SHA224)
+ case MBEDTLS_MD_SHA224:
+ return PSA_ALG_SHA_224;
+#endif
+#if defined(MBEDTLS_MD_CAN_SHA256)
+ case MBEDTLS_MD_SHA256:
+ return PSA_ALG_SHA_256;
+#endif
+#if defined(MBEDTLS_MD_CAN_SHA384)
+ case MBEDTLS_MD_SHA384:
+ return PSA_ALG_SHA_384;
+#endif
+#if defined(MBEDTLS_MD_CAN_SHA512)
+ case MBEDTLS_MD_SHA512:
+ return PSA_ALG_SHA_512;
+#endif
+ default:
+ return PSA_ALG_NONE;
+ }
+}
+
+mbedtls_md_type_t mbedtls_md_type_from_psa_alg(psa_algorithm_t psa_alg)
+{
+ switch (psa_alg) {
+#if defined(MBEDTLS_MD_CAN_MD5)
+ case PSA_ALG_MD5:
+ return MBEDTLS_MD_MD5;
+#endif
+#if defined(MBEDTLS_MD_CAN_RIPEMD160)
+ case PSA_ALG_RIPEMD160:
+ return MBEDTLS_MD_RIPEMD160;
+#endif
+#if defined(MBEDTLS_MD_CAN_SHA1)
+ case PSA_ALG_SHA_1:
+ return MBEDTLS_MD_SHA1;
+#endif
+#if defined(MBEDTLS_MD_CAN_SHA224)
+ case PSA_ALG_SHA_224:
+ return MBEDTLS_MD_SHA224;
+#endif
+#if defined(MBEDTLS_MD_CAN_SHA256)
+ case PSA_ALG_SHA_256:
+ return MBEDTLS_MD_SHA256;
+#endif
+#if defined(MBEDTLS_MD_CAN_SHA384)
+ case PSA_ALG_SHA_384:
+ return MBEDTLS_MD_SHA384;
+#endif
+#if defined(MBEDTLS_MD_CAN_SHA512)
+ case PSA_ALG_SHA_512:
+ return MBEDTLS_MD_SHA512;
+#endif
+ default:
+ return MBEDTLS_MD_NONE;
+ }
+}
+
+int mbedtls_md_error_from_psa(psa_status_t status)
+{
+ return PSA_TO_MBEDTLS_ERR_LIST(status, psa_to_md_errors,
+ psa_generic_status_to_mbedtls);
+}
+#endif /* MBEDTLS_PSA_CRYPTO_C */
+
+
/************************************************************************
* Functions above this separator are part of MBEDTLS_MD_LIGHT, *
* functions below are only available when MBEDTLS_MD_C is set. *
@@ -802,7 +891,8 @@
#if defined(MBEDTLS_MD_CAN_MD5)
MBEDTLS_MD_MD5,
#endif
-#if defined(MBEDTLS_SHA3_C)
+
+#if defined(MBEDTLS_MD_CAN_SHA3)
MBEDTLS_MD_SHA3_224,
MBEDTLS_MD_SHA3_256,
MBEDTLS_MD_SHA3_384,
diff --git a/library/md_psa.h b/library/md_psa.h
new file mode 100644
index 0000000..6645c83
--- /dev/null
+++ b/library/md_psa.h
@@ -0,0 +1,60 @@
+/**
+ * Translation between MD and PSA identifiers (algorithms, errors).
+ *
+ * Note: this internal module will go away when everything becomes based on
+ * PSA Crypto; it is a helper for the transition period.
+ *
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MBEDTLS_MD_PSA_H
+#define MBEDTLS_MD_PSA_H
+
+#include "common.h"
+
+#include "mbedtls/md.h"
+#include "psa/crypto.h"
+
+/**
+ * \brief This function returns the PSA algorithm identifier
+ * associated with the given digest type.
+ *
+ * \param md_type The type of digest to search for.
+ *
+ * \return The PSA algorithm identifier associated with \p md_type.
+ * \return PSA_ALG_NONE if the algorithm is not supported.
+ */
+psa_algorithm_t mbedtls_md_psa_alg_from_type(mbedtls_md_type_t md_type);
+
+/**
+ * \brief This function returns the given digest type
+ * associated with the PSA algorithm identifier.
+ *
+ * \param psa_alg The PSA algorithm identifier to search for.
+ *
+ * \return The MD type associated with \p psa_alg.
+ * \return MBEDTLS_MD_NONE if the algorithm is not supported.
+ */
+mbedtls_md_type_t mbedtls_md_type_from_psa_alg(psa_algorithm_t psa_alg);
+
+/** Convert PSA status to MD error code.
+ *
+ * \param status PSA status.
+ *
+ * \return The corresponding MD error code,
+ */
+int mbedtls_md_error_from_psa(psa_status_t status);
+
+#endif /* MBEDTLS_MD_PSA_H */
diff --git a/library/mps_common.h b/library/mps_common.h
index 4a10176..33b518b 100644
--- a/library/mps_common.h
+++ b/library/mps_common.h
@@ -169,7 +169,7 @@
*
*/
typedef size_t mbedtls_mps_stored_size_t;
-#define MBEDTLS_MPS_STORED_SIZE_MAX ((mbedtls_mps_stored_size_t) -1)
+#define MBEDTLS_MPS_STORED_SIZE_MAX (SIZE_MAX)
/** \brief The type of buffer sizes and offsets used in the MPS API
* and implementation.
@@ -183,7 +183,7 @@
* so almost 10%.
*/
typedef size_t mbedtls_mps_size_t;
-#define MBEDTLS_MPS_SIZE_MAX ((mbedtls_mps_size_t) -1)
+#define MBEDTLS_MPS_SIZE_MAX (SIZE_MAX)
#if MBEDTLS_MPS_STORED_SIZE_MAX > MBEDTLS_MPS_SIZE_MAX
#error "Misconfiguration of mbedtls_mps_size_t and mbedtls_mps_stored_size_t."
diff --git a/library/oid.c b/library/oid.c
index 8e57fe4..a580992 100644
--- a/library/oid.c
+++ b/library/oid.c
@@ -319,6 +319,18 @@
MBEDTLS_OID_X509_EXT_CERTIFICATE_POLICIES,
},
{
+ OID_DESCRIPTOR(MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER,
+ "id-ce-subjectKeyIdentifier",
+ "Subject Key Identifier"),
+ MBEDTLS_OID_X509_EXT_SUBJECT_KEY_IDENTIFIER,
+ },
+ {
+ OID_DESCRIPTOR(MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER,
+ "id-ce-authorityKeyIdentifier",
+ "Authority Key Identifier"),
+ MBEDTLS_OID_X509_EXT_AUTHORITY_KEY_IDENTIFIER,
+ },
+ {
NULL_OID_DESCRIPTOR,
0,
},
@@ -921,4 +933,180 @@
return (int) (size - n);
}
+static int oid_parse_number(unsigned int *num, const char **p, const char *bound)
+{
+ int ret = MBEDTLS_ERR_ASN1_INVALID_DATA;
+
+ *num = 0;
+
+ while (*p < bound && **p >= '0' && **p <= '9') {
+ ret = 0;
+ if (*num > (UINT_MAX / 10)) {
+ return MBEDTLS_ERR_ASN1_INVALID_DATA;
+ }
+ *num *= 10;
+ *num += **p - '0';
+ (*p)++;
+ }
+ return ret;
+}
+
+static size_t oid_subidentifier_num_bytes(unsigned int value)
+{
+ size_t num_bytes = 0;
+
+ do {
+ value >>= 7;
+ num_bytes++;
+ } while (value != 0);
+
+ return num_bytes;
+}
+
+static int oid_subidentifier_encode_into(unsigned char **p,
+ unsigned char *bound,
+ unsigned int value)
+{
+ size_t num_bytes = oid_subidentifier_num_bytes(value);
+
+ if ((size_t) (bound - *p) < num_bytes) {
+ return MBEDTLS_ERR_OID_BUF_TOO_SMALL;
+ }
+ (*p)[num_bytes - 1] = (unsigned char) (value & 0x7f);
+ value >>= 7;
+
+ for (size_t i = 2; i <= num_bytes; i++) {
+ (*p)[num_bytes - i] = 0x80 | (unsigned char) (value & 0x7f);
+ value >>= 7;
+ }
+ *p += num_bytes;
+
+ return 0;
+}
+
+/* Return the OID for the given x.y.z.... style numeric string */
+int mbedtls_oid_from_numeric_string(mbedtls_asn1_buf *oid,
+ const char *oid_str, size_t size)
+{
+ int ret = MBEDTLS_ERR_ASN1_INVALID_DATA;
+ const char *str_ptr = oid_str;
+ const char *str_bound = oid_str + size;
+ unsigned int val = 0;
+ unsigned int component1, component2;
+ size_t encoded_len;
+ unsigned char *resized_mem;
+
+ /* Count the number of dots to get a worst-case allocation size. */
+ size_t num_dots = 0;
+ for (size_t i = 0; i < size; i++) {
+ if (oid_str[i] == '.') {
+ num_dots++;
+ }
+ }
+ /* Allocate maximum possible required memory:
+ * There are (num_dots + 1) integer components, but the first 2 share the
+ * same subidentifier, so we only need num_dots subidentifiers maximum. */
+ if (num_dots == 0 || (num_dots > MBEDTLS_OID_MAX_COMPONENTS - 1)) {
+ return MBEDTLS_ERR_ASN1_INVALID_DATA;
+ }
+ /* Each byte can store 7 bits, calculate number of bytes for a
+ * subidentifier:
+ *
+ * bytes = ceil(subidentifer_size * 8 / 7)
+ */
+ size_t bytes_per_subidentifier = (((sizeof(unsigned int) * 8) - 1) / 7)
+ + 1;
+ size_t max_possible_bytes = num_dots * bytes_per_subidentifier;
+ oid->p = mbedtls_calloc(max_possible_bytes, 1);
+ if (oid->p == NULL) {
+ return MBEDTLS_ERR_ASN1_ALLOC_FAILED;
+ }
+ unsigned char *out_ptr = oid->p;
+ unsigned char *out_bound = oid->p + max_possible_bytes;
+
+ ret = oid_parse_number(&component1, &str_ptr, str_bound);
+ if (ret != 0) {
+ goto error;
+ }
+ if (component1 > 2) {
+ /* First component can't be > 2 */
+ ret = MBEDTLS_ERR_ASN1_INVALID_DATA;
+ goto error;
+ }
+ if (str_ptr >= str_bound || *str_ptr != '.') {
+ ret = MBEDTLS_ERR_ASN1_INVALID_DATA;
+ goto error;
+ }
+ str_ptr++;
+
+ ret = oid_parse_number(&component2, &str_ptr, str_bound);
+ if (ret != 0) {
+ goto error;
+ }
+ if ((component1 < 2) && (component2 > 39)) {
+ /* Root nodes 0 and 1 may have up to 40 children, numbered 0-39 */
+ ret = MBEDTLS_ERR_ASN1_INVALID_DATA;
+ goto error;
+ }
+ if (str_ptr < str_bound) {
+ if (*str_ptr == '.') {
+ str_ptr++;
+ } else {
+ ret = MBEDTLS_ERR_ASN1_INVALID_DATA;
+ goto error;
+ }
+ }
+
+ if (component2 > (UINT_MAX - (component1 * 40))) {
+ ret = MBEDTLS_ERR_ASN1_INVALID_DATA;
+ goto error;
+ }
+ ret = oid_subidentifier_encode_into(&out_ptr, out_bound,
+ (component1 * 40) + component2);
+ if (ret != 0) {
+ goto error;
+ }
+
+ while (str_ptr < str_bound) {
+ ret = oid_parse_number(&val, &str_ptr, str_bound);
+ if (ret != 0) {
+ goto error;
+ }
+ if (str_ptr < str_bound) {
+ if (*str_ptr == '.') {
+ str_ptr++;
+ } else {
+ ret = MBEDTLS_ERR_ASN1_INVALID_DATA;
+ goto error;
+ }
+ }
+
+ ret = oid_subidentifier_encode_into(&out_ptr, out_bound, val);
+ if (ret != 0) {
+ goto error;
+ }
+ }
+
+ encoded_len = out_ptr - oid->p;
+ resized_mem = mbedtls_calloc(encoded_len, 1);
+ if (resized_mem == NULL) {
+ ret = MBEDTLS_ERR_ASN1_ALLOC_FAILED;
+ goto error;
+ }
+ memcpy(resized_mem, oid->p, encoded_len);
+ mbedtls_free(oid->p);
+ oid->p = resized_mem;
+ oid->len = encoded_len;
+
+ oid->tag = MBEDTLS_ASN1_OID;
+
+ return 0;
+
+error:
+ mbedtls_free(oid->p);
+ oid->p = NULL;
+ oid->len = 0;
+ return ret;
+}
+
#endif /* MBEDTLS_OID_C */
diff --git a/library/pem.c b/library/pem.c
index aed4788..056c98c 100644
--- a/library/pem.c
+++ b/library/pem.c
@@ -29,7 +29,6 @@
#include "mbedtls/cipher.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/error.h"
-#include "hash_info.h"
#include <string.h>
diff --git a/library/pk.c b/library/pk.c
index ae1966b..91796de 100644
--- a/library/pk.c
+++ b/library/pk.c
@@ -23,8 +23,7 @@
#include "mbedtls/pk.h"
#include "pk_wrap.h"
#include "pkwrite.h"
-
-#include "hash_info.h"
+#include "pk_internal.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/error.h"
@@ -41,13 +40,7 @@
#if defined(MBEDTLS_PSA_CRYPTO_C)
#include "mbedtls/psa_util.h"
-#define PSA_PK_TO_MBEDTLS_ERR(status) psa_pk_status_to_mbedtls(status)
-#define PSA_PK_RSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \
- psa_to_pk_rsa_errors, \
- psa_pk_status_to_mbedtls)
-#define PSA_PK_ECDSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \
- psa_to_pk_ecdsa_errors, \
- psa_pk_status_to_mbedtls)
+#include "md_psa.h"
#endif
#include <limits.h>
@@ -60,6 +53,15 @@
{
ctx->pk_info = NULL;
ctx->pk_ctx = NULL;
+#if defined(MBEDTLS_PSA_CRYPTO_C)
+ ctx->priv_id = MBEDTLS_SVC_KEY_ID_INIT;
+#endif /* MBEDTLS_PSA_CRYPTO_C */
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+ memset(ctx->pub_raw, 0, sizeof(ctx->pub_raw));
+ ctx->pub_raw_len = 0;
+ ctx->ec_family = 0;
+ ctx->ec_bits = 0;
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
}
/*
@@ -71,10 +73,18 @@
return;
}
- if (ctx->pk_info != NULL) {
+ if ((ctx->pk_info != NULL) && (ctx->pk_info->ctx_free_func != NULL)) {
ctx->pk_info->ctx_free_func(ctx->pk_ctx);
}
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+ /* The ownership of the priv_id key for opaque keys is external of the PK
+ * module. It's the user responsibility to clear it after use. */
+ if ((ctx->pk_info != NULL) && (ctx->pk_info->type != MBEDTLS_PK_OPAQUE)) {
+ psa_destroy_key(ctx->priv_id);
+ }
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
+
mbedtls_platform_zeroize(ctx, sizeof(mbedtls_pk_context));
}
@@ -140,7 +150,8 @@
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
- if ((ctx->pk_ctx = info->ctx_alloc_func()) == NULL) {
+ if ((info->ctx_alloc_func != NULL) &&
+ ((ctx->pk_ctx = info->ctx_alloc_func()) == NULL)) {
return MBEDTLS_ERR_PK_ALLOC_FAILED;
}
@@ -158,7 +169,6 @@
{
const mbedtls_pk_info_t *info = NULL;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
- mbedtls_svc_key_id_t *pk_ctx;
psa_key_type_t type;
if (ctx == NULL || ctx->pk_info != NULL) {
@@ -179,19 +189,49 @@
return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
}
- if ((ctx->pk_ctx = info->ctx_alloc_func()) == NULL) {
- return MBEDTLS_ERR_PK_ALLOC_FAILED;
- }
-
ctx->pk_info = info;
-
- pk_ctx = (mbedtls_svc_key_id_t *) ctx->pk_ctx;
- *pk_ctx = key;
+ ctx->priv_id = key;
return 0;
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+int mbedtls_pk_update_public_key_from_keypair(mbedtls_pk_context *pk,
+ mbedtls_ecp_keypair *ecp_keypair)
+{
+ int ret = MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
+
+ if (pk == NULL) {
+ return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
+ }
+ /* The raw public key storing mechanism is only supported for EC keys so
+ * we fail silently for other ones. */
+ if ((pk->pk_info->type != MBEDTLS_PK_ECKEY) &&
+ (pk->pk_info->type != MBEDTLS_PK_ECKEY_DH) &&
+ (pk->pk_info->type != MBEDTLS_PK_ECDSA)) {
+ return 0;
+ }
+
+ ret = mbedtls_ecp_point_write_binary(&ecp_keypair->grp, &ecp_keypair->Q,
+ MBEDTLS_ECP_PF_UNCOMPRESSED,
+ &pk->pub_raw_len,
+ pk->pub_raw,
+ MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN);
+ if (ret != 0) {
+ return ret;
+ }
+
+ pk->ec_family = mbedtls_ecc_group_to_psa(ecp_keypair->grp.id,
+ &pk->ec_bits);
+ if (pk->ec_family == 0) {
+ return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
+ }
+
+ return 0;
+}
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
+
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
/*
* Initialize an RSA-alt context
@@ -315,12 +355,11 @@
return (key_usage & usage) == usage;
}
- const mbedtls_svc_key_id_t *key = (const mbedtls_svc_key_id_t *) ctx->pk_ctx;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_algorithm_t key_alg, key_alg2;
psa_status_t status;
- status = psa_get_key_attributes(*key, &attributes);
+ status = psa_get_key_attributes(ctx->priv_id, &attributes);
if (status != PSA_SUCCESS) {
return 0;
}
@@ -378,7 +417,7 @@
return 0;
}
- *hash_len = mbedtls_hash_info_get_size(md_alg);
+ *hash_len = mbedtls_md_get_size_from_type(md_alg);
if (*hash_len == 0) {
return -1;
@@ -527,7 +566,7 @@
psa_status_t status = PSA_ERROR_DATA_CORRUPT;
psa_status_t destruction_status = PSA_ERROR_DATA_CORRUPT;
- psa_algorithm_t psa_md_alg = mbedtls_hash_info_psa_from_md(md_alg);
+ psa_algorithm_t psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg);
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_algorithm_t psa_sig_alg = PSA_ALG_RSA_PSS_ANY_SALT(psa_md_alg);
@@ -695,16 +734,15 @@
}
#if defined(MBEDTLS_RSA_C)
- psa_md_alg = mbedtls_hash_info_psa_from_md(md_alg);
+ psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg);
if (psa_md_alg == 0) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
if (mbedtls_pk_get_type(ctx) == MBEDTLS_PK_OPAQUE) {
- const mbedtls_svc_key_id_t *key = (const mbedtls_svc_key_id_t *) ctx->pk_ctx;
psa_status_t status;
- status = psa_sign_hash(*key, PSA_ALG_RSA_PSS(psa_md_alg),
+ status = psa_sign_hash(ctx->priv_id, PSA_ALG_RSA_PSS(psa_md_alg),
hash, hash_len,
sig, sig_size, sig_len);
return PSA_PK_RSA_TO_MBEDTLS_ERR(status);
@@ -786,7 +824,8 @@
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
} else {
- if (pub->pk_info != prv->pk_info) {
+ if ((prv->pk_info->type != MBEDTLS_PK_OPAQUE) &&
+ (pub->pk_info != prv->pk_info)) {
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
}
@@ -873,24 +912,35 @@
#else /* !MBEDTLS_ECP_LIGHT && !MBEDTLS_RSA_C */
#if defined(MBEDTLS_ECP_LIGHT)
if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_ECKEY) {
- mbedtls_ecp_keypair *ec;
- unsigned char d[MBEDTLS_ECP_MAX_BYTES];
size_t d_len;
psa_ecc_family_t curve_id;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_key_type_t key_type;
size_t bits;
- int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
psa_status_t status;
/* export the private key material in the format PSA wants */
- ec = mbedtls_pk_ec(*pk);
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+ unsigned char d[MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH];
+ status = psa_export_key(pk->priv_id, d, sizeof(d), &d_len);
+ if (status != PSA_SUCCESS) {
+ return psa_pk_status_to_mbedtls(status);
+ }
+
+ curve_id = pk->ec_family;
+ bits = pk->ec_bits;
+#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
+ unsigned char d[MBEDTLS_ECP_MAX_BYTES];
+ mbedtls_ecp_keypair *ec = mbedtls_pk_ec_rw(*pk);
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
d_len = PSA_BITS_TO_BYTES(ec->grp.nbits);
if ((ret = mbedtls_ecp_write_key(ec, d, d_len)) != 0) {
return ret;
}
curve_id = mbedtls_ecc_group_to_psa(ec->grp.id, &bits);
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
key_type = PSA_KEY_TYPE_ECC_KEY_PAIR(curve_id);
/* prepare the key attributes */
diff --git a/library/pk_internal.h b/library/pk_internal.h
new file mode 100644
index 0000000..388f94a
--- /dev/null
+++ b/library/pk_internal.h
@@ -0,0 +1,135 @@
+/**
+ * \file pk_internal.h
+ *
+ * \brief Public Key abstraction layer: internal (i.e. library only) functions
+ * and definitions.
+ */
+/*
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MBEDTLS_PK_INTERNAL_H
+#define MBEDTLS_PK_INTERNAL_H
+
+#include "mbedtls/pk.h"
+
+#if defined(MBEDTLS_ECP_LIGHT)
+#include "mbedtls/ecp.h"
+#endif
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "psa/crypto.h"
+#endif
+
+#if defined(MBEDTLS_PSA_CRYPTO_C)
+#include "mbedtls/psa_util.h"
+#define PSA_PK_TO_MBEDTLS_ERR(status) psa_pk_status_to_mbedtls(status)
+#define PSA_PK_RSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \
+ psa_to_pk_rsa_errors, \
+ psa_pk_status_to_mbedtls)
+#define PSA_PK_ECDSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \
+ psa_to_pk_ecdsa_errors, \
+ psa_pk_status_to_mbedtls)
+#endif
+
+#if defined(MBEDTLS_ECP_LIGHT)
+/**
+ * Public function mbedtls_pk_ec() can be used to get direct access to the
+ * wrapped ecp_keypair structure pointed to the pk_ctx. However this is not
+ * ideal because it bypasses the PK module on the control of its internal
+ * structure (pk_context) fields.
+ * For backward compatibility we keep mbedtls_pk_ec() when ECP_C is defined, but
+ * we provide 2 very similar functions when only ECP_LIGHT is enabled and not
+ * ECP_C.
+ * These variants embed the "ro" or "rw" keywords in their name to make the
+ * usage of the returned pointer explicit. Of course the returned value is
+ * const or non-const accordingly.
+ */
+static inline const mbedtls_ecp_keypair *mbedtls_pk_ec_ro(const mbedtls_pk_context pk)
+{
+ switch (mbedtls_pk_get_type(&pk)) {
+ case MBEDTLS_PK_ECKEY:
+ case MBEDTLS_PK_ECKEY_DH:
+ case MBEDTLS_PK_ECDSA:
+ return (const mbedtls_ecp_keypair *) (pk).MBEDTLS_PRIVATE(pk_ctx);
+ default:
+ return NULL;
+ }
+}
+
+static inline mbedtls_ecp_keypair *mbedtls_pk_ec_rw(const mbedtls_pk_context pk)
+{
+ switch (mbedtls_pk_get_type(&pk)) {
+ case MBEDTLS_PK_ECKEY:
+ case MBEDTLS_PK_ECKEY_DH:
+ case MBEDTLS_PK_ECDSA:
+ return (mbedtls_ecp_keypair *) (pk).MBEDTLS_PRIVATE(pk_ctx);
+ default:
+ return NULL;
+ }
+}
+
+static inline mbedtls_ecp_group_id mbedtls_pk_get_group_id(const mbedtls_pk_context *pk)
+{
+ mbedtls_ecp_group_id id;
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) {
+ psa_key_attributes_t opaque_attrs = PSA_KEY_ATTRIBUTES_INIT;
+ psa_key_type_t opaque_key_type;
+ psa_ecc_family_t curve;
+
+ if (psa_get_key_attributes(pk->priv_id, &opaque_attrs) != PSA_SUCCESS) {
+ return MBEDTLS_ECP_DP_NONE;
+ }
+ opaque_key_type = psa_get_key_type(&opaque_attrs);
+ curve = PSA_KEY_TYPE_ECC_GET_FAMILY(opaque_key_type);
+ id = mbedtls_ecc_group_of_psa(curve, psa_get_key_bits(&opaque_attrs), 0);
+ psa_reset_key_attributes(&opaque_attrs);
+ } else
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+ {
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+ id = mbedtls_ecc_group_of_psa(pk->ec_family, pk->ec_bits, 0);
+#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
+ id = mbedtls_pk_ec_ro(*pk)->grp.id;
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
+ }
+
+ return id;
+}
+
+/* Helper for Montgomery curves */
+#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
+#define MBEDTLS_PK_HAVE_RFC8410_CURVES
+#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED || MBEDTLS_ECP_DP_CURVE448_ENABLED */
+#endif /* MBEDTLS_ECP_LIGHT */
+
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+/**
+ * \brief Copy the public key content in raw format from "ctx->pk_ctx"
+ * (which is an ecp_keypair) into the internal "ctx->pub_raw" buffer.
+ *
+ * \note This is a temporary function that can be removed as soon as the pk
+ * module is free from ECP_C
+ *
+ * \param pk It is the pk_context which is going to be updated. It acts both
+ * as input and output.
+ */
+int mbedtls_pk_update_public_key_from_keypair(mbedtls_pk_context *pk,
+ mbedtls_ecp_keypair *ecp_keypair);
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
+
+#endif /* MBEDTLS_PK_INTERNAL_H */
diff --git a/library/pk_wrap.c b/library/pk_wrap.c
index 6c9f97b..a4c2a3b 100644
--- a/library/pk_wrap.c
+++ b/library/pk_wrap.c
@@ -23,7 +23,9 @@
#if defined(MBEDTLS_PK_C)
#include "pk_wrap.h"
+#include "pk_internal.h"
#include "mbedtls/error.h"
+#include "md_psa.h"
/* Even if RSA not activated, for the sake of RSA-alt */
#include "mbedtls/rsa.h"
@@ -42,18 +44,10 @@
#if defined(MBEDTLS_PSA_CRYPTO_C)
#include "mbedtls/psa_util.h"
-#define PSA_PK_TO_MBEDTLS_ERR(status) psa_pk_status_to_mbedtls(status)
-#define PSA_PK_RSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \
- psa_to_pk_rsa_errors, \
- psa_pk_status_to_mbedtls)
-#define PSA_PK_ECDSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \
- psa_to_pk_ecdsa_errors, \
- psa_pk_status_to_mbedtls)
#endif
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "psa/crypto.h"
-#include "hash_info.h"
#if defined(MBEDTLS_PK_CAN_ECDSA_SOME)
#include "mbedtls/asn1write.h"
@@ -211,7 +205,7 @@
int key_len;
unsigned char buf[MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES];
psa_algorithm_t psa_alg_md =
- PSA_ALG_RSA_PKCS1V15_SIGN(mbedtls_hash_info_psa_from_md(md_alg));
+ PSA_ALG_RSA_PKCS1V15_SIGN(mbedtls_md_psa_alg_from_type(md_alg));
size_t rsa_len = mbedtls_rsa_get_len(rsa);
if (md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len) {
@@ -363,7 +357,7 @@
((void) p_rng);
psa_algorithm_t psa_md_alg;
- psa_md_alg = mbedtls_hash_info_psa_from_md(md_alg);
+ psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg);
if (psa_md_alg == 0) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
@@ -653,8 +647,12 @@
static size_t eckey_get_bitlen(mbedtls_pk_context *pk)
{
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+ return pk->ec_bits;
+#else
mbedtls_ecp_keypair *ecp = (mbedtls_ecp_keypair *) pk->pk_ctx;
return ecp->grp.pbits;
+#endif
}
#if defined(MBEDTLS_PK_CAN_ECDSA_VERIFY)
@@ -724,11 +722,20 @@
const unsigned char *hash, size_t hash_len,
const unsigned char *sig, size_t sig_len)
{
- mbedtls_ecp_keypair *ctx = pk->pk_ctx;
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
psa_status_t status;
+ unsigned char *p;
+ psa_algorithm_t psa_sig_md = PSA_ALG_ECDSA_ANY;
+ size_t signature_len;
+ ((void) md_alg);
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+ unsigned char buf[PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE];
+ psa_ecc_family_t curve = pk->ec_family;
+ size_t curve_bits = pk->ec_bits;
+#else
+ mbedtls_ecp_keypair *ctx = pk->pk_ctx;
size_t key_len;
/* This buffer will initially contain the public key and then the signature
* but at different points in time. For all curves except secp224k1, which
@@ -736,13 +743,10 @@
* (header byte + 2 numbers, while the signature is only 2 numbers),
* so use that as the buffer size. */
unsigned char buf[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH];
- unsigned char *p;
- psa_algorithm_t psa_sig_md = PSA_ALG_ECDSA_ANY;
size_t curve_bits;
psa_ecc_family_t curve =
mbedtls_ecc_group_to_psa(ctx->grp.id, &curve_bits);
- const size_t signature_part_size = (ctx->grp.nbits + 7) / 8;
- ((void) md_alg);
+#endif
if (curve == 0) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
@@ -752,6 +756,11 @@
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_HASH);
psa_set_key_algorithm(&attributes, psa_sig_md);
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+ status = psa_import_key(&attributes,
+ pk->pub_raw, pk->pub_raw_len,
+ &key_id);
+#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
ret = mbedtls_ecp_point_write_binary(&ctx->grp, &ctx->Q,
MBEDTLS_ECP_PF_UNCOMPRESSED,
&key_len, buf, sizeof(buf));
@@ -762,27 +771,30 @@
status = psa_import_key(&attributes,
buf, key_len,
&key_id);
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
if (status != PSA_SUCCESS) {
ret = PSA_PK_TO_MBEDTLS_ERR(status);
goto cleanup;
}
- /* We don't need the exported key anymore and can
- * reuse its buffer for signature extraction. */
- if (2 * signature_part_size > sizeof(buf)) {
+ signature_len = PSA_ECDSA_SIGNATURE_SIZE(curve_bits);
+ if (signature_len > sizeof(buf)) {
ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA;
goto cleanup;
}
p = (unsigned char *) sig;
+ /* extract_ecdsa_sig's last parameter is the size
+ * of each integer to be parsed, so it's actually half
+ * the size of the signature. */
if ((ret = extract_ecdsa_sig(&p, sig + sig_len, buf,
- signature_part_size)) != 0) {
+ signature_len/2)) != 0) {
goto cleanup;
}
status = psa_verify_hash(key_id, psa_sig_md,
hash, hash_len,
- buf, 2 * signature_part_size);
+ buf, signature_len);
if (status != PSA_SUCCESS) {
ret = PSA_PK_ECDSA_TO_MBEDTLS_ERR(status);
goto cleanup;
@@ -913,23 +925,27 @@
unsigned char *sig, size_t sig_size, size_t *sig_len,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
{
- mbedtls_ecp_keypair *ctx = pk->pk_ctx;
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
psa_status_t status;
- unsigned char buf[MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH];
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
psa_algorithm_t psa_sig_md =
- PSA_ALG_DETERMINISTIC_ECDSA(mbedtls_hash_info_psa_from_md(md_alg));
+ PSA_ALG_DETERMINISTIC_ECDSA(mbedtls_md_psa_alg_from_type(md_alg));
#else
psa_algorithm_t psa_sig_md =
- PSA_ALG_ECDSA(mbedtls_hash_info_psa_from_md(md_alg));
+ PSA_ALG_ECDSA(mbedtls_md_psa_alg_from_type(md_alg));
#endif
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+ psa_ecc_family_t curve = pk->ec_family;
+#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
+ mbedtls_ecp_keypair *ctx = pk->pk_ctx;
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+ unsigned char buf[MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH];
size_t curve_bits;
psa_ecc_family_t curve =
mbedtls_ecc_group_to_psa(ctx->grp.id, &curve_bits);
size_t key_len = PSA_BITS_TO_BYTES(curve_bits);
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
/* PSA has its own RNG */
((void) f_rng);
@@ -939,6 +955,12 @@
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+ if (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(pk->priv_id) == PSA_KEY_ID_NULL) {
+ return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
+ }
+ key_id = pk->priv_id;
+#else
if (key_len > sizeof(buf)) {
return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
}
@@ -958,6 +980,7 @@
ret = PSA_PK_TO_MBEDTLS_ERR(status);
goto cleanup;
}
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
status = psa_sign_hash(key_id, psa_sig_md, hash, hash_len,
sig, sig_size, sig_len);
@@ -969,8 +992,11 @@
ret = pk_ecdsa_sig_asn1_from_psa(sig, sig_len, sig_size);
cleanup:
+
+#if !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
mbedtls_platform_zeroize(buf, sizeof(buf));
status = psa_destroy_key(key_id);
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
if (ret == 0 && status != PSA_SUCCESS) {
ret = PSA_PK_TO_MBEDTLS_ERR(status);
}
@@ -1110,28 +1136,43 @@
*/
static int eckey_check_pair_psa(mbedtls_pk_context *pub, mbedtls_pk_context *prv)
{
- psa_status_t status, destruction_status;
- psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
- mbedtls_ecp_keypair *prv_ctx = prv->pk_ctx;
- mbedtls_ecp_keypair *pub_ctx = pub->pk_ctx;
+ psa_status_t status;
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- /* We are using MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH for the size of this
- * buffer because it will be used to hold the private key at first and
- * then its public part (but not at the same time). */
uint8_t prv_key_buf[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH];
size_t prv_key_len;
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+ mbedtls_svc_key_id_t key_id = prv->priv_id;
+
+ status = psa_export_public_key(key_id, prv_key_buf, sizeof(prv_key_buf),
+ &prv_key_len);
+ ret = PSA_PK_TO_MBEDTLS_ERR(status);
+ if (ret != 0) {
+ return ret;
+ }
+
+ if (memcmp(prv_key_buf, pub->pub_raw, pub->pub_raw_len) != 0) {
+ return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
+ }
+#else /* !MBEDTLS_PK_USE_PSA_EC_DATA */
+ psa_status_t destruction_status;
+ mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
+ psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
uint8_t pub_key_buf[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH];
size_t pub_key_len;
- mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
size_t curve_bits;
const psa_ecc_family_t curve =
- mbedtls_ecc_group_to_psa(prv_ctx->grp.id, &curve_bits);
+ mbedtls_ecc_group_to_psa(mbedtls_pk_ec_ro(*prv)->grp.id, &curve_bits);
const size_t curve_bytes = PSA_BITS_TO_BYTES(curve_bits);
+ if (curve == 0) {
+ return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
+ }
+
psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_KEY_PAIR(curve));
psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_EXPORT);
- ret = mbedtls_mpi_write_binary(&prv_ctx->d, prv_key_buf, curve_bytes);
+ ret = mbedtls_mpi_write_binary(&mbedtls_pk_ec_ro(*prv)->d,
+ prv_key_buf, curve_bytes);
if (ret != 0) {
return ret;
}
@@ -1154,7 +1195,8 @@
return PSA_PK_TO_MBEDTLS_ERR(destruction_status);
}
- ret = mbedtls_ecp_point_write_binary(&pub_ctx->grp, &pub_ctx->Q,
+ ret = mbedtls_ecp_point_write_binary(&mbedtls_pk_ec_rw(*pub)->grp,
+ &mbedtls_pk_ec_rw(*pub)->Q,
MBEDTLS_ECP_PF_UNCOMPRESSED,
&pub_key_len, pub_key_buf,
sizeof(pub_key_buf));
@@ -1165,6 +1207,7 @@
if (memcmp(prv_key_buf, pub_key_buf, curve_bytes) != 0) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
+#endif /* !MBEDTLS_PK_USE_PSA_EC_DATA */
return 0;
}
@@ -1187,6 +1230,7 @@
#endif
}
+#if !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
static void *eckey_alloc_wrap(void)
{
void *ctx = mbedtls_calloc(1, sizeof(mbedtls_ecp_keypair));
@@ -1203,13 +1247,20 @@
mbedtls_ecp_keypair_free((mbedtls_ecp_keypair *) ctx);
mbedtls_free(ctx);
}
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
static void eckey_debug(mbedtls_pk_context *pk, mbedtls_pk_debug_item *items)
{
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+ items->type = MBEDTLS_PK_DEBUG_PSA_EC;
+ items->name = "eckey.Q";
+ items->value = pk;
+#else
mbedtls_ecp_keypair *ecp = (mbedtls_ecp_keypair *) pk->pk_ctx;
items->type = MBEDTLS_PK_DEBUG_ECP;
items->name = "eckey.Q";
items->value = &(ecp->Q);
+#endif
}
const mbedtls_pk_info_t mbedtls_eckey_info = {
@@ -1234,8 +1285,13 @@
NULL,
NULL,
eckey_check_pair,
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+ NULL,
+ NULL,
+#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
eckey_alloc_wrap,
eckey_free_wrap,
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
eckey_rs_alloc,
eckey_rs_free,
@@ -1266,8 +1322,13 @@
NULL,
NULL,
eckey_check_pair,
- eckey_alloc_wrap, /* Same underlying key structure */
- eckey_free_wrap, /* Same underlying key structure */
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+ NULL,
+ NULL,
+#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
+ eckey_alloc_wrap, /* Same underlying key structure */
+ eckey_free_wrap, /* Same underlying key structure */
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
NULL,
NULL,
@@ -1356,8 +1417,13 @@
NULL,
NULL,
eckey_check_pair, /* Compatible key structures */
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+ NULL,
+ NULL,
+#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
eckey_alloc_wrap, /* Compatible key structures */
eckey_free_wrap, /* Compatible key structures */
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
ecdsa_rs_alloc,
ecdsa_rs_free,
@@ -1503,29 +1569,12 @@
#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
-
-static void *pk_opaque_alloc_wrap(void)
-{
- void *ctx = mbedtls_calloc(1, sizeof(mbedtls_svc_key_id_t));
-
- /* no _init() function to call, as calloc() already zeroized */
-
- return ctx;
-}
-
-static void pk_opaque_free_wrap(void *ctx)
-{
- mbedtls_platform_zeroize(ctx, sizeof(mbedtls_svc_key_id_t));
- mbedtls_free(ctx);
-}
-
static size_t pk_opaque_get_bitlen(mbedtls_pk_context *pk)
{
- const mbedtls_svc_key_id_t *key = pk->pk_ctx;
size_t bits;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
- if (PSA_SUCCESS != psa_get_key_attributes(*key, &attributes)) {
+ if (PSA_SUCCESS != psa_get_key_attributes(pk->priv_id, &attributes)) {
return 0;
}
@@ -1563,7 +1612,6 @@
((void) p_rng);
return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
#else /* !MBEDTLS_PK_CAN_ECDSA_SIGN && !MBEDTLS_RSA_C */
- const mbedtls_svc_key_id_t *key = pk->pk_ctx;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_algorithm_t alg;
psa_key_type_t type;
@@ -1573,7 +1621,7 @@
(void) f_rng;
(void) p_rng;
- status = psa_get_key_attributes(*key, &attributes);
+ status = psa_get_key_attributes(pk->priv_id, &attributes);
if (status != PSA_SUCCESS) {
return PSA_PK_TO_MBEDTLS_ERR(status);
}
@@ -1583,18 +1631,18 @@
#if defined(MBEDTLS_PK_CAN_ECDSA_SIGN)
if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) {
- alg = PSA_ALG_ECDSA(mbedtls_hash_info_psa_from_md(md_alg));
+ alg = PSA_ALG_ECDSA(mbedtls_md_psa_alg_from_type(md_alg));
} else
#endif /* MBEDTLS_PK_CAN_ECDSA_SIGN */
#if defined(MBEDTLS_RSA_C)
if (PSA_KEY_TYPE_IS_RSA(type)) {
- alg = PSA_ALG_RSA_PKCS1V15_SIGN(mbedtls_hash_info_psa_from_md(md_alg));
+ alg = PSA_ALG_RSA_PKCS1V15_SIGN(mbedtls_md_psa_alg_from_type(md_alg));
} else
#endif /* MBEDTLS_RSA_C */
return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
/* make the signature */
- status = psa_sign_hash(*key, alg, hash, hash_len,
+ status = psa_sign_hash(pk->priv_id, alg, hash, hash_len,
sig, sig_size, sig_len);
if (status != PSA_SUCCESS) {
#if defined(MBEDTLS_PK_CAN_ECDSA_SIGN)
@@ -1621,6 +1669,53 @@
#endif /* !MBEDTLS_PK_CAN_ECDSA_SIGN && !MBEDTLS_RSA_C */
}
+static int pk_opaque_ec_check_pair(mbedtls_pk_context *pub, mbedtls_pk_context *prv,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng)
+{
+ /* The main difference between this function and eckey_check_pair_psa() is
+ * that in the opaque case the private key is always stored in PSA side no
+ * matter if MBEDTLS_PK_USE_PSA_EC_DATA is enabled or not.
+ * When MBEDTLS_PK_USE_PSA_EC_DATA is enabled, we can simply use the
+ * eckey_check_pair_psa(). */
+ (void) f_rng;
+ (void) p_rng;
+
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+ return eckey_check_pair_psa(pub, prv);
+#elif defined(MBEDTLS_ECP_LIGHT)
+ psa_status_t status;
+ uint8_t exp_pub_key[MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN];
+ size_t exp_pub_key_len = 0;
+ uint8_t pub_key[MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN];
+ size_t pub_key_len = 0;
+ int ret;
+
+ status = psa_export_public_key(prv->priv_id, exp_pub_key, sizeof(exp_pub_key),
+ &exp_pub_key_len);
+ if (status != PSA_SUCCESS) {
+ ret = psa_pk_status_to_mbedtls(status);
+ return ret;
+ }
+ ret = mbedtls_ecp_point_write_binary(&(mbedtls_pk_ec_ro(*pub)->grp),
+ &(mbedtls_pk_ec_ro(*pub)->Q),
+ MBEDTLS_ECP_PF_UNCOMPRESSED,
+ &pub_key_len, pub_key, sizeof(pub_key));
+ if (ret != 0) {
+ return ret;
+ }
+ if ((exp_pub_key_len != pub_key_len) ||
+ memcmp(exp_pub_key, pub_key, exp_pub_key_len)) {
+ return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
+ }
+ return 0;
+#else
+ (void) pub;
+ (void) prv;
+ return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
+#endif /* !MBEDTLS_PK_USE_PSA_EC_DATA */
+}
+
const mbedtls_pk_info_t mbedtls_pk_ecdsa_opaque_info = {
MBEDTLS_PK_OPAQUE,
"Opaque",
@@ -1634,9 +1729,9 @@
#endif
NULL, /* decrypt - not relevant */
NULL, /* encrypt - not relevant */
- NULL, /* check_pair - could be done later or left NULL */
- pk_opaque_alloc_wrap,
- pk_opaque_free_wrap,
+ pk_opaque_ec_check_pair,
+ NULL, /* alloc - no need to allocate new data dynamically */
+ NULL, /* free - as for the alloc, there is no data to free */
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
NULL, /* restart alloc - not relevant */
NULL, /* restart free - not relevant */
@@ -1650,14 +1745,13 @@
unsigned char *output, size_t *olen, size_t osize,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
{
- const mbedtls_svc_key_id_t *key = pk->pk_ctx;
psa_status_t status;
/* PSA has its own RNG */
(void) f_rng;
(void) p_rng;
- status = psa_asymmetric_decrypt(*key, PSA_ALG_RSA_PKCS1V15_CRYPT,
+ status = psa_asymmetric_decrypt(pk->priv_id, PSA_ALG_RSA_PKCS1V15_CRYPT,
input, ilen,
NULL, 0,
output, osize, olen);
@@ -1687,8 +1781,8 @@
#endif /* PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY */
NULL, /* encrypt - will be done later */
NULL, /* check_pair - could be done later or left NULL */
- pk_opaque_alloc_wrap,
- pk_opaque_free_wrap,
+ NULL, /* alloc - no need to allocate new data dynamically */
+ NULL, /* free - as for the alloc, there is no data to free */
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
NULL, /* restart alloc - not relevant */
NULL, /* restart free - not relevant */
diff --git a/library/pkcs12.c b/library/pkcs12.c
index 515d9e1..ce2dcf2 100644
--- a/library/pkcs12.c
+++ b/library/pkcs12.c
@@ -39,7 +39,6 @@
#include "mbedtls/des.h"
#endif
-#include "hash_info.h"
#include "mbedtls/psa_util.h"
#if defined(MBEDTLS_ASN1_PARSE_C)
@@ -290,7 +289,7 @@
unsigned char diversifier[128];
unsigned char salt_block[128], pwd_block[128], hash_block[128] = { 0 };
- unsigned char hash_output[MBEDTLS_HASH_MAX_SIZE];
+ unsigned char hash_output[MBEDTLS_MD_MAX_SIZE];
unsigned char *p;
unsigned char c;
int use_password = 0;
@@ -314,7 +313,7 @@
use_password = (pwd && pwdlen != 0);
use_salt = (salt && saltlen != 0);
- hlen = mbedtls_hash_info_get_size(md_type);
+ hlen = mbedtls_md_get_size_from_type(md_type);
if (hlen <= 32) {
v = 64;
diff --git a/library/pkcs5.c b/library/pkcs5.c
index 0f4baf1..94da981 100644
--- a/library/pkcs5.c
+++ b/library/pkcs5.c
@@ -44,7 +44,6 @@
#include "mbedtls/platform.h"
-#include "hash_info.h"
#include "mbedtls/psa_util.h"
#if defined(MBEDTLS_ASN1_PARSE_C)
diff --git a/library/pkparse.c b/library/pkparse.c
index ade8a04..07fce5c 100644
--- a/library/pkparse.c
+++ b/library/pkparse.c
@@ -26,6 +26,7 @@
#include "mbedtls/oid.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/error.h"
+#include "pk_internal.h"
#include <string.h>
@@ -36,6 +37,9 @@
#if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECP_C)
#include "pkwrite.h"
#endif
+#if defined(MBEDTLS_ECP_LIGHT)
+#include "pk_internal.h"
+#endif
#if defined(MBEDTLS_ECDSA_C)
#include "mbedtls/ecdsa.h"
#endif
@@ -59,6 +63,12 @@
#include "mbedtls/platform.h"
+/* Helper for Montgomery curves */
+#if defined(MBEDTLS_ECP_LIGHT) && defined(MBEDTLS_PK_HAVE_RFC8410_CURVES)
+#define MBEDTLS_PK_IS_RFC8410_GROUP_ID(id) \
+ ((id == MBEDTLS_ECP_DP_CURVE25519) || (id == MBEDTLS_ECP_DP_CURVE448))
+#endif /* MBEDTLS_ECP_LIGHT && MBEDTLS_PK_HAVE_RFC8410_CURVES */
+
#if defined(MBEDTLS_FS_IO)
/*
* Load all data from a file into a given buffer.
@@ -454,6 +464,29 @@
}
#endif /* MBEDTLS_PK_PARSE_EC_EXTENDED */
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+/* Functions pk_use_ecparams() and pk_use_ecparams_rfc8410() update the
+ * ecp_keypair structure with proper group ID. The purpose of this helper
+ * function is to update ec_family and ec_bits accordingly. */
+static int pk_update_psa_ecparams(mbedtls_pk_context *pk,
+ mbedtls_ecp_group_id grp_id)
+{
+ psa_ecc_family_t ec_family;
+ size_t bits;
+
+ ec_family = mbedtls_ecc_group_to_psa(grp_id, &bits);
+
+ if ((pk->ec_family != 0) && (pk->ec_family != ec_family)) {
+ return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
+ }
+
+ pk->ec_family = ec_family;
+ pk->ec_bits = bits;
+
+ return 0;
+}
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
+
/*
* Use EC parameters to initialise an EC group
*
@@ -462,7 +495,7 @@
* specifiedCurve SpecifiedECDomain -- = SEQUENCE { ... }
* -- implicitCurve NULL
*/
-static int pk_use_ecparams(const mbedtls_asn1_buf *params, mbedtls_ecp_group *grp)
+static int pk_use_ecparams(const mbedtls_asn1_buf *params, mbedtls_pk_context *pk)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ecp_group_id grp_id;
@@ -481,43 +514,52 @@
#endif
}
- /*
- * grp may already be initialized; if so, make sure IDs match
- */
- if (grp->id != MBEDTLS_ECP_DP_NONE && grp->id != grp_id) {
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+ ret = pk_update_psa_ecparams(pk, grp_id);
+#else
+ /* grp may already be initialized; if so, make sure IDs match */
+ if (mbedtls_pk_ec_ro(*pk)->grp.id != MBEDTLS_ECP_DP_NONE &&
+ mbedtls_pk_ec_ro(*pk)->grp.id != grp_id) {
return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
}
- if ((ret = mbedtls_ecp_group_load(grp, grp_id)) != 0) {
+ if ((ret = mbedtls_ecp_group_load(&(mbedtls_pk_ec_rw(*pk)->grp),
+ grp_id)) != 0) {
return ret;
}
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
- return 0;
+ return ret;
}
-#if defined(MBEDTLS_ECP_LIGHT)
/*
* Helper function for deriving a public key from its private counterpart.
*/
-static int pk_derive_public_key(mbedtls_ecp_keypair *eck,
+static int pk_derive_public_key(mbedtls_pk_context *pk,
const unsigned char *d, size_t d_len,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
{
int ret;
#if defined(MBEDTLS_USE_PSA_CRYPTO)
- psa_status_t status, destruction_status;
- psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
- size_t curve_bits;
- psa_ecc_family_t curve = mbedtls_ecc_group_to_psa(eck->grp.id, &curve_bits);
- /* This buffer is used to store the private key at first and then the
- * public one (but not at the same time). Therefore we size it for the
- * latter since it's bigger. */
+ psa_status_t status;
+ (void) f_rng;
+ (void) p_rng;
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+ (void) d;
+ (void) d_len;
+
+ status = psa_export_public_key(pk->priv_id, pk->pub_raw, sizeof(pk->pub_raw),
+ &pk->pub_raw_len);
+ ret = psa_pk_status_to_mbedtls(status);
+#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
+ mbedtls_ecp_keypair *eck = (mbedtls_ecp_keypair *) pk->pk_ctx;
unsigned char key_buf[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH];
size_t key_len;
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
-
- (void) f_rng;
- (void) p_rng;
+ psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
+ size_t curve_bits;
+ psa_ecc_family_t curve = mbedtls_ecc_group_to_psa(eck->grp.id, &curve_bits);
+ psa_status_t destruction_status;
psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_KEY_PAIR(curve));
psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_EXPORT);
@@ -528,8 +570,6 @@
return ret;
}
- mbedtls_platform_zeroize(key_buf, sizeof(key_buf));
-
status = psa_export_public_key(key_id, key_buf, sizeof(key_buf), &key_len);
ret = psa_pk_status_to_mbedtls(status);
destruction_status = psa_destroy_key(key_id);
@@ -538,9 +578,10 @@
} else if (destruction_status != PSA_SUCCESS) {
return psa_pk_status_to_mbedtls(destruction_status);
}
-
ret = mbedtls_ecp_point_read_binary(&eck->grp, &eck->Q, key_buf, key_len);
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
#else /* MBEDTLS_USE_PSA_CRYPTO */
+ mbedtls_ecp_keypair *eck = (mbedtls_ecp_keypair *) pk->pk_ctx;
(void) d;
(void) d_len;
@@ -556,13 +597,24 @@
*/
static int pk_use_ecparams_rfc8410(const mbedtls_asn1_buf *params,
mbedtls_ecp_group_id grp_id,
- mbedtls_ecp_group *grp)
+ mbedtls_pk_context *pk)
{
+ int ret;
+
if (params->tag != 0 || params->len != 0) {
return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
}
- return mbedtls_ecp_group_load(grp, grp_id);
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+ ret = pk_update_psa_ecparams(pk, grp_id);
+#else
+ mbedtls_ecp_keypair *ecp = mbedtls_pk_ec_rw(*pk);
+ ret = mbedtls_ecp_group_load(&(ecp->grp), grp_id);
+ if (ret != 0) {
+ return ret;
+ }
+#endif
+ return ret;
}
/*
@@ -570,7 +622,7 @@
*
* CurvePrivateKey ::= OCTET STRING
*/
-static int pk_parse_key_rfc8410_der(mbedtls_ecp_keypair *eck,
+static int pk_parse_key_rfc8410_der(mbedtls_pk_context *pk,
unsigned char *key, size_t keylen, const unsigned char *end,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
{
@@ -585,28 +637,87 @@
return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
}
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+ psa_status_t status;
+
+ psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(pk->ec_family));
+ psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_EXPORT |
+ PSA_KEY_USAGE_DERIVE);
+ psa_set_key_algorithm(&attributes, PSA_ALG_ECDH);
+
+ status = psa_import_key(&attributes, key, len, &pk->priv_id);
+ if (status != PSA_SUCCESS) {
+ ret = psa_pk_status_to_mbedtls(status);
+ return ret;
+ }
+#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
+ mbedtls_ecp_keypair *eck = mbedtls_pk_ec_rw(*pk);
+
if ((ret = mbedtls_mpi_read_binary_le(&eck->d, key, len)) != 0) {
mbedtls_ecp_keypair_free(eck);
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret);
}
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
- // pk_parse_key_pkcs8_unencrypted_der() only supports version 1 PKCS8 keys,
- // which never contain a public key. As such, derive the public key
- // unconditionally.
- if ((ret = pk_derive_public_key(eck, key, len, f_rng, p_rng)) != 0) {
+ /* pk_parse_key_pkcs8_unencrypted_der() only supports version 1 PKCS8 keys,
+ * which never contain a public key. As such, derive the public key
+ * unconditionally. */
+ if ((ret = pk_derive_public_key(pk, key, len, f_rng, p_rng)) != 0) {
+#if !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
mbedtls_ecp_keypair_free(eck);
+#endif /* !MBEDTLS_PK_USE_PSA_EC_DATA */
return ret;
}
+ /* When MBEDTLS_PK_USE_PSA_EC_DATA the key is checked while importing it
+ * into PSA. */
+#if !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
if ((ret = mbedtls_ecp_check_privkey(&eck->grp, &eck->d)) != 0) {
mbedtls_ecp_keypair_free(eck);
return ret;
}
+#endif /* !MBEDTLS_PK_USE_PSA_EC_DATA */
return 0;
}
#endif /* MBEDTLS_PK_HAVE_RFC8410_CURVES */
-#endif /* MBEDTLS_ECP_LIGHT */
+
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+/*
+ * Create a temporary ecp_keypair for converting an EC point in compressed
+ * format to an uncompressed one
+ */
+static int pk_convert_compressed_ec(mbedtls_pk_context *pk,
+ const unsigned char *in_start, size_t in_len,
+ size_t *out_buf_len, unsigned char *out_buf,
+ size_t out_buf_size)
+{
+ mbedtls_ecp_keypair ecp_key;
+ mbedtls_ecp_group_id ecp_group_id;
+ int ret;
+
+ ecp_group_id = mbedtls_ecc_group_of_psa(pk->ec_family, pk->ec_bits, 0);
+
+ mbedtls_ecp_keypair_init(&ecp_key);
+ ret = mbedtls_ecp_group_load(&(ecp_key.grp), ecp_group_id);
+ if (ret != 0) {
+ return ret;
+ }
+ ret = mbedtls_ecp_point_read_binary(&(ecp_key.grp), &ecp_key.Q,
+ in_start, in_len);
+ if (ret != 0) {
+ goto exit;
+ }
+ ret = mbedtls_ecp_point_write_binary(&(ecp_key.grp), &ecp_key.Q,
+ MBEDTLS_ECP_PF_UNCOMPRESSED,
+ out_buf_len, out_buf, out_buf_size);
+
+exit:
+ mbedtls_ecp_keypair_free(&ecp_key);
+ return ret;
+}
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
/*
* EC public key is an EC point
@@ -616,15 +727,61 @@
* return code of mbedtls_ecp_point_read_binary() and leave p in a usable state.
*/
static int pk_get_ecpubkey(unsigned char **p, const unsigned char *end,
- mbedtls_ecp_keypair *key)
+ mbedtls_pk_context *pk)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- if ((ret = mbedtls_ecp_point_read_binary(&key->grp, &key->Q,
- (const unsigned char *) *p, end - *p)) == 0) {
- ret = mbedtls_ecp_check_pubkey(&key->grp, &key->Q);
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+ mbedtls_svc_key_id_t key;
+ psa_key_attributes_t key_attrs = PSA_KEY_ATTRIBUTES_INIT;
+ size_t len = (end - *p);
+
+ if (len > PSA_EXPORT_PUBLIC_KEY_MAX_SIZE) {
+ return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
+ /* Compressed point format are not supported yet by PSA crypto. As a
+ * consequence ecp functions are used to "convert" the point to
+ * uncompressed format */
+ if ((**p == 0x02) || (**p == 0x03)) {
+ ret = pk_convert_compressed_ec(pk, *p, len,
+ &(pk->pub_raw_len), pk->pub_raw,
+ PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
+ if (ret != 0) {
+ return ret;
+ }
+ } else {
+ /* Uncompressed format */
+ if ((end - *p) > MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN) {
+ return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL;
+ }
+ memcpy(pk->pub_raw, *p, (end - *p));
+ pk->pub_raw_len = end - *p;
+ }
+
+ /* Validate the key by trying to importing it */
+ psa_set_key_usage_flags(&key_attrs, 0);
+ psa_set_key_algorithm(&key_attrs, PSA_ALG_ECDSA_ANY);
+ psa_set_key_type(&key_attrs, PSA_KEY_TYPE_ECC_PUBLIC_KEY(pk->ec_family));
+ psa_set_key_bits(&key_attrs, pk->ec_bits);
+
+ if ((psa_import_key(&key_attrs, pk->pub_raw, pk->pub_raw_len,
+ &key) != PSA_SUCCESS) ||
+ (psa_destroy_key(key) != PSA_SUCCESS)) {
+ mbedtls_platform_zeroize(pk->pub_raw, MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN);
+ pk->pub_raw_len = 0;
+ return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
+ }
+ ret = 0;
+#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
+ mbedtls_ecp_keypair *ec_key = (mbedtls_ecp_keypair *) pk->pk_ctx;
+ if ((ret = mbedtls_ecp_point_read_binary(&ec_key->grp, &ec_key->Q,
+ (const unsigned char *) *p,
+ end - *p)) == 0) {
+ ret = mbedtls_ecp_check_pubkey(&ec_key->grp, &ec_key->Q);
+ }
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
+
/*
* We know mbedtls_ecp_point_read_binary consumed all bytes or failed
*/
@@ -794,15 +951,15 @@
#if defined(MBEDTLS_ECP_LIGHT)
if (pk_alg == MBEDTLS_PK_ECKEY_DH || pk_alg == MBEDTLS_PK_ECKEY) {
#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES)
- if (mbedtls_pk_is_rfc8410_curve(ec_grp_id)) {
- ret = pk_use_ecparams_rfc8410(&alg_params, ec_grp_id, &mbedtls_pk_ec(*pk)->grp);
+ if (MBEDTLS_PK_IS_RFC8410_GROUP_ID(ec_grp_id)) {
+ ret = pk_use_ecparams_rfc8410(&alg_params, ec_grp_id, pk);
} else
#endif
{
- ret = pk_use_ecparams(&alg_params, &mbedtls_pk_ec(*pk)->grp);
+ ret = pk_use_ecparams(&alg_params, pk);
}
if (ret == 0) {
- ret = pk_get_ecpubkey(p, end, mbedtls_pk_ec(*pk));
+ ret = pk_get_ecpubkey(p, end, pk);
}
} else
#endif /* MBEDTLS_ECP_LIGHT */
@@ -1013,7 +1170,7 @@
/*
* Parse a SEC1 encoded private EC key
*/
-static int pk_parse_key_sec1_der(mbedtls_ecp_keypair *eck,
+static int pk_parse_key_sec1_der(mbedtls_pk_context *pk,
const unsigned char *key, size_t keylen,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
{
@@ -1025,6 +1182,11 @@
unsigned char *d;
unsigned char *end = p + keylen;
unsigned char *end2;
+ mbedtls_ecp_keypair *eck = mbedtls_pk_ec_rw(*pk);
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+ psa_status_t status;
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
/*
* RFC 5915, or SEC1 Appendix C.4
@@ -1057,10 +1219,13 @@
d = p;
d_len = len;
+
+#if !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
if ((ret = mbedtls_mpi_read_binary(&eck->d, p, len)) != 0) {
mbedtls_ecp_keypair_free(eck);
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret);
}
+#endif
p += len;
@@ -1073,7 +1238,7 @@
MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED |
0)) == 0) {
if ((ret = pk_get_ecparams(&p, p + len, ¶ms)) != 0 ||
- (ret = pk_use_ecparams(¶ms, &eck->grp)) != 0) {
+ (ret = pk_use_ecparams(¶ms, pk)) != 0) {
mbedtls_ecp_keypair_free(eck);
return ret;
}
@@ -1102,7 +1267,7 @@
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
}
- if ((ret = pk_get_ecpubkey(&p, end2, eck)) == 0) {
+ if ((ret = pk_get_ecpubkey(&p, end2, pk)) == 0) {
pubkey_done = 1;
} else {
/*
@@ -1119,17 +1284,40 @@
}
}
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+ psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(pk->ec_family));
+ /* Setting largest masks for usage and key algorithms */
+ psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH |
+ PSA_KEY_USAGE_SIGN_MESSAGE |
+ PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_DERIVE);
+#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
+ psa_set_key_algorithm(&attributes,
+ PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_ANY_HASH));
+#else
+ psa_set_key_algorithm(&attributes, PSA_ALG_ECDSA(PSA_ALG_ANY_HASH));
+#endif
+ psa_set_key_enrollment_algorithm(&attributes, PSA_ALG_ECDH);
+
+ status = psa_import_key(&attributes, d, d_len, &pk->priv_id);
+ if (status != PSA_SUCCESS) {
+ ret = psa_pk_status_to_mbedtls(status);
+ return ret;
+ }
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
+
if (!pubkey_done) {
- if ((ret = pk_derive_public_key(eck, d, d_len, f_rng, p_rng)) != 0) {
+ if ((ret = pk_derive_public_key(pk, d, d_len, f_rng, p_rng)) != 0) {
mbedtls_ecp_keypair_free(eck);
return ret;
}
}
+#if !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
if ((ret = mbedtls_ecp_check_privkey(&eck->grp, &eck->d)) != 0) {
mbedtls_ecp_keypair_free(eck);
return ret;
}
+#endif /* !MBEDTLS_PK_USE_PSA_EC_DATA */
return 0;
}
@@ -1230,11 +1418,11 @@
#if defined(MBEDTLS_ECP_LIGHT)
if (pk_alg == MBEDTLS_PK_ECKEY || pk_alg == MBEDTLS_PK_ECKEY_DH) {
#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES)
- if (mbedtls_pk_is_rfc8410_curve(ec_grp_id)) {
+ if (MBEDTLS_PK_IS_RFC8410_GROUP_ID(ec_grp_id)) {
if ((ret =
- pk_use_ecparams_rfc8410(¶ms, ec_grp_id, &mbedtls_pk_ec(*pk)->grp)) != 0 ||
+ pk_use_ecparams_rfc8410(¶ms, ec_grp_id, pk)) != 0 ||
(ret =
- pk_parse_key_rfc8410_der(mbedtls_pk_ec(*pk), p, len, end, f_rng,
+ pk_parse_key_rfc8410_der(pk, p, len, end, f_rng,
p_rng)) != 0) {
mbedtls_pk_free(pk);
return ret;
@@ -1242,8 +1430,8 @@
} else
#endif
{
- if ((ret = pk_use_ecparams(¶ms, &mbedtls_pk_ec(*pk)->grp)) != 0 ||
- (ret = pk_parse_key_sec1_der(mbedtls_pk_ec(*pk), p, len, f_rng, p_rng)) != 0) {
+ if ((ret = pk_use_ecparams(¶ms, pk)) != 0 ||
+ (ret = pk_parse_key_sec1_der(pk, p, len, f_rng, p_rng)) != 0) {
mbedtls_pk_free(pk);
return ret;
}
@@ -1430,7 +1618,7 @@
pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY);
if ((ret = mbedtls_pk_setup(pk, pk_info)) != 0 ||
- (ret = pk_parse_key_sec1_der(mbedtls_pk_ec(*pk),
+ (ret = pk_parse_key_sec1_der(pk,
pem.buf, pem.buflen,
f_rng, p_rng)) != 0) {
mbedtls_pk_free(pk);
@@ -1554,18 +1742,18 @@
#if defined(MBEDTLS_ECP_LIGHT)
pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY);
if (mbedtls_pk_setup(pk, pk_info) == 0 &&
- pk_parse_key_sec1_der(mbedtls_pk_ec(*pk),
+ pk_parse_key_sec1_der(pk,
key, keylen, f_rng, p_rng) == 0) {
return 0;
}
mbedtls_pk_free(pk);
#endif /* MBEDTLS_ECP_LIGHT */
- /* If MBEDTLS_RSA_C is defined but MBEDTLS_ECP_C isn't,
+ /* If MBEDTLS_RSA_C is defined but MBEDTLS_ECP_LIGHT isn't,
* it is ok to leave the PK context initialized but not
* freed: It is the caller's responsibility to call pk_init()
* before calling this function, and to call pk_free()
- * when it fails. If MBEDTLS_ECP_C is defined but MBEDTLS_RSA_C
+ * when it fails. If MBEDTLS_ECP_LIGHT is defined but MBEDTLS_RSA_C
* isn't, this leads to mbedtls_pk_free() being called
* twice, once here and once by the caller, but this is
* also ok and in line with the mbedtls_pk_free() calls
diff --git a/library/pkwrite.c b/library/pkwrite.c
index b83a13e..218d0c1 100644
--- a/library/pkwrite.c
+++ b/library/pkwrite.c
@@ -26,6 +26,7 @@
#include "mbedtls/oid.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/error.h"
+#include "pk_internal.h"
#include <string.h>
@@ -37,7 +38,10 @@
#include "mbedtls/ecp.h"
#include "mbedtls/platform_util.h"
#endif
-#if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECP_C)
+#if defined(MBEDTLS_ECP_LIGHT)
+#include "pk_internal.h"
+#endif
+#if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECP_LIGHT)
#include "pkwrite.h"
#endif
#if defined(MBEDTLS_ECDSA_C)
@@ -53,6 +57,61 @@
#endif
#include "mbedtls/platform.h"
+/* Helper for Montgomery curves */
+#if defined(MBEDTLS_ECP_LIGHT)
+#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES)
+static inline int mbedtls_pk_is_rfc8410(const mbedtls_pk_context *pk)
+{
+ mbedtls_ecp_group_id id = mbedtls_pk_get_group_id(pk);
+
+#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
+ if (id == MBEDTLS_ECP_DP_CURVE25519) {
+ return 1;
+ }
+#endif
+#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
+ if (id == MBEDTLS_ECP_DP_CURVE448) {
+ return 1;
+ }
+#endif
+ return 0;
+}
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+/* It is assumed that the input key is opaque */
+static psa_ecc_family_t pk_get_opaque_ec_family(const mbedtls_pk_context *pk)
+{
+ psa_ecc_family_t ec_family = 0;
+ psa_key_attributes_t key_attrs = PSA_KEY_ATTRIBUTES_INIT;
+
+ if (psa_get_key_attributes(pk->priv_id, &key_attrs) != PSA_SUCCESS) {
+ return 0;
+ }
+ ec_family = PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(&key_attrs));
+ psa_reset_key_attributes(&key_attrs);
+
+ return ec_family;
+}
+#endif /* MBETLS_USE_PSA_CRYPTO */
+#endif /* MBEDTLS_PK_HAVE_RFC8410_CURVES */
+#endif /* MBEDTLS_ECP_LIGHT */
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+/* It is assumed that the input key is opaque */
+static psa_key_type_t pk_get_opaque_key_type(const mbedtls_pk_context *pk)
+{
+ psa_key_attributes_t opaque_attrs = PSA_KEY_ATTRIBUTES_INIT;
+ psa_key_type_t opaque_key_type;
+
+ if (psa_get_key_attributes(pk->priv_id, &opaque_attrs) != PSA_SUCCESS) {
+ return 0;
+ }
+ opaque_key_type = psa_get_key_type(&opaque_attrs);
+ psa_reset_key_attributes(&opaque_attrs);
+
+ return opaque_key_type;
+}
+#endif /* MBETLS_USE_PSA_CRYPTO */
+
#if defined(MBEDTLS_RSA_C)
/*
* RSAPublicKey ::= SEQUENCE {
@@ -61,11 +120,12 @@
* }
*/
static int pk_write_rsa_pubkey(unsigned char **p, unsigned char *start,
- mbedtls_rsa_context *rsa)
+ const mbedtls_pk_context *pk)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
mbedtls_mpi T;
+ mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*pk);
mbedtls_mpi_init(&T);
@@ -99,20 +159,20 @@
#endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_ECP_LIGHT)
-/*
- * EC public key is an EC point
- */
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
static int pk_write_ec_pubkey(unsigned char **p, unsigned char *start,
- mbedtls_ecp_keypair *ec)
+ const mbedtls_pk_context *pk)
{
- int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
- unsigned char buf[MBEDTLS_ECP_MAX_PT_LEN];
+ uint8_t buf[PSA_EXPORT_KEY_PAIR_MAX_SIZE];
- if ((ret = mbedtls_ecp_point_write_binary(&ec->grp, &ec->Q,
- MBEDTLS_ECP_PF_UNCOMPRESSED,
- &len, buf, sizeof(buf))) != 0) {
- return ret;
+ if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) {
+ if (psa_export_public_key(pk->priv_id, buf, sizeof(buf), &len) != PSA_SUCCESS) {
+ return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
+ }
+ } else {
+ len = pk->pub_raw_len;
+ memcpy(buf, pk->pub_raw, len);
}
if (*p < start || (size_t) (*p - start) < len) {
@@ -124,6 +184,47 @@
return (int) len;
}
+#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
+static int pk_write_ec_pubkey(unsigned char **p, unsigned char *start,
+ const mbedtls_pk_context *pk)
+{
+ size_t len = 0;
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ uint8_t buf[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
+#else
+ unsigned char buf[MBEDTLS_ECP_MAX_PT_LEN];
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+ mbedtls_ecp_keypair *ec = mbedtls_pk_ec(*pk);
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) {
+ if (psa_export_public_key(pk->priv_id, buf, sizeof(buf), &len) != PSA_SUCCESS) {
+ return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
+ }
+ *p -= len;
+ memcpy(*p, buf, len);
+ return (int) len;
+ } else
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+ {
+ if ((ret = mbedtls_ecp_point_write_binary(&ec->grp, &ec->Q,
+ MBEDTLS_ECP_PF_UNCOMPRESSED,
+ &len, buf, sizeof(buf))) != 0) {
+ return ret;
+ }
+ }
+
+ if (*p < start || (size_t) (*p - start) < len) {
+ return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
+ }
+
+ *p -= len;
+ memcpy(*p, buf, len);
+
+ return (int) len;
+}
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
/*
* ECParameters ::= CHOICE {
@@ -150,25 +251,97 @@
/*
* privateKey OCTET STRING -- always of length ceil(log2(n)/8)
*/
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
static int pk_write_ec_private(unsigned char **p, unsigned char *start,
- mbedtls_ecp_keypair *ec)
+ const mbedtls_pk_context *pk)
{
+ size_t byte_length;
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- size_t byte_length = (ec->grp.pbits + 7) / 8;
- unsigned char tmp[MBEDTLS_ECP_MAX_BYTES];
+ unsigned char tmp[MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH];
+ psa_status_t status;
- ret = mbedtls_ecp_write_key(ec, tmp, byte_length);
- if (ret != 0) {
- goto exit;
+ if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) {
+ status = psa_export_key(pk->priv_id, tmp, sizeof(tmp), &byte_length);
+ if (status != PSA_SUCCESS) {
+ ret = PSA_PK_ECDSA_TO_MBEDTLS_ERR(status);
+ return ret;
+ }
+ } else {
+ status = psa_export_key(pk->priv_id, tmp, sizeof(tmp), &byte_length);
+ if (status != PSA_SUCCESS) {
+ ret = PSA_PK_ECDSA_TO_MBEDTLS_ERR(status);
+ goto exit;
+ }
}
- ret = mbedtls_asn1_write_octet_string(p, start, tmp, byte_length);
+ ret = mbedtls_asn1_write_octet_string(p, start, tmp, byte_length);
exit:
- mbedtls_platform_zeroize(tmp, byte_length);
+ mbedtls_platform_zeroize(tmp, sizeof(tmp));
return ret;
}
+#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
+static int pk_write_ec_private(unsigned char **p, unsigned char *start,
+ const mbedtls_pk_context *pk)
+{
+ size_t byte_length;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ unsigned char tmp[MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH];
+ psa_status_t status;
+#else
+ unsigned char tmp[MBEDTLS_ECP_MAX_BYTES];
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) {
+ status = psa_export_key(pk->priv_id, tmp, sizeof(tmp), &byte_length);
+ if (status != PSA_SUCCESS) {
+ ret = PSA_PK_ECDSA_TO_MBEDTLS_ERR(status);
+ return ret;
+ }
+ } else
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+ {
+ mbedtls_ecp_keypair *ec = mbedtls_pk_ec_rw(*pk);
+ byte_length = (ec->grp.pbits + 7) / 8;
+
+ ret = mbedtls_ecp_write_key(ec, tmp, byte_length);
+ if (ret != 0) {
+ goto exit;
+ }
+ }
+ ret = mbedtls_asn1_write_octet_string(p, start, tmp, byte_length);
+exit:
+ mbedtls_platform_zeroize(tmp, sizeof(tmp));
+ return ret;
+}
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
#endif /* MBEDTLS_ECP_LIGHT */
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+static int pk_write_opaque_pubkey(unsigned char **p, unsigned char *start,
+ const mbedtls_pk_context *pk)
+{
+ size_t buffer_size;
+ size_t len = 0;
+
+ if (*p < start) {
+ return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
+ }
+
+ buffer_size = (size_t) (*p - start);
+ if (psa_export_public_key(pk->priv_id, start, buffer_size,
+ &len) != PSA_SUCCESS) {
+ return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
+ }
+
+ *p -= len;
+ memmove(*p, start, len);
+
+ return (int) len;
+}
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
int mbedtls_pk_write_pubkey(unsigned char **p, unsigned char *start,
const mbedtls_pk_context *key)
{
@@ -177,31 +350,17 @@
#if defined(MBEDTLS_RSA_C)
if (mbedtls_pk_get_type(key) == MBEDTLS_PK_RSA) {
- MBEDTLS_ASN1_CHK_ADD(len, pk_write_rsa_pubkey(p, start, mbedtls_pk_rsa(*key)));
+ MBEDTLS_ASN1_CHK_ADD(len, pk_write_rsa_pubkey(p, start, key));
} else
#endif
#if defined(MBEDTLS_ECP_LIGHT)
if (mbedtls_pk_get_type(key) == MBEDTLS_PK_ECKEY) {
- MBEDTLS_ASN1_CHK_ADD(len, pk_write_ec_pubkey(p, start, mbedtls_pk_ec(*key)));
+ MBEDTLS_ASN1_CHK_ADD(len, pk_write_ec_pubkey(p, start, key));
} else
#endif
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if (mbedtls_pk_get_type(key) == MBEDTLS_PK_OPAQUE) {
- size_t buffer_size;
- mbedtls_svc_key_id_t *key_id = (mbedtls_svc_key_id_t *) key->pk_ctx;
-
- if (*p < start) {
- return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
- }
-
- buffer_size = (size_t) (*p - start);
- if (psa_export_public_key(*key_id, start, buffer_size, &len)
- != PSA_SUCCESS) {
- return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
- } else {
- *p -= len;
- memmove(*p, start, len);
- }
+ MBEDTLS_ASN1_CHK_ADD(len, pk_write_opaque_pubkey(p, start, key));
} else
#endif /* MBEDTLS_USE_PSA_CRYPTO */
return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
@@ -247,40 +406,22 @@
pk_type = mbedtls_pk_get_type(key);
#if defined(MBEDTLS_ECP_LIGHT)
if (pk_type == MBEDTLS_PK_ECKEY) {
- ec_grp_id = mbedtls_pk_ec(*key)->grp.id;
+ ec_grp_id = mbedtls_pk_get_group_id(key);
}
#endif /* MBEDTLS_ECP_LIGHT */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if (pk_type == MBEDTLS_PK_OPAQUE) {
- psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
- psa_key_type_t key_type;
- mbedtls_svc_key_id_t key_id;
- key_id = *((mbedtls_svc_key_id_t *) key->pk_ctx);
- if (PSA_SUCCESS != psa_get_key_attributes(key_id, &attributes)) {
- return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
- }
- key_type = psa_get_key_type(&attributes);
-
+ psa_key_type_t opaque_key_type = pk_get_opaque_key_type(key);
#if defined(MBEDTLS_ECP_LIGHT)
- if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type)) {
- psa_ecc_family_t curve;
-
- curve = PSA_KEY_TYPE_ECC_GET_FAMILY(key_type);
- if (curve != 0) {
- ec_grp_id = mbedtls_ecc_group_of_psa(curve, psa_get_key_bits(&attributes), 0);
- if (ec_grp_id != MBEDTLS_ECP_DP_NONE) {
- /* The rest of the function works as for legacy EC contexts. */
- pk_type = MBEDTLS_PK_ECKEY;
- }
- }
- }
+ if (PSA_KEY_TYPE_IS_ECC(opaque_key_type)) {
+ pk_type = MBEDTLS_PK_ECKEY;
+ ec_grp_id = mbedtls_pk_get_group_id(key);
+ } else
#endif /* MBEDTLS_ECP_LIGHT */
- if (PSA_KEY_TYPE_IS_RSA(key_type)) {
+ if (PSA_KEY_TYPE_IS_RSA(opaque_key_type)) {
/* The rest of the function works as for legacy RSA contexts. */
pk_type = MBEDTLS_PK_RSA;
}
-
- psa_reset_key_attributes(&attributes);
}
/* `pk_type` will have been changed to non-opaque by here if this function can handle it */
if (pk_type == MBEDTLS_PK_OPAQUE) {
@@ -290,11 +431,13 @@
#if defined(MBEDTLS_ECP_LIGHT)
if (pk_type == MBEDTLS_PK_ECKEY) {
- /* Some groups have their own AlgorithmIdentifier OID, others are handled by mbedtls_oid_get_oid_by_pk_alg() below */
+ /* Some groups have their own AlgorithmIdentifier OID, others are handled
+ * by mbedtls_oid_get_oid_by_pk_alg() below */
ret = mbedtls_oid_get_oid_by_ec_grp_algid(ec_grp_id, &oid, &oid_len);
if (ret == 0) {
- /* Currently, none of the supported algorithms that have their own AlgorithmIdentifier OID have any parameters */
+ /* Currently, none of the supported algorithms that have their own
+ * AlgorithmIdentifier OID have any parameters */
has_par = 0;
} else if (ret == MBEDTLS_ERR_OID_NOT_FOUND) {
MBEDTLS_ASN1_CHK_ADD(par_len, pk_write_ec_param(&c, buf, ec_grp_id));
@@ -324,7 +467,7 @@
#if defined(MBEDTLS_ECP_LIGHT)
#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES)
/*
- * RFC8410
+ * RFC8410 section 7
*
* OneAsymmetricKey ::= SEQUENCE {
* version Version,
@@ -335,24 +478,26 @@
* [[2: publicKey [1] IMPLICIT PublicKey OPTIONAL ]],
* ...
* }
- *
+ * ...
* CurvePrivateKey ::= OCTET STRING
*/
static int pk_write_ec_rfc8410_der(unsigned char **p, unsigned char *buf,
- mbedtls_ecp_keypair *ec)
+ const mbedtls_pk_context *pk)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
size_t oid_len = 0;
const char *oid;
+ mbedtls_ecp_group_id grp_id;
/* privateKey */
- MBEDTLS_ASN1_CHK_ADD(len, pk_write_ec_private(p, buf, ec));
+ MBEDTLS_ASN1_CHK_ADD(len, pk_write_ec_private(p, buf, pk));
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, buf, len));
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, buf, MBEDTLS_ASN1_OCTET_STRING));
+ grp_id = mbedtls_pk_get_group_id(pk);
/* privateKeyAlgorithm */
- if ((ret = mbedtls_oid_get_oid_by_ec_grp_algid(ec->grp.id, &oid, &oid_len)) != 0) {
+ if ((ret = mbedtls_oid_get_oid_by_ec_grp_algid(grp_id, &oid, &oid_len)) != 0) {
return ret;
}
MBEDTLS_ASN1_CHK_ADD(len,
@@ -368,24 +513,91 @@
return (int) len;
}
#endif /* MBEDTLS_PK_HAVE_RFC8410_CURVES */
-#endif /* MBEDTLS_ECP_LIGHT */
-int mbedtls_pk_write_key_der(const mbedtls_pk_context *key, unsigned char *buf, size_t size)
+/*
+ * RFC 5915, or SEC1 Appendix C.4
+ *
+ * ECPrivateKey ::= SEQUENCE {
+ * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
+ * privateKey OCTET STRING,
+ * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
+ * publicKey [1] BIT STRING OPTIONAL
+ * }
+ */
+static int pk_write_ec_der(unsigned char **p, unsigned char *buf,
+ const mbedtls_pk_context *pk)
{
- int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- unsigned char *c;
size_t len = 0;
+ int ret;
+ size_t pub_len = 0, par_len = 0;
+ mbedtls_ecp_group_id grp_id;
- if (size == 0) {
+ /* publicKey */
+ MBEDTLS_ASN1_CHK_ADD(pub_len, pk_write_ec_pubkey(p, buf, pk));
+
+ if (*p - buf < 1) {
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
}
+ (*p)--;
+ **p = 0;
+ pub_len += 1;
- c = buf + size;
+ MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_asn1_write_len(p, buf, pub_len));
+ MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_asn1_write_tag(p, buf, MBEDTLS_ASN1_BIT_STRING));
+
+ MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_asn1_write_len(p, buf, pub_len));
+ MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_asn1_write_tag(p, buf,
+ MBEDTLS_ASN1_CONTEXT_SPECIFIC |
+ MBEDTLS_ASN1_CONSTRUCTED | 1));
+ len += pub_len;
+
+ /* parameters */
+ grp_id = mbedtls_pk_get_group_id(pk);
+ MBEDTLS_ASN1_CHK_ADD(par_len, pk_write_ec_param(p, buf, grp_id));
+ MBEDTLS_ASN1_CHK_ADD(par_len, mbedtls_asn1_write_len(p, buf, par_len));
+ MBEDTLS_ASN1_CHK_ADD(par_len, mbedtls_asn1_write_tag(p, buf,
+ MBEDTLS_ASN1_CONTEXT_SPECIFIC |
+ MBEDTLS_ASN1_CONSTRUCTED | 0));
+ len += par_len;
+
+ /* privateKey */
+ MBEDTLS_ASN1_CHK_ADD(len, pk_write_ec_private(p, buf, pk));
+
+ /* version */
+ MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_int(p, buf, 1));
+
+ MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, buf, len));
+ MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, buf, MBEDTLS_ASN1_CONSTRUCTED |
+ MBEDTLS_ASN1_SEQUENCE));
+
+ return (int) len;
+}
+#endif /* MBEDTLS_ECP_LIGHT */
#if defined(MBEDTLS_RSA_C)
- if (mbedtls_pk_get_type(key) == MBEDTLS_PK_RSA) {
+static int pk_write_rsa_der(unsigned char **p, unsigned char *buf,
+ const mbedtls_pk_context *pk)
+{
+ size_t len = 0;
+ int ret;
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) {
+ uint8_t tmp[PSA_EXPORT_KEY_PAIR_MAX_SIZE];
+ size_t tmp_len = 0;
+
+ if (psa_export_key(pk->priv_id, tmp, sizeof(tmp), &tmp_len) != PSA_SUCCESS) {
+ return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
+ }
+ *p -= tmp_len;
+ memcpy(*p, tmp, tmp_len);
+ len += tmp_len;
+ mbedtls_platform_zeroize(tmp, sizeof(tmp));
+ } else
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+ {
mbedtls_mpi T; /* Temporary holding the exported parameters */
- mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*key);
+ mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*pk);
/*
* Export the parameters one after another to avoid simultaneous copies.
@@ -395,21 +607,21 @@
/* Export QP */
if ((ret = mbedtls_rsa_export_crt(rsa, NULL, NULL, &T)) != 0 ||
- (ret = mbedtls_asn1_write_mpi(&c, buf, &T)) < 0) {
+ (ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) {
goto end_of_export;
}
len += ret;
/* Export DQ */
if ((ret = mbedtls_rsa_export_crt(rsa, NULL, &T, NULL)) != 0 ||
- (ret = mbedtls_asn1_write_mpi(&c, buf, &T)) < 0) {
+ (ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) {
goto end_of_export;
}
len += ret;
/* Export DP */
if ((ret = mbedtls_rsa_export_crt(rsa, &T, NULL, NULL)) != 0 ||
- (ret = mbedtls_asn1_write_mpi(&c, buf, &T)) < 0) {
+ (ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) {
goto end_of_export;
}
len += ret;
@@ -417,7 +629,7 @@
/* Export Q */
if ((ret = mbedtls_rsa_export(rsa, NULL, NULL,
&T, NULL, NULL)) != 0 ||
- (ret = mbedtls_asn1_write_mpi(&c, buf, &T)) < 0) {
+ (ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) {
goto end_of_export;
}
len += ret;
@@ -425,7 +637,7 @@
/* Export P */
if ((ret = mbedtls_rsa_export(rsa, NULL, &T,
NULL, NULL, NULL)) != 0 ||
- (ret = mbedtls_asn1_write_mpi(&c, buf, &T)) < 0) {
+ (ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) {
goto end_of_export;
}
len += ret;
@@ -433,7 +645,7 @@
/* Export D */
if ((ret = mbedtls_rsa_export(rsa, NULL, NULL,
NULL, &T, NULL)) != 0 ||
- (ret = mbedtls_asn1_write_mpi(&c, buf, &T)) < 0) {
+ (ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) {
goto end_of_export;
}
len += ret;
@@ -441,7 +653,7 @@
/* Export E */
if ((ret = mbedtls_rsa_export(rsa, NULL, NULL,
NULL, NULL, &T)) != 0 ||
- (ret = mbedtls_asn1_write_mpi(&c, buf, &T)) < 0) {
+ (ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) {
goto end_of_export;
}
len += ret;
@@ -449,7 +661,7 @@
/* Export N */
if ((ret = mbedtls_rsa_export(rsa, &T, NULL,
NULL, NULL, NULL)) != 0 ||
- (ret = mbedtls_asn1_write_mpi(&c, buf, &T)) < 0) {
+ (ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) {
goto end_of_export;
}
len += ret;
@@ -461,73 +673,64 @@
return ret;
}
- MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_int(&c, buf, 0));
- MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len));
- MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c,
+ MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_int(p, buf, 0));
+ MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, buf, len));
+ MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p,
buf, MBEDTLS_ASN1_CONSTRUCTED |
MBEDTLS_ASN1_SEQUENCE));
+ }
+
+ return (int) len;
+}
+#endif /* MBEDTLS_RSA_C */
+
+int mbedtls_pk_write_key_der(const mbedtls_pk_context *key, unsigned char *buf, size_t size)
+{
+ unsigned char *c;
+ size_t len = 0;
+#if defined(MBEDTLS_RSA_C)
+ int is_rsa_opaque = 0;
+#endif /* MBEDTLS_RSA_C */
+#if defined(MBEDTLS_ECP_LIGHT)
+ int is_ec_opaque = 0;
+#endif /* MBEDTLS_ECP_LIGHT */
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ psa_key_type_t opaque_key_type;
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+ if (size == 0) {
+ return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
+ }
+
+ c = buf + size;
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if (mbedtls_pk_get_type(key) == MBEDTLS_PK_OPAQUE) {
+ opaque_key_type = pk_get_opaque_key_type(key);
+#if defined(MBEDTLS_RSA_C)
+ is_rsa_opaque = PSA_KEY_TYPE_IS_RSA(opaque_key_type);
+#endif /* MBEDTLS_RSA_C */
+#if defined(MBEDTLS_ECP_LIGHT)
+ is_ec_opaque = PSA_KEY_TYPE_IS_ECC(opaque_key_type);
+#endif /* MBEDTLS_ECP_LIGHT */
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+#if defined(MBEDTLS_RSA_C)
+ if ((mbedtls_pk_get_type(key) == MBEDTLS_PK_RSA) || is_rsa_opaque) {
+ return pk_write_rsa_der(&c, buf, key);
} else
#endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_ECP_LIGHT)
- if (mbedtls_pk_get_type(key) == MBEDTLS_PK_ECKEY) {
- mbedtls_ecp_keypair *ec = mbedtls_pk_ec(*key);
- size_t pub_len = 0, par_len = 0;
-
+ if ((mbedtls_pk_get_type(key) == MBEDTLS_PK_ECKEY) || is_ec_opaque) {
#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES)
- if (mbedtls_pk_is_rfc8410_curve(ec->grp.id)) {
- return pk_write_ec_rfc8410_der(&c, buf, ec);
+ if (mbedtls_pk_is_rfc8410(key)) {
+ return pk_write_ec_rfc8410_der(&c, buf, key);
}
-#endif
-
- /*
- * RFC 5915, or SEC1 Appendix C.4
- *
- * ECPrivateKey ::= SEQUENCE {
- * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
- * privateKey OCTET STRING,
- * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
- * publicKey [1] BIT STRING OPTIONAL
- * }
- */
-
- /* publicKey */
- MBEDTLS_ASN1_CHK_ADD(pub_len, pk_write_ec_pubkey(&c, buf, ec));
-
- if (c - buf < 1) {
- return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
- }
- *--c = 0;
- pub_len += 1;
-
- MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_asn1_write_len(&c, buf, pub_len));
- MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_asn1_write_tag(&c, buf, MBEDTLS_ASN1_BIT_STRING));
-
- MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_asn1_write_len(&c, buf, pub_len));
- MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_asn1_write_tag(&c, buf,
- MBEDTLS_ASN1_CONTEXT_SPECIFIC |
- MBEDTLS_ASN1_CONSTRUCTED | 1));
- len += pub_len;
-
- /* parameters */
- MBEDTLS_ASN1_CHK_ADD(par_len, pk_write_ec_param(&c, buf, ec->grp.id));
-
- MBEDTLS_ASN1_CHK_ADD(par_len, mbedtls_asn1_write_len(&c, buf, par_len));
- MBEDTLS_ASN1_CHK_ADD(par_len, mbedtls_asn1_write_tag(&c, buf,
- MBEDTLS_ASN1_CONTEXT_SPECIFIC |
- MBEDTLS_ASN1_CONSTRUCTED | 0));
- len += par_len;
-
- /* privateKey */
- MBEDTLS_ASN1_CHK_ADD(len, pk_write_ec_private(&c, buf, ec));
-
- /* version */
- MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_int(&c, buf, 1));
-
- MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len));
- MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, buf, MBEDTLS_ASN1_CONSTRUCTED |
- MBEDTLS_ASN1_SEQUENCE));
+#endif /* MBEDTLS_PK_HAVE_RFC8410_CURVES */
+ return pk_write_ec_der(&c, buf, key);
} else
-#endif /* MBEDTLS_ECP_C */
+#endif /* MBEDTLS_ECP_LIGHT */
return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
return (int) len;
@@ -578,21 +781,50 @@
unsigned char output_buf[PRV_DER_MAX_BYTES];
const char *begin, *end;
size_t olen = 0;
+#if defined(MBEDTLS_ECP_LIGHT)
+ int is_ec_opaque = 0;
+#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES)
+ int is_montgomery_opaque = 0;
+#endif /* MBEDTLS_PK_HAVE_RFC8410_CURVES */
+#endif /* MBEDTLS_ECP_LIGHT */
+#if defined(MBEDTLS_RSA_C)
+ int is_rsa_opaque = 0;
+#endif
if ((ret = mbedtls_pk_write_key_der(key, output_buf, sizeof(output_buf))) < 0) {
return ret;
}
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if (mbedtls_pk_get_type(key) == MBEDTLS_PK_OPAQUE) {
+ psa_key_type_t opaque_key_type = pk_get_opaque_key_type(key);
+
#if defined(MBEDTLS_RSA_C)
- if (mbedtls_pk_get_type(key) == MBEDTLS_PK_RSA) {
+ is_rsa_opaque = PSA_KEY_TYPE_IS_RSA(opaque_key_type);
+#endif
+#if defined(MBEDTLS_ECP_LIGHT)
+ is_ec_opaque = PSA_KEY_TYPE_IS_ECC(opaque_key_type);
+#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES)
+ if (pk_get_opaque_ec_family(key) == PSA_ECC_FAMILY_MONTGOMERY) {
+ is_montgomery_opaque = 1;
+ }
+#endif /* MBEDTLS_PK_HAVE_RFC8410_CURVES */
+#endif /* MBEDTLS_ECP_LIGHT */
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+#if defined(MBEDTLS_RSA_C)
+ if ((mbedtls_pk_get_type(key) == MBEDTLS_PK_RSA) || is_rsa_opaque) {
begin = PEM_BEGIN_PRIVATE_KEY_RSA;
end = PEM_END_PRIVATE_KEY_RSA;
} else
#endif
#if defined(MBEDTLS_ECP_LIGHT)
- if (mbedtls_pk_get_type(key) == MBEDTLS_PK_ECKEY) {
+ if ((mbedtls_pk_get_type(key) == MBEDTLS_PK_ECKEY) || is_ec_opaque) {
#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES)
- if (mbedtls_pk_is_rfc8410_curve(mbedtls_pk_ec(*key)->grp.id)) {
+ if (is_montgomery_opaque ||
+ ((mbedtls_pk_get_type(key) == MBEDTLS_PK_ECKEY) &&
+ (mbedtls_pk_is_rfc8410(key)))) {
begin = PEM_BEGIN_PRIVATE_KEY_PKCS8;
end = PEM_END_PRIVATE_KEY_PKCS8;
} else
diff --git a/library/pkwrite.h b/library/pkwrite.h
index 537bd0f..8db2333 100644
--- a/library/pkwrite.h
+++ b/library/pkwrite.h
@@ -73,7 +73,7 @@
#endif /* MBEDTLS_RSA_C */
-#if defined(MBEDTLS_ECP_C)
+#if defined(MBEDTLS_ECP_LIGHT)
/*
* EC public keys:
* SubjectPublicKeyInfo ::= SEQUENCE { 1 + 2
@@ -98,34 +98,10 @@
*/
#define MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES (29 + 3 * MBEDTLS_ECP_MAX_BYTES)
-#else /* MBEDTLS_ECP_C */
+#else /* MBEDTLS_ECP_LIGHT */
#define MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES 0
#define MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES 0
-#endif /* MBEDTLS_ECP_C */
-
-#if defined(MBEDTLS_ECP_LIGHT)
-#include "mbedtls/ecp.h"
-
-#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
-#define MBEDTLS_PK_HAVE_RFC8410_CURVES
-
-static inline int mbedtls_pk_is_rfc8410_curve(mbedtls_ecp_group_id id)
-{
-#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
- if (id == MBEDTLS_ECP_DP_CURVE25519) {
- return 1;
- }
-#endif
-#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
- if (id == MBEDTLS_ECP_DP_CURVE448) {
- return 1;
- }
-#endif
- return 0;
-}
-#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED || MBEDTLS_ECP_DP_CURVE448_ENABLED */
#endif /* MBEDTLS_ECP_LIGHT */
-
#endif /* MBEDTLS_PK_WRITE_H */
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index f7e91d6..399e7f3 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -35,6 +35,7 @@
#include "psa_crypto_invasive.h"
#include "psa_crypto_driver_wrappers.h"
#include "psa_crypto_ecp.h"
+#include "psa_crypto_ffdh.h"
#include "psa_crypto_hash.h"
#include "psa_crypto_mac.h"
#include "psa_crypto_rsa.h"
@@ -81,7 +82,7 @@
#include "mbedtls/sha1.h"
#include "mbedtls/sha256.h"
#include "mbedtls/sha512.h"
-#include "hash_info.h"
+#include "md_psa.h"
#define ARRAY_LENGTH(array) (sizeof(array) / sizeof(*(array)))
@@ -128,6 +129,21 @@
(void) hash_alg;
return global_data.drivers_initialized;
}
+#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR) || \
+ defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY) || \
+ defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR)
+static int psa_is_dh_key_size_valid(size_t bits)
+{
+ if (bits != 2048 && bits != 3072 && bits != 4096 &&
+ bits != 6144 && bits != 8192) {
+ return 0;
+ }
+
+ return 1;
+}
+#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR ||
+ MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY ||
+ PSA_WANT_KEY_TYPE_DH_KEY_PAIR */
psa_status_t mbedtls_to_psa_error(int ret)
{
@@ -624,6 +640,20 @@
return PSA_SUCCESS;
} else if (PSA_KEY_TYPE_IS_ASYMMETRIC(type)) {
+#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR) || \
+ defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY)
+ if (PSA_KEY_TYPE_IS_DH(type)) {
+ if (psa_is_dh_key_size_valid(PSA_BYTES_TO_BITS(data_length)) == 0) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+ return mbedtls_psa_ffdh_import_key(attributes,
+ data, data_length,
+ key_buffer, key_buffer_size,
+ key_buffer_length,
+ bits);
+ }
+#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR) ||
+ * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY) */
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY)
if (PSA_KEY_TYPE_IS_ECC(type)) {
@@ -1326,7 +1356,8 @@
if (key_type_is_raw_bytes(type) ||
PSA_KEY_TYPE_IS_RSA(type) ||
- PSA_KEY_TYPE_IS_ECC(type)) {
+ PSA_KEY_TYPE_IS_ECC(type) ||
+ PSA_KEY_TYPE_IS_DH(type)) {
return psa_export_key_buffer_internal(
key_buffer, key_buffer_size,
data, data_size, data_length);
@@ -1392,47 +1423,59 @@
{
psa_key_type_t type = attributes->core.type;
- if (PSA_KEY_TYPE_IS_RSA(type) || PSA_KEY_TYPE_IS_ECC(type)) {
- if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type)) {
- /* Exporting public -> public */
- return psa_export_key_buffer_internal(
- key_buffer, key_buffer_size,
- data, data_size, data_length);
- }
-
- if (PSA_KEY_TYPE_IS_RSA(type)) {
+ if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type) &&
+ (PSA_KEY_TYPE_IS_RSA(type) || PSA_KEY_TYPE_IS_ECC(type) ||
+ PSA_KEY_TYPE_IS_DH(type))) {
+ /* Exporting public -> public */
+ return psa_export_key_buffer_internal(
+ key_buffer, key_buffer_size,
+ data, data_size, data_length);
+ } else if (PSA_KEY_TYPE_IS_RSA(type)) {
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
- defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
- return mbedtls_psa_rsa_export_public_key(attributes,
- key_buffer,
- key_buffer_size,
- data,
- data_size,
- data_length);
+ defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
+ return mbedtls_psa_rsa_export_public_key(attributes,
+ key_buffer,
+ key_buffer_size,
+ data,
+ data_size,
+ data_length);
#else
- /* We don't know how to convert a private RSA key to public. */
- return PSA_ERROR_NOT_SUPPORTED;
+ /* We don't know how to convert a private RSA key to public. */
+ return PSA_ERROR_NOT_SUPPORTED;
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) ||
* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
- } else {
+ } else if (PSA_KEY_TYPE_IS_ECC(type)) {
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
- defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY)
- return mbedtls_psa_ecp_export_public_key(attributes,
- key_buffer,
- key_buffer_size,
- data,
- data_size,
- data_length);
+ defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY)
+ return mbedtls_psa_ecp_export_public_key(attributes,
+ key_buffer,
+ key_buffer_size,
+ data,
+ data_size,
+ data_length);
#else
- /* We don't know how to convert a private ECC key to public */
- return PSA_ERROR_NOT_SUPPORTED;
+ /* We don't know how to convert a private ECC key to public */
+ return PSA_ERROR_NOT_SUPPORTED;
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) ||
* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */
- }
+ } else if (PSA_KEY_TYPE_IS_DH(type)) {
+#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR) || \
+ defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY)
+ return mbedtls_psa_export_ffdh_public_key(attributes,
+ key_buffer,
+ key_buffer_size,
+ data, data_size,
+ data_length);
+#else
+ return PSA_ERROR_NOT_SUPPORTED;
+#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR) ||
+ * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY) */
} else {
- /* This shouldn't happen in the reference implementation, but
- it is valid for a special-purpose implementation to omit
- support for exporting certain key types. */
+ (void) key_buffer;
+ (void) key_buffer_size;
+ (void) data;
+ (void) data_size;
+ (void) data_length;
return PSA_ERROR_NOT_SUPPORTED;
}
}
@@ -3567,7 +3610,7 @@
operation->ctx->grp.nbits);
psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg);
- operation->md_alg = mbedtls_hash_info_md_from_psa(hash_alg);
+ operation->md_alg = mbedtls_md_type_from_psa_alg(hash_alg);
operation->alg = alg;
/* We only need to store the same length of hash as the private key size
@@ -4989,7 +5032,8 @@
#if defined(BUILTIN_ALG_ANY_HKDF) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) || \
- defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS)
+ defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS) || \
+ defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC)
#define AT_LEAST_ONE_BUILTIN_KDF
#endif /* At least one builtin KDF */
@@ -5093,6 +5137,17 @@
sizeof(operation->ctx.tls12_ecjpake_to_pms.data));
} else
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS) */
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC)
+ if (PSA_ALG_IS_PBKDF2_HMAC(kdf_alg)) {
+ if (operation->ctx.pbkdf2.salt != NULL) {
+ mbedtls_platform_zeroize(operation->ctx.pbkdf2.salt,
+ operation->ctx.pbkdf2.salt_length);
+ mbedtls_free(operation->ctx.pbkdf2.salt);
+ }
+
+ status = PSA_SUCCESS;
+ } else
+#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC) */
{
status = PSA_ERROR_BAD_STATE;
}
@@ -5472,6 +5527,15 @@
&operation->ctx.tls12_ecjpake_to_pms, output, output_length);
} else
#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS */
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC)
+ if (PSA_ALG_IS_PBKDF2_HMAC(kdf_alg)) {
+ /* As output functionality is not added yet return
+ * PSA_ERROR_NOT_SUPPORTED for now if inputs are passed correctly.
+ * If input validation fails operation is aborted and output_bytes
+ * will return PSA_ERROR_BAD_STATE */
+ status = PSA_ERROR_NOT_SUPPORTED;
+ } else
+#endif /* MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC */
{
(void) kdf_alg;
@@ -5890,6 +5954,11 @@
return 1;
}
#endif
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC)
+ if (PSA_ALG_IS_PBKDF2_HMAC(kdf_alg)) {
+ return 1;
+ }
+#endif
return 0;
}
@@ -5958,6 +6027,11 @@
return PSA_SUCCESS;
}
#endif
+#if defined(PSA_WANT_ALG_FFDH)
+ if (alg == PSA_ALG_FFDH) {
+ return PSA_SUCCESS;
+ }
+#endif
(void) alg;
return PSA_ERROR_NOT_SUPPORTED;
}
@@ -6378,6 +6452,130 @@
return PSA_SUCCESS;
}
#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS */
+
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC)
+static psa_status_t psa_pbkdf2_set_input_cost(
+ psa_pbkdf2_key_derivation_t *pbkdf2,
+ psa_key_derivation_step_t step,
+ uint64_t data)
+{
+ if (step != PSA_KEY_DERIVATION_INPUT_COST) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ if (pbkdf2->state != PSA_PBKDF2_STATE_INIT) {
+ return PSA_ERROR_BAD_STATE;
+ }
+
+ if (data > PSA_VENDOR_PBKDF2_MAX_ITERATIONS) {
+ return PSA_ERROR_NOT_SUPPORTED;
+ }
+
+ if (data == 0) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ pbkdf2->input_cost = data;
+ pbkdf2->state = PSA_PBKDF2_STATE_INPUT_COST_SET;
+
+ return PSA_SUCCESS;
+}
+
+static psa_status_t psa_pbkdf2_set_salt(psa_pbkdf2_key_derivation_t *pbkdf2,
+ const uint8_t *data,
+ size_t data_length)
+{
+ if (pbkdf2->state != PSA_PBKDF2_STATE_INPUT_COST_SET &&
+ pbkdf2->state != PSA_PBKDF2_STATE_SALT_SET) {
+ return PSA_ERROR_BAD_STATE;
+ }
+
+ if (pbkdf2->state == PSA_PBKDF2_STATE_INPUT_COST_SET) {
+ pbkdf2->salt = mbedtls_calloc(1, data_length);
+ if (pbkdf2->salt == NULL) {
+ return PSA_ERROR_INSUFFICIENT_MEMORY;
+ }
+
+ memcpy(pbkdf2->salt, data, data_length);
+ pbkdf2->salt_length = data_length;
+ } else if (pbkdf2->state == PSA_PBKDF2_STATE_SALT_SET) {
+ uint8_t *next_salt;
+
+ next_salt = mbedtls_calloc(1, data_length + pbkdf2->salt_length);
+ if (next_salt == NULL) {
+ return PSA_ERROR_INSUFFICIENT_MEMORY;
+ }
+
+ memcpy(next_salt, pbkdf2->salt, pbkdf2->salt_length);
+ memcpy(next_salt + pbkdf2->salt_length, data, data_length);
+ pbkdf2->salt_length += data_length;
+ mbedtls_free(pbkdf2->salt);
+ pbkdf2->salt = next_salt;
+ }
+
+ pbkdf2->state = PSA_PBKDF2_STATE_SALT_SET;
+
+ return PSA_SUCCESS;
+}
+
+static psa_status_t psa_pbkdf2_hmac_set_password(psa_algorithm_t hash_alg,
+ const uint8_t *input,
+ size_t input_len,
+ uint8_t *output,
+ size_t *output_len)
+{
+ psa_status_t status = PSA_SUCCESS;
+ if (input_len > PSA_HASH_BLOCK_LENGTH(hash_alg)) {
+ status = psa_hash_compute(hash_alg, input, input_len, output,
+ PSA_HMAC_MAX_HASH_BLOCK_SIZE, output_len);
+ } else {
+ memcpy(output, input, input_len);
+ *output_len = PSA_HASH_BLOCK_LENGTH(hash_alg);
+ }
+ return status;
+}
+
+static psa_status_t psa_pbkdf2_set_password(psa_pbkdf2_key_derivation_t *pbkdf2,
+ psa_algorithm_t kdf_alg,
+ const uint8_t *data,
+ size_t data_length)
+{
+ psa_status_t status = PSA_SUCCESS;
+ if (pbkdf2->state != PSA_PBKDF2_STATE_SALT_SET) {
+ return PSA_ERROR_BAD_STATE;
+ }
+
+ if (data_length != 0) {
+ if (PSA_ALG_IS_PBKDF2_HMAC(kdf_alg)) {
+ psa_algorithm_t hash_alg = PSA_ALG_PBKDF2_HMAC_GET_HASH(kdf_alg);
+ status = psa_pbkdf2_hmac_set_password(hash_alg, data, data_length,
+ pbkdf2->password,
+ &pbkdf2->password_length);
+ }
+ }
+
+ pbkdf2->state = PSA_PBKDF2_STATE_PASSWORD_SET;
+
+ return status;
+}
+
+static psa_status_t psa_pbkdf2_input(psa_pbkdf2_key_derivation_t *pbkdf2,
+ psa_algorithm_t kdf_alg,
+ psa_key_derivation_step_t step,
+ const uint8_t *data,
+ size_t data_length)
+{
+ switch (step) {
+ case PSA_KEY_DERIVATION_INPUT_SALT:
+ return psa_pbkdf2_set_salt(pbkdf2, data, data_length);
+ case PSA_KEY_DERIVATION_INPUT_PASSWORD:
+ return psa_pbkdf2_set_password(pbkdf2, kdf_alg, data, data_length);
+ default:
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+}
+#endif /* MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC */
+
/** Check whether the given key type is acceptable for the given
* input step of a key derivation.
*
@@ -6419,6 +6617,17 @@
return PSA_SUCCESS;
}
break;
+ case PSA_KEY_DERIVATION_INPUT_PASSWORD:
+ if (key_type == PSA_KEY_TYPE_PASSWORD) {
+ return PSA_SUCCESS;
+ }
+ if (key_type == PSA_KEY_TYPE_DERIVE) {
+ return PSA_SUCCESS;
+ }
+ if (key_type == PSA_KEY_TYPE_NONE) {
+ return PSA_SUCCESS;
+ }
+ break;
}
return PSA_ERROR_INVALID_ARGUMENT;
}
@@ -6462,6 +6671,12 @@
&operation->ctx.tls12_ecjpake_to_pms, step, data, data_length);
} else
#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS */
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC)
+ if (PSA_ALG_IS_PBKDF2_HMAC(kdf_alg)) {
+ status = psa_pbkdf2_input(&operation->ctx.pbkdf2, kdf_alg,
+ step, data, data_length);
+ } else
+#endif /* MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC */
{
/* This can't happen unless the operation object was not initialized */
(void) data;
@@ -6485,6 +6700,12 @@
psa_status_t status;
psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg(operation);
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC)
+ if (PSA_ALG_IS_PBKDF2_HMAC(kdf_alg)) {
+ status = psa_pbkdf2_set_input_cost(
+ &operation->ctx.pbkdf2, step, value);
+ } else
+#endif /* MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC */
{
(void) step;
(void) value;
@@ -6533,9 +6754,10 @@
return status;
}
- /* Passing a key object as a SECRET input unlocks the permission
- * to output to a key object. */
- if (step == PSA_KEY_DERIVATION_INPUT_SECRET) {
+ /* Passing a key object as a SECRET or PASSWORD input unlocks the
+ * permission to output to a key object. */
+ if (step == PSA_KEY_DERIVATION_INPUT_SECRET ||
+ step == PSA_KEY_DERIVATION_INPUT_PASSWORD) {
operation->can_output_key = 1;
}
@@ -6575,6 +6797,19 @@
shared_secret_size,
shared_secret_length);
#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECDH */
+
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_FFDH)
+ case PSA_ALG_FFDH:
+ return mbedtls_psa_key_agreement_ffdh(attributes,
+ peer_key,
+ peer_key_length,
+ key_buffer,
+ key_buffer_size,
+ shared_secret,
+ shared_secret_size,
+ shared_secret_length);
+#endif /* MBEDTLS_PSA_BUILTIN_ALG_FFDH */
+
default:
(void) attributes;
(void) key_buffer;
@@ -6956,6 +7191,14 @@
return PSA_SUCCESS;
} else
#endif /* defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR) */
+
+#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR)
+ if (PSA_KEY_TYPE_IS_DH(type) && PSA_KEY_TYPE_IS_KEY_PAIR(type)) {
+ if (psa_is_dh_key_size_valid(bits) == 0) {
+ return PSA_ERROR_NOT_SUPPORTED;
+ }
+ } else
+#endif /* defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR) */
{
return PSA_ERROR_NOT_SUPPORTED;
}
@@ -7007,6 +7250,15 @@
key_buffer_length);
} else
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) */
+
+#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR)
+ if (PSA_KEY_TYPE_IS_DH(type) && PSA_KEY_TYPE_IS_KEY_PAIR(type)) {
+ return mbedtls_psa_ffdh_generate_key(attributes,
+ key_buffer,
+ key_buffer_size,
+ key_buffer_length);
+ } else
+#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR) */
{
(void) key_buffer_length;
return PSA_ERROR_NOT_SUPPORTED;
@@ -7308,6 +7560,7 @@
return PSA_SUCCESS;
}
+#if defined(PSA_WANT_ALG_SOME_PAKE)
psa_status_t psa_pake_setup(
psa_pake_operation_t *operation,
const psa_pake_cipher_suite_t *cipher_suite)
@@ -8024,5 +8277,6 @@
return status;
}
+#endif /* PSA_WANT_ALG_SOME_PAKE */
#endif /* MBEDTLS_PSA_CRYPTO_C */
diff --git a/library/psa_crypto_ecp.c b/library/psa_crypto_ecp.c
index f70d804..4880208 100644
--- a/library/psa_crypto_ecp.c
+++ b/library/psa_crypto_ecp.c
@@ -26,7 +26,7 @@
#include "psa_crypto_core.h"
#include "psa_crypto_ecp.h"
#include "psa_crypto_random_impl.h"
-#include "hash_info.h"
+#include "md_psa.h"
#include <stdlib.h>
#include <string.h>
@@ -366,7 +366,7 @@
if (PSA_ALG_ECDSA_IS_DETERMINISTIC(alg)) {
#if defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg);
- mbedtls_md_type_t md_alg = mbedtls_hash_info_md_from_psa(hash_alg);
+ mbedtls_md_type_t md_alg = mbedtls_md_type_from_psa_alg(hash_alg);
MBEDTLS_MPI_CHK(mbedtls_ecdsa_sign_det_ext(
&ecp->grp, &r, &s,
&ecp->d, hash,
diff --git a/library/psa_crypto_ffdh.c b/library/psa_crypto_ffdh.c
new file mode 100644
index 0000000..4550a72
--- /dev/null
+++ b/library/psa_crypto_ffdh.c
@@ -0,0 +1,299 @@
+/*
+ * PSA FFDH layer on top of Mbed TLS crypto
+ */
+/*
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "common.h"
+
+#if defined(MBEDTLS_PSA_CRYPTO_C)
+
+#include <psa/crypto.h>
+#include "psa_crypto_core.h"
+#include "psa_crypto_ffdh.h"
+#include "psa_crypto_random_impl.h"
+#include "mbedtls/platform.h"
+
+#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR) || \
+ defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY) || \
+ defined(MBEDTLS_PSA_BUILTIN_ALG_FFDH)
+static psa_status_t mbedtls_psa_ffdh_set_prime_generator(size_t key_size,
+ mbedtls_mpi *P,
+ mbedtls_mpi *G)
+{
+ const unsigned char *dhm_P = NULL;
+ const unsigned char *dhm_G = NULL;
+ size_t dhm_size_P = 0;
+ size_t dhm_size_G = 0;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ if (P == NULL && G == NULL) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ static const unsigned char dhm_P_2048[] =
+ MBEDTLS_DHM_RFC7919_FFDHE2048_P_BIN;
+ static const unsigned char dhm_P_3072[] =
+ MBEDTLS_DHM_RFC7919_FFDHE3072_P_BIN;
+ static const unsigned char dhm_P_4096[] =
+ MBEDTLS_DHM_RFC7919_FFDHE4096_P_BIN;
+ static const unsigned char dhm_P_6144[] =
+ MBEDTLS_DHM_RFC7919_FFDHE6144_P_BIN;
+ static const unsigned char dhm_P_8192[] =
+ MBEDTLS_DHM_RFC7919_FFDHE8192_P_BIN;
+ static const unsigned char dhm_G_2048[] =
+ MBEDTLS_DHM_RFC7919_FFDHE2048_G_BIN;
+ static const unsigned char dhm_G_3072[] =
+ MBEDTLS_DHM_RFC7919_FFDHE3072_G_BIN;
+ static const unsigned char dhm_G_4096[] =
+ MBEDTLS_DHM_RFC7919_FFDHE4096_G_BIN;
+ static const unsigned char dhm_G_6144[] =
+ MBEDTLS_DHM_RFC7919_FFDHE6144_G_BIN;
+ static const unsigned char dhm_G_8192[] =
+ MBEDTLS_DHM_RFC7919_FFDHE8192_G_BIN;
+
+ switch (key_size) {
+ case sizeof(dhm_P_2048):
+ dhm_P = dhm_P_2048;
+ dhm_G = dhm_G_2048;
+ dhm_size_P = sizeof(dhm_P_2048);
+ dhm_size_G = sizeof(dhm_G_2048);
+ break;
+ case sizeof(dhm_P_3072):
+ dhm_P = dhm_P_3072;
+ dhm_G = dhm_G_3072;
+ dhm_size_P = sizeof(dhm_P_3072);
+ dhm_size_G = sizeof(dhm_G_3072);
+ break;
+ case sizeof(dhm_P_4096):
+ dhm_P = dhm_P_4096;
+ dhm_G = dhm_G_4096;
+ dhm_size_P = sizeof(dhm_P_4096);
+ dhm_size_G = sizeof(dhm_G_4096);
+ break;
+ case sizeof(dhm_P_6144):
+ dhm_P = dhm_P_6144;
+ dhm_G = dhm_G_6144;
+ dhm_size_P = sizeof(dhm_P_6144);
+ dhm_size_G = sizeof(dhm_G_6144);
+ break;
+ case sizeof(dhm_P_8192):
+ dhm_P = dhm_P_8192;
+ dhm_G = dhm_G_8192;
+ dhm_size_P = sizeof(dhm_P_8192);
+ dhm_size_G = sizeof(dhm_G_8192);
+ break;
+ default:
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ if (P != NULL) {
+ MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(P, dhm_P,
+ dhm_size_P));
+ }
+ if (G != NULL) {
+ MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(G, dhm_G,
+ dhm_size_G));
+ }
+
+cleanup:
+ if (ret != 0) {
+ return mbedtls_to_psa_error(ret);
+ }
+
+ return PSA_SUCCESS;
+}
+#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR ||
+ MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY ||
+ MBEDTLS_PSA_BUILTIN_ALG_FFDH */
+
+#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR) || \
+ defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY)
+psa_status_t mbedtls_psa_export_ffdh_public_key(
+ const psa_key_attributes_t *attributes,
+ const uint8_t *key_buffer,
+ size_t key_buffer_size,
+ uint8_t *data,
+ size_t data_size,
+ size_t *data_length)
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+ mbedtls_mpi GX, G, X, P;
+ psa_key_type_t type = attributes->core.type;
+
+ if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type)) {
+ if (key_buffer_size > data_size) {
+ return PSA_ERROR_BUFFER_TOO_SMALL;
+ }
+ memcpy(data, key_buffer, key_buffer_size);
+ memset(data + key_buffer_size, 0,
+ data_size - key_buffer_size);
+ *data_length = key_buffer_size;
+ return PSA_SUCCESS;
+ }
+
+ mbedtls_mpi_init(&GX); mbedtls_mpi_init(&G);
+ mbedtls_mpi_init(&X); mbedtls_mpi_init(&P);
+
+ status = mbedtls_psa_ffdh_set_prime_generator(data_size, &P, &G);
+
+ if (status != PSA_SUCCESS) {
+ goto cleanup;
+ }
+
+ MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&X, key_buffer,
+ key_buffer_size));
+
+ MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&GX, &G, &X, &P, NULL));
+ MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&GX, data, data_size));
+
+ *data_length = data_size;
+
+ ret = 0;
+cleanup:
+ mbedtls_mpi_free(&P); mbedtls_mpi_free(&G);
+ mbedtls_mpi_free(&X); mbedtls_mpi_free(&GX);
+
+ if (status == PSA_SUCCESS && ret != 0) {
+ status = mbedtls_to_psa_error(ret);
+ }
+
+ return status;
+}
+
+psa_status_t mbedtls_psa_ffdh_generate_key(
+ const psa_key_attributes_t *attributes,
+ uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length)
+{
+ mbedtls_mpi X, P;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+ mbedtls_mpi_init(&P); mbedtls_mpi_init(&X);
+ (void) attributes;
+
+ status = mbedtls_psa_ffdh_set_prime_generator(key_buffer_size, &P, NULL);
+
+ if (status != PSA_SUCCESS) {
+ goto cleanup;
+ }
+
+ /* RFC7919: Traditional finite field Diffie-Hellman has each peer choose their
+ secret exponent from the range [2, P-2].
+ Select random value in range [3, P-1] and decrease it by 1. */
+ MBEDTLS_MPI_CHK(mbedtls_mpi_random(&X, 3, &P, mbedtls_psa_get_random,
+ MBEDTLS_PSA_RANDOM_STATE));
+ MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&X, &X, 1));
+ MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&X, key_buffer, key_buffer_size));
+ *key_buffer_length = key_buffer_size;
+
+cleanup:
+ mbedtls_mpi_free(&P); mbedtls_mpi_free(&X);
+ if (status == PSA_SUCCESS && ret != 0) {
+ return mbedtls_to_psa_error(ret);
+ }
+
+ return status;
+}
+
+psa_status_t mbedtls_psa_ffdh_import_key(
+ const psa_key_attributes_t *attributes,
+ const uint8_t *data, size_t data_length,
+ uint8_t *key_buffer, size_t key_buffer_size,
+ size_t *key_buffer_length, size_t *bits)
+{
+ (void) attributes;
+
+ if (key_buffer_size < data_length) {
+ return PSA_ERROR_BUFFER_TOO_SMALL;
+ }
+ memcpy(key_buffer, data, data_length);
+ *key_buffer_length = data_length;
+ *bits = PSA_BYTES_TO_BITS(data_length);
+
+ return PSA_SUCCESS;
+}
+
+#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR ||
+ MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY */
+
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_FFDH)
+psa_status_t mbedtls_psa_key_agreement_ffdh(
+ const psa_key_attributes_t *attributes,
+ const uint8_t *peer_key,
+ size_t peer_key_length,
+ const uint8_t *key_buffer,
+ size_t key_buffer_size,
+ uint8_t *shared_secret,
+ size_t shared_secret_size,
+ size_t *shared_secret_length)
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+ mbedtls_mpi P, G, X, GY, K;
+ const size_t calculated_shared_secret_size = peer_key_length;
+
+ if (peer_key_length != key_buffer_size ||
+ calculated_shared_secret_size > shared_secret_size) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ if (!PSA_KEY_TYPE_IS_DH_KEY_PAIR(psa_get_key_type(attributes))) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ mbedtls_mpi_init(&P); mbedtls_mpi_init(&G);
+ mbedtls_mpi_init(&X); mbedtls_mpi_init(&GY);
+ mbedtls_mpi_init(&K);
+
+ status = mbedtls_psa_ffdh_set_prime_generator(
+ PSA_BITS_TO_BYTES(attributes->core.bits), &P, &G);
+
+ if (status != PSA_SUCCESS) {
+ goto cleanup;
+ }
+
+ MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&X, key_buffer,
+ key_buffer_size));
+
+ MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&GY, peer_key,
+ peer_key_length));
+
+ /* Calculate shared secret public key: K = G^(XY) mod P = GY^X mod P */
+ MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&K, &GY, &X, &P, NULL));
+
+ MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&K, shared_secret,
+ calculated_shared_secret_size));
+
+ *shared_secret_length = calculated_shared_secret_size;
+
+ ret = 0;
+
+cleanup:
+ mbedtls_mpi_free(&P); mbedtls_mpi_free(&G);
+ mbedtls_mpi_free(&X); mbedtls_mpi_free(&GY);
+ mbedtls_mpi_free(&K);
+
+ if (status == PSA_SUCCESS && ret != 0) {
+ status = mbedtls_to_psa_error(ret);
+ }
+
+ return status;
+}
+#endif /* MBEDTLS_PSA_BUILTIN_ALG_FFDH */
+
+#endif /* MBEDTLS_PSA_CRYPTO_C */
diff --git a/library/psa_crypto_ffdh.h b/library/psa_crypto_ffdh.h
new file mode 100644
index 0000000..5d7d951
--- /dev/null
+++ b/library/psa_crypto_ffdh.h
@@ -0,0 +1,144 @@
+/*
+ * PSA FFDH layer on top of Mbed TLS crypto
+ */
+/*
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef PSA_CRYPTO_FFDH_H
+#define PSA_CRYPTO_FFDH_H
+
+#include <psa/crypto.h>
+#include <mbedtls/dhm.h>
+
+/** Perform a key agreement and return the FFDH shared secret.
+ *
+ * \param[in] attributes The attributes of the key to use for the
+ * operation.
+ * \param[in] peer_key The buffer containing the key context
+ * of the peer's public key.
+ * \param[in] peer_key_length Size of the \p peer_key buffer in
+ * bytes.
+ * \param[in] key_buffer The buffer containing the private key
+ * context.
+ * \param[in] key_buffer_size Size of the \p key_buffer buffer in
+ * bytes.
+ * \param[out] shared_secret The buffer to which the shared secret
+ * is to be written.
+ * \param[in] shared_secret_size Size of the \p shared_secret buffer in
+ * bytes.
+ * \param[out] shared_secret_length On success, the number of bytes that make
+ * up the returned shared secret.
+ * \retval #PSA_SUCCESS
+ * Success. Shared secret successfully calculated.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \p key_buffer_size, \p peer_key_length, \p shared_secret_size
+ * do not match
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ */
+psa_status_t mbedtls_psa_key_agreement_ffdh(
+ const psa_key_attributes_t *attributes,
+ const uint8_t *peer_key,
+ size_t peer_key_length,
+ const uint8_t *key_buffer,
+ size_t key_buffer_size,
+ uint8_t *shared_secret,
+ size_t shared_secret_size,
+ size_t *shared_secret_length);
+
+/** Export a public key or the public part of a DH key pair in binary format.
+ *
+ * \param[in] attributes The attributes for the key to export.
+ * \param[in] key_buffer Material or context of the key to export.
+ * \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes.
+ * \param[out] data Buffer where the key data is to be written.
+ * \param[in] data_size Size of the \p data buffer in bytes.
+ * \param[out] data_length On success, the number of bytes written in
+ * \p data
+ *
+ * \retval #PSA_SUCCESS The public key was exported successfully.
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * The size of \p key_buffer is too small.
+ * \retval #PSA_ERROR_NOT_PERMITTED
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ */
+psa_status_t mbedtls_psa_export_ffdh_public_key(
+ const psa_key_attributes_t *attributes,
+ const uint8_t *key_buffer,
+ size_t key_buffer_size,
+ uint8_t *data,
+ size_t data_size,
+ size_t *data_length);
+
+/**
+ * \brief Generate DH key.
+ *
+ * \note The signature of the function is that of a PSA driver generate_key
+ * entry point.
+ *
+ * \param[in] attributes The attributes for the key to generate.
+ * \param[out] key_buffer Buffer where the key data is to be written.
+ * \param[in] key_buffer_size Size of \p key_buffer in bytes.
+ * \param[out] key_buffer_length On success, the number of bytes written in
+ * \p key_buffer.
+ *
+ * \retval #PSA_SUCCESS
+ * The key was generated successfully.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * Key size in bits is invalid.
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * The size of \p key_buffer is too small.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ */
+psa_status_t mbedtls_psa_ffdh_generate_key(
+ const psa_key_attributes_t *attributes,
+ uint8_t *key_buffer,
+ size_t key_buffer_size,
+ size_t *key_buffer_length);
+
+/**
+ * \brief Import DH key.
+ *
+ * \note The signature of the function is that of a PSA driver import_key
+ * entry point.
+ *
+ * \param[in] attributes The attributes for the key to import.
+ * \param[in] data The buffer containing the key data in import
+ * format.
+ * \param[in] data_length Size of the \p data buffer in bytes.
+ * \param[out] key_buffer The buffer containing the key data in output
+ * format.
+ * \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes. This
+ * size is greater or equal to \p data_length.
+ * \param[out] key_buffer_length The length of the data written in \p
+ * key_buffer in bytes.
+ * \param[out] bits The key size in number of bits.
+ *
+ * \retval #PSA_SUCCESS
+ * The key was generated successfully.
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * The size of \p key_buffer is too small.
+ */
+psa_status_t mbedtls_psa_ffdh_import_key(
+ const psa_key_attributes_t *attributes,
+ const uint8_t *data, size_t data_length,
+ uint8_t *key_buffer, size_t key_buffer_size,
+ size_t *key_buffer_length, size_t *bits);
+
+#endif /* PSA_CRYPTO_FFDH_H */
diff --git a/library/psa_crypto_rsa.c b/library/psa_crypto_rsa.c
index 3ff589d..ab93146 100644
--- a/library/psa_crypto_rsa.c
+++ b/library/psa_crypto_rsa.c
@@ -28,6 +28,7 @@
#include "psa_crypto_random_impl.h"
#include "psa_crypto_rsa.h"
#include "psa_crypto_hash.h"
+#include "md_psa.h"
#include <stdlib.h>
#include <string.h>
@@ -37,7 +38,6 @@
#include <mbedtls/error.h>
#include <mbedtls/pk.h>
#include "pk_wrap.h"
-#include "hash_info.h"
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) || \
@@ -318,7 +318,7 @@
mbedtls_md_type_t *md_alg)
{
psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg);
- *md_alg = mbedtls_hash_info_md_from_psa(hash_alg);
+ *md_alg = mbedtls_md_type_from_psa_alg(hash_alg);
/* The Mbed TLS RSA module uses an unsigned int for hash length
* parameters. Validate that it fits so that we don't risk an
@@ -332,7 +332,7 @@
if (*md_alg == MBEDTLS_MD_NONE) {
return PSA_ERROR_NOT_SUPPORTED;
}
- if (mbedtls_hash_info_get_size(*md_alg) != hash_length) {
+ if (mbedtls_md_get_size_from_type(*md_alg) != hash_length) {
return PSA_ERROR_INVALID_ARGUMENT;
}
}
@@ -527,7 +527,7 @@
mbedtls_rsa_context *rsa)
{
psa_algorithm_t hash_alg = PSA_ALG_RSA_OAEP_GET_HASH(alg);
- mbedtls_md_type_t md_alg = mbedtls_hash_info_md_from_psa(hash_alg);
+ mbedtls_md_type_t md_alg = mbedtls_md_type_from_psa_alg(hash_alg);
return mbedtls_rsa_set_padding(rsa, MBEDTLS_RSA_PKCS_V21, md_alg);
}
diff --git a/library/psa_util.c b/library/psa_util.c
index 43a10a3..c354f34 100644
--- a/library/psa_util.c
+++ b/library/psa_util.c
@@ -33,7 +33,7 @@
/* PSA_SUCCESS is kept at the top of each error table since
* it's the most common status when everything functions properly. */
-#if !defined(MBEDTLS_MD_C) || !defined(MBEDTLS_MD5_C) || defined(MBEDTLS_USE_PSA_CRYPTO)
+#if defined(MBEDTLS_MD_LIGHT)
const mbedtls_error_pair_t psa_to_md_errors[] =
{
{ PSA_SUCCESS, 0 },
diff --git a/library/rsa.c b/library/rsa.c
index 87b3311..8126ae9 100644
--- a/library/rsa.c
+++ b/library/rsa.c
@@ -46,7 +46,7 @@
#include "mbedtls/error.h"
#include "constant_time_internal.h"
#include "mbedtls/constant_time.h"
-#include "hash_info.h"
+#include "md_psa.h"
#include <string.h>
@@ -478,7 +478,7 @@
if ((padding == MBEDTLS_RSA_PKCS_V21) &&
(hash_id != MBEDTLS_MD_NONE)) {
/* Just make sure this hash is supported in this build. */
- if (mbedtls_hash_info_psa_from_md(hash_id) == PSA_ALG_NONE) {
+ if (mbedtls_md_info_from_type(hash_id) == NULL) {
return MBEDTLS_ERR_RSA_INVALID_PADDING;
}
}
@@ -1076,7 +1076,7 @@
unsigned char *p;
unsigned int hlen;
size_t i, use_len;
- unsigned char mask[MBEDTLS_HASH_MAX_SIZE];
+ unsigned char mask[MBEDTLS_MD_MAX_SIZE];
int ret = 0;
const mbedtls_md_info_t *md_info;
mbedtls_md_context_t md_ctx;
@@ -1229,7 +1229,7 @@
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
}
- hlen = mbedtls_hash_info_get_size((mbedtls_md_type_t) ctx->hash_id);
+ hlen = mbedtls_md_get_size_from_type((mbedtls_md_type_t) ctx->hash_id);
if (hlen == 0) {
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
}
@@ -1380,7 +1380,7 @@
size_t ilen, i, pad_len;
unsigned char *p, bad, pad_done;
unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
- unsigned char lhash[MBEDTLS_HASH_MAX_SIZE];
+ unsigned char lhash[MBEDTLS_MD_MAX_SIZE];
unsigned int hlen;
/*
@@ -1396,7 +1396,7 @@
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
}
- hlen = mbedtls_hash_info_get_size((mbedtls_md_type_t) ctx->hash_id);
+ hlen = mbedtls_md_get_size_from_type((mbedtls_md_type_t) ctx->hash_id);
if (hlen == 0) {
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
}
@@ -1596,7 +1596,7 @@
if (md_alg != MBEDTLS_MD_NONE) {
/* Gather length of hash to sign */
- size_t exp_hashlen = mbedtls_hash_info_get_size(md_alg);
+ size_t exp_hashlen = mbedtls_md_get_size_from_type(md_alg);
if (exp_hashlen == 0) {
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
}
@@ -1606,7 +1606,7 @@
}
}
- hlen = mbedtls_hash_info_get_size((mbedtls_md_type_t) ctx->hash_id);
+ hlen = mbedtls_md_get_size_from_type((mbedtls_md_type_t) ctx->hash_id);
if (hlen == 0) {
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
}
@@ -1744,7 +1744,7 @@
/* Are we signing hashed or raw data? */
if (md_alg != MBEDTLS_MD_NONE) {
- unsigned char md_size = mbedtls_hash_info_get_size(md_alg);
+ unsigned char md_size = mbedtls_md_get_size_from_type(md_alg);
if (md_size == 0) {
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
}
@@ -1966,7 +1966,7 @@
size_t siglen;
unsigned char *p;
unsigned char *hash_start;
- unsigned char result[MBEDTLS_HASH_MAX_SIZE];
+ unsigned char result[MBEDTLS_MD_MAX_SIZE];
unsigned int hlen;
size_t observed_salt_len, msb;
unsigned char buf[MBEDTLS_MPI_MAX_SIZE] = { 0 };
@@ -1995,7 +1995,7 @@
if (md_alg != MBEDTLS_MD_NONE) {
/* Gather length of hash to sign */
- size_t exp_hashlen = mbedtls_hash_info_get_size(md_alg);
+ size_t exp_hashlen = mbedtls_md_get_size_from_type(md_alg);
if (exp_hashlen == 0) {
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
}
@@ -2005,7 +2005,7 @@
}
}
- hlen = mbedtls_hash_info_get_size(mgf1_hash_id);
+ hlen = mbedtls_md_get_size_from_type(mgf1_hash_id);
if (hlen == 0) {
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
}
diff --git a/library/ssl_ciphersuites.c b/library/ssl_ciphersuites.c
index 9cef3fe..793ec6a 100644
--- a/library/ssl_ciphersuites.c
+++ b/library/ssl_ciphersuites.c
@@ -28,6 +28,9 @@
#include "mbedtls/ssl_ciphersuites.h"
#include "mbedtls/ssl.h"
#include "ssl_misc.h"
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "md_psa.h"
+#endif
#include <string.h>
@@ -1966,10 +1969,10 @@
case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
return PSA_ALG_RSA_PKCS1V15_SIGN(
- mbedtls_hash_info_psa_from_md(info->mac));
+ mbedtls_md_psa_alg_from_type(info->mac));
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
- return PSA_ALG_ECDSA(mbedtls_hash_info_psa_from_md(info->mac));
+ return PSA_ALG_ECDSA(mbedtls_md_psa_alg_from_type(info->mac));
case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
diff --git a/library/ssl_cookie.c b/library/ssl_cookie.c
index ba25389..ae7a420 100644
--- a/library/ssl_cookie.c
+++ b/library/ssl_cookie.c
@@ -36,6 +36,7 @@
#include <string.h>
#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "md_psa.h"
#define PSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \
psa_to_ssl_errors, \
psa_generic_status_to_mbedtls)
@@ -114,7 +115,7 @@
(void) f_rng;
(void) p_rng;
- alg = mbedtls_hash_info_psa_from_md(COOKIE_MD);
+ alg = mbedtls_md_psa_alg_from_type(COOKIE_MD);
if (alg == 0) {
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
}
@@ -364,10 +365,7 @@
cur_time = ctx->serial;
#endif
- cookie_time = ((unsigned long) cookie[0] << 24) |
- ((unsigned long) cookie[1] << 16) |
- ((unsigned long) cookie[2] << 8) |
- ((unsigned long) cookie[3]);
+ cookie_time = (unsigned long) MBEDTLS_GET_UINT32_BE(cookie, 0);
if (ctx->timeout != 0 && cur_time - cookie_time > ctx->timeout) {
ret = -1;
diff --git a/library/ssl_misc.h b/library/ssl_misc.h
index d7c47e6..2d6d7ba 100644
--- a/library/ssl_misc.h
+++ b/library/ssl_misc.h
@@ -30,7 +30,6 @@
#if defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3)
#include "psa/crypto.h"
#include "mbedtls/psa_util.h"
-#include "hash_info.h"
#endif
#if defined(MBEDTLS_MD_CAN_MD5)
@@ -55,6 +54,7 @@
#endif
#include "mbedtls/pk.h"
+#include "pk_internal.h"
#include "common.h"
/* Shorthand for restartable ECC */
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 331bb79..f0067f4 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -41,6 +41,7 @@
#include <string.h>
#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "md_psa.h"
#include "mbedtls/psa_util.h"
#include "psa/crypto.h"
#endif
@@ -843,11 +844,11 @@
#if defined(MBEDTLS_USE_PSA_CRYPTO)
status = psa_hash_abort(&ssl->handshake->fin_sha256_psa);
if (status != PSA_SUCCESS) {
- return PSA_TO_MD_ERR(status);
+ return mbedtls_md_error_from_psa(status);
}
status = psa_hash_setup(&ssl->handshake->fin_sha256_psa, PSA_ALG_SHA_256);
if (status != PSA_SUCCESS) {
- return PSA_TO_MD_ERR(status);
+ return mbedtls_md_error_from_psa(status);
}
#else
mbedtls_md_free(&ssl->handshake->fin_sha256);
@@ -868,11 +869,11 @@
#if defined(MBEDTLS_USE_PSA_CRYPTO)
status = psa_hash_abort(&ssl->handshake->fin_sha384_psa);
if (status != PSA_SUCCESS) {
- return PSA_TO_MD_ERR(status);
+ return mbedtls_md_error_from_psa(status);
}
status = psa_hash_setup(&ssl->handshake->fin_sha384_psa, PSA_ALG_SHA_384);
if (status != PSA_SUCCESS) {
- return PSA_TO_MD_ERR(status);
+ return mbedtls_md_error_from_psa(status);
}
#else
mbedtls_md_free(&ssl->handshake->fin_sha384);
@@ -910,7 +911,7 @@
#if defined(MBEDTLS_USE_PSA_CRYPTO)
status = psa_hash_update(&ssl->handshake->fin_sha256_psa, buf, len);
if (status != PSA_SUCCESS) {
- return PSA_TO_MD_ERR(status);
+ return mbedtls_md_error_from_psa(status);
}
#else
ret = mbedtls_md_update(&ssl->handshake->fin_sha256, buf, len);
@@ -923,7 +924,7 @@
#if defined(MBEDTLS_USE_PSA_CRYPTO)
status = psa_hash_update(&ssl->handshake->fin_sha384_psa, buf, len);
if (status != PSA_SUCCESS) {
- return PSA_TO_MD_ERR(status);
+ return mbedtls_md_error_from_psa(status);
}
#else
ret = mbedtls_md_update(&ssl->handshake->fin_sha384, buf, len);
@@ -940,8 +941,8 @@
const unsigned char *buf, size_t len)
{
#if defined(MBEDTLS_USE_PSA_CRYPTO)
- return PSA_TO_MD_ERR(psa_hash_update(
- &ssl->handshake->fin_sha256_psa, buf, len));
+ return mbedtls_md_error_from_psa(psa_hash_update(
+ &ssl->handshake->fin_sha256_psa, buf, len));
#else
return mbedtls_md_update(&ssl->handshake->fin_sha256, buf, len);
#endif
@@ -953,8 +954,8 @@
const unsigned char *buf, size_t len)
{
#if defined(MBEDTLS_USE_PSA_CRYPTO)
- return PSA_TO_MD_ERR(psa_hash_update(
- &ssl->handshake->fin_sha384_psa, buf, len));
+ return mbedtls_md_error_from_psa(psa_hash_update(
+ &ssl->handshake->fin_sha384_psa, buf, len));
#else
return mbedtls_md_update(&ssl->handshake->fin_sha384, buf, len);
#endif
@@ -1155,8 +1156,7 @@
size_t length;
const mbedtls_ecp_group_id *curve_list = ssl->conf->curve_list;
- for (length = 0; (curve_list[length] != MBEDTLS_ECP_DP_NONE) &&
- (length < MBEDTLS_ECP_DP_MAX); length++) {
+ for (length = 0; (curve_list[length] != MBEDTLS_ECP_DP_NONE); length++) {
}
/* Leave room for zero termination */
@@ -4613,10 +4613,7 @@
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
}
- session_len = ((size_t) p[0] << 24) |
- ((size_t) p[1] << 16) |
- ((size_t) p[2] << 8) |
- ((size_t) p[3]);
+ session_len = MBEDTLS_GET_UINT32_BE(p, 0);
p += 4;
/* This has been allocated by ssl_handshake_init(), called by
@@ -4711,10 +4708,7 @@
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
}
- ssl->badmac_seen = ((uint32_t) p[0] << 24) |
- ((uint32_t) p[1] << 16) |
- ((uint32_t) p[2] << 8) |
- ((uint32_t) p[3]);
+ ssl->badmac_seen = MBEDTLS_GET_UINT32_BE(p, 0);
p += 4;
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
@@ -4722,24 +4716,10 @@
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
}
- ssl->in_window_top = ((uint64_t) p[0] << 56) |
- ((uint64_t) p[1] << 48) |
- ((uint64_t) p[2] << 40) |
- ((uint64_t) p[3] << 32) |
- ((uint64_t) p[4] << 24) |
- ((uint64_t) p[5] << 16) |
- ((uint64_t) p[6] << 8) |
- ((uint64_t) p[7]);
+ ssl->in_window_top = MBEDTLS_GET_UINT64_BE(p, 0);
p += 8;
- ssl->in_window = ((uint64_t) p[0] << 56) |
- ((uint64_t) p[1] << 48) |
- ((uint64_t) p[2] << 40) |
- ((uint64_t) p[3] << 32) |
- ((uint64_t) p[4] << 24) |
- ((uint64_t) p[5] << 16) |
- ((uint64_t) p[6] << 8) |
- ((uint64_t) p[7]);
+ ssl->in_window = MBEDTLS_GET_UINT64_BE(p, 0);
p += 8;
#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */
@@ -4973,7 +4953,7 @@
MBEDTLS_SSL_IANA_TLS_GROUP_NONE
};
-static int ssl_preset_suiteb_ciphersuites[] = {
+static const int ssl_preset_suiteb_ciphersuites[] = {
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
0
@@ -6647,7 +6627,7 @@
exit:
psa_hash_abort(&sha256_psa);
- return PSA_TO_MD_ERR(status);
+ return mbedtls_md_error_from_psa(status);
#else
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_md_context_t sha256;
@@ -6709,7 +6689,7 @@
exit:
psa_hash_abort(&sha384_psa);
- return PSA_TO_MD_ERR(status);
+ return mbedtls_md_error_from_psa(status);
#else
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_md_context_t sha384;
@@ -7388,13 +7368,12 @@
/* and in the unlikely case the above assumption no longer holds
* we are making sure that pk_ec() here does not return a NULL
*/
- const mbedtls_ecp_keypair *ec = mbedtls_pk_ec(*pk);
- if (ec == NULL) {
- MBEDTLS_SSL_DEBUG_MSG(1, ("mbedtls_pk_ec() returned NULL"));
+ mbedtls_ecp_group_id grp_id = mbedtls_pk_get_group_id(pk);
+ if (grp_id == MBEDTLS_ECP_DP_NONE) {
+ MBEDTLS_SSL_DEBUG_MSG(1, ("invalid group ID"));
return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
}
-
- if (mbedtls_ssl_check_curve(ssl, ec->grp.id) != 0) {
+ if (mbedtls_ssl_check_curve(ssl, grp_id) != 0) {
ssl->session_negotiate->verify_result |=
MBEDTLS_X509_BADCERT_BAD_KEY;
@@ -7763,7 +7742,7 @@
exit:
#if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_hash_abort(&sha256_psa);
- return PSA_TO_MD_ERR(status);
+ return mbedtls_md_error_from_psa(status);
#else
mbedtls_md_free(&sha256);
return ret;
@@ -7852,7 +7831,7 @@
exit:
#if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_hash_abort(&sha384_psa);
- return PSA_TO_MD_ERR(status);
+ return mbedtls_md_error_from_psa(status);
#else
mbedtls_md_free(&sha384);
return ret;
@@ -8314,9 +8293,9 @@
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
- mac_alg = mbedtls_hash_info_psa_from_md(ciphersuite_info->mac);
+ mac_alg = mbedtls_md_psa_alg_from_type(ciphersuite_info->mac);
if (mac_alg == 0) {
- MBEDTLS_SSL_DEBUG_MSG(1, ("mbedtls_hash_info_psa_from_md for %u not found",
+ MBEDTLS_SSL_DEBUG_MSG(1, ("mbedtls_md_psa_alg_from_type for %u not found",
(unsigned) ciphersuite_info->mac));
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
}
@@ -8763,7 +8742,7 @@
{
psa_status_t status;
psa_hash_operation_t hash_operation = PSA_HASH_OPERATION_INIT;
- psa_algorithm_t hash_alg = mbedtls_hash_info_psa_from_md(md_alg);
+ psa_algorithm_t hash_alg = mbedtls_md_psa_alg_from_type(md_alg);
MBEDTLS_SSL_DEBUG_MSG(3, ("Perform PSA-based computation of digest of ServerKeyExchange"));
@@ -8892,7 +8871,7 @@
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if (ssl->handshake->key_cert && ssl->handshake->key_cert->key) {
psa_algorithm_t psa_hash_alg =
- mbedtls_hash_info_psa_from_md(hash_alg_received);
+ mbedtls_md_psa_alg_from_type(hash_alg_received);
if (sig_alg_received == MBEDTLS_SSL_SIG_ECDSA &&
!mbedtls_pk_can_do_ext(ssl->handshake->key_cert->key,
@@ -9102,14 +9081,7 @@
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
}
- start = ((uint64_t) p[0] << 56) |
- ((uint64_t) p[1] << 48) |
- ((uint64_t) p[2] << 40) |
- ((uint64_t) p[3] << 32) |
- ((uint64_t) p[4] << 24) |
- ((uint64_t) p[5] << 16) |
- ((uint64_t) p[6] << 8) |
- ((uint64_t) p[7]);
+ start = MBEDTLS_GET_UINT64_BE(p, 0);
p += 8;
session->start = (time_t) start;
@@ -9132,10 +9104,7 @@
memcpy(session->master, p, 48);
p += 48;
- session->verify_result = ((uint32_t) p[0] << 24) |
- ((uint32_t) p[1] << 16) |
- ((uint32_t) p[2] << 8) |
- ((uint32_t) p[3]);
+ session->verify_result = MBEDTLS_GET_UINT32_BE(p, 0);
p += 4;
/* Immediately clear invalid pointer values that have been read, in case
@@ -9254,10 +9223,7 @@
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
}
- session->ticket_lifetime = ((uint32_t) p[0] << 24) |
- ((uint32_t) p[1] << 16) |
- ((uint32_t) p[2] << 8) |
- ((uint32_t) p[3]);
+ session->ticket_lifetime = MBEDTLS_GET_UINT32_BE(p, 0);
p += 4;
#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
diff --git a/library/ssl_tls12_client.c b/library/ssl_tls12_client.c
index d94d829..fc96dae 100644
--- a/library/ssl_tls12_client.c
+++ b/library/ssl_tls12_client.c
@@ -50,8 +50,6 @@
#include "mbedtls/platform_util.h"
#endif
-#include "hash_info.h"
-
#if defined(MBEDTLS_SSL_RENEGOTIATION)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_renegotiation_ext(mbedtls_ssl_context *ssl,
@@ -1986,7 +1984,6 @@
static int ssl_get_ecdh_params_from_cert(mbedtls_ssl_context *ssl)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- const mbedtls_ecp_keypair *peer_key;
mbedtls_pk_context *peer_pk;
#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
@@ -2007,22 +2004,24 @@
return MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH;
}
- peer_key = mbedtls_pk_ec(*peer_pk);
+#if defined(MBEDTLS_ECP_C)
+ const mbedtls_ecp_keypair *peer_key = mbedtls_pk_ec_ro(*peer_pk);
+#endif /* MBEDTLS_ECP_C */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
- size_t olen = 0;
uint16_t tls_id = 0;
psa_ecc_family_t ecc_family;
+ mbedtls_ecp_group_id grp_id = mbedtls_pk_get_group_id(peer_pk);
- if (mbedtls_ssl_check_curve(ssl, peer_key->grp.id) != 0) {
+ if (mbedtls_ssl_check_curve(ssl, grp_id) != 0) {
MBEDTLS_SSL_DEBUG_MSG(1, ("bad server certificate (ECDH curve)"));
return MBEDTLS_ERR_SSL_BAD_CERTIFICATE;
}
- tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id(peer_key->grp.id);
+ tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id(grp_id);
if (tls_id == 0) {
MBEDTLS_SSL_DEBUG_MSG(1, ("ECC group %u not suported",
- peer_key->grp.id));
+ grp_id));
return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
}
@@ -2034,6 +2033,12 @@
ssl->handshake->ecdh_psa_type = PSA_KEY_TYPE_ECC_KEY_PAIR(ecc_family);
/* Store peer's public key in psa format. */
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+ memcpy(ssl->handshake->ecdh_psa_peerkey, peer_pk->pub_raw, peer_pk->pub_raw_len);
+ ssl->handshake->ecdh_psa_peerkey_len = peer_pk->pub_raw_len;
+ ret = 0;
+#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
+ size_t olen = 0;
ret = mbedtls_ecp_point_write_binary(&peer_key->grp, &peer_key->Q,
MBEDTLS_ECP_PF_UNCOMPRESSED, &olen,
ssl->handshake->ecdh_psa_peerkey,
@@ -2043,9 +2048,9 @@
MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ecp_point_write_binary"), ret);
return ret;
}
-
ssl->handshake->ecdh_psa_peerkey_len = olen;
-#else
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
+#else /* MBEDTLS_USE_PSA_CRYPTO */
if ((ret = mbedtls_ecdh_get_params(&ssl->handshake->ecdh_ctx, peer_key,
MBEDTLS_ECDH_THEIRS)) != 0) {
MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ecdh_get_params"), ret);
@@ -2056,7 +2061,7 @@
MBEDTLS_SSL_DEBUG_MSG(1, ("bad server certificate (ECDH curve)"));
return MBEDTLS_ERR_SSL_BAD_CERTIFICATE;
}
-#endif
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
/* We don't need the peer's public key anymore. Free it,
* so that more RAM is available for upcoming expensive
@@ -2284,7 +2289,7 @@
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
if (mbedtls_ssl_ciphersuite_uses_server_signature(ciphersuite_info)) {
size_t sig_len, hashlen;
- unsigned char hash[MBEDTLS_HASH_MAX_SIZE];
+ unsigned char hash[MBEDTLS_MD_MAX_SIZE];
mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE;
mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
@@ -2401,7 +2406,7 @@
mbedtls_pk_rsassa_pss_options rsassa_pss_options;
rsassa_pss_options.mgf1_hash_id = md_alg;
rsassa_pss_options.expected_salt_len =
- mbedtls_hash_info_get_size(md_alg);
+ mbedtls_md_get_size_from_type(md_alg);
if (rsassa_pss_options.expected_salt_len == 0) {
return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
}
diff --git a/library/ssl_tls12_server.c b/library/ssl_tls12_server.c
index 42f5fe9..30c35f3 100644
--- a/library/ssl_tls12_server.c
+++ b/library/ssl_tls12_server.c
@@ -30,7 +30,6 @@
#include "mbedtls/platform_util.h"
#include "constant_time_internal.h"
#include "mbedtls/constant_time.h"
-#include "hash_info.h"
#include <string.h>
@@ -666,7 +665,7 @@
uint16_t *curves_tls_id)
{
uint16_t *curr_tls_id = curves_tls_id;
- mbedtls_ecp_group_id grp_id = mbedtls_pk_ec(*pk)->grp.id;
+ mbedtls_ecp_group_id grp_id = mbedtls_pk_ec_ro(*pk)->grp.id;
mbedtls_ecp_group_id curr_grp_id;
while (*curr_tls_id != 0) {
@@ -1088,9 +1087,7 @@
#if defined(MBEDTLS_SSL_RENEGOTIATION)
if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS) {
/* This couldn't be done in ssl_prepare_handshake_record() */
- unsigned int cli_msg_seq = (ssl->in_msg[4] << 8) |
- ssl->in_msg[5];
-
+ unsigned int cli_msg_seq = (unsigned int) MBEDTLS_GET_UINT16_BE(ssl->in_msg, 4);
if (cli_msg_seq != ssl->handshake->in_msg_seq) {
MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message_seq: "
"%u (expected %u)", cli_msg_seq,
@@ -1102,8 +1099,7 @@
} else
#endif
{
- unsigned int cli_msg_seq = (ssl->in_msg[4] << 8) |
- ssl->in_msg[5];
+ unsigned int cli_msg_seq = (unsigned int) MBEDTLS_GET_UINT16_BE(ssl->in_msg, 4);
ssl->handshake->out_msg_seq = cli_msg_seq;
ssl->handshake->in_msg_seq = cli_msg_seq + 1;
}
@@ -2600,7 +2596,7 @@
psa_ecc_family_t ecc_family;
size_t key_len;
mbedtls_pk_context *pk;
- mbedtls_ecp_keypair *key;
+ mbedtls_ecp_group_id grp_id;
pk = mbedtls_ssl_own_key(ssl);
@@ -2608,14 +2604,17 @@
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
}
+#if !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+ mbedtls_ecp_keypair *key = mbedtls_pk_ec_rw(*pk);
+#endif /* !MBEDTLS_PK_USE_PSA_EC_DATA */
+
switch (mbedtls_pk_get_type(pk)) {
case MBEDTLS_PK_OPAQUE:
if (!mbedtls_pk_can_do(pk, MBEDTLS_PK_ECKEY)) {
return MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH;
}
- ssl->handshake->ecdh_psa_privkey =
- *((mbedtls_svc_key_id_t *) pk->pk_ctx);
+ ssl->handshake->ecdh_psa_privkey = pk->priv_id;
/* Key should not be destroyed in the TLS library */
ssl->handshake->ecdh_psa_privkey_is_external = 1;
@@ -2637,12 +2636,11 @@
case MBEDTLS_PK_ECKEY:
case MBEDTLS_PK_ECKEY_DH:
case MBEDTLS_PK_ECDSA:
- key = mbedtls_pk_ec(*pk);
- if (key == NULL) {
+ grp_id = mbedtls_pk_get_group_id(pk);
+ if (grp_id == MBEDTLS_ECP_DP_NONE) {
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
}
-
- tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id(key->grp.id);
+ tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id(grp_id);
if (tls_id == 0) {
/* This elliptic curve is not supported */
return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
@@ -2662,11 +2660,19 @@
PSA_KEY_TYPE_ECC_KEY_PAIR(ssl->handshake->ecdh_psa_type));
psa_set_key_bits(&key_attributes, ssl->handshake->ecdh_bits);
+#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
+ status = psa_export_key(pk->priv_id, buf, sizeof(buf), &key_len);
+ if (status != PSA_SUCCESS) {
+ ret = PSA_TO_MBEDTLS_ERR(status);
+ goto cleanup;
+ }
+#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
key_len = PSA_BITS_TO_BYTES(key->grp.pbits);
ret = mbedtls_ecp_write_key(key, buf, key_len);
if (ret != 0) {
goto cleanup;
}
+#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
status = psa_import_key(&key_attributes, buf, key_len,
&ssl->handshake->ecdh_psa_privkey);
@@ -2705,7 +2711,7 @@
}
if ((ret = mbedtls_ecdh_get_params(&ssl->handshake->ecdh_ctx,
- mbedtls_pk_ec(*mbedtls_ssl_own_key(ssl)),
+ mbedtls_pk_ec_ro(*mbedtls_ssl_own_key(ssl)),
MBEDTLS_ECDH_OURS)) != 0) {
MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ecdh_get_params"), ret);
return ret;
@@ -3074,7 +3080,7 @@
size_t dig_signed_len = ssl->out_msg + ssl->out_msglen - dig_signed;
size_t hashlen = 0;
- unsigned char hash[MBEDTLS_HASH_MAX_SIZE];
+ unsigned char hash[MBEDTLS_MD_MAX_SIZE];
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c
index e1d0c6c..3dffc1d 100644
--- a/library/ssl_tls13_client.c
+++ b/library/ssl_tls13_client.c
@@ -33,6 +33,7 @@
#include "ssl_client.h"
#include "ssl_tls13_keys.h"
#include "ssl_debug_helpers.h"
+#include "md_psa.h"
#define PSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \
psa_to_ssl_errors, \
@@ -672,7 +673,7 @@
ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(ciphersuite);
if (ciphersuite_info != NULL) {
- return mbedtls_psa_translate_md(ciphersuite_info->mac);
+ return mbedtls_md_psa_alg_from_type(ciphersuite_info->mac);
}
return PSA_ALG_NONE;
@@ -850,7 +851,7 @@
/* Get current state of handshake transcript. */
ret = mbedtls_ssl_get_handshake_transcript(
- ssl, mbedtls_hash_info_md_from_psa(hash_alg),
+ ssl, mbedtls_md_type_from_psa_alg(hash_alg),
transcript, sizeof(transcript), &transcript_len);
if (ret != 0) {
return ret;
@@ -1126,7 +1127,7 @@
return ret;
}
- if (mbedtls_psa_translate_md(ssl->handshake->ciphersuite_info->mac)
+ if (mbedtls_md_psa_alg_from_type(ssl->handshake->ciphersuite_info->mac)
!= hash_alg) {
MBEDTLS_SSL_DEBUG_MSG(
1, ("Invalid ciphersuite for external psk."));
@@ -1696,7 +1697,7 @@
cipher_suite, ciphersuite_info->name));
#if defined(MBEDTLS_HAVE_TIME)
- ssl->session_negotiate->start = time(NULL);
+ ssl->session_negotiate->start = mbedtls_time(NULL);
#endif /* MBEDTLS_HAVE_TIME */
/* ...
@@ -2844,7 +2845,7 @@
return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
}
- psa_hash_alg = mbedtls_psa_translate_md(ciphersuite_info->mac);
+ psa_hash_alg = mbedtls_md_psa_alg_from_type(ciphersuite_info->mac);
hash_length = PSA_HASH_LENGTH(psa_hash_alg);
if (hash_length == -1 ||
(size_t) hash_length > sizeof(session->resumption_key)) {
diff --git a/library/ssl_tls13_generic.c b/library/ssl_tls13_generic.c
index a00785b..a59f01c 100644
--- a/library/ssl_tls13_generic.c
+++ b/library/ssl_tls13_generic.c
@@ -29,7 +29,7 @@
#include "mbedtls/platform.h"
#include "mbedtls/constant_time.h"
#include "psa/crypto.h"
-#include "mbedtls/psa_util.h"
+#include "md_psa.h"
#include "ssl_misc.h"
#include "ssl_tls13_invasive.h"
@@ -274,7 +274,7 @@
goto error;
}
- hash_alg = mbedtls_hash_info_psa_from_md(md_alg);
+ hash_alg = mbedtls_md_psa_alg_from_type(md_alg);
if (hash_alg == 0) {
goto error;
}
@@ -1076,7 +1076,7 @@
}
/* Hash verify buffer with indicated hash function */
- psa_algorithm = mbedtls_hash_info_psa_from_md(md_alg);
+ psa_algorithm = mbedtls_md_psa_alg_from_type(md_alg);
status = psa_hash_compute(psa_algorithm,
verify_buffer,
verify_buffer_len,
diff --git a/library/ssl_tls13_keys.c b/library/ssl_tls13_keys.c
index 46caa45..540f854 100644
--- a/library/ssl_tls13_keys.c
+++ b/library/ssl_tls13_keys.c
@@ -34,6 +34,7 @@
#include "ssl_tls13_invasive.h"
#include "psa/crypto.h"
+#include "md_psa.h"
#define PSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \
psa_to_ssl_errors, \
@@ -677,7 +678,7 @@
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ssl_handshake_params *handshake = ssl->handshake;
- psa_algorithm_t const hash_alg = mbedtls_hash_info_psa_from_md(
+ psa_algorithm_t const hash_alg = mbedtls_md_psa_alg_from_type(
handshake->ciphersuite_info->mac);
/*
@@ -792,7 +793,7 @@
mbedtls_md_type_t const md_type = ssl->handshake->ciphersuite_info->mac;
- psa_algorithm_t hash_alg = mbedtls_hash_info_psa_from_md(
+ psa_algorithm_t hash_alg = mbedtls_md_psa_alg_from_type(
ssl->handshake->ciphersuite_info->mac);
size_t const hash_len = PSA_HASH_LENGTH(hash_alg);
@@ -1163,7 +1164,7 @@
md_type = ciphersuite_info->mac;
- hash_alg = mbedtls_hash_info_psa_from_md(ciphersuite_info->mac);
+ hash_alg = mbedtls_md_psa_alg_from_type(ciphersuite_info->mac);
hash_len = PSA_HASH_LENGTH(hash_alg);
ret = mbedtls_ssl_get_handshake_transcript(ssl, md_type,
@@ -1291,7 +1292,7 @@
return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
}
- hash_alg = mbedtls_hash_info_psa_from_md(handshake->ciphersuite_info->mac);
+ hash_alg = mbedtls_md_psa_alg_from_type(handshake->ciphersuite_info->mac);
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
if (mbedtls_ssl_tls13_key_exchange_mode_with_psk(ssl)) {
ret = mbedtls_ssl_tls13_export_handshake_psk(ssl, &psk, &psk_len);
@@ -1365,7 +1366,7 @@
md_type = ciphersuite_info->mac;
- hash_alg = mbedtls_hash_info_psa_from_md(ciphersuite_info->mac);
+ hash_alg = mbedtls_md_psa_alg_from_type(ciphersuite_info->mac);
hash_len = PSA_HASH_LENGTH(hash_alg);
ret = mbedtls_ssl_get_handshake_transcript(ssl, md_type,
@@ -1472,7 +1473,7 @@
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ssl_handshake_params *handshake = ssl->handshake;
- psa_algorithm_t const hash_alg = mbedtls_hash_info_psa_from_md(
+ psa_algorithm_t const hash_alg = mbedtls_md_psa_alg_from_type(
handshake->ciphersuite_info->mac);
unsigned char *shared_secret = NULL;
size_t shared_secret_len = 0;
@@ -1608,7 +1609,7 @@
md_type = handshake->ciphersuite_info->mac;
- hash_alg = mbedtls_hash_info_psa_from_md(handshake->ciphersuite_info->mac);
+ hash_alg = mbedtls_md_psa_alg_from_type(handshake->ciphersuite_info->mac);
hash_len = PSA_HASH_LENGTH(hash_alg);
/* Compute current handshake transcript. It's the caller's responsibility
@@ -1766,7 +1767,7 @@
}
ret = mbedtls_ssl_tls13_derive_resumption_master_secret(
- mbedtls_psa_translate_md(md_type),
+ mbedtls_md_psa_alg_from_type(md_type),
handshake->tls13_master_secrets.app,
transcript, transcript_len,
&ssl->session_negotiate->app_secrets);
@@ -1781,7 +1782,7 @@
MBEDTLS_SSL_DEBUG_BUF(
4, "Resumption master secret",
ssl->session_negotiate->app_secrets.resumption_master_secret,
- PSA_HASH_LENGTH(mbedtls_psa_translate_md(md_type)));
+ PSA_HASH_LENGTH(mbedtls_md_psa_alg_from_type(md_type)));
MBEDTLS_SSL_DEBUG_MSG(
2, ("<= mbedtls_ssl_tls13_compute_resumption_master_secret"));
diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c
index 33121af..cf61191 100644
--- a/library/ssl_tls13_server.c
+++ b/library/ssl_tls13_server.c
@@ -25,6 +25,7 @@
#include "mbedtls/error.h"
#include "mbedtls/platform.h"
#include "mbedtls/constant_time.h"
+#include "md_psa.h"
#include "ssl_misc.h"
#include "ssl_tls13_keys.h"
@@ -332,7 +333,7 @@
/* Get current state of handshake transcript. */
ret = mbedtls_ssl_get_handshake_transcript(
- ssl, mbedtls_hash_info_md_from_psa(psk_hash_alg),
+ ssl, mbedtls_md_type_from_psa_alg(psk_hash_alg),
transcript, sizeof(transcript), &transcript_len);
if (ret != 0) {
return ret;
@@ -406,7 +407,7 @@
/* MAC of selected ciphersuite MUST be same with PSK binder if exist.
* Otherwise, client should reject.
*/
- if (psk_hash_alg == mbedtls_psa_translate_md(ciphersuite_info->mac)) {
+ if (psk_hash_alg == mbedtls_md_psa_alg_from_type(ciphersuite_info->mac)) {
*selected_ciphersuite = cipher_suite;
*selected_ciphersuite_info = ciphersuite_info;
return 0;
@@ -612,7 +613,7 @@
ret = ssl_tls13_offered_psks_check_binder_match(
ssl, binder, binder_len, psk_type,
- mbedtls_psa_translate_md(ciphersuite_info->mac));
+ mbedtls_md_psa_alg_from_type(ciphersuite_info->mac));
if (ret != SSL_TLS1_3_OFFERED_PSK_MATCH) {
/* For security reasons, the handshake should be aborted when we
* fail to validate a binder value. See RFC 8446 section 4.2.11.2
@@ -1846,7 +1847,7 @@
MBEDTLS_SERVER_HELLO_RANDOM_LEN);
#if defined(MBEDTLS_HAVE_TIME)
- ssl->session_negotiate->start = time(NULL);
+ ssl->session_negotiate->start = mbedtls_time(NULL);
#endif /* MBEDTLS_HAVE_TIME */
return ret;
@@ -2783,7 +2784,7 @@
ciphersuite_info =
(mbedtls_ssl_ciphersuite_t *) ssl->handshake->ciphersuite_info;
- psa_hash_alg = mbedtls_psa_translate_md(ciphersuite_info->mac);
+ psa_hash_alg = mbedtls_md_psa_alg_from_type(ciphersuite_info->mac);
hash_length = PSA_HASH_LENGTH(psa_hash_alg);
if (hash_length == -1 ||
(size_t) hash_length > sizeof(session->resumption_key)) {
diff --git a/library/x509.c b/library/x509.c
index c9524c9..8a44264 100644
--- a/library/x509.c
+++ b/library/x509.c
@@ -1201,6 +1201,87 @@
return 0;
}
+/* Check mbedtls_x509_get_subject_alt_name for detailed description.
+ *
+ * In some cases while parsing subject alternative names the sequence tag is optional
+ * (e.g. CertSerialNumber). This function is designed to handle such case.
+ */
+int mbedtls_x509_get_subject_alt_name_ext(unsigned char **p,
+ const unsigned char *end,
+ mbedtls_x509_sequence *subject_alt_name)
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t tag_len;
+ mbedtls_asn1_sequence *cur = subject_alt_name;
+
+ while (*p < end) {
+ mbedtls_x509_subject_alternative_name tmp_san_name;
+ mbedtls_x509_buf tmp_san_buf;
+ memset(&tmp_san_name, 0, sizeof(tmp_san_name));
+
+ tmp_san_buf.tag = **p;
+ (*p)++;
+
+ if ((ret = mbedtls_asn1_get_len(p, end, &tag_len)) != 0) {
+ return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
+ }
+
+ tmp_san_buf.p = *p;
+ tmp_san_buf.len = tag_len;
+
+ if ((tmp_san_buf.tag & MBEDTLS_ASN1_TAG_CLASS_MASK) !=
+ MBEDTLS_ASN1_CONTEXT_SPECIFIC) {
+ return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
+ }
+
+ /*
+ * Check that the SAN is structured correctly by parsing it.
+ * The SAN structure is discarded afterwards.
+ */
+ ret = mbedtls_x509_parse_subject_alt_name(&tmp_san_buf, &tmp_san_name);
+ /*
+ * In case the extension is malformed, return an error,
+ * and clear the allocated sequences.
+ */
+ if (ret != 0 && ret != MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE) {
+ mbedtls_asn1_sequence_free(subject_alt_name->next);
+ subject_alt_name->next = NULL;
+ return ret;
+ }
+
+ mbedtls_x509_free_subject_alt_name(&tmp_san_name);
+ /* Allocate and assign next pointer */
+ if (cur->buf.p != NULL) {
+ if (cur->next != NULL) {
+ return MBEDTLS_ERR_X509_INVALID_EXTENSIONS;
+ }
+
+ cur->next = mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence));
+
+ if (cur->next == NULL) {
+ return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_ALLOC_FAILED);
+ }
+
+ cur = cur->next;
+ }
+
+ cur->buf = tmp_san_buf;
+ *p += tmp_san_buf.len;
+ }
+
+ /* Set final sequence entry's next pointer to NULL */
+ cur->next = NULL;
+
+ if (*p != end) {
+ return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
+ }
+
+ return 0;
+}
+
/*
* SubjectAltName ::= GeneralNames
*
@@ -1234,8 +1315,7 @@
mbedtls_x509_sequence *subject_alt_name)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- size_t len, tag_len;
- mbedtls_asn1_sequence *cur = subject_alt_name;
+ size_t len;
/* Get main sequence tag */
if ((ret = mbedtls_asn1_get_tag(p, end, &len,
@@ -1248,71 +1328,7 @@
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
}
- while (*p < end) {
- mbedtls_x509_subject_alternative_name dummy_san_buf;
- mbedtls_x509_buf tmp_san_buf;
- memset(&dummy_san_buf, 0, sizeof(dummy_san_buf));
-
- tmp_san_buf.tag = **p;
- (*p)++;
-
- if ((ret = mbedtls_asn1_get_len(p, end, &tag_len)) != 0) {
- return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
- }
-
- tmp_san_buf.p = *p;
- tmp_san_buf.len = tag_len;
-
- if ((tmp_san_buf.tag & MBEDTLS_ASN1_TAG_CLASS_MASK) !=
- MBEDTLS_ASN1_CONTEXT_SPECIFIC) {
- return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
- MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
- }
-
- /*
- * Check that the SAN is structured correctly.
- */
- ret = mbedtls_x509_parse_subject_alt_name(&tmp_san_buf, &dummy_san_buf);
- /*
- * In case the extension is malformed, return an error,
- * and clear the allocated sequences.
- */
- if (ret != 0 && ret != MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE) {
- mbedtls_asn1_sequence_free(subject_alt_name->next);
- subject_alt_name->next = NULL;
- return ret;
- }
-
- mbedtls_x509_free_subject_alt_name(&dummy_san_buf);
- /* Allocate and assign next pointer */
- if (cur->buf.p != NULL) {
- if (cur->next != NULL) {
- return MBEDTLS_ERR_X509_INVALID_EXTENSIONS;
- }
-
- cur->next = mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence));
-
- if (cur->next == NULL) {
- return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
- MBEDTLS_ERR_ASN1_ALLOC_FAILED);
- }
-
- cur = cur->next;
- }
-
- cur->buf = tmp_san_buf;
- *p += tmp_san_buf.len;
- }
-
- /* Set final sequence entry's next pointer to NULL */
- cur->next = NULL;
-
- if (*p != end) {
- return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
- }
-
- return 0;
+ return mbedtls_x509_get_subject_alt_name_ext(p, end, subject_alt_name);
}
int mbedtls_x509_get_ns_cert_type(unsigned char **p,
@@ -1424,7 +1440,7 @@
break;
/*
- * RFC822 Name
+ * rfc822Name
*/
case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_RFC822_NAME):
{
diff --git a/library/x509_crt.c b/library/x509_crt.c
index 874d8f6..9b3414a 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -47,9 +47,10 @@
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "psa/crypto.h"
#include "mbedtls/psa_util.h"
+#include "md_psa.h"
#endif /* MBEDTLS_USE_PSA_CRYPTO */
-#include "hash_info.h"
#include "x509_invasive.h"
+#include "pk_internal.h"
#include "mbedtls/platform.h"
@@ -237,7 +238,7 @@
if (pk_alg == MBEDTLS_PK_ECDSA ||
pk_alg == MBEDTLS_PK_ECKEY ||
pk_alg == MBEDTLS_PK_ECKEY_DH) {
- const mbedtls_ecp_group_id gid = mbedtls_pk_ec(*pk)->grp.id;
+ const mbedtls_ecp_group_id gid = mbedtls_pk_get_group_id(pk);
if (gid == MBEDTLS_ECP_DP_NONE) {
return -1;
@@ -592,6 +593,114 @@
}
/*
+ * SubjectKeyIdentifier ::= KeyIdentifier
+ *
+ * KeyIdentifier ::= OCTET STRING
+ */
+static int x509_get_subject_key_id(unsigned char **p,
+ const unsigned char *end,
+ mbedtls_x509_buf *subject_key_id)
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t len = 0u;
+
+ if ((ret = mbedtls_asn1_get_tag(p, end, &len,
+ MBEDTLS_ASN1_OCTET_STRING)) != 0) {
+ return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
+ }
+
+ subject_key_id->len = len;
+ subject_key_id->tag = MBEDTLS_ASN1_OCTET_STRING;
+ subject_key_id->p = *p;
+ *p += len;
+
+ if (*p != end) {
+ return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
+ }
+
+ return 0;
+}
+
+/*
+ * AuthorityKeyIdentifier ::= SEQUENCE {
+ * keyIdentifier [0] KeyIdentifier OPTIONAL,
+ * authorityCertIssuer [1] GeneralNames OPTIONAL,
+ * authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL }
+ *
+ * KeyIdentifier ::= OCTET STRING
+ */
+static int x509_get_authority_key_id(unsigned char **p,
+ unsigned char *end,
+ mbedtls_x509_authority *authority_key_id)
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t len = 0u;
+
+ if ((ret = mbedtls_asn1_get_tag(p, end, &len,
+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
+ return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
+ }
+
+ if (*p + len != end) {
+ return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
+ }
+
+ ret = mbedtls_asn1_get_tag(p, end, &len,
+ MBEDTLS_ASN1_CONTEXT_SPECIFIC);
+
+ /* KeyIdentifier is an OPTIONAL field */
+ if (ret == 0) {
+ authority_key_id->keyIdentifier.len = len;
+ authority_key_id->keyIdentifier.p = *p;
+ /* Setting tag of the keyIdentfier intentionally to 0x04.
+ * Although the .keyIdentfier field is CONTEXT_SPECIFIC ([0] OPTIONAL),
+ * its tag with the content is the payload of on OCTET STRING primitive */
+ authority_key_id->keyIdentifier.tag = MBEDTLS_ASN1_OCTET_STRING;
+
+ *p += len;
+ } else if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
+ return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
+ }
+
+ if (*p < end) {
+ /* Getting authorityCertIssuer using the required specific class tag [1] */
+ if ((ret = mbedtls_asn1_get_tag(p, end, &len,
+ MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED |
+ 1)) != 0) {
+ /* authorityCertIssuer and authorityCertSerialNumber MUST both
+ be present or both be absent. At this point we expect to have both. */
+ return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
+ }
+ /* "end" also includes the CertSerialNumber field so "len" shall be used */
+ ret = mbedtls_x509_get_subject_alt_name_ext(p,
+ (*p+len),
+ &authority_key_id->authorityCertIssuer);
+ if (ret != 0) {
+ return ret;
+ }
+
+ /* Getting authorityCertSerialNumber using the required specific class tag [2] */
+ if ((ret = mbedtls_asn1_get_tag(p, end, &len,
+ MBEDTLS_ASN1_CONTEXT_SPECIFIC | 2)) != 0) {
+ return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
+ }
+ authority_key_id->authorityCertSerialNumber.len = len;
+ authority_key_id->authorityCertSerialNumber.p = *p;
+ authority_key_id->authorityCertSerialNumber.tag = MBEDTLS_ASN1_INTEGER;
+ *p += len;
+ }
+
+ if (*p != end) {
+ return MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
+ }
+
+ return 0;
+}
+
+/*
* id-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-ce 32 }
*
* anyPolicy OBJECT IDENTIFIER ::= { id-ce-certificatePolicies 0 }
@@ -889,8 +998,25 @@
}
break;
+ case MBEDTLS_X509_EXT_SUBJECT_KEY_IDENTIFIER:
+ /* Parse subject key identifier */
+ if ((ret = x509_get_subject_key_id(p, end_ext_data,
+ &crt->subject_key_id)) != 0) {
+ return ret;
+ }
+ break;
+
+ case MBEDTLS_X509_EXT_AUTHORITY_KEY_IDENTIFIER:
+ /* Parse authority key identifier */
+ if ((ret = x509_get_authority_key_id(p, end_ext_octet,
+ &crt->authority_key_id)) != 0) {
+ return ret;
+ }
+ break;
case MBEDTLS_X509_EXT_SUBJECT_ALT_NAME:
- /* Parse subject alt name */
+ /* Parse subject alt name
+ * SubjectAltName ::= GeneralNames
+ */
if ((ret = mbedtls_x509_get_subject_alt_name(p, end_ext_octet,
&crt->subject_alt_names)) != 0) {
return ret;
@@ -1550,6 +1676,27 @@
#endif /* MBEDTLS_FS_IO */
#if !defined(MBEDTLS_X509_REMOVE_INFO)
+#define PRINT_ITEM(i) \
+ do { \
+ ret = mbedtls_snprintf(p, n, "%s" i, sep); \
+ MBEDTLS_X509_SAFE_SNPRINTF; \
+ sep = ", "; \
+ } while (0)
+
+#define CERT_TYPE(type, name) \
+ do { \
+ if (ns_cert_type & (type)) { \
+ PRINT_ITEM(name); \
+ } \
+ } while (0)
+
+#define KEY_USAGE(code, name) \
+ do { \
+ if (key_usage & (code)) { \
+ PRINT_ITEM(name); \
+ } \
+ } while (0)
+
static int x509_info_ext_key_usage(char **buf, size_t *size,
const mbedtls_x509_sequence *extended_key_usage)
{
@@ -1877,7 +2024,7 @@
const mbedtls_x509_crt_profile *profile)
{
int flags = 0;
- unsigned char hash[MBEDTLS_HASH_MAX_SIZE];
+ unsigned char hash[MBEDTLS_MD_MAX_SIZE];
#if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_algorithm_t psa_algorithm;
#else
@@ -1917,7 +2064,7 @@
}
#if defined(MBEDTLS_USE_PSA_CRYPTO)
- psa_algorithm = mbedtls_hash_info_psa_from_md(crl_list->sig_md);
+ psa_algorithm = mbedtls_md_psa_alg_from_type(crl_list->sig_md);
if (psa_hash_compute(psa_algorithm,
crl_list->tbs.p,
crl_list->tbs.len,
@@ -1986,7 +2133,7 @@
mbedtls_x509_crt_restart_ctx *rs_ctx)
{
size_t hash_len;
- unsigned char hash[MBEDTLS_HASH_MAX_SIZE];
+ unsigned char hash[MBEDTLS_MD_MAX_SIZE];
#if !defined(MBEDTLS_USE_PSA_CRYPTO)
const mbedtls_md_info_t *md_info;
md_info = mbedtls_md_info_from_type(child->sig_md);
@@ -1997,7 +2144,7 @@
return -1;
}
#else
- psa_algorithm_t hash_alg = mbedtls_hash_info_psa_from_md(child->sig_md);
+ psa_algorithm_t hash_alg = mbedtls_md_psa_alg_from_type(child->sig_md);
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
status = psa_hash_compute(hash_alg,
@@ -2667,7 +2814,6 @@
static int x509_inet_pton_ipv4(const char *src, void *dst)
{
- /* note: allows leading 0's, e.g. 000.000.000.000 */
const unsigned char *p = (const unsigned char *) src;
uint8_t *res = (uint8_t *) dst;
uint8_t digit, num_digits = 0;
@@ -2681,13 +2827,20 @@
if (digit > 9) {
break;
}
+
+ /* Don't allow leading zeroes. These might mean octal format,
+ * which this implementation does not support. */
+ if (octet == 0 && num_digits > 0) {
+ return -1;
+ }
+
octet = octet * 10 + digit;
num_digits++;
p++;
} while (num_digits < 3);
if (octet >= 256 || num_digits > 3 || num_digits == 0) {
- break;
+ return -1;
}
*res++ = (uint8_t) octet;
num_octets++;
@@ -2758,6 +2911,21 @@
return -1;
}
+static int x509_crt_check_san_uri(const mbedtls_x509_sequence *san,
+ const char *cn, size_t cn_len)
+{
+ for (const mbedtls_x509_sequence *cur = san; cur != NULL; cur = cur->next) {
+ const unsigned char san_type = (unsigned char) cur->buf.tag &
+ MBEDTLS_ASN1_TAG_VALUE_MASK;
+ if (san_type == MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER &&
+ cur->buf.len == cn_len && memcmp(cur->buf.p, cn, cn_len) == 0) {
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
/*
* Check for SAN match, see RFC 5280 Section 4.2.1.6
*/
@@ -2765,23 +2933,38 @@
const char *cn, size_t cn_len)
{
int san_ip = 0;
+ int san_uri = 0;
+ /* Prioritize DNS name over other subtypes due to popularity */
for (const mbedtls_x509_sequence *cur = san; cur != NULL; cur = cur->next) {
switch ((unsigned char) cur->buf.tag & MBEDTLS_ASN1_TAG_VALUE_MASK) {
- case MBEDTLS_X509_SAN_DNS_NAME: /* dNSName */
+ case MBEDTLS_X509_SAN_DNS_NAME:
if (x509_crt_check_cn(&cur->buf, cn, cn_len) == 0) {
return 0;
}
break;
- case MBEDTLS_X509_SAN_IP_ADDRESS: /* iPAddress */
+ case MBEDTLS_X509_SAN_IP_ADDRESS:
san_ip = 1;
break;
+ case MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER:
+ san_uri = 1;
+ break;
/* (We may handle other types here later.) */
default: /* Unrecognized type */
break;
}
}
+ if (san_ip) {
+ if (x509_crt_check_san_ip(san, cn, cn_len) == 0) {
+ return 0;
+ }
+ }
+ if (san_uri) {
+ if (x509_crt_check_san_uri(san, cn, cn_len) == 0) {
+ return 0;
+ }
+ }
- return san_ip ? x509_crt_check_san_ip(san, cn, cn_len) : -1;
+ return -1;
}
/*
@@ -3049,6 +3232,7 @@
mbedtls_asn1_sequence_free(cert_cur->ext_key_usage.next);
mbedtls_asn1_sequence_free(cert_cur->subject_alt_names.next);
mbedtls_asn1_sequence_free(cert_cur->certificate_policies.next);
+ mbedtls_asn1_sequence_free(cert_cur->authority_key_id.authorityCertIssuer.next);
if (cert_cur->raw.p != NULL && cert_cur->own_buffer) {
mbedtls_platform_zeroize(cert_cur->raw.p, cert_cur->raw.len);
diff --git a/library/x509write_crt.c b/library/x509write_crt.c
index 70d7e93..59fd589 100644
--- a/library/x509write_crt.c
+++ b/library/x509write_crt.c
@@ -31,10 +31,12 @@
#include "mbedtls/asn1write.h"
#include "mbedtls/error.h"
#include "mbedtls/oid.h"
+#include "mbedtls/platform.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/md.h"
#include <string.h>
+#include <stdint.h>
#if defined(MBEDTLS_PEM_WRITE_C)
#include "mbedtls/pem.h"
@@ -43,9 +45,18 @@
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "psa/crypto.h"
#include "mbedtls/psa_util.h"
+#include "md_psa.h"
#endif /* MBEDTLS_USE_PSA_CRYPTO */
-#include "hash_info.h"
+#define CHECK_OVERFLOW_ADD(a, b) \
+ do \
+ { \
+ if (a > SIZE_MAX - (b)) \
+ { \
+ return MBEDTLS_ERR_X509_BAD_INPUT_DATA; \
+ } \
+ a += b; \
+ } while (0)
void mbedtls_x509write_crt_init(mbedtls_x509write_cert *ctx)
{
@@ -152,6 +163,137 @@
return 0;
}
+int mbedtls_x509write_crt_set_subject_alternative_name(mbedtls_x509write_cert *ctx,
+ const mbedtls_x509_san_list *san_list)
+{
+ int ret = 0;
+ const mbedtls_x509_san_list *cur;
+ unsigned char *buf;
+ unsigned char *p;
+ size_t len;
+ size_t buflen = 0;
+
+ /* Determine the maximum size of the SubjectAltName list */
+ for (cur = san_list; cur != NULL; cur = cur->next) {
+ /* Calculate size of the required buffer */
+ switch (cur->node.type) {
+ case MBEDTLS_X509_SAN_DNS_NAME:
+ case MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER:
+ case MBEDTLS_X509_SAN_IP_ADDRESS:
+ case MBEDTLS_X509_SAN_RFC822_NAME:
+ /* length of value for each name entry,
+ * maximum 4 bytes for the length field,
+ * 1 byte for the tag/type.
+ */
+ CHECK_OVERFLOW_ADD(buflen, cur->node.san.unstructured_name.len);
+ CHECK_OVERFLOW_ADD(buflen, 4 + 1);
+ break;
+ case MBEDTLS_X509_SAN_DIRECTORY_NAME:
+ {
+ const mbedtls_asn1_named_data *chunk = &cur->node.san.directory_name;
+ while (chunk != NULL) {
+ // Max 4 bytes for length, +1 for tag,
+ // additional 4 max for length, +1 for tag.
+ // See x509_write_name for more information.
+ CHECK_OVERFLOW_ADD(buflen, 4 + 1 + 4 + 1);
+ CHECK_OVERFLOW_ADD(buflen, chunk->oid.len);
+ CHECK_OVERFLOW_ADD(buflen, chunk->val.len);
+ chunk = chunk->next;
+ }
+ CHECK_OVERFLOW_ADD(buflen, 4 + 1);
+ break;
+ }
+ default:
+ /* Not supported - return. */
+ return MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
+ }
+ }
+
+ /* Add the extra length field and tag */
+ CHECK_OVERFLOW_ADD(buflen, 4 + 1);
+
+ /* Allocate buffer */
+ buf = mbedtls_calloc(1, buflen);
+ if (buf == NULL) {
+ return MBEDTLS_ERR_ASN1_ALLOC_FAILED;
+ }
+ p = buf + buflen;
+
+ /* Write ASN.1-based structure */
+ cur = san_list;
+ len = 0;
+ while (cur != NULL) {
+ size_t single_san_len = 0;
+ switch (cur->node.type) {
+ case MBEDTLS_X509_SAN_DNS_NAME:
+ case MBEDTLS_X509_SAN_RFC822_NAME:
+ case MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER:
+ case MBEDTLS_X509_SAN_IP_ADDRESS:
+ {
+ const unsigned char *unstructured_name =
+ (const unsigned char *) cur->node.san.unstructured_name.p;
+ size_t unstructured_name_len = cur->node.san.unstructured_name.len;
+
+ MBEDTLS_ASN1_CHK_CLEANUP_ADD(single_san_len,
+ mbedtls_asn1_write_raw_buffer(
+ &p, buf,
+ unstructured_name, unstructured_name_len));
+ MBEDTLS_ASN1_CHK_CLEANUP_ADD(single_san_len, mbedtls_asn1_write_len(
+ &p, buf, unstructured_name_len));
+ MBEDTLS_ASN1_CHK_CLEANUP_ADD(single_san_len,
+ mbedtls_asn1_write_tag(
+ &p, buf,
+ MBEDTLS_ASN1_CONTEXT_SPECIFIC | cur->node.type));
+ }
+ break;
+ case MBEDTLS_X509_SAN_DIRECTORY_NAME:
+ MBEDTLS_ASN1_CHK_CLEANUP_ADD(single_san_len,
+ mbedtls_x509_write_names(&p, buf,
+ (mbedtls_asn1_named_data *) &
+ cur->node
+ .san.directory_name));
+ MBEDTLS_ASN1_CHK_CLEANUP_ADD(single_san_len,
+ mbedtls_asn1_write_len(&p, buf, single_san_len));
+ MBEDTLS_ASN1_CHK_CLEANUP_ADD(single_san_len,
+ mbedtls_asn1_write_tag(&p, buf,
+ MBEDTLS_ASN1_CONTEXT_SPECIFIC |
+ MBEDTLS_ASN1_CONSTRUCTED |
+ MBEDTLS_X509_SAN_DIRECTORY_NAME));
+ break;
+ default:
+ /* Error out on an unsupported SAN */
+ ret = MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
+ goto cleanup;
+ }
+ cur = cur->next;
+ /* check for overflow */
+ if (len > SIZE_MAX - single_san_len) {
+ ret = MBEDTLS_ERR_X509_BAD_INPUT_DATA;
+ goto cleanup;
+ }
+ len += single_san_len;
+ }
+
+ MBEDTLS_ASN1_CHK_CLEANUP_ADD(len, mbedtls_asn1_write_len(&p, buf, len));
+ MBEDTLS_ASN1_CHK_CLEANUP_ADD(len,
+ mbedtls_asn1_write_tag(&p, buf,
+ MBEDTLS_ASN1_CONSTRUCTED |
+ MBEDTLS_ASN1_SEQUENCE));
+
+ ret = mbedtls_x509write_crt_set_extension(
+ ctx,
+ MBEDTLS_OID_SUBJECT_ALT_NAME,
+ MBEDTLS_OID_SIZE(MBEDTLS_OID_SUBJECT_ALT_NAME),
+ 0,
+ buf + buflen - len,
+ len);
+
+cleanup:
+ mbedtls_free(buf);
+ return ret;
+}
+
+
int mbedtls_x509write_crt_set_extension(mbedtls_x509write_cert *ctx,
const char *oid, size_t oid_len,
int critical,
@@ -426,7 +568,7 @@
unsigned char *c, *c2;
unsigned char sig[MBEDTLS_PK_SIGNATURE_MAX_SIZE];
size_t hash_length = 0;
- unsigned char hash[MBEDTLS_HASH_MAX_SIZE];
+ unsigned char hash[MBEDTLS_MD_MAX_SIZE];
#if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_algorithm_t psa_algorithm;
@@ -585,7 +727,7 @@
/* Compute hash of CRT. */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
- psa_algorithm = mbedtls_hash_info_psa_from_md(ctx->md_alg);
+ psa_algorithm = mbedtls_md_psa_alg_from_type(ctx->md_alg);
status = psa_hash_compute(psa_algorithm,
c,
diff --git a/library/x509write_csr.c b/library/x509write_csr.c
index deb6617..d792d34 100644
--- a/library/x509write_csr.c
+++ b/library/x509write_csr.c
@@ -36,8 +36,8 @@
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "psa/crypto.h"
#include "mbedtls/psa_util.h"
+#include "md_psa.h"
#endif /* MBEDTLS_USE_PSA_CRYPTO */
-#include "hash_info.h"
#include <string.h>
#include <stdlib.h>
@@ -243,13 +243,13 @@
const char *sig_oid;
size_t sig_oid_len = 0;
unsigned char *c, *c2;
- unsigned char hash[MBEDTLS_HASH_MAX_SIZE];
+ unsigned char hash[MBEDTLS_MD_MAX_SIZE];
size_t pub_len = 0, sig_and_oid_len = 0, sig_len;
size_t len = 0;
mbedtls_pk_type_t pk_alg;
#if defined(MBEDTLS_USE_PSA_CRYPTO)
size_t hash_len;
- psa_algorithm_t hash_alg = mbedtls_hash_info_psa_from_md(ctx->md_alg);
+ psa_algorithm_t hash_alg = mbedtls_md_psa_alg_from_type(ctx->md_alg);
#endif /* MBEDTLS_USE_PSA_CRYPTO */
/* Write the CSR backwards starting from the end of buf */