1 /* 2 * Copyright 2021 NXP 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 * 6 */ 7 8 #include <errno.h> 9 #include <stdbool.h> 10 #include <stdint.h> 11 #include <stdio.h> 12 #include <stdlib.h> 13 #include <string.h> 14 15 #include <arch_helpers.h> 16 #include "caam.h" 17 #include <common/debug.h> 18 #include <drivers/auth/crypto_mod.h> 19 20 #include "jobdesc.h" 21 #include "rsa.h" 22 #include "sec_hw_specific.h" 23 24 /* This array contains DER value for SHA-256 */ 25 static const uint8_t hash_identifier[] = { 26 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 27 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 28 0x04, 0x20 29 }; 30 31 static void rsa_done(uint32_t *desc, uint32_t status, void *arg, 32 void *job_ring) 33 { 34 INFO("RSA Desc SUCCESS with status %x\n", status); 35 } 36 37 static int rsa_public_verif_sec(uint8_t *sign, uint8_t *to, 38 uint8_t *rsa_pub_key, uint32_t klen) 39 { 40 int ret = 0; 41 struct rsa_context ctx __aligned(CACHE_WRITEBACK_GRANULE); 42 struct job_descriptor jobdesc __aligned(CACHE_WRITEBACK_GRANULE); 43 44 jobdesc.arg = NULL; 45 jobdesc.callback = rsa_done; 46 47 memset(&ctx, 0, sizeof(struct rsa_context)); 48 49 ctx.pkin.a = sign; 50 ctx.pkin.a_siz = klen; 51 ctx.pkin.n = rsa_pub_key; 52 ctx.pkin.n_siz = klen; 53 ctx.pkin.e = rsa_pub_key + klen; 54 ctx.pkin.e_siz = klen; 55 56 cnstr_jobdesc_pkha_rsaexp(jobdesc.desc, &ctx.pkin, to, klen); 57 58 #if defined(SEC_MEM_NON_COHERENT) && defined(IMAGE_BL2) 59 flush_dcache_range((uintptr_t)sign, klen); 60 flush_dcache_range((uintptr_t)rsa_pub_key, 2 * klen); 61 flush_dcache_range((uintptr_t)&ctx.pkin, sizeof(ctx.pkin)); 62 inv_dcache_range((uintptr_t)to, klen); 63 64 dmbsy(); 65 dsbsy(); 66 isb(); 67 #endif 68 69 /* Finally, generate the requested random data bytes */ 70 ret = run_descriptor_jr(&jobdesc); 71 if (ret != 0) { 72 ERROR("Error in running descriptor\n"); 73 ret = -1; 74 } 75 #if defined(SEC_MEM_NON_COHERENT) && defined(IMAGE_BL2) 76 inv_dcache_range((uintptr_t)to, klen); 77 dmbsy(); 78 dsbsy(); 79 isb(); 80 #endif 81 return ret; 82 } 83 84 /* 85 * Construct encoded hash EM' wrt PKCSv1.5. This function calculates the 86 * pointers for padding, DER value and hash. And finally, constructs EM' 87 * which includes hash of complete CSF header and ESBC image. If SG flag 88 * is on, hash of SG table and entries is also included. 89 */ 90 static int construct_img_encoded_hash_second(uint8_t *hash, uint8_t hash_len, 91 uint8_t *encoded_hash_second, 92 unsigned int key_len) 93 { 94 /* 95 * RSA PKCSv1.5 encoding format for encoded message is below 96 * EM = 0x0 || 0x1 || PS || 0x0 || DER || Hash 97 * PS is Padding String 98 * DER is DER value for SHA-256 99 * Hash is SHA-256 hash 100 * ********************************************************* 101 * representative points to first byte of EM initially and is 102 * filled with 0x0 103 * representative is incremented by 1 and second byte is filled 104 * with 0x1 105 * padding points to third byte of EM 106 * digest points to full length of EM - 32 bytes 107 * hash_id (DER value) points to 19 bytes before pDigest 108 * separator is one byte which separates padding and DER 109 */ 110 111 unsigned int len; 112 uint8_t *representative; 113 uint8_t *padding, *digest; 114 uint8_t *hash_id, *separator; 115 int i; 116 int ret = 0; 117 118 if (hash_len != SHA256_BYTES) { 119 return -1; 120 } 121 122 /* Key length = Modulus length */ 123 len = (key_len / 2U) - 1U; 124 representative = encoded_hash_second; 125 representative[0] = 0U; 126 representative[1] = 1U; /* block type 1 */ 127 128 padding = &representative[2]; 129 digest = &representative[1] + len - 32; 130 hash_id = digest - sizeof(hash_identifier); 131 separator = hash_id - 1; 132 133 /* fill padding area pointed by padding with 0xff */ 134 memset(padding, 0xff, separator - padding); 135 136 /* fill byte pointed by separator */ 137 *separator = 0U; 138 139 /* fill SHA-256 DER value pointed by HashId */ 140 memcpy(hash_id, hash_identifier, sizeof(hash_identifier)); 141 142 /* fill hash pointed by Digest */ 143 for (i = 0; i < SHA256_BYTES; i++) { 144 digest[i] = hash[i]; 145 } 146 147 return ret; 148 } 149 150 int rsa_verify_signature(void *hash_ptr, unsigned int hash_len, 151 void *sig_ptr, unsigned int sig_len, 152 void *pk_ptr, unsigned int pk_len) 153 { 154 uint8_t img_encoded_hash_second[RSA_4K_KEY_SZ_BYTES]; 155 uint8_t encoded_hash[RSA_4K_KEY_SZ_BYTES] __aligned(CACHE_WRITEBACK_GRANULE); 156 int ret = 0; 157 158 ret = construct_img_encoded_hash_second(hash_ptr, hash_len, 159 img_encoded_hash_second, 160 pk_len); 161 if (ret != 0) { 162 ERROR("Encoded Hash Failure\n"); 163 return CRYPTO_ERR_SIGNATURE; 164 } 165 166 ret = rsa_public_verif_sec(sig_ptr, encoded_hash, pk_ptr, pk_len / 2); 167 if (ret != 0) { 168 ERROR("RSA signature Failure\n"); 169 return CRYPTO_ERR_SIGNATURE; 170 } 171 172 ret = memcmp(img_encoded_hash_second, encoded_hash, sig_len); 173 if (ret != 0) { 174 ERROR("Comparison Failure\n"); 175 return CRYPTO_ERR_SIGNATURE; 176 } 177 178 return CRYPTO_SUCCESS; 179 } 180