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