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