blob: c2e6286a966ade9f84114bc10611fafe523ec3dc [file] [log] [blame]
Aditya Deshpandee41f7e42023-01-12 16:29:02 +00001#include "mbedtls/platform.h"
2#include "p256-m_driver_entrypoints.h"
3#include "p256-m/p256-m.h"
4#include "psa/crypto.h"
5#include "psa_crypto_driver_wrappers.h"
6
7#if defined(MBEDTLS_P256M_EXAMPLE_DRIVER_ENABLED)
8
Aditya Deshpande695e44b2023-01-23 14:59:29 +00009psa_status_t p256_to_psa_error( int ret )
Aditya Deshpandee41f7e42023-01-12 16:29:02 +000010{
11 switch( ret )
12 {
13 case P256_SUCCESS:
14 return( PSA_SUCCESS );
15 case P256_INVALID_PUBKEY:
16 case P256_INVALID_PRIVKEY:
17 return( PSA_ERROR_INVALID_ARGUMENT );
18 case P256_INVALID_SIGNATURE:
19 return( PSA_ERROR_INVALID_SIGNATURE );
20 case P256_RANDOM_FAILED:
21 default:
22 return( PSA_ERROR_GENERIC_ERROR );
23 }
24}
25
Aditya Deshpande695e44b2023-01-23 14:59:29 +000026psa_status_t p256_transparent_generate_key(
Aditya Deshpandee41f7e42023-01-12 16:29:02 +000027 const psa_key_attributes_t *attributes,
28 uint8_t *key_buffer,
29 size_t key_buffer_size,
30 size_t *key_buffer_length )
31{
32 /* We don't use this argument, but the specification mandates the signature
33 * of driver entry-points. (void) used to avoid compiler warning. */
34 (void) attributes;
35
36 psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
37
38 /*
39 * p256-m generates a 32 byte private key, and expects to write to a buffer
40 * that is of that size. */
41 if( key_buffer_size != 32 )
42 return( status );
43
44 /*
45 * p256-m's keypair generation function outputs both public and private
46 * keys. Allocate a buffer to which the public key will be written. The
47 * private key will be written to key_buffer, which is passed to this
48 * function as an argument. */
49 uint8_t *public_key_buffer = NULL;
50 public_key_buffer = mbedtls_calloc( 1, 64);
51 if( public_key_buffer == NULL)
52 return( PSA_ERROR_INSUFFICIENT_MEMORY );
53
Aditya Deshpande695e44b2023-01-23 14:59:29 +000054 status = p256_to_psa_error(
Aditya Deshpandee41f7e42023-01-12 16:29:02 +000055 p256_gen_keypair(key_buffer, public_key_buffer) );
56 if( status == PSA_SUCCESS )
57 *key_buffer_length = 32;
58
59 /*
60 * The storage format for a SECP256R1 keypair is just the private key, so
61 * the public key does not need to be passed back to the caller. Therefore
62 * the buffer containing it can be freed. */
63 free( public_key_buffer );
64
65 return status;
66}
67
Aditya Deshpande695e44b2023-01-23 14:59:29 +000068psa_status_t p256_transparent_key_agreement(
Aditya Deshpandee41f7e42023-01-12 16:29:02 +000069 const psa_key_attributes_t *attributes,
70 const uint8_t *key_buffer,
71 size_t key_buffer_size,
72 psa_algorithm_t alg,
73 const uint8_t *peer_key,
74 size_t peer_key_length,
75 uint8_t *shared_secret,
76 size_t shared_secret_size,
77 size_t *shared_secret_length )
78{
79 /* We don't use these arguments, but the specification mandates the
80 * sginature of driver entry-points. (void) used to avoid compiler
81 * warning. */
82 (void) attributes;
83 (void) alg;
84
85 /*
86 * Check that private key = 32 bytes, peer public key = 65 bytes,
87 * and that the shared secret buffer is big enough. */
88 psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
89 if( key_buffer_size != 32 || shared_secret_size < 32 ||
90 peer_key_length != 65 )
91 return ( status );
92
Aditya Deshpande695e44b2023-01-23 14:59:29 +000093 status = p256_to_psa_error(
Aditya Deshpandee41f7e42023-01-12 16:29:02 +000094 p256_ecdh_shared_secret(shared_secret, key_buffer, peer_key+1) );
95 if( status == PSA_SUCCESS )
96 *shared_secret_length = 32;
97
98 return status;
99}
100
Aditya Deshpande695e44b2023-01-23 14:59:29 +0000101psa_status_t p256_transparent_sign_hash(
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000102 const psa_key_attributes_t *attributes,
103 const uint8_t *key_buffer,
104 size_t key_buffer_size,
105 psa_algorithm_t alg,
106 const uint8_t *hash,
107 size_t hash_length,
108 uint8_t *signature,
109 size_t signature_size,
110 size_t *signature_length )
111{
112 /* We don't use these arguments, but the specification mandates the
113 * sginature of driver entry-points. (void) used to avoid compiler
114 * warning. */
115 (void) attributes;
116 (void) alg;
117
118 psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
119 if( key_buffer_size != 32 || signature_size != 64)
120 return( status );
121
Aditya Deshpande695e44b2023-01-23 14:59:29 +0000122 status = p256_to_psa_error(
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000123 p256_ecdsa_sign(signature, key_buffer, hash, hash_length) );
124 if( status == PSA_SUCCESS )
125 *signature_length = 64;
126
127 return status;
128}
129
130/* This function expects the key buffer to contain a 65 byte public key,
131 * as exported by psa_export_public_key() */
Aditya Deshpande695e44b2023-01-23 14:59:29 +0000132static psa_status_t p256_verify_hash_with_public_key(
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000133 const uint8_t *key_buffer,
134 size_t key_buffer_size,
135 const uint8_t *hash,
136 size_t hash_length,
137 const uint8_t *signature,
138 size_t signature_length )
139{
140 psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
141 if( key_buffer_size != 65 || signature_length != 64 || *key_buffer != 0x04 )
142 return status;
143
144 const uint8_t *public_key_buffer = key_buffer + 1;
Aditya Deshpande695e44b2023-01-23 14:59:29 +0000145 status = p256_to_psa_error(
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000146 p256_ecdsa_verify( signature, public_key_buffer, hash, hash_length) );
147
148 return status;
149}
150
Aditya Deshpande695e44b2023-01-23 14:59:29 +0000151psa_status_t p256_transparent_verify_hash(
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000152 const psa_key_attributes_t *attributes,
153 const uint8_t *key_buffer,
154 size_t key_buffer_size,
155 psa_algorithm_t alg,
156 const uint8_t *hash,
157 size_t hash_length,
158 const uint8_t *signature,
159 size_t signature_length )
160{
161 /* We don't use this argument, but the specification mandates the signature
162 * of driver entry-points. (void) used to avoid compiler warning. */
163 (void) alg;
164
165 psa_status_t status;
166 uint8_t *public_key_buffer = NULL;
167 size_t public_key_buffer_size = 65;
168 public_key_buffer = mbedtls_calloc( 1, public_key_buffer_size);
169 if( public_key_buffer == NULL)
170 return( PSA_ERROR_INSUFFICIENT_MEMORY );
171 size_t *public_key_length = NULL;
172 public_key_length = mbedtls_calloc( 1, sizeof(size_t) );
173 if( public_key_length == NULL)
174 return( PSA_ERROR_INSUFFICIENT_MEMORY );
175 *public_key_length = 65;
176
177 /* The contents of key_buffer may either be the 32 byte private key
178 * (keypair representation), or the 65 byte public key. To ensure the
179 * latter is obtained, the public key is exported. */
180 status = psa_driver_wrapper_export_public_key(
181 attributes,
182 key_buffer,
183 key_buffer_size,
184 public_key_buffer,
185 public_key_buffer_size,
186 public_key_length );
187 if( status != PSA_SUCCESS )
188 goto exit;
189
Aditya Deshpande695e44b2023-01-23 14:59:29 +0000190 status = p256_verify_hash_with_public_key(
Aditya Deshpandee41f7e42023-01-12 16:29:02 +0000191 public_key_buffer,
192 public_key_buffer_size,
193 hash,
194 hash_length,
195 signature,
196 signature_length );
197
198exit:
199 free( public_key_buffer );
200 free( public_key_length );
201 return ( status );
202}
203
204#endif /* MBEDTLS_P256M_EXAMPLE_DRIVER_ENABLED */