blob: d272dcbb1e04898a0cc9fa64b26ebbba3208f3b8 [file] [log] [blame]
Aditya Deshpande045b3702023-02-20 17:08:30 +00001/*
2 * Driver entry points for p256-m
3 */
4/*
5 * Copyright The Mbed TLS Contributors
Dave Rodgmanfffeae82023-11-03 09:28:10 +00006 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Aditya Deshpande045b3702023-02-20 17:08:30 +00007 */
8
Aditya Deshpandee41f7e42023-01-12 16:29:02 +00009#include "mbedtls/platform.h"
10#include "p256-m_driver_entrypoints.h"
11#include "p256-m/p256-m.h"
12#include "psa/crypto.h"
Aditya Deshpande7b9934d2023-04-18 17:00:17 +010013#include <stddef.h>
Manuel Pégourié-Gonnard5424cf22023-08-07 10:56:12 +020014#include <string.h>
Xiaokang Qianfe9666b2023-09-11 10:36:20 +000015#include "psa_crypto_driver_wrappers_no_static.h"
Aditya Deshpandee41f7e42023-01-12 16:29:02 +000016
Gilles Peskineefaee9a2023-09-20 20:49:47 +020017#if defined(MBEDTLS_PSA_P256M_DRIVER_ENABLED)
Aditya Deshpandee41f7e42023-01-12 16:29:02 +000018
Aditya Deshpande641cb892023-04-19 03:31:10 +010019/* INFORMATION ON PSA KEY EXPORT FORMATS:
20 *
21 * PSA exports SECP256R1 keys in two formats:
22 * 1. Keypair format: 32 byte string which is just the private key (public key
23 * can be calculated from the private key)
24 * 2. Public Key format: A leading byte 0x04 (indicating uncompressed format),
25 * followed by the 64 byte public key. This results in a
26 * total of 65 bytes.
27 *
28 * p256-m's internal format for private keys matches PSA. Its format for public
Manuel Pégourié-Gonnard5ca69342023-09-20 09:28:02 +020029 * keys is only 64 bytes: the same as PSA but without the leading byte (0x04).
Aditya Deshpande641cb892023-04-19 03:31:10 +010030 * Hence, when passing public keys from PSA to p256-m, the leading byte is
31 * removed.
Manuel Pégourié-Gonnardba63e0c2023-08-09 11:53:09 +020032 *
33 * Shared secret and signature have the same format between PSA and p256-m.
Aditya Deshpande641cb892023-04-19 03:31:10 +010034 */
Manuel Pégourié-Gonnardba63e0c2023-08-09 11:53:09 +020035#define PSA_PUBKEY_SIZE 65
36#define PSA_PUBKEY_HEADER_BYTE 0x04
37#define P256_PUBKEY_SIZE 64
38#define PRIVKEY_SIZE 32
39#define SHARED_SECRET_SIZE 32
40#define SIGNATURE_SIZE 64
41
42#define CURVE_BITS 256
Aditya Deshpande641cb892023-04-19 03:31:10 +010043
44/* Convert between p256-m and PSA error codes */
45static psa_status_t p256_to_psa_error(int ret)
Aditya Deshpandee41f7e42023-01-12 16:29:02 +000046{
Aditya Deshpandeac363d82023-03-21 18:56:31 +000047 switch (ret) {
Aditya Deshpandee41f7e42023-01-12 16:29:02 +000048 case P256_SUCCESS:
Aditya Deshpandeac363d82023-03-21 18:56:31 +000049 return PSA_SUCCESS;
Aditya Deshpandee41f7e42023-01-12 16:29:02 +000050 case P256_INVALID_PUBKEY:
51 case P256_INVALID_PRIVKEY:
Aditya Deshpandeac363d82023-03-21 18:56:31 +000052 return PSA_ERROR_INVALID_ARGUMENT;
Aditya Deshpandee41f7e42023-01-12 16:29:02 +000053 case P256_INVALID_SIGNATURE:
Aditya Deshpandeac363d82023-03-21 18:56:31 +000054 return PSA_ERROR_INVALID_SIGNATURE;
Aditya Deshpandee41f7e42023-01-12 16:29:02 +000055 case P256_RANDOM_FAILED:
56 default:
Aditya Deshpandeac363d82023-03-21 18:56:31 +000057 return PSA_ERROR_GENERIC_ERROR;
Aditya Deshpandee41f7e42023-01-12 16:29:02 +000058 }
59}
60
Manuel Pégourié-Gonnard5424cf22023-08-07 10:56:12 +020061psa_status_t p256_transparent_import_key(const psa_key_attributes_t *attributes,
62 const uint8_t *data,
63 size_t data_length,
64 uint8_t *key_buffer,
65 size_t key_buffer_size,
66 size_t *key_buffer_length,
67 size_t *bits)
68{
69 /* Check the key size */
Manuel Pégourié-Gonnardba63e0c2023-08-09 11:53:09 +020070 if (*bits != 0 && *bits != CURVE_BITS) {
Manuel Pégourié-Gonnard5424cf22023-08-07 10:56:12 +020071 return PSA_ERROR_NOT_SUPPORTED;
72 }
73
74 /* Validate the key (and its type and size) */
75 psa_key_type_t type = psa_get_key_type(attributes);
76 if (type == PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1)) {
Manuel Pégourié-Gonnardba63e0c2023-08-09 11:53:09 +020077 if (data_length != PSA_PUBKEY_SIZE) {
Manuel Pégourié-Gonnard5424cf22023-08-07 10:56:12 +020078 return *bits == 0 ? PSA_ERROR_NOT_SUPPORTED : PSA_ERROR_INVALID_ARGUMENT;
79 }
Manuel Pégourié-Gonnard5ca69342023-09-20 09:28:02 +020080 /* See INFORMATION ON PSA KEY EXPORT FORMATS near top of file */
Manuel Pégourié-Gonnard5424cf22023-08-07 10:56:12 +020081 if (p256_validate_pubkey(data + 1) != P256_SUCCESS) {
82 return PSA_ERROR_INVALID_ARGUMENT;
83 }
84 } else if (type == PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)) {
Manuel Pégourié-Gonnardba63e0c2023-08-09 11:53:09 +020085 if (data_length != PRIVKEY_SIZE) {
Manuel Pégourié-Gonnard5424cf22023-08-07 10:56:12 +020086 return *bits == 0 ? PSA_ERROR_NOT_SUPPORTED : PSA_ERROR_INVALID_ARGUMENT;
87 }
88 if (p256_validate_privkey(data) != P256_SUCCESS) {
89 return PSA_ERROR_INVALID_ARGUMENT;
90 }
91 } else {
92 return PSA_ERROR_NOT_SUPPORTED;
93 }
Manuel Pégourié-Gonnardba63e0c2023-08-09 11:53:09 +020094 *bits = CURVE_BITS;
Manuel Pégourié-Gonnard5424cf22023-08-07 10:56:12 +020095
96 /* We only support the export format for input, so just copy. */
97 if (key_buffer_size < data_length) {
98 return PSA_ERROR_BUFFER_TOO_SMALL;
99 }
100 memcpy(key_buffer, data, data_length);
101 *key_buffer_length = data_length;
102
103 return PSA_SUCCESS;
104}
105
Manuel Pégourié-Gonnard18d71422023-08-07 11:18:05 +0200106psa_status_t p256_transparent_export_public_key(const psa_key_attributes_t *attributes,
107 const uint8_t *key_buffer,
108 size_t key_buffer_size,
109 uint8_t *data,
110 size_t data_size,
111 size_t *data_length)
112{
113 /* Is this the right curve? */
114 size_t bits = psa_get_key_bits(attributes);
115 psa_key_type_t type = psa_get_key_type(attributes);
Manuel Pégourié-Gonnardba63e0c2023-08-09 11:53:09 +0200116 if (bits != CURVE_BITS || type != PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)) {
Manuel Pégourié-Gonnard18d71422023-08-07 11:18:05 +0200117 return PSA_ERROR_NOT_SUPPORTED;
118 }
119
Manuel Pégourié-Gonnardf0251e02023-08-08 12:23:42 +0200120 /* Validate sizes, as p256-m expects fixed-size buffers */
Manuel Pégourié-Gonnardba63e0c2023-08-09 11:53:09 +0200121 if (key_buffer_size != PRIVKEY_SIZE) {
Manuel Pégourié-Gonnardfbea9d22023-09-20 09:22:29 +0200122 return PSA_ERROR_INVALID_ARGUMENT;
Manuel Pégourié-Gonnard18d71422023-08-07 11:18:05 +0200123 }
Manuel Pégourié-Gonnardba63e0c2023-08-09 11:53:09 +0200124 if (data_size < PSA_PUBKEY_SIZE) {
Manuel Pégourié-Gonnard18d71422023-08-07 11:18:05 +0200125 return PSA_ERROR_BUFFER_TOO_SMALL;
126 }
127
Manuel Pégourié-Gonnard5ca69342023-09-20 09:28:02 +0200128 /* See INFORMATION ON PSA KEY EXPORT FORMATS near top of file */
Manuel Pégourié-Gonnardba63e0c2023-08-09 11:53:09 +0200129 data[0] = PSA_PUBKEY_HEADER_BYTE;
Manuel Pégourié-Gonnard18d71422023-08-07 11:18:05 +0200130 int ret = p256_public_from_private(data + 1, key_buffer);
Manuel Pégourié-Gonnardf0251e02023-08-08 12:23:42 +0200131 if (ret == P256_SUCCESS) {
Manuel Pégourié-Gonnardba63e0c2023-08-09 11:53:09 +0200132 *data_length = PSA_PUBKEY_SIZE;
Manuel Pégourié-Gonnard18d71422023-08-07 11:18:05 +0200133 }
Manuel Pégourié-Gonnard18d71422023-08-07 11:18:05 +0200134
Manuel Pégourié-Gonnardf0251e02023-08-08 12:23:42 +0200135 return p256_to_psa_error(ret);
Manuel Pégourié-Gonnard18d71422023-08-07 11:18:05 +0200136}
137
Aditya Deshpande695e44b2023-01-23 14:59:29 +0000138psa_status_t p256_transparent_generate_key(
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000139 const psa_key_attributes_t *attributes,
140 uint8_t *key_buffer,
141 size_t key_buffer_size,
Aditya Deshpandeac363d82023-03-21 18:56:31 +0000142 size_t *key_buffer_length)
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000143{
144 /* We don't use this argument, but the specification mandates the signature
145 * of driver entry-points. (void) used to avoid compiler warning. */
146 (void) attributes;
147
Manuel Pégourié-Gonnardf0251e02023-08-08 12:23:42 +0200148 /* Validate sizes, as p256-m expects fixed-size buffers */
Manuel Pégourié-Gonnardba63e0c2023-08-09 11:53:09 +0200149 if (key_buffer_size != PRIVKEY_SIZE) {
Manuel Pégourié-Gonnardf0251e02023-08-08 12:23:42 +0200150 return PSA_ERROR_BUFFER_TOO_SMALL;
Aditya Deshpandeac363d82023-03-21 18:56:31 +0000151 }
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000152
153 /*
154 * p256-m's keypair generation function outputs both public and private
155 * keys. Allocate a buffer to which the public key will be written. The
156 * private key will be written to key_buffer, which is passed to this
157 * function as an argument. */
Manuel Pégourié-Gonnardba63e0c2023-08-09 11:53:09 +0200158 uint8_t public_key_buffer[P256_PUBKEY_SIZE];
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000159
Manuel Pégourié-Gonnardf0251e02023-08-08 12:23:42 +0200160 int ret = p256_gen_keypair(key_buffer, public_key_buffer);
161 if (ret == P256_SUCCESS) {
Manuel Pégourié-Gonnardba63e0c2023-08-09 11:53:09 +0200162 *key_buffer_length = PRIVKEY_SIZE;
Aditya Deshpandeac363d82023-03-21 18:56:31 +0000163 }
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000164
Manuel Pégourié-Gonnardf0251e02023-08-08 12:23:42 +0200165 return p256_to_psa_error(ret);
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000166}
167
Aditya Deshpande695e44b2023-01-23 14:59:29 +0000168psa_status_t p256_transparent_key_agreement(
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000169 const psa_key_attributes_t *attributes,
170 const uint8_t *key_buffer,
171 size_t key_buffer_size,
172 psa_algorithm_t alg,
173 const uint8_t *peer_key,
174 size_t peer_key_length,
175 uint8_t *shared_secret,
176 size_t shared_secret_size,
Aditya Deshpandeac363d82023-03-21 18:56:31 +0000177 size_t *shared_secret_length)
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000178{
179 /* We don't use these arguments, but the specification mandates the
180 * sginature of driver entry-points. (void) used to avoid compiler
181 * warning. */
182 (void) attributes;
183 (void) alg;
184
Manuel Pégourié-Gonnardf0251e02023-08-08 12:23:42 +0200185 /* Validate sizes, as p256-m expects fixed-size buffers */
Manuel Pégourié-Gonnardba63e0c2023-08-09 11:53:09 +0200186 if (key_buffer_size != PRIVKEY_SIZE || peer_key_length != PSA_PUBKEY_SIZE) {
Manuel Pégourié-Gonnardf0251e02023-08-08 12:23:42 +0200187 return PSA_ERROR_INVALID_ARGUMENT;
188 }
Manuel Pégourié-Gonnardba63e0c2023-08-09 11:53:09 +0200189 if (shared_secret_size < SHARED_SECRET_SIZE) {
Manuel Pégourié-Gonnardf0251e02023-08-08 12:23:42 +0200190 return PSA_ERROR_BUFFER_TOO_SMALL;
Aditya Deshpandeac363d82023-03-21 18:56:31 +0000191 }
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000192
Manuel Pégourié-Gonnard5ca69342023-09-20 09:28:02 +0200193 /* See INFORMATION ON PSA KEY EXPORT FORMATS near top of file */
Manuel Pégourié-Gonnard3ec976c2023-09-20 16:12:46 +0200194 const uint8_t *peer_key_p256m = peer_key + 1;
Manuel Pégourié-Gonnard5ca69342023-09-20 09:28:02 +0200195 int ret = p256_ecdh_shared_secret(shared_secret, key_buffer, peer_key_p256m);
Manuel Pégourié-Gonnardf0251e02023-08-08 12:23:42 +0200196 if (ret == P256_SUCCESS) {
Manuel Pégourié-Gonnardba63e0c2023-08-09 11:53:09 +0200197 *shared_secret_length = SHARED_SECRET_SIZE;
Aditya Deshpandeac363d82023-03-21 18:56:31 +0000198 }
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000199
Manuel Pégourié-Gonnardf0251e02023-08-08 12:23:42 +0200200 return p256_to_psa_error(ret);
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000201}
202
Aditya Deshpande695e44b2023-01-23 14:59:29 +0000203psa_status_t p256_transparent_sign_hash(
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000204 const psa_key_attributes_t *attributes,
205 const uint8_t *key_buffer,
206 size_t key_buffer_size,
207 psa_algorithm_t alg,
208 const uint8_t *hash,
209 size_t hash_length,
210 uint8_t *signature,
211 size_t signature_size,
Aditya Deshpandeac363d82023-03-21 18:56:31 +0000212 size_t *signature_length)
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000213{
214 /* We don't use these arguments, but the specification mandates the
215 * sginature of driver entry-points. (void) used to avoid compiler
216 * warning. */
217 (void) attributes;
218 (void) alg;
219
Manuel Pégourié-Gonnardf0251e02023-08-08 12:23:42 +0200220 /* Validate sizes, as p256-m expects fixed-size buffers */
Manuel Pégourié-Gonnardba63e0c2023-08-09 11:53:09 +0200221 if (key_buffer_size != PRIVKEY_SIZE) {
Manuel Pégourié-Gonnardfbea9d22023-09-20 09:22:29 +0200222 return PSA_ERROR_INVALID_ARGUMENT;
Manuel Pégourié-Gonnardf0251e02023-08-08 12:23:42 +0200223 }
Manuel Pégourié-Gonnardba63e0c2023-08-09 11:53:09 +0200224 if (signature_size < SIGNATURE_SIZE) {
Manuel Pégourié-Gonnardf0251e02023-08-08 12:23:42 +0200225 return PSA_ERROR_BUFFER_TOO_SMALL;
Aditya Deshpandeac363d82023-03-21 18:56:31 +0000226 }
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000227
Manuel Pégourié-Gonnardf0251e02023-08-08 12:23:42 +0200228 int ret = p256_ecdsa_sign(signature, key_buffer, hash, hash_length);
229 if (ret == P256_SUCCESS) {
Manuel Pégourié-Gonnardba63e0c2023-08-09 11:53:09 +0200230 *signature_length = SIGNATURE_SIZE;
Aditya Deshpandeac363d82023-03-21 18:56:31 +0000231 }
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000232
Manuel Pégourié-Gonnardf0251e02023-08-08 12:23:42 +0200233 return p256_to_psa_error(ret);
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000234}
235
Manuel Pégourié-Gonnardba63e0c2023-08-09 11:53:09 +0200236/* This function expects the key buffer to contain a PSA public key,
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000237 * as exported by psa_export_public_key() */
Aditya Deshpande695e44b2023-01-23 14:59:29 +0000238static psa_status_t p256_verify_hash_with_public_key(
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000239 const uint8_t *key_buffer,
240 size_t key_buffer_size,
241 const uint8_t *hash,
242 size_t hash_length,
243 const uint8_t *signature,
Aditya Deshpandeac363d82023-03-21 18:56:31 +0000244 size_t signature_length)
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000245{
Manuel Pégourié-Gonnardf0251e02023-08-08 12:23:42 +0200246 /* Validate sizes, as p256-m expects fixed-size buffers */
Manuel Pégourié-Gonnardba63e0c2023-08-09 11:53:09 +0200247 if (key_buffer_size != PSA_PUBKEY_SIZE || *key_buffer != PSA_PUBKEY_HEADER_BYTE) {
Manuel Pégourié-Gonnardfbea9d22023-09-20 09:22:29 +0200248 return PSA_ERROR_INVALID_ARGUMENT;
Manuel Pégourié-Gonnardf0251e02023-08-08 12:23:42 +0200249 }
Manuel Pégourié-Gonnardba63e0c2023-08-09 11:53:09 +0200250 if (signature_length != SIGNATURE_SIZE) {
Manuel Pégourié-Gonnardf0251e02023-08-08 12:23:42 +0200251 return PSA_ERROR_INVALID_SIGNATURE;
Aditya Deshpandeac363d82023-03-21 18:56:31 +0000252 }
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000253
Manuel Pégourié-Gonnard5ca69342023-09-20 09:28:02 +0200254 /* See INFORMATION ON PSA KEY EXPORT FORMATS near top of file */
255 const uint8_t *public_key_p256m = key_buffer + 1;
256 int ret = p256_ecdsa_verify(signature, public_key_p256m, hash, hash_length);
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000257
Manuel Pégourié-Gonnardf0251e02023-08-08 12:23:42 +0200258 return p256_to_psa_error(ret);
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000259}
260
Aditya Deshpande695e44b2023-01-23 14:59:29 +0000261psa_status_t p256_transparent_verify_hash(
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000262 const psa_key_attributes_t *attributes,
263 const uint8_t *key_buffer,
264 size_t key_buffer_size,
265 psa_algorithm_t alg,
266 const uint8_t *hash,
267 size_t hash_length,
268 const uint8_t *signature,
Aditya Deshpandeac363d82023-03-21 18:56:31 +0000269 size_t signature_length)
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000270{
271 /* We don't use this argument, but the specification mandates the signature
272 * of driver entry-points. (void) used to avoid compiler warning. */
273 (void) alg;
274
275 psa_status_t status;
Manuel Pégourié-Gonnardba63e0c2023-08-09 11:53:09 +0200276 uint8_t public_key_buffer[PSA_PUBKEY_SIZE];
277 size_t public_key_buffer_size = PSA_PUBKEY_SIZE;
Aditya Deshpande7b9934d2023-04-18 17:00:17 +0100278
Manuel Pégourié-Gonnardba63e0c2023-08-09 11:53:09 +0200279 size_t public_key_length = PSA_PUBKEY_SIZE;
Aditya Deshpande7b9934d2023-04-18 17:00:17 +0100280 /* As p256-m doesn't require dynamic allocation, we want to avoid it in
281 * the entrypoint functions as well. psa_driver_wrapper_export_public_key()
282 * requires size_t*, so we use a pointer to a stack variable. */
283 size_t *public_key_length_ptr = &public_key_length;
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000284
Aditya Deshpande641cb892023-04-19 03:31:10 +0100285 /* The contents of key_buffer may either be the 32 byte private key
286 * (keypair format), or 0x04 followed by the 64 byte public key (public
287 * key format). To ensure the key is in the latter format, the public key
288 * is exported. */
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000289 status = psa_driver_wrapper_export_public_key(
Aditya Deshpandeac363d82023-03-21 18:56:31 +0000290 attributes,
291 key_buffer,
292 key_buffer_size,
293 public_key_buffer,
294 public_key_buffer_size,
Aditya Deshpande7b9934d2023-04-18 17:00:17 +0100295 public_key_length_ptr);
Aditya Deshpandeac363d82023-03-21 18:56:31 +0000296 if (status != PSA_SUCCESS) {
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000297 goto exit;
Aditya Deshpandeac363d82023-03-21 18:56:31 +0000298 }
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000299
Aditya Deshpande695e44b2023-01-23 14:59:29 +0000300 status = p256_verify_hash_with_public_key(
Aditya Deshpandeac363d82023-03-21 18:56:31 +0000301 public_key_buffer,
302 public_key_buffer_size,
303 hash,
304 hash_length,
305 signature,
306 signature_length);
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000307
308exit:
Aditya Deshpandeac363d82023-03-21 18:56:31 +0000309 return status;
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000310}
311
Gilles Peskineefaee9a2023-09-20 20:49:47 +0200312#endif /* MBEDTLS_PSA_P256M_DRIVER_ENABLED */