blob: 4324858378d2b2a7ae718d8f3e79b6b21d46ccce [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
6 * SPDX-License-Identifier: Apache-2.0
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License"); you may
9 * not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
Aditya Deshpandee41f7e42023-01-12 16:29:02 +000021#include "mbedtls/platform.h"
22#include "p256-m_driver_entrypoints.h"
23#include "p256-m/p256-m.h"
24#include "psa/crypto.h"
25#include "psa_crypto_driver_wrappers.h"
26
27#if defined(MBEDTLS_P256M_EXAMPLE_DRIVER_ENABLED)
28
Aditya Deshpandeac363d82023-03-21 18:56:31 +000029psa_status_t p256_to_psa_error(int ret)
Aditya Deshpandee41f7e42023-01-12 16:29:02 +000030{
Aditya Deshpandeac363d82023-03-21 18:56:31 +000031 switch (ret) {
Aditya Deshpandee41f7e42023-01-12 16:29:02 +000032 case P256_SUCCESS:
Aditya Deshpandeac363d82023-03-21 18:56:31 +000033 return PSA_SUCCESS;
Aditya Deshpandee41f7e42023-01-12 16:29:02 +000034 case P256_INVALID_PUBKEY:
35 case P256_INVALID_PRIVKEY:
Aditya Deshpandeac363d82023-03-21 18:56:31 +000036 return PSA_ERROR_INVALID_ARGUMENT;
Aditya Deshpandee41f7e42023-01-12 16:29:02 +000037 case P256_INVALID_SIGNATURE:
Aditya Deshpandeac363d82023-03-21 18:56:31 +000038 return PSA_ERROR_INVALID_SIGNATURE;
Aditya Deshpandee41f7e42023-01-12 16:29:02 +000039 case P256_RANDOM_FAILED:
40 default:
Aditya Deshpandeac363d82023-03-21 18:56:31 +000041 return PSA_ERROR_GENERIC_ERROR;
Aditya Deshpandee41f7e42023-01-12 16:29:02 +000042 }
43}
44
Aditya Deshpande695e44b2023-01-23 14:59:29 +000045psa_status_t p256_transparent_generate_key(
Aditya Deshpandee41f7e42023-01-12 16:29:02 +000046 const psa_key_attributes_t *attributes,
47 uint8_t *key_buffer,
48 size_t key_buffer_size,
Aditya Deshpandeac363d82023-03-21 18:56:31 +000049 size_t *key_buffer_length)
Aditya Deshpandee41f7e42023-01-12 16:29:02 +000050{
51 /* We don't use this argument, but the specification mandates the signature
52 * of driver entry-points. (void) used to avoid compiler warning. */
53 (void) attributes;
54
55 psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
56
57 /*
58 * p256-m generates a 32 byte private key, and expects to write to a buffer
59 * that is of that size. */
Aditya Deshpandeac363d82023-03-21 18:56:31 +000060 if (key_buffer_size != 32) {
61 return status;
62 }
Aditya Deshpandee41f7e42023-01-12 16:29:02 +000063
64 /*
65 * p256-m's keypair generation function outputs both public and private
66 * keys. Allocate a buffer to which the public key will be written. The
67 * private key will be written to key_buffer, which is passed to this
68 * function as an argument. */
69 uint8_t *public_key_buffer = NULL;
Aditya Deshpandeac363d82023-03-21 18:56:31 +000070 public_key_buffer = mbedtls_calloc(1, 64);
71 if (public_key_buffer == NULL) {
72 return PSA_ERROR_INSUFFICIENT_MEMORY;
73 }
Aditya Deshpandee41f7e42023-01-12 16:29:02 +000074
Aditya Deshpande695e44b2023-01-23 14:59:29 +000075 status = p256_to_psa_error(
Aditya Deshpandeac363d82023-03-21 18:56:31 +000076 p256_gen_keypair(key_buffer, public_key_buffer));
77 if (status == PSA_SUCCESS) {
Aditya Deshpandee41f7e42023-01-12 16:29:02 +000078 *key_buffer_length = 32;
Aditya Deshpandeac363d82023-03-21 18:56:31 +000079 }
Aditya Deshpandee41f7e42023-01-12 16:29:02 +000080
81 /*
82 * The storage format for a SECP256R1 keypair is just the private key, so
83 * the public key does not need to be passed back to the caller. Therefore
84 * the buffer containing it can be freed. */
Aditya Deshpandeac363d82023-03-21 18:56:31 +000085 free(public_key_buffer);
Aditya Deshpandee41f7e42023-01-12 16:29:02 +000086
87 return status;
88}
89
Aditya Deshpande695e44b2023-01-23 14:59:29 +000090psa_status_t p256_transparent_key_agreement(
Aditya Deshpandee41f7e42023-01-12 16:29:02 +000091 const psa_key_attributes_t *attributes,
92 const uint8_t *key_buffer,
93 size_t key_buffer_size,
94 psa_algorithm_t alg,
95 const uint8_t *peer_key,
96 size_t peer_key_length,
97 uint8_t *shared_secret,
98 size_t shared_secret_size,
Aditya Deshpandeac363d82023-03-21 18:56:31 +000099 size_t *shared_secret_length)
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000100{
101 /* We don't use these arguments, but the specification mandates the
102 * sginature of driver entry-points. (void) used to avoid compiler
103 * warning. */
104 (void) attributes;
105 (void) alg;
106
107 /*
108 * Check that private key = 32 bytes, peer public key = 65 bytes,
109 * and that the shared secret buffer is big enough. */
110 psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
Aditya Deshpandeac363d82023-03-21 18:56:31 +0000111 if (key_buffer_size != 32 || shared_secret_size < 32 ||
112 peer_key_length != 65) {
113 return status;
114 }
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000115
Aditya Deshpande695e44b2023-01-23 14:59:29 +0000116 status = p256_to_psa_error(
Aditya Deshpandeac363d82023-03-21 18:56:31 +0000117 p256_ecdh_shared_secret(shared_secret, key_buffer, peer_key+1));
118 if (status == PSA_SUCCESS) {
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000119 *shared_secret_length = 32;
Aditya Deshpandeac363d82023-03-21 18:56:31 +0000120 }
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000121
122 return status;
123}
124
Aditya Deshpande695e44b2023-01-23 14:59:29 +0000125psa_status_t p256_transparent_sign_hash(
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000126 const psa_key_attributes_t *attributes,
127 const uint8_t *key_buffer,
128 size_t key_buffer_size,
129 psa_algorithm_t alg,
130 const uint8_t *hash,
131 size_t hash_length,
132 uint8_t *signature,
133 size_t signature_size,
Aditya Deshpandeac363d82023-03-21 18:56:31 +0000134 size_t *signature_length)
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000135{
136 /* We don't use these arguments, but the specification mandates the
137 * sginature of driver entry-points. (void) used to avoid compiler
138 * warning. */
139 (void) attributes;
140 (void) alg;
141
142 psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
Aditya Deshpandeac363d82023-03-21 18:56:31 +0000143 if (key_buffer_size != 32 || signature_size != 64) {
144 return status;
145 }
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000146
Aditya Deshpande695e44b2023-01-23 14:59:29 +0000147 status = p256_to_psa_error(
Aditya Deshpandeac363d82023-03-21 18:56:31 +0000148 p256_ecdsa_sign(signature, key_buffer, hash, hash_length));
149 if (status == PSA_SUCCESS) {
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000150 *signature_length = 64;
Aditya Deshpandeac363d82023-03-21 18:56:31 +0000151 }
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000152
153 return status;
154}
155
156/* This function expects the key buffer to contain a 65 byte public key,
157 * as exported by psa_export_public_key() */
Aditya Deshpande695e44b2023-01-23 14:59:29 +0000158static psa_status_t p256_verify_hash_with_public_key(
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000159 const uint8_t *key_buffer,
160 size_t key_buffer_size,
161 const uint8_t *hash,
162 size_t hash_length,
163 const uint8_t *signature,
Aditya Deshpandeac363d82023-03-21 18:56:31 +0000164 size_t signature_length)
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000165{
166 psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
Aditya Deshpandeac363d82023-03-21 18:56:31 +0000167 if (key_buffer_size != 65 || signature_length != 64 || *key_buffer != 0x04) {
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000168 return status;
Aditya Deshpandeac363d82023-03-21 18:56:31 +0000169 }
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000170
171 const uint8_t *public_key_buffer = key_buffer + 1;
Aditya Deshpande695e44b2023-01-23 14:59:29 +0000172 status = p256_to_psa_error(
Aditya Deshpandeac363d82023-03-21 18:56:31 +0000173 p256_ecdsa_verify(signature, public_key_buffer, hash, hash_length));
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000174
175 return status;
176}
177
Aditya Deshpande695e44b2023-01-23 14:59:29 +0000178psa_status_t p256_transparent_verify_hash(
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000179 const psa_key_attributes_t *attributes,
180 const uint8_t *key_buffer,
181 size_t key_buffer_size,
182 psa_algorithm_t alg,
183 const uint8_t *hash,
184 size_t hash_length,
185 const uint8_t *signature,
Aditya Deshpandeac363d82023-03-21 18:56:31 +0000186 size_t signature_length)
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000187{
188 /* We don't use this argument, but the specification mandates the signature
189 * of driver entry-points. (void) used to avoid compiler warning. */
190 (void) alg;
191
192 psa_status_t status;
193 uint8_t *public_key_buffer = NULL;
194 size_t public_key_buffer_size = 65;
Aditya Deshpandeac363d82023-03-21 18:56:31 +0000195 public_key_buffer = mbedtls_calloc(1, public_key_buffer_size);
196 if (public_key_buffer == NULL) {
197 return PSA_ERROR_INSUFFICIENT_MEMORY;
198 }
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000199 size_t *public_key_length = NULL;
Aditya Deshpandeac363d82023-03-21 18:56:31 +0000200 public_key_length = mbedtls_calloc(1, sizeof(size_t));
201 if (public_key_length == NULL) {
202 return PSA_ERROR_INSUFFICIENT_MEMORY;
203 }
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000204 *public_key_length = 65;
205
206 /* The contents of key_buffer may either be the 32 byte private key
207 * (keypair representation), or the 65 byte public key. To ensure the
208 * latter is obtained, the public key is exported. */
209 status = psa_driver_wrapper_export_public_key(
Aditya Deshpandeac363d82023-03-21 18:56:31 +0000210 attributes,
211 key_buffer,
212 key_buffer_size,
213 public_key_buffer,
214 public_key_buffer_size,
215 public_key_length);
216 if (status != PSA_SUCCESS) {
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000217 goto exit;
Aditya Deshpandeac363d82023-03-21 18:56:31 +0000218 }
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000219
Aditya Deshpande695e44b2023-01-23 14:59:29 +0000220 status = p256_verify_hash_with_public_key(
Aditya Deshpandeac363d82023-03-21 18:56:31 +0000221 public_key_buffer,
222 public_key_buffer_size,
223 hash,
224 hash_length,
225 signature,
226 signature_length);
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000227
228exit:
Aditya Deshpandeac363d82023-03-21 18:56:31 +0000229 free(public_key_buffer);
230 free(public_key_length);
231 return status;
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000232}
233
234#endif /* MBEDTLS_P256M_EXAMPLE_DRIVER_ENABLED */