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