1 /* 2 * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <stddef.h> 9 #include <string.h> 10 11 /* mbed TLS headers */ 12 #include <mbedtls/gcm.h> 13 #include <mbedtls/md.h> 14 #include <mbedtls/memory_buffer_alloc.h> 15 #include <mbedtls/oid.h> 16 #include <mbedtls/platform.h> 17 18 #include <common/debug.h> 19 #include <drivers/auth/crypto_mod.h> 20 #include <drivers/auth/mbedtls/mbedtls_common.h> 21 #include <drivers/auth/mbedtls/mbedtls_config.h> 22 #include <plat/common/platform.h> 23 24 #define LIB_NAME "mbed TLS" 25 26 /* 27 * AlgorithmIdentifier ::= SEQUENCE { 28 * algorithm OBJECT IDENTIFIER, 29 * parameters ANY DEFINED BY algorithm OPTIONAL 30 * } 31 * 32 * SubjectPublicKeyInfo ::= SEQUENCE { 33 * algorithm AlgorithmIdentifier, 34 * subjectPublicKey BIT STRING 35 * } 36 * 37 * DigestInfo ::= SEQUENCE { 38 * digestAlgorithm AlgorithmIdentifier, 39 * digest OCTET STRING 40 * } 41 */ 42 43 /* 44 * Initialize the library and export the descriptor 45 */ 46 static void init(void) 47 { 48 /* Initialize mbed TLS */ 49 mbedtls_init(); 50 } 51 52 /* 53 * Verify a signature. 54 * 55 * Parameters are passed using the DER encoding format following the ASN.1 56 * structures detailed above. 57 */ 58 static int verify_signature(void *data_ptr, unsigned int data_len, 59 void *sig_ptr, unsigned int sig_len, 60 void *sig_alg, unsigned int sig_alg_len, 61 void *pk_ptr, unsigned int pk_len) 62 { 63 mbedtls_asn1_buf sig_oid, sig_params; 64 mbedtls_asn1_buf signature; 65 mbedtls_md_type_t md_alg; 66 mbedtls_pk_type_t pk_alg; 67 mbedtls_pk_context pk = {0}; 68 int rc; 69 void *sig_opts = NULL; 70 const mbedtls_md_info_t *md_info; 71 unsigned char *p, *end; 72 unsigned char hash[MBEDTLS_MD_MAX_SIZE]; 73 74 /* Get pointers to signature OID and parameters */ 75 p = (unsigned char *)sig_alg; 76 end = (unsigned char *)(p + sig_alg_len); 77 rc = mbedtls_asn1_get_alg(&p, end, &sig_oid, &sig_params); 78 if (rc != 0) { 79 return CRYPTO_ERR_SIGNATURE; 80 } 81 82 /* Get the actual signature algorithm (MD + PK) */ 83 rc = mbedtls_x509_get_sig_alg(&sig_oid, &sig_params, &md_alg, &pk_alg, &sig_opts); 84 if (rc != 0) { 85 return CRYPTO_ERR_SIGNATURE; 86 } 87 88 /* Parse the public key */ 89 mbedtls_pk_init(&pk); 90 p = (unsigned char *)pk_ptr; 91 end = (unsigned char *)(p + pk_len); 92 rc = mbedtls_pk_parse_subpubkey(&p, end, &pk); 93 if (rc != 0) { 94 rc = CRYPTO_ERR_SIGNATURE; 95 goto end2; 96 } 97 98 /* Get the signature (bitstring) */ 99 p = (unsigned char *)sig_ptr; 100 end = (unsigned char *)(p + sig_len); 101 signature.tag = *p; 102 rc = mbedtls_asn1_get_bitstring_null(&p, end, &signature.len); 103 if (rc != 0) { 104 rc = CRYPTO_ERR_SIGNATURE; 105 goto end1; 106 } 107 signature.p = p; 108 109 /* Calculate the hash of the data */ 110 md_info = mbedtls_md_info_from_type(md_alg); 111 if (md_info == NULL) { 112 rc = CRYPTO_ERR_SIGNATURE; 113 goto end1; 114 } 115 p = (unsigned char *)data_ptr; 116 rc = mbedtls_md(md_info, p, data_len, hash); 117 if (rc != 0) { 118 rc = CRYPTO_ERR_SIGNATURE; 119 goto end1; 120 } 121 122 /* Verify the signature */ 123 rc = mbedtls_pk_verify_ext(pk_alg, sig_opts, &pk, md_alg, hash, 124 mbedtls_md_get_size(md_info), 125 signature.p, signature.len); 126 if (rc != 0) { 127 rc = CRYPTO_ERR_SIGNATURE; 128 goto end1; 129 } 130 131 /* Signature verification success */ 132 rc = CRYPTO_SUCCESS; 133 134 end1: 135 mbedtls_pk_free(&pk); 136 end2: 137 mbedtls_free(sig_opts); 138 return rc; 139 } 140 141 /* 142 * Match a hash 143 * 144 * Digest info is passed in DER format following the ASN.1 structure detailed 145 * above. 146 */ 147 static int verify_hash(void *data_ptr, unsigned int data_len, 148 void *digest_info_ptr, unsigned int digest_info_len) 149 { 150 mbedtls_asn1_buf hash_oid, params; 151 mbedtls_md_type_t md_alg; 152 const mbedtls_md_info_t *md_info; 153 unsigned char *p, *end, *hash; 154 unsigned char data_hash[MBEDTLS_MD_MAX_SIZE]; 155 size_t len; 156 int rc; 157 158 /* Digest info should be an MBEDTLS_ASN1_SEQUENCE */ 159 p = (unsigned char *)digest_info_ptr; 160 end = p + digest_info_len; 161 rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | 162 MBEDTLS_ASN1_SEQUENCE); 163 if (rc != 0) { 164 return CRYPTO_ERR_HASH; 165 } 166 167 /* Get the hash algorithm */ 168 rc = mbedtls_asn1_get_alg(&p, end, &hash_oid, ¶ms); 169 if (rc != 0) { 170 return CRYPTO_ERR_HASH; 171 } 172 173 rc = mbedtls_oid_get_md_alg(&hash_oid, &md_alg); 174 if (rc != 0) { 175 return CRYPTO_ERR_HASH; 176 } 177 178 md_info = mbedtls_md_info_from_type(md_alg); 179 if (md_info == NULL) { 180 return CRYPTO_ERR_HASH; 181 } 182 183 /* Hash should be octet string type */ 184 rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING); 185 if (rc != 0) { 186 return CRYPTO_ERR_HASH; 187 } 188 189 /* Length of hash must match the algorithm's size */ 190 if (len != mbedtls_md_get_size(md_info)) { 191 return CRYPTO_ERR_HASH; 192 } 193 hash = p; 194 195 /* Calculate the hash of the data */ 196 p = (unsigned char *)data_ptr; 197 rc = mbedtls_md(md_info, p, data_len, data_hash); 198 if (rc != 0) { 199 return CRYPTO_ERR_HASH; 200 } 201 202 /* Compare values */ 203 rc = memcmp(data_hash, hash, mbedtls_md_get_size(md_info)); 204 if (rc != 0) { 205 return CRYPTO_ERR_HASH; 206 } 207 208 return CRYPTO_SUCCESS; 209 } 210 211 #if MEASURED_BOOT 212 /* 213 * Calculate a hash 214 * 215 * output points to the computed hash 216 */ 217 int calc_hash(unsigned int alg, void *data_ptr, 218 unsigned int data_len, unsigned char *output) 219 { 220 const mbedtls_md_info_t *md_info; 221 222 md_info = mbedtls_md_info_from_type((mbedtls_md_type_t)alg); 223 if (md_info == NULL) { 224 return CRYPTO_ERR_HASH; 225 } 226 227 /* Calculate the hash of the data */ 228 return mbedtls_md(md_info, data_ptr, data_len, output); 229 } 230 #endif /* MEASURED_BOOT */ 231 232 #if TF_MBEDTLS_USE_AES_GCM 233 /* 234 * Stack based buffer allocation for decryption operation. It could 235 * be configured to balance stack usage vs execution speed. 236 */ 237 #define DEC_OP_BUF_SIZE 128 238 239 static int aes_gcm_decrypt(void *data_ptr, size_t len, const void *key, 240 unsigned int key_len, const void *iv, 241 unsigned int iv_len, const void *tag, 242 unsigned int tag_len) 243 { 244 mbedtls_gcm_context ctx; 245 mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES; 246 unsigned char buf[DEC_OP_BUF_SIZE]; 247 unsigned char tag_buf[CRYPTO_MAX_TAG_SIZE]; 248 unsigned char *pt = data_ptr; 249 size_t dec_len; 250 int diff, i, rc; 251 252 mbedtls_gcm_init(&ctx); 253 254 rc = mbedtls_gcm_setkey(&ctx, cipher, key, key_len * 8); 255 if (rc != 0) { 256 rc = CRYPTO_ERR_DECRYPTION; 257 goto exit_gcm; 258 } 259 260 rc = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_DECRYPT, iv, iv_len, NULL, 0); 261 if (rc != 0) { 262 rc = CRYPTO_ERR_DECRYPTION; 263 goto exit_gcm; 264 } 265 266 while (len > 0) { 267 dec_len = MIN(sizeof(buf), len); 268 269 rc = mbedtls_gcm_update(&ctx, dec_len, pt, buf); 270 if (rc != 0) { 271 rc = CRYPTO_ERR_DECRYPTION; 272 goto exit_gcm; 273 } 274 275 memcpy(pt, buf, dec_len); 276 pt += dec_len; 277 len -= dec_len; 278 } 279 280 rc = mbedtls_gcm_finish(&ctx, tag_buf, sizeof(tag_buf)); 281 if (rc != 0) { 282 rc = CRYPTO_ERR_DECRYPTION; 283 goto exit_gcm; 284 } 285 286 /* Check tag in "constant-time" */ 287 for (diff = 0, i = 0; i < tag_len; i++) 288 diff |= ((const unsigned char *)tag)[i] ^ tag_buf[i]; 289 290 if (diff != 0) { 291 rc = CRYPTO_ERR_DECRYPTION; 292 goto exit_gcm; 293 } 294 295 /* GCM decryption success */ 296 rc = CRYPTO_SUCCESS; 297 298 exit_gcm: 299 mbedtls_gcm_free(&ctx); 300 return rc; 301 } 302 303 /* 304 * Authenticated decryption of an image 305 */ 306 static int auth_decrypt(enum crypto_dec_algo dec_algo, void *data_ptr, 307 size_t len, const void *key, unsigned int key_len, 308 unsigned int key_flags, const void *iv, 309 unsigned int iv_len, const void *tag, 310 unsigned int tag_len) 311 { 312 int rc; 313 314 assert((key_flags & ENC_KEY_IS_IDENTIFIER) == 0); 315 316 switch (dec_algo) { 317 case CRYPTO_GCM_DECRYPT: 318 rc = aes_gcm_decrypt(data_ptr, len, key, key_len, iv, iv_len, 319 tag, tag_len); 320 if (rc != 0) 321 return rc; 322 break; 323 default: 324 return CRYPTO_ERR_DECRYPTION; 325 } 326 327 return CRYPTO_SUCCESS; 328 } 329 #endif /* TF_MBEDTLS_USE_AES_GCM */ 330 331 /* 332 * Register crypto library descriptor 333 */ 334 #if MEASURED_BOOT 335 #if TF_MBEDTLS_USE_AES_GCM 336 REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash, 337 auth_decrypt); 338 #else 339 REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash, 340 NULL); 341 #endif 342 #else /* MEASURED_BOOT */ 343 #if TF_MBEDTLS_USE_AES_GCM 344 REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, 345 auth_decrypt); 346 #else 347 REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL); 348 #endif 349 #endif /* MEASURED_BOOT */ 350