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