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 <stddef.h> 8 #include <string.h> 9 10 /* mbed TLS headers */ 11 #include <mbedtls/md.h> 12 #include <mbedtls/memory_buffer_alloc.h> 13 #include <mbedtls/oid.h> 14 #include <mbedtls/platform.h> 15 #include <mbedtls/x509.h> 16 17 #include <common/debug.h> 18 #include <drivers/auth/crypto_mod.h> 19 #include <drivers/auth/mbedtls/mbedtls_common.h> 20 #include <drivers/auth/mbedtls/mbedtls_config.h> 21 22 #define LIB_NAME "mbed TLS" 23 24 /* 25 * AlgorithmIdentifier ::= SEQUENCE { 26 * algorithm OBJECT IDENTIFIER, 27 * parameters ANY DEFINED BY algorithm OPTIONAL 28 * } 29 * 30 * SubjectPublicKeyInfo ::= SEQUENCE { 31 * algorithm AlgorithmIdentifier, 32 * subjectPublicKey BIT STRING 33 * } 34 * 35 * DigestInfo ::= SEQUENCE { 36 * digestAlgorithm AlgorithmIdentifier, 37 * digest OCTET STRING 38 * } 39 */ 40 41 /* 42 * Initialize the library and export the descriptor 43 */ 44 static void init(void) 45 { 46 /* Initialize mbed TLS */ 47 mbedtls_init(); 48 } 49 50 /* 51 * Verify a signature. 52 * 53 * Parameters are passed using the DER encoding format following the ASN.1 54 * structures detailed above. 55 */ 56 static int verify_signature(void *data_ptr, unsigned int data_len, 57 void *sig_ptr, unsigned int sig_len, 58 void *sig_alg, unsigned int sig_alg_len, 59 void *pk_ptr, unsigned int pk_len) 60 { 61 mbedtls_asn1_buf sig_oid, sig_params; 62 mbedtls_asn1_buf signature; 63 mbedtls_md_type_t md_alg; 64 mbedtls_pk_type_t pk_alg; 65 mbedtls_pk_context pk = {0}; 66 int rc; 67 void *sig_opts = NULL; 68 const mbedtls_md_info_t *md_info; 69 unsigned char *p, *end; 70 unsigned char hash[MBEDTLS_MD_MAX_SIZE]; 71 72 /* Get pointers to signature OID and parameters */ 73 p = (unsigned char *)sig_alg; 74 end = (unsigned char *)(p + sig_alg_len); 75 rc = mbedtls_asn1_get_alg(&p, end, &sig_oid, &sig_params); 76 if (rc != 0) { 77 return CRYPTO_ERR_SIGNATURE; 78 } 79 80 /* Get the actual signature algorithm (MD + PK) */ 81 rc = mbedtls_x509_get_sig_alg(&sig_oid, &sig_params, &md_alg, &pk_alg, &sig_opts); 82 if (rc != 0) { 83 return CRYPTO_ERR_SIGNATURE; 84 } 85 86 /* Parse the public key */ 87 mbedtls_pk_init(&pk); 88 p = (unsigned char *)pk_ptr; 89 end = (unsigned char *)(p + pk_len); 90 rc = mbedtls_pk_parse_subpubkey(&p, end, &pk); 91 if (rc != 0) { 92 rc = CRYPTO_ERR_SIGNATURE; 93 goto end2; 94 } 95 96 /* Get the signature (bitstring) */ 97 p = (unsigned char *)sig_ptr; 98 end = (unsigned char *)(p + sig_len); 99 signature.tag = *p; 100 rc = mbedtls_asn1_get_bitstring_null(&p, end, &signature.len); 101 if (rc != 0) { 102 rc = CRYPTO_ERR_SIGNATURE; 103 goto end1; 104 } 105 signature.p = p; 106 107 /* Calculate the hash of the data */ 108 md_info = mbedtls_md_info_from_type(md_alg); 109 if (md_info == NULL) { 110 rc = CRYPTO_ERR_SIGNATURE; 111 goto end1; 112 } 113 p = (unsigned char *)data_ptr; 114 rc = mbedtls_md(md_info, p, data_len, hash); 115 if (rc != 0) { 116 rc = CRYPTO_ERR_SIGNATURE; 117 goto end1; 118 } 119 120 /* Verify the signature */ 121 rc = mbedtls_pk_verify_ext(pk_alg, sig_opts, &pk, md_alg, hash, 122 mbedtls_md_get_size(md_info), 123 signature.p, signature.len); 124 if (rc != 0) { 125 rc = CRYPTO_ERR_SIGNATURE; 126 goto end1; 127 } 128 129 /* Signature verification success */ 130 rc = CRYPTO_SUCCESS; 131 132 end1: 133 mbedtls_pk_free(&pk); 134 end2: 135 mbedtls_free(sig_opts); 136 return rc; 137 } 138 139 /* 140 * Match a hash 141 * 142 * Digest info is passed in DER format following the ASN.1 structure detailed 143 * above. 144 */ 145 static int verify_hash(void *data_ptr, unsigned int data_len, 146 void *digest_info_ptr, unsigned int digest_info_len) 147 { 148 mbedtls_asn1_buf hash_oid, params; 149 mbedtls_md_type_t md_alg; 150 const mbedtls_md_info_t *md_info; 151 unsigned char *p, *end, *hash; 152 unsigned char data_hash[MBEDTLS_MD_MAX_SIZE]; 153 size_t len; 154 int rc; 155 156 /* Digest info should be an MBEDTLS_ASN1_SEQUENCE */ 157 p = (unsigned char *)digest_info_ptr; 158 end = p + digest_info_len; 159 rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | 160 MBEDTLS_ASN1_SEQUENCE); 161 if (rc != 0) { 162 return CRYPTO_ERR_HASH; 163 } 164 165 /* Get the hash algorithm */ 166 rc = mbedtls_asn1_get_alg(&p, end, &hash_oid, ¶ms); 167 if (rc != 0) { 168 return CRYPTO_ERR_HASH; 169 } 170 171 rc = mbedtls_oid_get_md_alg(&hash_oid, &md_alg); 172 if (rc != 0) { 173 return CRYPTO_ERR_HASH; 174 } 175 176 md_info = mbedtls_md_info_from_type(md_alg); 177 if (md_info == NULL) { 178 return CRYPTO_ERR_HASH; 179 } 180 181 /* Hash should be octet string type */ 182 rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING); 183 if (rc != 0) { 184 return CRYPTO_ERR_HASH; 185 } 186 187 /* Length of hash must match the algorithm's size */ 188 if (len != mbedtls_md_get_size(md_info)) { 189 return CRYPTO_ERR_HASH; 190 } 191 hash = p; 192 193 /* Calculate the hash of the data */ 194 p = (unsigned char *)data_ptr; 195 rc = mbedtls_md(md_info, p, data_len, data_hash); 196 if (rc != 0) { 197 return CRYPTO_ERR_HASH; 198 } 199 200 /* Compare values */ 201 rc = memcmp(data_hash, hash, mbedtls_md_get_size(md_info)); 202 if (rc != 0) { 203 return CRYPTO_ERR_HASH; 204 } 205 206 return CRYPTO_SUCCESS; 207 } 208 209 #if MEASURED_BOOT 210 /* 211 * Calculate a hash 212 * 213 * output points to the computed hash 214 */ 215 int calc_hash(unsigned int alg, void *data_ptr, 216 unsigned int data_len, unsigned char *output) 217 { 218 const mbedtls_md_info_t *md_info; 219 220 md_info = mbedtls_md_info_from_type((mbedtls_md_type_t)alg); 221 if (md_info == NULL) { 222 return CRYPTO_ERR_HASH; 223 } 224 225 /* Calculate the hash of the data */ 226 return mbedtls_md(md_info, data_ptr, data_len, output); 227 } 228 #endif /* MEASURED_BOOT */ 229 230 /* 231 * Register crypto library descriptor 232 */ 233 #if MEASURED_BOOT 234 REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash); 235 #else 236 REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash); 237 #endif /* MEASURED_BOOT */ 238