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; 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_oid_get_sig_alg(&sig_oid, &md_alg, &pk_alg); 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 return CRYPTO_ERR_SIGNATURE; 91 } 92 93 /* Get the signature (bitstring) */ 94 p = (unsigned char *)sig_ptr; 95 end = (unsigned char *)(p + sig_len); 96 signature.tag = *p; 97 rc = mbedtls_asn1_get_bitstring_null(&p, end, &signature.len); 98 if (rc != 0) { 99 rc = CRYPTO_ERR_SIGNATURE; 100 goto end; 101 } 102 signature.p = p; 103 104 /* Calculate the hash of the data */ 105 md_info = mbedtls_md_info_from_type(md_alg); 106 if (md_info == NULL) { 107 rc = CRYPTO_ERR_SIGNATURE; 108 goto end; 109 } 110 p = (unsigned char *)data_ptr; 111 rc = mbedtls_md(md_info, p, data_len, hash); 112 if (rc != 0) { 113 rc = CRYPTO_ERR_SIGNATURE; 114 goto end; 115 } 116 117 /* Verify the signature */ 118 rc = mbedtls_pk_verify_ext(pk_alg, sig_opts, &pk, md_alg, hash, 119 mbedtls_md_get_size(md_info), 120 signature.p, signature.len); 121 if (rc != 0) { 122 rc = CRYPTO_ERR_SIGNATURE; 123 goto end; 124 } 125 126 /* Signature verification success */ 127 rc = CRYPTO_SUCCESS; 128 129 end: 130 mbedtls_pk_free(&pk); 131 return rc; 132 } 133 134 /* 135 * Match a hash 136 * 137 * Digest info is passed in DER format following the ASN.1 structure detailed 138 * above. 139 */ 140 static int verify_hash(void *data_ptr, unsigned int data_len, 141 void *digest_info_ptr, unsigned int digest_info_len) 142 { 143 mbedtls_asn1_buf hash_oid, params; 144 mbedtls_md_type_t md_alg; 145 const mbedtls_md_info_t *md_info; 146 unsigned char *p, *end, *hash; 147 unsigned char data_hash[MBEDTLS_MD_MAX_SIZE]; 148 size_t len; 149 int rc; 150 151 /* Digest info should be an MBEDTLS_ASN1_SEQUENCE */ 152 p = (unsigned char *)digest_info_ptr; 153 end = p + digest_info_len; 154 rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | 155 MBEDTLS_ASN1_SEQUENCE); 156 if (rc != 0) { 157 return CRYPTO_ERR_HASH; 158 } 159 160 /* Get the hash algorithm */ 161 rc = mbedtls_asn1_get_alg(&p, end, &hash_oid, ¶ms); 162 if (rc != 0) { 163 return CRYPTO_ERR_HASH; 164 } 165 166 rc = mbedtls_oid_get_md_alg(&hash_oid, &md_alg); 167 if (rc != 0) { 168 return CRYPTO_ERR_HASH; 169 } 170 171 md_info = mbedtls_md_info_from_type(md_alg); 172 if (md_info == NULL) { 173 return CRYPTO_ERR_HASH; 174 } 175 176 /* Hash should be octet string type */ 177 rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING); 178 if (rc != 0) { 179 return CRYPTO_ERR_HASH; 180 } 181 182 /* Length of hash must match the algorithm's size */ 183 if (len != mbedtls_md_get_size(md_info)) { 184 return CRYPTO_ERR_HASH; 185 } 186 hash = p; 187 188 /* Calculate the hash of the data */ 189 p = (unsigned char *)data_ptr; 190 rc = mbedtls_md(md_info, p, data_len, data_hash); 191 if (rc != 0) { 192 return CRYPTO_ERR_HASH; 193 } 194 195 /* Compare values */ 196 rc = memcmp(data_hash, hash, mbedtls_md_get_size(md_info)); 197 if (rc != 0) { 198 return CRYPTO_ERR_HASH; 199 } 200 201 return CRYPTO_SUCCESS; 202 } 203 204 /* 205 * Register crypto library descriptor 206 */ 207 REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash); 208