1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #include <assert.h> 8*91f16700Schasinglulu 9*91f16700Schasinglulu #include <common/debug.h> 10*91f16700Schasinglulu #include <drivers/auth/crypto_mod.h> 11*91f16700Schasinglulu 12*91f16700Schasinglulu /* Variable exported by the crypto library through REGISTER_CRYPTO_LIB() */ 13*91f16700Schasinglulu 14*91f16700Schasinglulu /* 15*91f16700Schasinglulu * The crypto module is responsible for verifying digital signatures and hashes. 16*91f16700Schasinglulu * It relies on a crypto library to perform the cryptographic operations. 17*91f16700Schasinglulu * 18*91f16700Schasinglulu * The crypto module itself does not impose any specific format on signatures, 19*91f16700Schasinglulu * signature algorithm, keys or hashes, but most cryptographic libraries will 20*91f16700Schasinglulu * take the parameters as the following DER encoded ASN.1 structures: 21*91f16700Schasinglulu * 22*91f16700Schasinglulu * AlgorithmIdentifier ::= SEQUENCE { 23*91f16700Schasinglulu * algorithm OBJECT IDENTIFIER, 24*91f16700Schasinglulu * parameters ANY DEFINED BY algorithm OPTIONAL 25*91f16700Schasinglulu * } 26*91f16700Schasinglulu * 27*91f16700Schasinglulu * DigestInfo ::= SEQUENCE { 28*91f16700Schasinglulu * digestAlgorithm AlgorithmIdentifier, 29*91f16700Schasinglulu * digest OCTET STRING 30*91f16700Schasinglulu * } 31*91f16700Schasinglulu * 32*91f16700Schasinglulu * SubjectPublicKeyInfo ::= SEQUENCE { 33*91f16700Schasinglulu * algorithm AlgorithmIdentifier, 34*91f16700Schasinglulu * subjectPublicKey BIT STRING 35*91f16700Schasinglulu * } 36*91f16700Schasinglulu * 37*91f16700Schasinglulu * SignatureAlgorithm ::= AlgorithmIdentifier 38*91f16700Schasinglulu * 39*91f16700Schasinglulu * SignatureValue ::= BIT STRING 40*91f16700Schasinglulu */ 41*91f16700Schasinglulu 42*91f16700Schasinglulu /* 43*91f16700Schasinglulu * Perform some static checking and call the library initialization function 44*91f16700Schasinglulu */ 45*91f16700Schasinglulu void crypto_mod_init(void) 46*91f16700Schasinglulu { 47*91f16700Schasinglulu assert(crypto_lib_desc.name != NULL); 48*91f16700Schasinglulu assert(crypto_lib_desc.init != NULL); 49*91f16700Schasinglulu #if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \ 50*91f16700Schasinglulu CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC 51*91f16700Schasinglulu assert(crypto_lib_desc.verify_signature != NULL); 52*91f16700Schasinglulu assert(crypto_lib_desc.verify_hash != NULL); 53*91f16700Schasinglulu #endif /* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \ 54*91f16700Schasinglulu CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */ 55*91f16700Schasinglulu 56*91f16700Schasinglulu #if CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \ 57*91f16700Schasinglulu CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC 58*91f16700Schasinglulu assert(crypto_lib_desc.calc_hash != NULL); 59*91f16700Schasinglulu #endif /* CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \ 60*91f16700Schasinglulu CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */ 61*91f16700Schasinglulu 62*91f16700Schasinglulu /* Initialize the cryptographic library */ 63*91f16700Schasinglulu crypto_lib_desc.init(); 64*91f16700Schasinglulu INFO("Using crypto library '%s'\n", crypto_lib_desc.name); 65*91f16700Schasinglulu } 66*91f16700Schasinglulu 67*91f16700Schasinglulu #if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \ 68*91f16700Schasinglulu CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC 69*91f16700Schasinglulu /* 70*91f16700Schasinglulu * Function to verify a digital signature 71*91f16700Schasinglulu * 72*91f16700Schasinglulu * Parameters: 73*91f16700Schasinglulu * 74*91f16700Schasinglulu * data_ptr, data_len: signed data 75*91f16700Schasinglulu * sig_ptr, sig_len: the digital signature 76*91f16700Schasinglulu * sig_alg_ptr, sig_alg_len: the digital signature algorithm 77*91f16700Schasinglulu * pk_ptr, pk_len: the public key 78*91f16700Schasinglulu */ 79*91f16700Schasinglulu int crypto_mod_verify_signature(void *data_ptr, unsigned int data_len, 80*91f16700Schasinglulu void *sig_ptr, unsigned int sig_len, 81*91f16700Schasinglulu void *sig_alg_ptr, unsigned int sig_alg_len, 82*91f16700Schasinglulu void *pk_ptr, unsigned int pk_len) 83*91f16700Schasinglulu { 84*91f16700Schasinglulu assert(data_ptr != NULL); 85*91f16700Schasinglulu assert(data_len != 0); 86*91f16700Schasinglulu assert(sig_ptr != NULL); 87*91f16700Schasinglulu assert(sig_len != 0); 88*91f16700Schasinglulu assert(sig_alg_ptr != NULL); 89*91f16700Schasinglulu assert(sig_alg_len != 0); 90*91f16700Schasinglulu assert(pk_ptr != NULL); 91*91f16700Schasinglulu assert(pk_len != 0); 92*91f16700Schasinglulu 93*91f16700Schasinglulu return crypto_lib_desc.verify_signature(data_ptr, data_len, 94*91f16700Schasinglulu sig_ptr, sig_len, 95*91f16700Schasinglulu sig_alg_ptr, sig_alg_len, 96*91f16700Schasinglulu pk_ptr, pk_len); 97*91f16700Schasinglulu } 98*91f16700Schasinglulu 99*91f16700Schasinglulu /* 100*91f16700Schasinglulu * Verify a hash by comparison 101*91f16700Schasinglulu * 102*91f16700Schasinglulu * Parameters: 103*91f16700Schasinglulu * 104*91f16700Schasinglulu * data_ptr, data_len: data to be hashed 105*91f16700Schasinglulu * digest_info_ptr, digest_info_len: hash to be compared 106*91f16700Schasinglulu */ 107*91f16700Schasinglulu int crypto_mod_verify_hash(void *data_ptr, unsigned int data_len, 108*91f16700Schasinglulu void *digest_info_ptr, unsigned int digest_info_len) 109*91f16700Schasinglulu { 110*91f16700Schasinglulu assert(data_ptr != NULL); 111*91f16700Schasinglulu assert(data_len != 0); 112*91f16700Schasinglulu assert(digest_info_ptr != NULL); 113*91f16700Schasinglulu assert(digest_info_len != 0); 114*91f16700Schasinglulu 115*91f16700Schasinglulu return crypto_lib_desc.verify_hash(data_ptr, data_len, 116*91f16700Schasinglulu digest_info_ptr, digest_info_len); 117*91f16700Schasinglulu } 118*91f16700Schasinglulu #endif /* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \ 119*91f16700Schasinglulu CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */ 120*91f16700Schasinglulu 121*91f16700Schasinglulu #if CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \ 122*91f16700Schasinglulu CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC 123*91f16700Schasinglulu /* 124*91f16700Schasinglulu * Calculate a hash 125*91f16700Schasinglulu * 126*91f16700Schasinglulu * Parameters: 127*91f16700Schasinglulu * 128*91f16700Schasinglulu * alg: message digest algorithm 129*91f16700Schasinglulu * data_ptr, data_len: data to be hashed 130*91f16700Schasinglulu * output: resulting hash 131*91f16700Schasinglulu */ 132*91f16700Schasinglulu int crypto_mod_calc_hash(enum crypto_md_algo alg, void *data_ptr, 133*91f16700Schasinglulu unsigned int data_len, 134*91f16700Schasinglulu unsigned char output[CRYPTO_MD_MAX_SIZE]) 135*91f16700Schasinglulu { 136*91f16700Schasinglulu assert(data_ptr != NULL); 137*91f16700Schasinglulu assert(data_len != 0); 138*91f16700Schasinglulu assert(output != NULL); 139*91f16700Schasinglulu 140*91f16700Schasinglulu return crypto_lib_desc.calc_hash(alg, data_ptr, data_len, output); 141*91f16700Schasinglulu } 142*91f16700Schasinglulu #endif /* CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \ 143*91f16700Schasinglulu CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */ 144*91f16700Schasinglulu 145*91f16700Schasinglulu int crypto_mod_convert_pk(void *full_pk_ptr, unsigned int full_pk_len, 146*91f16700Schasinglulu void **hashed_pk_ptr, unsigned int *hashed_pk_len) 147*91f16700Schasinglulu { 148*91f16700Schasinglulu if (crypto_lib_desc.convert_pk != NULL) { 149*91f16700Schasinglulu return crypto_lib_desc.convert_pk(full_pk_ptr, full_pk_len, 150*91f16700Schasinglulu hashed_pk_ptr, hashed_pk_len); 151*91f16700Schasinglulu } 152*91f16700Schasinglulu 153*91f16700Schasinglulu *hashed_pk_ptr = full_pk_ptr; 154*91f16700Schasinglulu *hashed_pk_len = full_pk_len; 155*91f16700Schasinglulu 156*91f16700Schasinglulu return 0; 157*91f16700Schasinglulu } 158*91f16700Schasinglulu 159*91f16700Schasinglulu /* 160*91f16700Schasinglulu * Authenticated decryption of data 161*91f16700Schasinglulu * 162*91f16700Schasinglulu * Parameters: 163*91f16700Schasinglulu * 164*91f16700Schasinglulu * dec_algo: authenticated decryption algorithm 165*91f16700Schasinglulu * data_ptr, len: data to be decrypted (inout param) 166*91f16700Schasinglulu * key, key_len, key_flags: symmetric decryption key 167*91f16700Schasinglulu * iv, iv_len: initialization vector 168*91f16700Schasinglulu * tag, tag_len: authentication tag 169*91f16700Schasinglulu */ 170*91f16700Schasinglulu int crypto_mod_auth_decrypt(enum crypto_dec_algo dec_algo, void *data_ptr, 171*91f16700Schasinglulu size_t len, const void *key, unsigned int key_len, 172*91f16700Schasinglulu unsigned int key_flags, const void *iv, 173*91f16700Schasinglulu unsigned int iv_len, const void *tag, 174*91f16700Schasinglulu unsigned int tag_len) 175*91f16700Schasinglulu { 176*91f16700Schasinglulu assert(crypto_lib_desc.auth_decrypt != NULL); 177*91f16700Schasinglulu assert(data_ptr != NULL); 178*91f16700Schasinglulu assert(len != 0U); 179*91f16700Schasinglulu assert(key != NULL); 180*91f16700Schasinglulu assert(key_len != 0U); 181*91f16700Schasinglulu assert(iv != NULL); 182*91f16700Schasinglulu assert((iv_len != 0U) && (iv_len <= CRYPTO_MAX_IV_SIZE)); 183*91f16700Schasinglulu assert(tag != NULL); 184*91f16700Schasinglulu assert((tag_len != 0U) && (tag_len <= CRYPTO_MAX_TAG_SIZE)); 185*91f16700Schasinglulu 186*91f16700Schasinglulu return crypto_lib_desc.auth_decrypt(dec_algo, data_ptr, len, key, 187*91f16700Schasinglulu key_len, key_flags, iv, iv_len, tag, 188*91f16700Schasinglulu tag_len); 189*91f16700Schasinglulu } 190