Add key management utilities to p256-m
Those will be needed in order for the driver to implement all the PSA
key management entry points (currently only implements key generation).
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
diff --git a/3rdparty/p256-m/p256-m/p256-m.c b/3rdparty/p256-m/p256-m/p256-m.c
index 53d306f..de550cf 100644
--- a/3rdparty/p256-m/p256-m/p256-m.c
+++ b/3rdparty/p256-m/p256-m/p256-m.c
@@ -1468,4 +1468,49 @@
return P256_INVALID_SIGNATURE;
}
+/**********************************************************************
+ *
+ * Key management utilities
+ *
+ **********************************************************************/
+
+int p256_validate_pubkey(const uint8_t pub[64])
+{
+ uint32_t x[8], y[8];
+ int ret = point_from_bytes(x, y, pub);
+
+ return ret == 0 ? P256_SUCCESS : P256_INVALID_PUBKEY;
+}
+
+int p256_validate_privkey(const uint8_t priv[32])
+{
+ uint32_t s[8];
+ int ret = scalar_from_bytes(s, priv);
+ zeroize(s, sizeof(s));
+
+ return ret == 0 ? P256_SUCCESS : P256_INVALID_PRIVKEY;
+}
+
+int p256_public_from_private(uint8_t pub[64], const uint8_t priv[32])
+{
+ int ret;
+ uint32_t s[8];
+
+ ret = scalar_from_bytes(s, priv);
+ if (ret != 0)
+ return P256_INVALID_PRIVKEY;
+
+ /* compute and ouput the associated public key */
+ uint32_t x[8], y[8];
+ scalar_mult(x, y, p256_gx, p256_gy, s);
+
+ /* the associated public key is not a secret, the scalar was */
+ CT_UNPOISON(x, 32);
+ CT_UNPOISON(y, 32);
+ zeroize(s, sizeof(s));
+
+ point_to_bytes(pub, x, y);
+ return P256_SUCCESS;
+}
+
#endif
diff --git a/3rdparty/p256-m/p256-m/p256-m.h b/3rdparty/p256-m/p256-m/p256-m.h
index 398c846..d4b053a 100644
--- a/3rdparty/p256-m/p256-m/p256-m.h
+++ b/3rdparty/p256-m/p256-m/p256-m.h
@@ -89,6 +89,45 @@
int p256_ecdsa_verify(const uint8_t sig[64], const uint8_t pub[64],
const uint8_t *hash, size_t hlen);
+/*
+ * Public key validation
+ *
+ * Note: you never need to call this function, as all other function always
+ * validate their input; however it's availabe if you want to validate the key
+ * without performing an operation.
+ *
+ * [in] pub: the public key, as two big-endian integers
+ *
+ * return: P256_SUCCESS if the key is valid
+ * P256_INVALID_PUBKEY if pub is invalid
+ */
+int p256_validate_pubkey(const uint8_t pub[64]);
+
+/*
+ * Private key validation
+ *
+ * Note: you never need to call this function, as all other function always
+ * validate their input; however it's availabe if you want to validate the key
+ * without performing an operation.
+ *
+ * [in] priv: the private key, as a big-endian integer
+ *
+ * return: P256_SUCCESS if the key is valid
+ * P256_INVALID_PRIVKEY if priv is invalid
+ */
+int p256_validate_privkey(const uint8_t priv[32]);
+
+/*
+ * Compute public key from private key
+ *
+ * [out] pub: the associated public key, as two big-endian integers
+ * [in] priv: the private key, as a big-endian integer
+ *
+ * return: P256_SUCCESS on success
+ * P256_INVALID_PRIVKEY if priv is invalid
+ */
+int p256_public_from_private(uint8_t pub[64], const uint8_t priv[32]);
+
#ifdef __cplusplus
}
#endif