Skip to content

Commit 2357786

Browse files
committed
crypto: Add PSA driver for key management using CryptoCell
-This adds a source-code version of PSA crypto driver for use by nrf_cc3xx library. This driver allows optimized build by filtering according to any of these enabled features: - ECC using Weierstrass curves - ECC using Curve25519 (Montgomery or Twisted Edwards) - RSA -This driver support generate, import and export public key Note: Provided as a single commit for easier review. Usage requires nrfxlib update and a new version of nrf_cc3xx (v0.9.21) Signed-off-by: Frank Audun Kvamtrø <frank.kvamtro@nordicsemi.no>
1 parent 8ac49f2 commit 2357786

1 file changed

Lines changed: 381 additions & 0 deletions

File tree

Lines changed: 381 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,381 @@
1+
/*
2+
* Copyright (c) 2021, Arm Limited. All rights reserved.
3+
* Copyright (c) 2026 Nordic Semiconductor ASA.
4+
*
5+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
6+
*
7+
*/
8+
9+
/** \file cc3xx_psa_key_generation.c
10+
*
11+
* This file contains the implementation of the entry points associated to the
12+
* key generation (i.e. random generation and extraction of public keys) as
13+
* described by the PSA Cryptoprocessor Driver interface specification
14+
*
15+
*/
16+
#include <psa/crypto.h>
17+
#include <stdint.h>
18+
#include <stdbool.h>
19+
#include <string.h>
20+
#include <cc3xx_psa_key_generation.h>
21+
#include <cc3xx_asn1_util.h>
22+
#include <cc3xx_psa_rsa_util.h>
23+
#include <zephyr/sys/util.h>
24+
25+
26+
#if defined(PSA_NEED_CC3XX_ECDSA) || defined(PSA_NEED_CC3XX_ECDH_WEIERSTRASS)
27+
#define PSA_NEED_CC3XX_ECC_WEIERSTRASS 1
28+
#endif
29+
30+
static size_t calculate_rsa_key_size(const uint8_t *key_data, size_t key_data_len, bool is_keypair)
31+
{
32+
int ret;
33+
uint8_t **key_start_pnt = (unsigned char **)&key_data;
34+
uint8_t *key_end_pnt = (unsigned char *)key_data + key_data_len;
35+
size_t len;
36+
37+
/* Move the pointer after the sequence */
38+
ret = cc3xx_asn1_get_tag(key_start_pnt, key_end_pnt, &len,
39+
0x20 | /* Constructed */
40+
0x10); /* Sequence */
41+
if (ret < 0) {
42+
return 0;
43+
}
44+
45+
if (is_keypair) {
46+
/* The key pair has a version number as an integer */
47+
ret = cc3xx_asn1_get_tag(key_start_pnt, key_end_pnt, &len, 0x2); /* Integer */
48+
if (ret < 0) {
49+
return 0;
50+
}
51+
52+
*key_start_pnt += len;
53+
}
54+
55+
/* Get the modulus n */
56+
ret = cc3xx_asn1_get_tag(key_start_pnt, key_end_pnt, &len, 0x2); /* Integer */
57+
if (ret < 0) {
58+
return 0;
59+
}
60+
61+
if (*key_start_pnt[0] == 0x00) {
62+
len -= 1;
63+
}
64+
65+
/* The buffer size for the modulus n is the RSA key size */
66+
return PSA_BYTES_TO_BITS(len);
67+
}
68+
69+
static size_t calculate_ecc_key_size(size_t key_data_len, psa_ecc_family_t curve_family,
70+
bool is_keypair)
71+
{
72+
/**
73+
* For montgomery and twisted edwards curve the bits should be equal to the buffer -1.
74+
* The -1 is because the key size is 255 bits but the buffer size will always be a multiple
75+
* of 8 (256 bits). Private and public keys use the same structure and size so no need to
76+
* distinguish between them.
77+
*/
78+
if (curve_family == PSA_ECC_FAMILY_MONTGOMERY ||
79+
curve_family == PSA_ECC_FAMILY_TWISTED_EDWARDS) {
80+
return PSA_BYTES_TO_BITS(key_data_len) - 1;
81+
}
82+
83+
/* Keypairs are generaly simpler because only the private key is used */
84+
if (is_keypair) {
85+
/* 521 bit curves are a special case since they are not a multiple of 8 */
86+
if (key_data_len == PSA_BITS_TO_BYTES(521)) {
87+
return 521;
88+
}
89+
90+
return PSA_BYTES_TO_BITS(key_data_len);
91+
}
92+
93+
/**
94+
* For the SECP_R1, SECP_R2, SECP_K1 the public key has the structure
95+
* 04 | X | Y
96+
* and the bit size of the curve is equivalent to the X/Y length.
97+
*/
98+
99+
/* 521 bit curves are a special case since they are not a multiple of 8 */
100+
if (key_data_len == (1 + 2 * PSA_BITS_TO_BYTES(521))) {
101+
return 521;
102+
}
103+
104+
return PSA_BYTES_TO_BITS(key_data_len - 1) / 2;
105+
}
106+
107+
static size_t calculate_key_size(psa_key_type_t key_type, const uint8_t *key_buff,
108+
size_t key_buff_len)
109+
{
110+
/* For unstructured keys we can only rely on the buffer size to calculate the key size */
111+
if (PSA_KEY_TYPE_IS_UNSTRUCTURED(key_type)) {
112+
return PSA_BYTES_TO_BITS(key_buff_len);
113+
}
114+
115+
/* For RSA keys we need to parse the ASN1 and get the modulus n */
116+
if (IS_ENABLED(PSA_NEED_CC3XX_KEY_TYPE_RSA_ANY) && PSA_KEY_TYPE_IS_RSA(key_type)) {
117+
return calculate_rsa_key_size(key_buff, key_buff_len,
118+
key_type == PSA_KEY_TYPE_RSA_KEY_PAIR);
119+
}
120+
121+
if (IS_ENABLED(PSA_NEED_CC3XX_KEY_TYPE_ECC_ANY) && PSA_KEY_TYPE_IS_ECC(key_type)) {
122+
psa_ecc_family_t curve_family = PSA_KEY_TYPE_ECC_GET_FAMILY(key_type);
123+
124+
return calculate_ecc_key_size(key_buff_len, curve_family,
125+
PSA_KEY_TYPE_IS_KEY_PAIR(key_type));
126+
}
127+
128+
return PSA_ERROR_INVALID_ARGUMENT;
129+
}
130+
131+
static psa_status_t validate_ecc_key_size(psa_ecc_family_t curve, size_t bits)
132+
{
133+
switch (curve) {
134+
case PSA_ECC_FAMILY_SECP_R1:
135+
if (bits != 160 && bits != 192 && bits != 224 && bits != 256 && bits != 384 &&
136+
bits != 521) {
137+
return PSA_ERROR_INVALID_ARGUMENT;
138+
}
139+
140+
return PSA_SUCCESS;
141+
case PSA_ECC_FAMILY_SECP_K1:
142+
if (bits != 160 && bits != 192 && bits != 224 && bits != 256) {
143+
return PSA_ERROR_INVALID_ARGUMENT;
144+
}
145+
146+
return PSA_SUCCESS;
147+
case PSA_ECC_FAMILY_MONTGOMERY:
148+
case PSA_ECC_FAMILY_TWISTED_EDWARDS:
149+
if (bits != 255) {
150+
return PSA_ERROR_NOT_SUPPORTED;
151+
}
152+
153+
return PSA_SUCCESS;
154+
case PSA_ECC_FAMILY_BRAINPOOL_P_R1:
155+
/**
156+
* The driver should only return not supported, while the core handles
157+
* invalid checks, as it might choose another driver if e.g. a 192r1 is
158+
* chosen
159+
*/
160+
if (bits != 256) {
161+
return PSA_ERROR_NOT_SUPPORTED;
162+
}
163+
164+
return PSA_SUCCESS;
165+
default:
166+
return PSA_ERROR_NOT_SUPPORTED;
167+
}
168+
}
169+
170+
static psa_status_t cc3xx_generate_key_ecc(const psa_key_attributes_t *attributes,
171+
uint8_t *key_buffer, size_t key_buffer_size,
172+
size_t *key_buffer_length)
173+
{
174+
psa_key_type_t key_type = psa_get_key_type(attributes);
175+
176+
if (IS_ENABLED(PSA_NEED_CC3XX_ECC_WEIERSTRASS) &&
177+
PSA_ECC_FAMILY_IS_WEIERSTRASS(key_type)) {
178+
return cc3xx_internal_gen_ecc_wstr_keypair(attributes, key_buffer, key_buffer_size,
179+
key_buffer_length);
180+
} else if (IS_ENABLED(PSA_NEED_CC3XX_ECDH_MONTGOMERY_255) &&
181+
PSA_KEY_TYPE_ECC_GET_FAMILY(key_type) == PSA_ECC_FAMILY_MONTGOMERY) {
182+
return cc3xx_internal_gen_ecc_mont_keypair(attributes, key_buffer, key_buffer_size);
183+
} else if (IS_ENABLED(PSA_NEED_CC3XX_PURE_EDDSA_TWISTED_EDWARDS_255) &&
184+
PSA_KEY_TYPE_ECC_GET_FAMILY(key_type) == PSA_ECC_FAMILY_TWISTED_EDWARDS) {
185+
return cc3xx_internal_gen_ecc_edwards_keypair(attributes, key_buffer,
186+
key_buffer_size);
187+
} else {
188+
/* ECC type did not match supported features */
189+
return -PSA_ERROR_NOT_SUPPORTED;
190+
}
191+
}
192+
193+
static psa_status_t cc3xx_import_key_ecc(const psa_key_attributes_t *attributes,
194+
const uint8_t *data, size_t data_length,
195+
uint8_t *key_buffer, size_t key_buffer_size,
196+
size_t *key_buffer_length, size_t *key_bits)
197+
{
198+
psa_key_type_t key_type = psa_get_key_type(attributes);
199+
size_t attr_bits = psa_get_key_bits(attributes);
200+
psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY(key_type);
201+
202+
if (IS_ENABLED(PSA_NEED_CC3XX_ECC_WEIERSTRASS) &&
203+
PSA_ECC_FAMILY_IS_WEIERSTRASS(key_type)) {
204+
return cc3xx_internal_check_wrst_key(curve, attr_bits, key_type, data, data_length);
205+
} else if (IS_ENABLED(PSA_NEED_CC3XX_ECDH_MONTGOMERY_255) &&
206+
curve == PSA_ECC_FAMILY_MONTGOMERY) {
207+
return cc3xx_internal_check_mont_key(key_type, data, data_length);
208+
} else if (IS_ENABLED(PSA_NEED_CC3XX_PURE_EDDSA_TWISTED_EDWARDS_255) &&
209+
curve == PSA_ECC_FAMILY_TWISTED_EDWARDS) {
210+
return cc3xx_internal_check_edw_key(key_type, data, data_length);
211+
}
212+
213+
return PSA_ERROR_NOT_SUPPORTED;
214+
}
215+
216+
static psa_status_t cc3xx_export_public_key_ecc(const psa_key_attributes_t *attributes,
217+
const uint8_t *key_buffer, size_t key_buffer_size,
218+
uint8_t *data, size_t data_size,
219+
size_t *data_length)
220+
{
221+
psa_key_type_t key_type = psa_get_key_type(attributes);
222+
223+
if (IS_ENABLED(PSA_NEED_CC3XX_ECC_WEIERSTRASS) &&
224+
PSA_ECC_FAMILY_IS_WEIERSTRASS(key_type)) {
225+
return cc3xx_internal_export_ecc_wrst_public_key(
226+
attributes, key_buffer, key_buffer_size,
227+
data, data_size, data_length);
228+
} else if (IS_ENABLED(PSA_NEED_CC3XX_ECDH_MONTGOMERY_255) &&
229+
PSA_KEY_TYPE_ECC_GET_FAMILY(key_type) == PSA_ECC_FAMILY_MONTGOMERY) {
230+
return cc3xx_internal_export_ecc_mont_public_key(
231+
attributes, key_buffer, key_buffer_size,
232+
data, data_size, data_length);
233+
} else if (IS_ENABLED(PSA_NEED_CC3XX_PURE_EDDSA_TWISTED_EDWARDS_255) &&
234+
PSA_KEY_TYPE_ECC_GET_FAMILY(key_type) == PSA_ECC_FAMILY_TWISTED_EDWARDS) {
235+
return cc3xx_internal_export_ecc_edwards_public_key(
236+
attributes, key_buffer, key_buffer_size,
237+
data, data_size, data_length);
238+
} else {
239+
/* ECC type did not match supported features */
240+
return PSA_ERROR_NOT_SUPPORTED;
241+
}
242+
}
243+
244+
static psa_status_t validate_key_size(psa_key_type_t type, size_t bits)
245+
{
246+
if (IS_ENABLED(PSA_NEED_CC3XX_KEY_TYPE_ECC_ANY) && PSA_KEY_TYPE_IS_ECC(type)) {
247+
psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY(type);
248+
249+
return validate_ecc_key_size(curve, bits);
250+
}
251+
252+
if (IS_ENABLED(PSA_NEED_CC3XX_KEY_TYPE_RSA_ANY)) {
253+
switch (type) {
254+
case PSA_KEY_TYPE_RSA_KEY_PAIR:
255+
case PSA_KEY_TYPE_RSA_PUBLIC_KEY:
256+
return cc3xx_check_rsa_key_size(bits);
257+
default:
258+
break;
259+
}
260+
}
261+
262+
return PSA_ERROR_NOT_SUPPORTED;
263+
}
264+
265+
/** \defgroup psa_key_generation PSA driver entry points for key handling
266+
*
267+
* Entry points for random key generation and key format manipulation and
268+
* translation as described by the PSA Cryptoprocessor Driver interface
269+
* specification
270+
*
271+
* @{
272+
*/
273+
psa_status_t cc3xx_generate_key(const psa_key_attributes_t *attributes, uint8_t *key_buffer,
274+
size_t key_buffer_size, size_t *key_buffer_length)
275+
{
276+
psa_key_type_t key_type = psa_get_key_type(attributes);
277+
size_t key_bits = psa_get_key_bits(attributes);
278+
psa_status_t err = PSA_ERROR_NOT_SUPPORTED;
279+
280+
if (key_buffer_size < PSA_BITS_TO_BYTES(key_bits)) {
281+
return PSA_ERROR_BUFFER_TOO_SMALL;
282+
}
283+
284+
err = validate_key_size(key_type, key_bits);
285+
if (err != PSA_SUCCESS) {
286+
return err;
287+
}
288+
289+
if (!PSA_KEY_TYPE_IS_KEY_PAIR(key_type)) {
290+
return PSA_ERROR_INVALID_ARGUMENT;
291+
}
292+
293+
if (IS_ENABLED(PSA_NEED_CC3XX_KEY_TYPE_ECC_ANY) && PSA_KEY_TYPE_IS_ECC(key_type)) {
294+
return cc3xx_generate_key_ecc(attributes, key_buffer, key_buffer_size,
295+
key_buffer_length);
296+
} else if (IS_ENABLED(PSA_NEED_CC3XX_KEY_TYPE_RSA_ANY) && PSA_KEY_TYPE_IS_RSA(key_type)) {
297+
return cc3xx_internal_gen_rsa_keypair(attributes, key_buffer,
298+
key_buffer_size, key_buffer_length);
299+
} else {
300+
return PSA_ERROR_NOT_SUPPORTED;
301+
}
302+
}
303+
304+
psa_status_t cc3xx_import_key(const psa_key_attributes_t *attributes, const uint8_t *data,
305+
size_t data_length, uint8_t *key_buffer, size_t key_buffer_size,
306+
size_t *key_buffer_length, size_t *key_bits)
307+
{
308+
psa_status_t err = PSA_ERROR_CORRUPTION_DETECTED;
309+
size_t attr_bits = psa_get_key_bits(attributes);
310+
psa_key_type_t key_type = psa_get_key_type(attributes);
311+
312+
if (data == NULL || key_buffer == NULL || key_buffer_length == NULL || key_bits == NULL ||
313+
data_length == 0) {
314+
return PSA_ERROR_INVALID_ARGUMENT;
315+
}
316+
317+
if (data_length > key_buffer_size) {
318+
return PSA_ERROR_INVALID_ARGUMENT;
319+
}
320+
321+
/* if the bits are not set we need to calculate it */
322+
if (attr_bits == 0) {
323+
attr_bits = calculate_key_size(key_type, data, data_length);
324+
}
325+
326+
/* Validate ECC or RSA key size */
327+
err = validate_key_size(key_type, attr_bits);
328+
if (err != PSA_SUCCESS) {
329+
return err;
330+
}
331+
332+
if (IS_ENABLED(PSA_NEED_CC3XX_KEY_TYPE_ECC_ANY) && PSA_KEY_TYPE_IS_ECC(key_type)) {
333+
err = cc3xx_import_key_ecc(attributes, data, data_length, key_buffer,
334+
key_buffer_size, key_buffer_length, key_bits);
335+
}
336+
337+
if (err != PSA_SUCCESS) {
338+
return err;
339+
}
340+
341+
/* Note: No conversion required for RSA key pair */
342+
343+
memcpy(key_buffer, data, data_length);
344+
*key_bits = attr_bits;
345+
*key_buffer_length = data_length;
346+
347+
return PSA_SUCCESS;
348+
}
349+
350+
psa_status_t cc3xx_export_public_key(const psa_key_attributes_t *attributes,
351+
const uint8_t *key_buffer, size_t key_buffer_size,
352+
uint8_t *data, size_t data_size, size_t *data_length)
353+
{
354+
psa_key_type_t key_type = psa_get_key_type(attributes);
355+
size_t key_bits = psa_get_key_bits(attributes);
356+
psa_status_t err = PSA_ERROR_CORRUPTION_DETECTED;
357+
358+
/* Initialise the return value to 0 */
359+
*data_length = 0;
360+
361+
err = validate_key_size(key_type, key_bits);
362+
if (err != PSA_SUCCESS) {
363+
return err;
364+
}
365+
366+
if (PSA_KEY_TYPE_IS_PUBLIC_KEY(key_type)) {
367+
/* Revert to software driver when the key is public (no conversion needed) */
368+
return PSA_ERROR_NOT_SUPPORTED;
369+
}
370+
371+
if (IS_ENABLED(PSA_NEED_CC3XX_KEY_TYPE_ECC_ANY) && PSA_KEY_TYPE_IS_ECC(key_type)) {
372+
return cc3xx_export_public_key_ecc(attributes, key_buffer, key_buffer_size,
373+
data, data_size, data_length);
374+
} else if (IS_ENABLED(PSA_NEED_CC3XX_KEY_TYPE_RSA_ANY) && PSA_KEY_TYPE_IS_RSA(key_type)) {
375+
return cc3xx_rsa_psa_priv_to_psa_publ((uint8_t *)key_buffer, key_buffer_size,
376+
data, data_size, data_length);
377+
} else {
378+
/* ECC type did not match supported features */
379+
return PSA_ERROR_NOT_SUPPORTED;
380+
}
381+
}

0 commit comments

Comments
 (0)