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