1 /*
2 * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #include "crypto.h"
9
10 #include <string.h>
11 #include "mbedtls/sha256.h"
12 #include "mbedtls/aes.h"
13 #include "mbedtls/hkdf.h"
14 #include "mbedtls/md.h"
15 #include "mbedtls/memory_buffer_alloc.h"
16 #include "otp.h"
17
18 static int mbedtls_is_initialised = 0;
19 static uint8_t mbedtls_memory_buf[512];
20
mbedtls_init(uint8_t mbedtls_memory_buf[],size_t size)21 static void mbedtls_init(uint8_t mbedtls_memory_buf[], size_t size)
22 {
23 mbedtls_memory_buffer_alloc_init(mbedtls_memory_buf,
24 size);
25 }
26
bl1_derive_key(enum tfm_bl1_key_id_t input_key,const uint8_t * label,size_t label_length,const uint8_t * context,size_t context_length,uint8_t * output_key,size_t output_length)27 int32_t bl1_derive_key(enum tfm_bl1_key_id_t input_key, const uint8_t *label,
28 size_t label_length, const uint8_t *context,
29 size_t context_length, uint8_t *output_key,
30 size_t output_length)
31 {
32 int rc = 0;
33 uint8_t state[64] = {0};
34 uint8_t key_buf[32] = {0};
35 uint32_t state_len = context_length + label_length;
36 const mbedtls_md_info_t *sha256_info = NULL;
37
38 if (state_len > sizeof(state)) {
39 return -1;
40 }
41
42 memcpy(state, label, label_length);
43 memcpy(&state[label_length], context, context_length);
44
45 if (!mbedtls_is_initialised) {
46 mbedtls_init(mbedtls_memory_buf, sizeof(mbedtls_memory_buf));
47 mbedtls_is_initialised = 1;
48 }
49
50 rc = bl1_otp_read_key(input_key, key_buf);
51 if (rc) {
52 return rc;
53 }
54
55
56 sha256_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
57
58 rc = mbedtls_hkdf(sha256_info, NULL, 0, key_buf,
59 sizeof(key_buf), state, state_len,
60 output_key, output_length);
61
62 return rc;
63 }
64
bl1_sha256_compute(const uint8_t * data,size_t data_length,uint8_t * hash)65 int32_t bl1_sha256_compute(const uint8_t *data,
66 size_t data_length,
67 uint8_t *hash)
68 {
69 int rc = 0;
70 fih_int fih_rc;
71 mbedtls_sha256_context ctx;
72
73 if (!mbedtls_is_initialised) {
74 mbedtls_init(mbedtls_memory_buf, sizeof(mbedtls_memory_buf));
75 mbedtls_is_initialised = 1;
76 }
77
78 mbedtls_sha256_init(&ctx);
79
80 rc = mbedtls_sha256_starts(&ctx, 0);
81 fih_rc = fih_int_encode_zero_equality(rc);
82 if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
83 goto out;
84 }
85
86 rc = mbedtls_sha256_update(&ctx, data, data_length);
87 fih_rc = fih_int_encode_zero_equality(rc);
88 if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
89 goto out;
90 }
91
92 rc = mbedtls_sha256_finish(&ctx, hash);
93 fih_rc = fih_int_encode_zero_equality(rc);
94 if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
95 goto out;
96 }
97
98 out:
99 mbedtls_sha256_free(&ctx);
100 FIH_RET(fih_rc);
101 }
102
bl1_aes_256_ctr_decrypt(enum tfm_bl1_key_id_t key_id,const uint8_t * key_material,uint8_t * counter,const uint8_t * ciphertext,size_t ciphertext_length,uint8_t * plaintext)103 int32_t bl1_aes_256_ctr_decrypt(enum tfm_bl1_key_id_t key_id,
104 const uint8_t *key_material,
105 uint8_t *counter,
106 const uint8_t *ciphertext,
107 size_t ciphertext_length,
108 uint8_t *plaintext)
109 {
110 int rc = 0;
111 uint8_t stream_block[16];
112 uint8_t key_buf[32];
113 mbedtls_aes_context ctx;
114 size_t nc_off = 0;
115 const uint8_t *input_key = key_buf;
116
117 if (ciphertext_length == 0) {
118 return 0;
119 }
120
121 if (ciphertext == NULL || plaintext == NULL || counter == NULL) {
122 return -2;
123 }
124
125 if (key_material == NULL) {
126 rc = bl1_otp_read_key(key_id, key_buf);
127 if (rc) {
128 return rc;
129 }
130 } else {
131 input_key = key_material;
132 }
133
134
135 if (!mbedtls_is_initialised) {
136 mbedtls_init(mbedtls_memory_buf, sizeof(mbedtls_memory_buf));
137 mbedtls_is_initialised = 1;
138 }
139
140 mbedtls_aes_init(&ctx);
141
142 rc = mbedtls_aes_setkey_enc(&ctx, input_key, 256);
143 if (rc) {
144 goto out;
145 }
146
147 rc = mbedtls_aes_crypt_ctr(&ctx, ciphertext_length, &nc_off, counter,
148 stream_block, ciphertext, plaintext);
149 if (rc) {
150 goto out;
151 }
152
153 out:
154 mbedtls_aes_free(&ctx);
155
156 memset(key_buf, 0, 32);
157 memset(stream_block, 0, 16);
158
159 return rc;
160 }
161