1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2014-2019, Linaro Limited 4 */ 5 6 #include <crypto/crypto.h> 7 #include <stdlib.h> 8 #include <string.h> 9 #include <tee_api_types.h> 10 #include <tee/tee_cryp_utl.h> 11 #include <trace.h> 12 #include <utee_defines.h> 13 14 #include "acipher_helpers.h" 15 16 TEE_Result crypto_acipher_alloc_dsa_keypair(struct dsa_keypair *s, 17 size_t key_size_bits __unused) 18 { 19 memset(s, 0, sizeof(*s)); 20 if (!bn_alloc_max(&s->g)) 21 return TEE_ERROR_OUT_OF_MEMORY; 22 23 if (!bn_alloc_max(&s->p)) 24 goto err; 25 if (!bn_alloc_max(&s->q)) 26 goto err; 27 if (!bn_alloc_max(&s->y)) 28 goto err; 29 if (!bn_alloc_max(&s->x)) 30 goto err; 31 return TEE_SUCCESS; 32 err: 33 crypto_bignum_free(&s->g); 34 crypto_bignum_free(&s->p); 35 crypto_bignum_free(&s->q); 36 crypto_bignum_free(&s->y); 37 return TEE_ERROR_OUT_OF_MEMORY; 38 } 39 40 TEE_Result crypto_acipher_alloc_dsa_public_key(struct dsa_public_key *s, 41 size_t key_size_bits __unused) 42 { 43 memset(s, 0, sizeof(*s)); 44 if (!bn_alloc_max(&s->g)) 45 return TEE_ERROR_OUT_OF_MEMORY; 46 47 if (!bn_alloc_max(&s->p)) 48 goto err; 49 if (!bn_alloc_max(&s->q)) 50 goto err; 51 if (!bn_alloc_max(&s->y)) 52 goto err; 53 return TEE_SUCCESS; 54 err: 55 crypto_bignum_free(&s->g); 56 crypto_bignum_free(&s->p); 57 crypto_bignum_free(&s->q); 58 return TEE_ERROR_OUT_OF_MEMORY; 59 } 60 61 TEE_Result crypto_acipher_gen_dsa_key(struct dsa_keypair *key, size_t key_size) 62 { 63 dsa_key ltc_tmp_key = { }; 64 int ltc_res = 0; 65 66 if (key_size != 8 * mp_unsigned_bin_size(key->p)) 67 return TEE_ERROR_BAD_PARAMETERS; 68 69 ltc_res = mp_init_multi(<c_tmp_key.g, <c_tmp_key.p, <c_tmp_key.q, 70 <c_tmp_key.x, <c_tmp_key.y, NULL); 71 if (ltc_res) 72 return TEE_ERROR_OUT_OF_MEMORY; 73 74 /* Copy the key parameters */ 75 mp_copy(key->g, ltc_tmp_key.g); 76 mp_copy(key->p, ltc_tmp_key.p); 77 mp_copy(key->q, ltc_tmp_key.q); 78 79 /* Generate the DSA key */ 80 ltc_res = dsa_generate_key(NULL, find_prng("prng_crypto"), 81 <c_tmp_key); 82 if (ltc_res) 83 return TEE_ERROR_BAD_PARAMETERS; 84 85 /* Copy the key */ 86 mp_copy(ltc_tmp_key.y, key->y); 87 mp_copy(ltc_tmp_key.x, key->x); 88 89 /* Free the temporary key */ 90 dsa_free(<c_tmp_key); 91 92 return TEE_SUCCESS; 93 } 94 95 TEE_Result crypto_acipher_dsa_sign(uint32_t algo, struct dsa_keypair *key, 96 const uint8_t *msg, size_t msg_len, 97 uint8_t *sig, size_t *sig_len) 98 { 99 TEE_Result res; 100 size_t hash_size; 101 int ltc_res; 102 void *r, *s; 103 dsa_key ltc_key = { 104 .type = PK_PRIVATE, 105 .qord = mp_unsigned_bin_size(key->q), 106 .g = key->g, 107 .p = key->p, 108 .q = key->q, 109 .y = key->y, 110 .x = key->x, 111 }; 112 113 if (algo != TEE_ALG_DSA_SHA1 && 114 algo != TEE_ALG_DSA_SHA224 && 115 algo != TEE_ALG_DSA_SHA256) { 116 res = TEE_ERROR_NOT_IMPLEMENTED; 117 goto err; 118 } 119 120 res = tee_alg_get_digest_size(TEE_DIGEST_HASH_TO_ALGO(algo), 121 &hash_size); 122 if (res != TEE_SUCCESS) 123 goto err; 124 if (mp_unsigned_bin_size(ltc_key.q) < hash_size) 125 hash_size = mp_unsigned_bin_size(ltc_key.q); 126 if (msg_len != hash_size) { 127 res = TEE_ERROR_SECURITY; 128 goto err; 129 } 130 131 if (*sig_len < 2 * mp_unsigned_bin_size(ltc_key.q)) { 132 *sig_len = 2 * mp_unsigned_bin_size(ltc_key.q); 133 res = TEE_ERROR_SHORT_BUFFER; 134 goto err; 135 } 136 137 ltc_res = mp_init_multi(&r, &s, NULL); 138 if (ltc_res != CRYPT_OK) { 139 res = TEE_ERROR_OUT_OF_MEMORY; 140 goto err; 141 } 142 143 ltc_res = dsa_sign_hash_raw(msg, msg_len, r, s, NULL, 144 find_prng("prng_crypto"), <c_key); 145 146 if (ltc_res == CRYPT_OK) { 147 *sig_len = 2 * mp_unsigned_bin_size(ltc_key.q); 148 memset(sig, 0, *sig_len); 149 mp_to_unsigned_bin(r, (uint8_t *)sig + *sig_len/2 - 150 mp_unsigned_bin_size(r)); 151 mp_to_unsigned_bin(s, (uint8_t *)sig + *sig_len - 152 mp_unsigned_bin_size(s)); 153 res = TEE_SUCCESS; 154 } else { 155 res = TEE_ERROR_GENERIC; 156 } 157 158 mp_clear_multi(r, s, NULL); 159 160 err: 161 return res; 162 } 163 164 TEE_Result crypto_acipher_dsa_verify(uint32_t algo, struct dsa_public_key *key, 165 const uint8_t *msg, size_t msg_len, 166 const uint8_t *sig, size_t sig_len) 167 { 168 TEE_Result res; 169 int ltc_stat, ltc_res; 170 void *r, *s; 171 dsa_key ltc_key = { 172 .type = PK_PUBLIC, 173 .qord = mp_unsigned_bin_size(key->q), 174 .g = key->g, 175 .p = key->p, 176 .q = key->q, 177 .y = key->y 178 }; 179 180 if (algo != TEE_ALG_DSA_SHA1 && 181 algo != TEE_ALG_DSA_SHA224 && 182 algo != TEE_ALG_DSA_SHA256) { 183 res = TEE_ERROR_NOT_IMPLEMENTED; 184 goto err; 185 } 186 187 ltc_res = mp_init_multi(&r, &s, NULL); 188 if (ltc_res != CRYPT_OK) { 189 res = TEE_ERROR_OUT_OF_MEMORY; 190 goto err; 191 } 192 mp_read_unsigned_bin(r, (uint8_t *)sig, sig_len/2); 193 mp_read_unsigned_bin(s, (uint8_t *)sig + sig_len/2, sig_len/2); 194 ltc_res = dsa_verify_hash_raw(r, s, msg, msg_len, <c_stat, <c_key); 195 mp_clear_multi(r, s, NULL); 196 res = convert_ltc_verify_status(ltc_res, ltc_stat); 197 err: 198 return res; 199 } 200