1553 lines
56 KiB
C
1553 lines
56 KiB
C
|
|
/*
|
||
|
|
* Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved.
|
||
|
|
*/
|
||
|
|
|
||
|
|
#include "cipher_osal.h"
|
||
|
|
|
||
|
|
#define rsa_var_null_goto_lab(var, ret, lab) \
|
||
|
|
do { \
|
||
|
|
if ((var) == GK_NULL) { \
|
||
|
|
gk_err_cipher("%s-%d: %s is null\n", __FUNCTION__, __LINE__, #var); \
|
||
|
|
ret = GK_ERR_CIPHER_INVALID_POINT; \
|
||
|
|
goto lab; \
|
||
|
|
} \
|
||
|
|
} while (0);
|
||
|
|
|
||
|
|
#define rsa_ret_fail_goto_lab(ret, lab) \
|
||
|
|
do { \
|
||
|
|
if ((ret) != GK_SUCCESS) { \
|
||
|
|
gk_err_cipher("%s-%d: ret 0x%x\n", __FUNCTION__, __LINE__, ret); \
|
||
|
|
goto lab; \
|
||
|
|
} \
|
||
|
|
} while (0);
|
||
|
|
|
||
|
|
#define rsa_func_fail_return(val, ret, func) \
|
||
|
|
do { \
|
||
|
|
if (val) { \
|
||
|
|
gk_err_cipher("%s-%d: call %s failed, ret 0x%x\n", __FUNCTION__, __LINE__, #func, ret); \
|
||
|
|
return ret; \
|
||
|
|
} \
|
||
|
|
} while (0)
|
||
|
|
|
||
|
|
#define rsa_not_equal_return(var, val, ret) \
|
||
|
|
do { \
|
||
|
|
if ((var) != (val)) { \
|
||
|
|
gk_err_cipher("%s(0x%x) isn't equal 0x%x\n", #var, var, val); \
|
||
|
|
return ret; \
|
||
|
|
} \
|
||
|
|
} while (0)
|
||
|
|
|
||
|
|
typedef struct {
|
||
|
|
gk_cipher_hash_type hash_type;
|
||
|
|
gk_u32 hlen;
|
||
|
|
gk_u32 klen;
|
||
|
|
gk_u32 em_bit;
|
||
|
|
gk_u8 key_bt;
|
||
|
|
gk_u8 *in_data;
|
||
|
|
gk_u32 in_len;
|
||
|
|
gk_u8 *out_data;
|
||
|
|
gk_u32 out_len;
|
||
|
|
} rsa_padding_s;
|
||
|
|
|
||
|
|
typedef struct {
|
||
|
|
gk_u8 *masked_db;
|
||
|
|
gk_u8 *masked_seed;
|
||
|
|
gk_u8 salt[CIPHER_MAX_RSA_KEY_LEN];
|
||
|
|
gk_u32 msb_bits;
|
||
|
|
gk_u32 slen;
|
||
|
|
gk_u32 key_len;
|
||
|
|
} rsa_pkcs1_pss_s;
|
||
|
|
|
||
|
|
typedef struct {
|
||
|
|
gk_u8 arr_em[CIPHER_MAX_RSA_KEY_LEN];
|
||
|
|
gk_u8 sign_hash[HASH_RESULT_MAX_LEN];
|
||
|
|
} rsa_sign_buf;
|
||
|
|
|
||
|
|
#define RSA_SIGN 1
|
||
|
|
#define ASN1_HASH_SHA1 "\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14"
|
||
|
|
#define ASN1_HASH_SHA224 "\x30\x2D\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04\x05\x00\x04\x1C"
|
||
|
|
#define ASN1_HASH_SHA256 "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20"
|
||
|
|
#define ASN1_HASH_SHA384 "\x30\x41\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02\x05\x00\x04\x30"
|
||
|
|
#define ASN1_HASH_SHA512 "\x30\x51\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03\x05\x00\x04\x40"
|
||
|
|
|
||
|
|
static const gk_s8 g_empty_l_sha1[] =
|
||
|
|
"\xda\x39\xa3\xee\x5e\x6b\x4b\x0d"
|
||
|
|
"\x32\x55\xbf\xef\x95\x60\x18\x90"
|
||
|
|
"\xaf\xd8\x07\x09";
|
||
|
|
|
||
|
|
static const gk_s8 g_empty_l_sha224[] =
|
||
|
|
"\xd1\x4a\x02\x8c\x2a\x3a\x2b\xc9"
|
||
|
|
"\x47\x61\x02\xbb\x28\x82\x34\xc4"
|
||
|
|
"\x15\xa2\xb0\x1f\x82\x8e\xa6\x2a"
|
||
|
|
"\xc5\xb3\xe4\x2f";
|
||
|
|
|
||
|
|
static const gk_s8 g_empty_l_sha256[] =
|
||
|
|
"\xe3\xb0\xc4\x42\x98\xfc\x1c\x14"
|
||
|
|
"\x9a\xfb\xf4\xc8\x99\x6f\xb9\x24"
|
||
|
|
"\x27\xae\x41\xe4\x64\x9b\x93\x4c"
|
||
|
|
"\xa4\x95\x99\x1b\x78\x52\xb8\x55";
|
||
|
|
|
||
|
|
static const gk_s8 g_empty_l_sha384[] =
|
||
|
|
"\x38\xb0\x60\xa7\x51\xac\x96\x38"
|
||
|
|
"\x4c\xd9\x32\x7e\xb1\xb1\xe3\x6a"
|
||
|
|
"\x21\xfd\xb7\x11\x14\xbe\x07\x43"
|
||
|
|
"\x4c\x0c\xc7\xbf\x63\xf6\xe1\xda"
|
||
|
|
"\x27\x4e\xde\xbf\xe7\x6f\x65\xfb"
|
||
|
|
"\xd5\x1a\xd2\xf1\x48\x98\xb9\x5b";
|
||
|
|
|
||
|
|
static const gk_s8 g_empty_l_sha512[] =
|
||
|
|
"\xcf\x83\xe1\x35\x7e\xef\xb8\xbd"
|
||
|
|
"\xf1\x54\x28\x50\xd6\x6d\x80\x07"
|
||
|
|
"\xd6\x20\xe4\x05\x0b\x57\x15\xdc"
|
||
|
|
"\x83\xf4\xa9\x21\xd3\x6c\xe9\xce"
|
||
|
|
"\x47\xd0\xd1\x3c\x5d\x85\xf2\xb0"
|
||
|
|
"\xff\x83\x18\xd2\x87\x7e\xec\x2f"
|
||
|
|
"\x63\xb9\x31\xbd\x47\x41\x7a\x81"
|
||
|
|
"\xa5\x38\x32\x7a\xf9\x27\xda\x3e";
|
||
|
|
|
||
|
|
static gk_s32 rsa_private(const gk_cipher_rsa_private_key *pri_key,
|
||
|
|
gk_cipher_ca_type ca_type, const gk_u8 *input, gk_u8 *output)
|
||
|
|
{
|
||
|
|
cipher_rsa_data_s rsa_data;
|
||
|
|
|
||
|
|
inlet_var_is_null_return(pri_key);
|
||
|
|
inlet_var_is_null_return(pri_key->d);
|
||
|
|
inlet_var_is_null_return(pri_key->n);
|
||
|
|
inlet_var_is_null_return(input);
|
||
|
|
inlet_var_is_null_return(output);
|
||
|
|
|
||
|
|
rsa_data.rsa_n = pri_key->n;
|
||
|
|
rsa_data.rsa_k = pri_key->d;
|
||
|
|
rsa_data.rsa_n_len = pri_key->n_len;
|
||
|
|
rsa_data.rsa_k_len = pri_key->d_len;
|
||
|
|
rsa_data.input_data = (gk_u8 *)input;
|
||
|
|
rsa_data.output_data = output;
|
||
|
|
rsa_data.data_len = pri_key->n_len;
|
||
|
|
rsa_data.ca_type = GK_CIPHER_KEY_SRC_USER;
|
||
|
|
|
||
|
|
return cipher_ioctl(g_cipher_dev_fd, CMD_CIPHER_CALCRSA, &rsa_data);
|
||
|
|
}
|
||
|
|
|
||
|
|
static gk_s32 rsa_public(const gk_cipher_rsa_pub_key *pub_key, const gk_u8 *input, gk_u8 *output)
|
||
|
|
{
|
||
|
|
cipher_rsa_data_s rsa_data;
|
||
|
|
|
||
|
|
inlet_var_is_null_return(pub_key);
|
||
|
|
inlet_var_is_null_return(pub_key->n);
|
||
|
|
inlet_var_is_null_return(pub_key->e);
|
||
|
|
inlet_var_is_null_return(input);
|
||
|
|
inlet_var_is_null_return(output);
|
||
|
|
|
||
|
|
rsa_data.rsa_n = pub_key->n;
|
||
|
|
rsa_data.rsa_k = pub_key->e;
|
||
|
|
rsa_data.rsa_n_len = pub_key->n_len;
|
||
|
|
rsa_data.rsa_k_len = pub_key->e_len;
|
||
|
|
rsa_data.input_data = (gk_u8 *)input;
|
||
|
|
rsa_data.output_data = output;
|
||
|
|
rsa_data.data_len = pub_key->n_len;
|
||
|
|
rsa_data.ca_type = GK_CIPHER_KEY_SRC_USER;
|
||
|
|
return cipher_ioctl(g_cipher_dev_fd, CMD_CIPHER_CALCRSA, &rsa_data);
|
||
|
|
}
|
||
|
|
|
||
|
|
static gk_s32 rsa_get_attr(gk_u32 scheme, gk_u16 rsa_n_len, rsa_padding_s *pad)
|
||
|
|
{
|
||
|
|
gk_s32 ret = GK_SUCCESS;
|
||
|
|
|
||
|
|
inlet_var_over_max_return(rsa_n_len, 512); /* 512 rsa n length */
|
||
|
|
|
||
|
|
pad->klen = rsa_n_len;
|
||
|
|
|
||
|
|
switch (scheme) {
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_NO_PADDING:
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_BLOCK_TYPE_0:
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_BLOCK_TYPE_1:
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_BLOCK_TYPE_2:
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_RSAES_PKCS1_V1_5:
|
||
|
|
pad->hlen = 0; /* 0 pad hlen */
|
||
|
|
pad->hash_type = GK_CIPHER_HASH_TYPE_BUTT;
|
||
|
|
break;
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_RSAES_OAEP_SHA1:
|
||
|
|
case GK_CIPHER_RSA_SIGN_SCHEME_RSASSA_PKCS1_V15_SHA1:
|
||
|
|
case GK_CIPHER_RSA_SIGN_SCHEME_RSASSA_PKCS1_PSS_SHA1:
|
||
|
|
pad->hlen = 20; /* 20 pad hlen */
|
||
|
|
pad->hash_type = GK_CIPHER_HASH_TYPE_SHA1;
|
||
|
|
break;
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_RSAES_OAEP_SHA224:
|
||
|
|
case GK_CIPHER_RSA_SIGN_SCHEME_RSASSA_PKCS1_V15_SHA224:
|
||
|
|
case GK_CIPHER_RSA_SIGN_SCHEME_RSASSA_PKCS1_PSS_SHA224:
|
||
|
|
pad->hlen = 28; /* 28 pad hlen */
|
||
|
|
pad->hash_type = GK_CIPHER_HASH_TYPE_SHA224;
|
||
|
|
break;
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_RSAES_OAEP_SHA256:
|
||
|
|
case GK_CIPHER_RSA_SIGN_SCHEME_RSASSA_PKCS1_V15_SHA256:
|
||
|
|
case GK_CIPHER_RSA_SIGN_SCHEME_RSASSA_PKCS1_PSS_SHA256:
|
||
|
|
pad->hlen = 32; /* 32 pad hlen */
|
||
|
|
pad->hash_type = GK_CIPHER_HASH_TYPE_SHA256;
|
||
|
|
break;
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_RSAES_OAEP_SHA384:
|
||
|
|
case GK_CIPHER_RSA_SIGN_SCHEME_RSASSA_PKCS1_V15_SHA384:
|
||
|
|
case GK_CIPHER_RSA_SIGN_SCHEME_RSASSA_PKCS1_PSS_SHA384:
|
||
|
|
pad->hlen = 48; /* 48 pad hlen */
|
||
|
|
pad->hash_type = GK_CIPHER_HASH_TYPE_SHA384;
|
||
|
|
break;
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_RSAES_OAEP_SHA512:
|
||
|
|
case GK_CIPHER_RSA_SIGN_SCHEME_RSASSA_PKCS1_V15_SHA512:
|
||
|
|
case GK_CIPHER_RSA_SIGN_SCHEME_RSASSA_PKCS1_PSS_SHA512:
|
||
|
|
pad->hlen = 64; /* 64 pad hlen */
|
||
|
|
pad->hash_type = GK_CIPHER_HASH_TYPE_SHA512;
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
gk_err_cipher("RSA scheme (0x%x) is invalid.\n", scheme);
|
||
|
|
ret = GK_ERR_CIPHER_INVALID_PARA;
|
||
|
|
}
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
static gk_s32 rsa_pkcs1_mgf1_get_md_len(gk_cipher_hash_type hash_type, gk_u32 *md_len)
|
||
|
|
{
|
||
|
|
switch (hash_type) {
|
||
|
|
case GK_CIPHER_HASH_TYPE_SHA1:
|
||
|
|
*md_len = 20; /* 20 md len */
|
||
|
|
break;
|
||
|
|
case GK_CIPHER_HASH_TYPE_SHA224:
|
||
|
|
*md_len = 28; /* 28 md len */
|
||
|
|
break;
|
||
|
|
case GK_CIPHER_HASH_TYPE_SHA256:
|
||
|
|
*md_len = 32; /* 32 md len */
|
||
|
|
break;
|
||
|
|
case GK_CIPHER_HASH_TYPE_SHA384:
|
||
|
|
*md_len = 48; /* 48 md len */
|
||
|
|
break;
|
||
|
|
case GK_CIPHER_HASH_TYPE_SHA512:
|
||
|
|
*md_len = 64; /* 64 md len */
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
*md_len = 0;
|
||
|
|
gk_err_cipher("hash type is invalid.\n");
|
||
|
|
return GK_ERR_CIPHER_INVALID_PARA;
|
||
|
|
}
|
||
|
|
return GK_SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
static gk_s32 rsa_pkcs1_mgf1(gk_cipher_hash_type hash_type,
|
||
|
|
gk_u8 *seed, gk_u32 seed_len, gk_u8 *mask, gk_u32 mask_len)
|
||
|
|
{
|
||
|
|
gk_s32 ret = GK_FAILURE;
|
||
|
|
gk_u32 i, out_len;
|
||
|
|
gk_cipher_hash_attr hash_attr;
|
||
|
|
gk_u8 *ptr_cnt = GK_NULL;
|
||
|
|
gk_u8 *ptr_md = GK_NULL;
|
||
|
|
gk_u8 *ptr_seed = GK_NULL;
|
||
|
|
|
||
|
|
ptr_cnt = (gk_u8 *)memalign(ARCH_DMA_MINALIGN, 4); /* 4 align */
|
||
|
|
if (ptr_cnt == GK_NULL) {
|
||
|
|
gk_err_cipher("memalign for ptr_cnt invalid.\n");
|
||
|
|
return GK_ERR_CIPHER_INVALID_POINT;
|
||
|
|
}
|
||
|
|
|
||
|
|
ptr_md = (gk_u8 *)memalign(ARCH_DMA_MINALIGN, HASH_RESULT_MAX_LEN);
|
||
|
|
rsa_var_null_goto_lab(ptr_md, ret, free_ptr_cnt);
|
||
|
|
|
||
|
|
ptr_seed = (gk_u8 *)memalign(ARCH_DMA_MINALIGN, seed_len);
|
||
|
|
rsa_var_null_goto_lab(ptr_md, ret, free_ptr_md);
|
||
|
|
|
||
|
|
crypto_memset(ptr_cnt, 4, 0, 4); /* 4 ptr_cnt size */
|
||
|
|
crypto_memset(ptr_md, HASH_RESULT_MAX_LEN, 0, HASH_RESULT_MAX_LEN);
|
||
|
|
crypto_memcpy(ptr_seed, seed_len, seed, seed_len);
|
||
|
|
|
||
|
|
/* PKCS#1 V2.1 only use sha1 function, Others allow for future expansion */
|
||
|
|
hash_attr.sha_type = hash_type;
|
||
|
|
for (i = 0, out_len = 0; out_len < mask_len; i++) {
|
||
|
|
gk_handle hash_handle;
|
||
|
|
gk_u32 j, md_len;
|
||
|
|
|
||
|
|
ret = rsa_pkcs1_mgf1_get_md_len(hash_type, &md_len);
|
||
|
|
rsa_ret_fail_goto_lab(ret, free_ptr_seed);
|
||
|
|
|
||
|
|
ptr_cnt[0] = (gk_u8)((i >> 24) & 0xFF); /* 0 ptr_cnt index, 24 right shift */
|
||
|
|
ptr_cnt[1] = (gk_u8)((i >> 16) & 0xFF); /* 1 ptr_cnt index, 16 right shift */
|
||
|
|
ptr_cnt[2] = (gk_u8)((i >> 8) & 0xFF); /* 2 ptr_cnt index, 8 right shift */
|
||
|
|
ptr_cnt[3] = (gk_u8)(i & 0xFF); /* 3 ptr_cnt index */
|
||
|
|
|
||
|
|
ret = gk_api_cipher_hash_init(&hash_attr, &hash_handle) ||
|
||
|
|
gk_api_cipher_hash_update(hash_handle, ptr_seed, seed_len) ||
|
||
|
|
gk_api_cipher_hash_update(hash_handle, ptr_cnt, 4) || /* 4 ptr_cnt size */
|
||
|
|
gk_api_cipher_hash_final(hash_handle, ptr_md);
|
||
|
|
rsa_ret_fail_goto_lab(ret, free_ptr_seed);
|
||
|
|
|
||
|
|
for (j = 0; (j < md_len) && (out_len < mask_len); j++)
|
||
|
|
mask[out_len++] ^= ptr_md[j];
|
||
|
|
}
|
||
|
|
|
||
|
|
free_ptr_seed:
|
||
|
|
free(ptr_seed);
|
||
|
|
ptr_seed = GK_NULL;
|
||
|
|
|
||
|
|
free_ptr_md:
|
||
|
|
free(ptr_md);
|
||
|
|
ptr_md = GK_NULL;
|
||
|
|
|
||
|
|
free_ptr_cnt:
|
||
|
|
free(ptr_cnt);
|
||
|
|
ptr_cnt = GK_NULL;
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
static gk_s32 mbedtls_get_random_number(gk_void *param, gk_u8 *rand, size_t size)
|
||
|
|
{
|
||
|
|
gk_u32 i;
|
||
|
|
gk_s32 ret;
|
||
|
|
gk_u32 randnum, left_size;
|
||
|
|
|
||
|
|
crypto_memset(rand, size, 0, size);
|
||
|
|
for (i = 0; i < size; i += 4) { /* 4 word bytes */
|
||
|
|
ret = mpi_cipher_get_random_number(&randnum, -1);
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, mpi_cipher_get_random_number);
|
||
|
|
|
||
|
|
left_size = (size - i) > 4 ? 4 : (size - i); /* 4 word bytes */
|
||
|
|
switch (left_size) {
|
||
|
|
case 4: /* left 4 */
|
||
|
|
rand[i + 3] = (gk_u8)(randnum >> 24) & 0xFF; /* 3 rand index, 24 right shift */
|
||
|
|
/* fall through */
|
||
|
|
case 3: /* left 3 */
|
||
|
|
rand[i + 2] = (gk_u8)(randnum >> 16) & 0xFF; /* 2 rand index, 16 right shift */
|
||
|
|
/* fall through */
|
||
|
|
case 2: /* left 2 */
|
||
|
|
rand[i + 1] = (gk_u8)(randnum >> 8) & 0xFF; /* 1 rand index, 8 right shift */
|
||
|
|
/* fall through */
|
||
|
|
case 1: /* left 1 */
|
||
|
|
rand[i + 0] = (gk_u8)(randnum >> 0) & 0xFF; /* 0 rand index */
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
gk_err_cipher("left size %u is error\n", left_size);
|
||
|
|
return GK_ERR_CIPHER_INVALID_PARA;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/* non-zero random octet string */
|
||
|
|
for (i = 0; i < size; i++) {
|
||
|
|
if (rand[i] != 0x00)
|
||
|
|
continue;
|
||
|
|
|
||
|
|
ret = mpi_cipher_get_random_number(&randnum, -1);
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, mpi_cipher_get_random_number);
|
||
|
|
rand[i] = (gk_u8)(randnum) & 0xFF;
|
||
|
|
i = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
return GK_SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
static gk_u32 rsa_get_bit_num(gk_u8 *big_num, gk_u32 num_len)
|
||
|
|
{
|
||
|
|
static const gk_s8 bits[16] = {0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4}; /* 16 bits size */
|
||
|
|
gk_u32 i;
|
||
|
|
|
||
|
|
inlet_var_is_null_return(big_num);
|
||
|
|
|
||
|
|
for (i = 0; i < num_len; i++) {
|
||
|
|
gk_u32 num;
|
||
|
|
num = bits[(big_num[i] & 0xF0) >> 4]; /* 4 right shift */
|
||
|
|
|
||
|
|
if (num > 0)
|
||
|
|
return (num_len - i - 1) * 8 + num + 4; /* 8, 4 */
|
||
|
|
|
||
|
|
num = bits[big_num[i] & 0xF];
|
||
|
|
if (num > 0)
|
||
|
|
return (num_len - i - 1) * 8 + num; /* 8 */
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* PKCS #1: EME-OAEP encoding */
|
||
|
|
/* ************************************************************
|
||
|
|
+----------+---------+--+-------+
|
||
|
|
DB = | lHash | PS |01| M |
|
||
|
|
+----------+---------+--+-------+
|
||
|
|
|
|
||
|
|
+----------+ V
|
||
|
|
| ptr_seed |--> MGF ---> xor
|
||
|
|
+----------+ |
|
||
|
|
| |
|
||
|
|
+--+ V |
|
||
|
|
|00| xor <----- MGF <-----|
|
||
|
|
+--+ | |
|
||
|
|
| | |
|
||
|
|
V V V
|
||
|
|
+--+----------+----------------------------+
|
||
|
|
EM = |00|maskedSeed| maskedDB |
|
||
|
|
+--+----------+----------------------------+
|
||
|
|
1 hlen k - hlen- 1
|
||
|
|
|
||
|
|
so: PS_LEN = k - hlen - 1 - (hlen + mlen + 1) = k - 2hlen - mlen - 2 > 0
|
||
|
|
so: mlen < k - 2hlen - 2
|
||
|
|
************************************************************ */
|
||
|
|
static gk_s32 rsa_padding_add_pkcs1_oaep(rsa_padding_s *pad)
|
||
|
|
{
|
||
|
|
gk_s32 ret;
|
||
|
|
gk_u32 db_len;
|
||
|
|
gk_u8 *ptr_db = GK_NULL;
|
||
|
|
gk_u8 *ptr_seed = GK_NULL;
|
||
|
|
const gk_s8 *l_hash = g_empty_l_sha1;
|
||
|
|
|
||
|
|
/* In the v2.1 of PKCS #1, L is the empty string; */
|
||
|
|
/* other uses outside the scope of rsa specifications */
|
||
|
|
if (pad->hash_type == GK_CIPHER_HASH_TYPE_SHA224) {
|
||
|
|
l_hash = g_empty_l_sha224;
|
||
|
|
} else if (pad->hash_type == GK_CIPHER_HASH_TYPE_SHA256) {
|
||
|
|
l_hash = g_empty_l_sha256;
|
||
|
|
} else if (pad->hash_type == GK_CIPHER_HASH_TYPE_SHA384) {
|
||
|
|
l_hash = g_empty_l_sha384;
|
||
|
|
} else if (pad->hash_type == GK_CIPHER_HASH_TYPE_SHA512) {
|
||
|
|
l_hash = g_empty_l_sha512;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (pad->in_len > pad->klen - 2 * pad->hlen - 2) { /* 2 */
|
||
|
|
gk_err_cipher("input_len is invalid.\n");
|
||
|
|
return GK_ERR_CIPHER_INVALID_PARA;
|
||
|
|
}
|
||
|
|
|
||
|
|
pad->out_data[0] = 0;
|
||
|
|
ptr_seed = pad->out_data + 1;
|
||
|
|
ptr_db = pad->out_data + pad->hlen + 1;
|
||
|
|
db_len = pad->klen - pad->hlen - 1;
|
||
|
|
|
||
|
|
/* set lHash */
|
||
|
|
crypto_memcpy(ptr_db, db_len, l_hash, pad->hlen);
|
||
|
|
|
||
|
|
/* set PS with 0x00 */
|
||
|
|
crypto_memset(&ptr_db[pad->hlen], db_len - pad->hlen, 0, db_len - pad->in_len - pad->hlen - 1);
|
||
|
|
|
||
|
|
/* set 0x01 after PS */
|
||
|
|
ptr_db[db_len - pad->in_len - 1] = 0x01;
|
||
|
|
|
||
|
|
/* set M */
|
||
|
|
crypto_memcpy(&ptr_db[db_len - pad->in_len], pad->in_len, pad->in_data, pad->in_len);
|
||
|
|
|
||
|
|
/* compute maskedDB */
|
||
|
|
ret = mbedtls_get_random_number(GK_NULL, ptr_seed, pad->hlen);
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, mbedtls_get_random_number);
|
||
|
|
|
||
|
|
ret = rsa_pkcs1_mgf1(pad->hash_type, ptr_seed, pad->hlen, ptr_db, pad->klen - pad->hlen - 1);
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, rsa_pkcs1_mgf1);
|
||
|
|
|
||
|
|
/* compute maskedSeed */
|
||
|
|
ret = rsa_pkcs1_mgf1(pad->hash_type, ptr_db, pad->klen - pad->hlen - 1, ptr_seed, pad->hlen);
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, rsa_pkcs1_mgf1);
|
||
|
|
|
||
|
|
pad->out_len = pad->klen;
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* PKCS #1: RSAES-PKCS1-V1_5-ENCRYPT */
|
||
|
|
/*************************************************
|
||
|
|
formula: EM = 0x00 || 0x02 || PS || 0x00 || M
|
||
|
|
|
||
|
|
formula: PS_LEN > 8, mlen < klen - 11
|
||
|
|
*************************************************/
|
||
|
|
static gk_s32 rsa_padding_add_pkcs1_v15(rsa_padding_s *pad)
|
||
|
|
{
|
||
|
|
gk_u32 index = 0;
|
||
|
|
gk_s32 ret;
|
||
|
|
|
||
|
|
if (pad->in_len > pad->klen - 11) { /* 11 */
|
||
|
|
gk_err_cipher("input_len is invalid.\n");
|
||
|
|
return GK_ERR_CIPHER_INVALID_PARA;
|
||
|
|
}
|
||
|
|
|
||
|
|
pad->out_data[index++] = 0x00;
|
||
|
|
pad->out_data[index++] = 0x02;
|
||
|
|
ret = mbedtls_get_random_number(GK_NULL, &pad->out_data[index], pad->klen - pad->in_len - 3); /* 3 */
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, mbedtls_get_random_number);
|
||
|
|
|
||
|
|
index += pad->klen - pad->in_len - 3; /* 3 */
|
||
|
|
pad->out_data[index++] = 0x00;
|
||
|
|
crypto_memcpy(&pad->out_data[index], pad->klen - index, pad->in_data, pad->in_len);
|
||
|
|
|
||
|
|
pad->out_len = pad->klen;
|
||
|
|
|
||
|
|
return GK_SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* PKCS #1: block type 0,1,2 message padding */
|
||
|
|
/* ************************************************
|
||
|
|
formula: EB = 00 || BT || PS || 00 || D
|
||
|
|
|
||
|
|
formula: PS_LEN >= 8, mlen < klen - 11
|
||
|
|
************************************************ */
|
||
|
|
static gk_s32 rsa_padding_add_pkcs1_type(rsa_padding_s *pad)
|
||
|
|
{
|
||
|
|
gk_u32 pad_len;
|
||
|
|
gk_u8 *key_eb = GK_NULL;
|
||
|
|
gk_s32 ret;
|
||
|
|
|
||
|
|
if (pad->in_len > pad->klen - 11) { /* 11 */
|
||
|
|
gk_err_cipher("input_len is invalid.\n");
|
||
|
|
return GK_ERR_CIPHER_INVALID_PARA;
|
||
|
|
}
|
||
|
|
|
||
|
|
key_eb = pad->out_data;
|
||
|
|
|
||
|
|
*(key_eb++) = 0;
|
||
|
|
*(key_eb++) = pad->key_bt; /* Private Key BT (Block Type) */
|
||
|
|
|
||
|
|
/* pad out with 0xff data */
|
||
|
|
pad_len = pad->klen - 3 - pad->in_len; /* 3 */
|
||
|
|
if (pad->key_bt == 0x00) {
|
||
|
|
crypto_memset(key_eb, pad->klen - (gk_u32)(key_eb - pad->out_data), 0x00, pad_len);
|
||
|
|
} else if (pad->key_bt == 0x01) {
|
||
|
|
crypto_memset(key_eb, pad->klen - (gk_u32)(key_eb - pad->out_data), 0xFF, pad_len);
|
||
|
|
} else if (pad->key_bt == 0x02) {
|
||
|
|
ret = mbedtls_get_random_number(GK_NULL, key_eb, pad_len);
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, mbedtls_get_random_number);
|
||
|
|
} else {
|
||
|
|
gk_err_cipher("BT(0x%x) is invalid.\n", pad->key_bt);
|
||
|
|
return GK_ERR_CIPHER_INVALID_PARA;
|
||
|
|
}
|
||
|
|
|
||
|
|
key_eb += pad_len;
|
||
|
|
*(key_eb++) = 0x00;
|
||
|
|
crypto_memcpy(key_eb, pad->klen - (gk_u32)(key_eb - pad->out_data), pad->in_data, pad->in_len);
|
||
|
|
pad->out_len = pad->klen;
|
||
|
|
|
||
|
|
return GK_SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* PKCS #1: RSAES-PKCS1-V1_5-Signature */
|
||
|
|
/* ********************************************************
|
||
|
|
formula: EM = 0x00 || 0x01 || PS || 0x00 || T
|
||
|
|
|
||
|
|
T ::= SEQUENCE {
|
||
|
|
digestAlgorithm AlgorithmIdentifier,
|
||
|
|
digest OCTET STRING
|
||
|
|
}
|
||
|
|
The first field identifies the hash function and the second
|
||
|
|
contains the hash value
|
||
|
|
********************************************************* */
|
||
|
|
static gk_void rsa_padding_add_emsa_pkcs1_v15_sha1(rsa_padding_s *pad, gk_u8 *p)
|
||
|
|
{
|
||
|
|
gk_u32 pad_len, buf_len;
|
||
|
|
|
||
|
|
pad_len = pad->klen - 3 - 35; /* 3, 35 */
|
||
|
|
buf_len = pad->klen - (gk_u32)(p - pad->out_data);
|
||
|
|
crypto_memset(p, buf_len, 0xFF, pad_len);
|
||
|
|
p += pad_len;
|
||
|
|
*p++ = 0;
|
||
|
|
buf_len = pad->klen - (gk_u32)(p - pad->out_data);
|
||
|
|
crypto_memcpy(p, buf_len, ASN1_HASH_SHA1, 15); /* 15 copy size */
|
||
|
|
p += 15; /* 15 p shift */
|
||
|
|
buf_len = pad->klen - (gk_u32)(p - pad->out_data);
|
||
|
|
crypto_memcpy(p, buf_len, pad->in_data, pad->in_len);
|
||
|
|
}
|
||
|
|
|
||
|
|
static gk_void rsa_padding_add_emsa_pkcs1_v15_sha224(rsa_padding_s *pad, gk_u8 *p)
|
||
|
|
{
|
||
|
|
gk_u32 pad_len, buf_len;
|
||
|
|
|
||
|
|
pad_len = pad->klen - 3 - 19 - pad->in_len; /* 3, 19 */
|
||
|
|
buf_len = pad->klen - (gk_u32)(p - pad->out_data);
|
||
|
|
crypto_memset(p, buf_len, 0xFF, pad_len);
|
||
|
|
p += pad_len;
|
||
|
|
*p++ = 0;
|
||
|
|
buf_len = pad->klen - (gk_u32)(p - pad->out_data);
|
||
|
|
crypto_memcpy(p, buf_len, ASN1_HASH_SHA224, 19); /* 19 copy size */
|
||
|
|
p += 19; /* 19 p shift */
|
||
|
|
buf_len = pad->klen - (gk_u32)(p - pad->out_data);
|
||
|
|
crypto_memcpy(p, buf_len, pad->in_data, pad->in_len);
|
||
|
|
}
|
||
|
|
|
||
|
|
static gk_void rsa_padding_add_emsa_pkcs1_v15_sha256(rsa_padding_s *pad, gk_u8 *p)
|
||
|
|
{
|
||
|
|
gk_u32 pad_len, buf_len;
|
||
|
|
|
||
|
|
pad_len = pad->klen - 3 - 19 - pad->in_len; /* 3, 19 */
|
||
|
|
buf_len = pad->klen - (gk_u32)(p - pad->out_data);
|
||
|
|
crypto_memset(p, buf_len, 0xFF, pad_len);
|
||
|
|
p += pad_len;
|
||
|
|
*p++ = 0;
|
||
|
|
buf_len = pad->klen - (gk_u32)(p - pad->out_data);
|
||
|
|
crypto_memcpy(p, buf_len, ASN1_HASH_SHA256, 19); /* 19 copy size */
|
||
|
|
p += 19; /* 19 p shift */
|
||
|
|
buf_len = pad->klen - (gk_u32)(p - pad->out_data);
|
||
|
|
crypto_memcpy(p, buf_len, pad->in_data, pad->in_len);
|
||
|
|
}
|
||
|
|
|
||
|
|
static gk_void rsa_padding_add_emsa_pkcs1_v15_sha384(rsa_padding_s *pad, gk_u8 *p)
|
||
|
|
{
|
||
|
|
gk_u32 pad_len, buf_len;
|
||
|
|
|
||
|
|
pad_len = pad->klen - 3 - 19 - pad->in_len; /* 3, 19 */
|
||
|
|
buf_len = pad->klen - (gk_u32)(p - pad->out_data);
|
||
|
|
crypto_memset(p, buf_len, 0xFF, pad_len);
|
||
|
|
p += pad_len;
|
||
|
|
*p++ = 0;
|
||
|
|
buf_len = pad->klen - (gk_u32)(p - pad->out_data);
|
||
|
|
crypto_memcpy(p, buf_len, ASN1_HASH_SHA384, 19); /* 19 copy size */
|
||
|
|
p += 19; /* 19 p shift */
|
||
|
|
buf_len = pad->klen - (gk_u32)(p - pad->out_data);
|
||
|
|
crypto_memcpy(p, buf_len, pad->in_data, pad->in_len);
|
||
|
|
}
|
||
|
|
|
||
|
|
static gk_void rsa_padding_add_emsa_pkcs1_v15_sha512(rsa_padding_s *pad, gk_u8 *p)
|
||
|
|
{
|
||
|
|
gk_u32 pad_len, buf_len;
|
||
|
|
|
||
|
|
pad_len = pad->klen - 3 - 19 - pad->in_len; /* 3, 19 */
|
||
|
|
buf_len = pad->klen - (gk_u32)(p - pad->out_data);
|
||
|
|
crypto_memset(p, buf_len, 0xFF, pad_len);
|
||
|
|
|
||
|
|
p += pad_len;
|
||
|
|
*p++ = 0;
|
||
|
|
crypto_memcpy(p, pad->klen, ASN1_HASH_SHA512, 19); /* 19 copy size */
|
||
|
|
|
||
|
|
p += 19; /* 19 p shift */
|
||
|
|
buf_len = pad->klen - (gk_u32)(p - pad->out_data);
|
||
|
|
crypto_memcpy(p, buf_len, pad->in_data, pad->in_len);
|
||
|
|
}
|
||
|
|
|
||
|
|
static gk_s32 rsa_padding_add_emsa_pkcs1_v15(rsa_padding_s *pad)
|
||
|
|
{
|
||
|
|
gk_u8 *p = pad->out_data;
|
||
|
|
|
||
|
|
pad->out_len = pad->klen;
|
||
|
|
*p++ = 0;
|
||
|
|
*p++ = RSA_SIGN;
|
||
|
|
|
||
|
|
switch (pad->hash_type) {
|
||
|
|
case GK_CIPHER_HASH_TYPE_SHA1:
|
||
|
|
rsa_padding_add_emsa_pkcs1_v15_sha1(pad, p);
|
||
|
|
break;
|
||
|
|
case GK_CIPHER_HASH_TYPE_SHA224:
|
||
|
|
rsa_padding_add_emsa_pkcs1_v15_sha224(pad, p);
|
||
|
|
break;
|
||
|
|
case GK_CIPHER_HASH_TYPE_SHA256:
|
||
|
|
rsa_padding_add_emsa_pkcs1_v15_sha256(pad, p);
|
||
|
|
break;
|
||
|
|
case GK_CIPHER_HASH_TYPE_SHA384:
|
||
|
|
rsa_padding_add_emsa_pkcs1_v15_sha384(pad, p);
|
||
|
|
break;
|
||
|
|
case GK_CIPHER_HASH_TYPE_SHA512:
|
||
|
|
rsa_padding_add_emsa_pkcs1_v15_sha512(pad, p);
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
gk_err_cipher("RSA unsuporrt hash type: 0x%x.\n", pad->hash_type);
|
||
|
|
return GK_ERR_CIPHER_INVALID_PARA;
|
||
|
|
}
|
||
|
|
|
||
|
|
return GK_SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* *****************************************************************
|
||
|
|
+-----------+
|
||
|
|
| M |
|
||
|
|
+-----------+
|
||
|
|
|
|
||
|
|
V
|
||
|
|
Hash
|
||
|
|
|
|
||
|
|
V
|
||
|
|
+--------+----------+----------+
|
||
|
|
M' = |Padding1| mHash | salt |
|
||
|
|
+--------+----------+----------+
|
||
|
|
|
|
||
|
|
+--------+----------+ V
|
||
|
|
DB = |Padding2|maskedseed| Hash
|
||
|
|
+--------+----------+ |
|
||
|
|
| |
|
||
|
|
V | +--+
|
||
|
|
xor <----- MGF <----| |bc|
|
||
|
|
| | +--+
|
||
|
|
| | |
|
||
|
|
V V V
|
||
|
|
+-------------------+----- -------+--+
|
||
|
|
EM = | maskedDB | maskedseed |bc|
|
||
|
|
+-------------------+-------------+--+
|
||
|
|
***************************************************************** */
|
||
|
|
static gk_s32 rsa_padding_add_pkcs1_pss_hash(rsa_padding_s *pad, rsa_pkcs1_pss_s *pss)
|
||
|
|
{
|
||
|
|
gk_s32 ret;
|
||
|
|
gk_u32 mlen, index;
|
||
|
|
gk_u8 *ptr_m = GK_NULL;
|
||
|
|
gk_handle hash_handle = 0;
|
||
|
|
gk_cipher_hash_attr hash_attr;
|
||
|
|
|
||
|
|
mlen = pss->slen + pad->hlen + 8; /* 8 */
|
||
|
|
ptr_m = (gk_u8 *)memalign(ARCH_DMA_MINALIGN, mlen);
|
||
|
|
rsa_func_fail_return(ptr_m == GK_NULL, GK_ERR_CIPHER_INVALID_POINT, memalign);
|
||
|
|
|
||
|
|
/* M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt */
|
||
|
|
index = 0;
|
||
|
|
crypto_memset(ptr_m, mlen, 0x00, 8); /* 8 clean size */
|
||
|
|
index += 8; /* 8 */
|
||
|
|
crypto_memcpy(&ptr_m[index], mlen - index, pad->in_data, pad->in_len);
|
||
|
|
index += pad->in_len;
|
||
|
|
crypto_memcpy(&ptr_m[index], mlen - index, pss->salt, pss->slen);
|
||
|
|
index += pss->slen;
|
||
|
|
|
||
|
|
crypto_memset(&hash_attr, sizeof(hash_attr), 0, sizeof(gk_cipher_hash_attr));
|
||
|
|
hash_attr.sha_type = pad->hash_type;
|
||
|
|
ret = gk_api_cipher_hash_init(&hash_attr, &hash_handle) ||
|
||
|
|
gk_api_cipher_hash_update(hash_handle, ptr_m, index) ||
|
||
|
|
gk_api_cipher_hash_final(hash_handle, pss->masked_seed);
|
||
|
|
free(ptr_m); /* Must free ptr_m befort return */
|
||
|
|
ptr_m = GK_NULL;
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, gk_api_cipher_hash_final);
|
||
|
|
|
||
|
|
/* formula: maskedDB = DB xor dbMask, DB = PS || 0x01 || salt */
|
||
|
|
index = 0;
|
||
|
|
crypto_memset(&pss->masked_db[index],
|
||
|
|
pss->key_len - index, 0x00, pss->key_len - pss->slen - pad->hlen - 2); /* 2 */
|
||
|
|
index += pss->key_len - pss->slen - pad->hlen - 2; /* 2 */
|
||
|
|
pss->masked_db[index++] = 0x01;
|
||
|
|
crypto_memcpy(&pss->masked_db[index], pss->key_len - index, pss->salt, pss->slen);
|
||
|
|
ret = rsa_pkcs1_mgf1(pad->hash_type,
|
||
|
|
pss->masked_seed, pad->hlen, pss->masked_db, pss->key_len - pad->hlen - 1);
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, rsa_pkcs1_mgf1);
|
||
|
|
|
||
|
|
pad->out_data[pss->key_len - 1] = 0xBC;
|
||
|
|
|
||
|
|
if (pss->msb_bits)
|
||
|
|
pad->out_data[0] &= 0xFF >> (8 - pss->msb_bits); /* 8 */
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
static gk_s32 rsa_padding_add_pkcs1_pss(rsa_padding_s *pad)
|
||
|
|
{
|
||
|
|
rsa_pkcs1_pss_s pss;
|
||
|
|
gk_s32 ret;
|
||
|
|
|
||
|
|
crypto_memset(&pss, sizeof(rsa_pkcs1_pss_s), 0, sizeof(rsa_pkcs1_pss_s));
|
||
|
|
pss.slen = pad->hlen;
|
||
|
|
pss.key_len = (pad->em_bit + 7) / 8; /* 7, 8 */
|
||
|
|
pss.msb_bits = (pad->em_bit - 1) & 0x07;
|
||
|
|
|
||
|
|
pad->out_len = pss.key_len;
|
||
|
|
|
||
|
|
if (pss.key_len < (pad->hlen + pss.slen + 2)) { /* 2 */
|
||
|
|
gk_err_cipher("message too long\n");
|
||
|
|
return GK_ERR_CIPHER_INVALID_PARA;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (pss.msb_bits == 0) {
|
||
|
|
*pad->out_data++ = 0;
|
||
|
|
pss.key_len--;
|
||
|
|
}
|
||
|
|
|
||
|
|
pss.masked_db = pad->out_data;
|
||
|
|
pss.masked_seed = pad->out_data + pss.key_len - pad->hlen - 1;
|
||
|
|
|
||
|
|
/* Generate a random octet string salt of length sLen */
|
||
|
|
ret = mbedtls_get_random_number(GK_NULL, pss.salt, pss.slen);
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, mbedtls_get_random_number);
|
||
|
|
|
||
|
|
return rsa_padding_add_pkcs1_pss_hash(pad, &pss);
|
||
|
|
}
|
||
|
|
|
||
|
|
static gk_s32 rsa_padding_check_pkcs1_oaep(rsa_padding_s *pad)
|
||
|
|
{
|
||
|
|
gk_s32 ret;
|
||
|
|
gk_u32 i;
|
||
|
|
const gk_s8 *l_hash = g_empty_l_sha1;
|
||
|
|
gk_u8 *ptr_seed = GK_NULL;
|
||
|
|
gk_u8 *ptr_db = GK_NULL;
|
||
|
|
gk_u8 *masked_db = GK_NULL;
|
||
|
|
|
||
|
|
if (pad->hash_type == GK_CIPHER_HASH_TYPE_SHA224) {
|
||
|
|
l_hash = g_empty_l_sha224;
|
||
|
|
} else if (pad->hash_type == GK_CIPHER_HASH_TYPE_SHA256) {
|
||
|
|
l_hash = g_empty_l_sha256;
|
||
|
|
} else if (pad->hash_type == GK_CIPHER_HASH_TYPE_SHA384) {
|
||
|
|
l_hash = g_empty_l_sha384;
|
||
|
|
} else if (pad->hash_type == GK_CIPHER_HASH_TYPE_SHA512) {
|
||
|
|
l_hash = g_empty_l_sha512;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (pad->klen < 2 * pad->hlen + 2) { /* 2 */
|
||
|
|
gk_err_cipher("input_len is invalid.\n");
|
||
|
|
return GK_ERR_CIPHER_INVALID_PARA;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (pad->in_data[0] != 0x00) {
|
||
|
|
gk_err_cipher("EM[0] != 0.\n");
|
||
|
|
return GK_ERR_CIPHER_FAILED_DECRYPT;
|
||
|
|
}
|
||
|
|
|
||
|
|
pad->out_len = 0;
|
||
|
|
masked_db = pad->in_data + pad->hlen + 1;
|
||
|
|
ptr_seed = pad->in_data + 1;
|
||
|
|
ptr_db = pad->in_data + pad->hlen + 1;
|
||
|
|
ret = rsa_pkcs1_mgf1(pad->hash_type, masked_db, pad->klen - pad->hlen - 1, ptr_seed, pad->hlen);
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, rsa_pkcs1_mgf1);
|
||
|
|
|
||
|
|
ret = rsa_pkcs1_mgf1(pad->hash_type, ptr_seed, pad->hlen, ptr_db, pad->klen - pad->hlen - 1);
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, rsa_pkcs1_mgf1);
|
||
|
|
|
||
|
|
ret = memcmp(ptr_db, l_hash, pad->hlen);
|
||
|
|
rsa_func_fail_return(ret != 0, GK_ERR_CIPHER_FAILED_DECRYPT, memcmp);
|
||
|
|
|
||
|
|
for (i = pad->hlen; i < pad->klen - pad->hlen - 1; i++) {
|
||
|
|
if ((ptr_db[i] == 0x01)) {
|
||
|
|
crypto_memcpy(pad->out_data, pad->klen, ptr_db + i + 1, pad->klen - pad->hlen - i - 2); /* 2 */
|
||
|
|
pad->out_len = pad->klen - pad->hlen - i - 2; /* 2 */
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (i >= pad->klen - pad->hlen - 1) {
|
||
|
|
gk_err_cipher("PS error.\n");
|
||
|
|
return GK_ERR_CIPHER_FAILED_DECRYPT;
|
||
|
|
}
|
||
|
|
|
||
|
|
return GK_SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
static gk_s32 rsa_padding_check_pkcs1_v15(rsa_padding_s *pad)
|
||
|
|
{
|
||
|
|
gk_u32 index = 0;
|
||
|
|
|
||
|
|
if (pad->klen < 11) { /* 11 pad->klen max size */
|
||
|
|
gk_err_cipher("input_len is invalid.\n");
|
||
|
|
return GK_ERR_CIPHER_INVALID_PARA;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (pad->in_data[index] != 0x00) {
|
||
|
|
gk_err_cipher("EM[0] != 0x00.\n");
|
||
|
|
return GK_ERR_CIPHER_FAILED_DECRYPT;
|
||
|
|
}
|
||
|
|
|
||
|
|
index++;
|
||
|
|
if (pad->in_data[index] != 0x02) {
|
||
|
|
gk_err_cipher("EM[1] != 0x02.\n");
|
||
|
|
return GK_ERR_CIPHER_FAILED_DECRYPT;
|
||
|
|
}
|
||
|
|
|
||
|
|
index++;
|
||
|
|
for (; index < pad->klen; index++) {
|
||
|
|
/* The length of PS is large than 8 octets */
|
||
|
|
if ((index >= 10) && (pad->in_data[index] == 0x00)) { /* 10 */
|
||
|
|
crypto_memcpy(pad->out_data, pad->klen, &pad->in_data[index + 1], pad->klen - 1 - index);
|
||
|
|
pad->out_len = pad->klen - 1 - index;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (index >= pad->klen) {
|
||
|
|
gk_err_cipher("PS error.\n");
|
||
|
|
return GK_ERR_CIPHER_FAILED_DECRYPT;
|
||
|
|
}
|
||
|
|
|
||
|
|
return GK_SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
static gk_s32 rsa_padding_check_pkcs1_type(rsa_padding_s *pad)
|
||
|
|
{
|
||
|
|
gk_u8 *key_eb = pad->in_data;
|
||
|
|
|
||
|
|
if (*key_eb != 0x00) {
|
||
|
|
gk_err_cipher("EB[0] != 0x00.\n");
|
||
|
|
return GK_ERR_CIPHER_FAILED_DECRYPT;
|
||
|
|
}
|
||
|
|
|
||
|
|
key_eb++;
|
||
|
|
if (*key_eb != pad->key_bt) {
|
||
|
|
gk_err_cipher("EB[1] != BT(0x%x).\n", pad->key_bt);
|
||
|
|
return GK_ERR_CIPHER_FAILED_DECRYPT;
|
||
|
|
}
|
||
|
|
|
||
|
|
key_eb++;
|
||
|
|
if (pad->key_bt == 0x00) {
|
||
|
|
for (; key_eb < pad->in_data + pad->in_len - 1; key_eb++) {
|
||
|
|
if ((*key_eb == 0x00) && (*(key_eb + 1) != 0))
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
} else if (pad->key_bt == 0x01) {
|
||
|
|
for (; key_eb < pad->in_data + pad->in_len - 1; key_eb++) {
|
||
|
|
if (*key_eb == 0xFF) {
|
||
|
|
continue;
|
||
|
|
} else if (*key_eb == 0x00) {
|
||
|
|
break;
|
||
|
|
} else {
|
||
|
|
key_eb = pad->in_data + pad->in_len - 1;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} else if (pad->key_bt == 0x02) {
|
||
|
|
for (; key_eb < pad->in_data + pad->in_len - 1; key_eb++) {
|
||
|
|
if (*key_eb == 0x00)
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
gk_err_cipher("BT(0x%x) is invalid.\n", pad->key_bt);
|
||
|
|
return GK_ERR_CIPHER_INVALID_PARA;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (key_eb >= (pad->in_data + pad->in_len - 1)) {
|
||
|
|
gk_err_cipher("PS Error.\n");
|
||
|
|
return GK_ERR_CIPHER_FAILED_DECRYPT;
|
||
|
|
}
|
||
|
|
|
||
|
|
key_eb++;
|
||
|
|
pad->out_len = pad->in_data + pad->klen - key_eb;
|
||
|
|
crypto_memcpy(pad->out_data, pad->klen, key_eb, pad->out_len);
|
||
|
|
|
||
|
|
return GK_SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
static gk_s32 rsa_padding_check_emsa_pkcs1_v15_type(rsa_padding_s *pad, gk_u8 *p)
|
||
|
|
{
|
||
|
|
gk_s32 ret;
|
||
|
|
gk_u32 len;
|
||
|
|
|
||
|
|
len = pad->klen - (gk_u32)(p - pad->in_data);
|
||
|
|
|
||
|
|
switch (pad->hash_type) {
|
||
|
|
case GK_CIPHER_HASH_TYPE_SHA1:
|
||
|
|
rsa_not_equal_return(len, 35, GK_FAILURE); /* 35 len size */
|
||
|
|
ret = memcmp(p, ASN1_HASH_SHA1, 15); /* 15 compare size */
|
||
|
|
rsa_func_fail_return(ret != 0, GK_FAILURE, memcmp);
|
||
|
|
crypto_memcpy(pad->out_data, pad->klen, p + 15, pad->hlen); /* 15 copy shift */
|
||
|
|
break;
|
||
|
|
case GK_CIPHER_HASH_TYPE_SHA224:
|
||
|
|
rsa_not_equal_return(len, (19 + pad->hlen), GK_FAILURE); /* len size: 19 + pad->hlen */
|
||
|
|
ret = memcmp(p, ASN1_HASH_SHA224, 19); /* 19 compare size */
|
||
|
|
rsa_func_fail_return(ret != 0, GK_FAILURE, memcmp);
|
||
|
|
crypto_memcpy(pad->out_data, pad->klen, p + 19, pad->hlen); /* 19 copy shift */
|
||
|
|
break;
|
||
|
|
case GK_CIPHER_HASH_TYPE_SHA256:
|
||
|
|
rsa_not_equal_return(len, (19 + pad->hlen), GK_FAILURE); /* len size: 19 + pad->hlen */
|
||
|
|
ret = memcmp(p, ASN1_HASH_SHA256, 19); /* 19 compare size */
|
||
|
|
rsa_func_fail_return(ret != 0, GK_FAILURE, memcmp);
|
||
|
|
crypto_memcpy(pad->out_data, pad->klen, p + 19, pad->hlen); /* 19 copy shift */
|
||
|
|
break;
|
||
|
|
case GK_CIPHER_HASH_TYPE_SHA384:
|
||
|
|
rsa_not_equal_return(len, (19 + pad->hlen), GK_FAILURE); /* len size: 19 + pad->hlen */
|
||
|
|
ret = memcmp(p, ASN1_HASH_SHA384, 19); /* 19 compare size */
|
||
|
|
rsa_func_fail_return(ret != 0, GK_FAILURE, memcmp);
|
||
|
|
crypto_memcpy(pad->out_data, pad->klen, p + 19, pad->hlen); /* 19 copy shift */
|
||
|
|
break;
|
||
|
|
case GK_CIPHER_HASH_TYPE_SHA512:
|
||
|
|
rsa_not_equal_return(len, (19 + pad->hlen), GK_FAILURE); /* len size: 19 + pad->hlen */
|
||
|
|
ret = memcmp(p, ASN1_HASH_SHA512, 19); /* 19 compare size */
|
||
|
|
rsa_func_fail_return(ret != 0, GK_FAILURE, memcmp);
|
||
|
|
crypto_memcpy(pad->out_data, pad->klen, p + 19, pad->hlen); /* 19 copy shift */
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
gk_err_cipher("RSA unsuporrt hash type: 0x%x.\n", pad->hash_type);
|
||
|
|
return GK_ERR_CIPHER_INVALID_PARA;
|
||
|
|
}
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
static gk_s32 rsa_padding_check_emsa_pkcs1_v15(rsa_padding_s *pad)
|
||
|
|
{
|
||
|
|
gk_u8 *p = pad->in_data;
|
||
|
|
|
||
|
|
pad->out_len = pad->hlen;
|
||
|
|
|
||
|
|
/* formula: EM = 01 || PS || 00 || T */
|
||
|
|
if (*p++ != 0) {
|
||
|
|
gk_err_cipher("RSA EM[0] must be 0\n");
|
||
|
|
return GK_FAILURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (*p++ != RSA_SIGN) {
|
||
|
|
gk_err_cipher("RSA EM PS error\n");
|
||
|
|
return GK_FAILURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
while (*p != 0) {
|
||
|
|
if (p >= pad->in_data + pad->klen - 1 || *p != 0xFF) {
|
||
|
|
gk_err_cipher("RSA PS error\n");
|
||
|
|
return GK_FAILURE;
|
||
|
|
}
|
||
|
|
p++;
|
||
|
|
}
|
||
|
|
p++; // skip 0x00
|
||
|
|
|
||
|
|
return rsa_padding_check_emsa_pkcs1_v15_type(pad, p);
|
||
|
|
}
|
||
|
|
|
||
|
|
static gk_s32 rsa_padding_check_pkcs1_pss_hash(rsa_padding_s *pad, gk_u8 *mhash, rsa_pkcs1_pss_s *pss)
|
||
|
|
{
|
||
|
|
gk_s32 ret;
|
||
|
|
gk_u32 mlen;
|
||
|
|
gk_u8 *ptr_m = GK_NULL;
|
||
|
|
gk_handle hash_handle = 0;
|
||
|
|
gk_cipher_hash_attr hash_attr;
|
||
|
|
gk_u8 arr_h[HASH_RESULT_MAX_LEN] = {0};
|
||
|
|
|
||
|
|
mlen = pss->slen + pad->hlen + 8; /* 8 */
|
||
|
|
ptr_m = (gk_u8 *)cipher_malloc(mlen);
|
||
|
|
rsa_func_fail_return(ptr_m == GK_NULL, GK_ERR_CIPHER_INVALID_POINT, cipher_malloc);
|
||
|
|
crypto_memset(ptr_m, mlen, 0, mlen);
|
||
|
|
|
||
|
|
/* M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt */
|
||
|
|
crypto_memset(ptr_m, mlen, 0x00, 8); /* 8, 0 counts */
|
||
|
|
crypto_memcpy(&ptr_m[8], mlen - 8, mhash, pad->hlen); /* 8, 0 counts */
|
||
|
|
crypto_memcpy(&ptr_m[8 + pad->hlen], mlen - 8 - pad->hlen, pss->salt, pss->slen); /* 8, 0 counts */
|
||
|
|
|
||
|
|
crypto_memset(&hash_attr, sizeof(hash_attr), 0, sizeof(gk_cipher_hash_attr));
|
||
|
|
hash_attr.sha_type = pad->hash_type;
|
||
|
|
ret = gk_api_cipher_hash_init(&hash_attr, &hash_handle) ||
|
||
|
|
gk_api_cipher_hash_update(hash_handle, ptr_m, mlen) ||
|
||
|
|
gk_api_cipher_hash_final(hash_handle, arr_h);
|
||
|
|
free(ptr_m); /* Must free ptr_m befort return */
|
||
|
|
ptr_m = GK_NULL;
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, gk_api_cipher_hash_final);
|
||
|
|
|
||
|
|
ret = crypto_memcmp(arr_h, pss->masked_seed, pad->hlen);
|
||
|
|
rsa_func_fail_return(ret != 0, GK_FAILURE, crypto_memcmp);
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
static gk_s32 rsa_padding_check_pkcs1_pss(rsa_padding_s *pad, gk_u8 *mhash)
|
||
|
|
{
|
||
|
|
gk_u32 ret;
|
||
|
|
gk_u32 index, tmp_len;
|
||
|
|
rsa_pkcs1_pss_s pss;
|
||
|
|
|
||
|
|
crypto_memset(&pss, sizeof(rsa_pkcs1_pss_s), 0, sizeof(rsa_pkcs1_pss_s));
|
||
|
|
pss.slen = pad->hlen;
|
||
|
|
pss.key_len = (pad->em_bit + 7) / 8; /* 7, 8 */
|
||
|
|
pss.msb_bits = (pad->em_bit - 1) & 0x07;
|
||
|
|
|
||
|
|
if (pss.key_len < (pad->hlen + pss.slen + 2)) { /* 2 */
|
||
|
|
gk_err_cipher("message too long\n");
|
||
|
|
return GK_ERR_CIPHER_INVALID_PARA;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (pad->in_data[0] & (0xFF << pss.msb_bits)) {
|
||
|
|
gk_err_cipher("inconsistent, EM[0] invalid\n");
|
||
|
|
return GK_FAILURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (pss.msb_bits == 0) {
|
||
|
|
pad->in_data++;
|
||
|
|
pss.key_len--;
|
||
|
|
}
|
||
|
|
|
||
|
|
pss.masked_db = pad->in_data;
|
||
|
|
pss.masked_seed = pad->in_data + pss.key_len - pad->hlen - 1;
|
||
|
|
|
||
|
|
if (pad->in_data[pss.key_len - 1] != 0xBC) {
|
||
|
|
gk_err_cipher("inconsistent, EM[key_len - 1] != 0xBC\n");
|
||
|
|
return GK_ERR_CIPHER_INVALID_PARA;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* formula: maskedDB = DB xor dbMask, DB = PS || 0x01 || salt */
|
||
|
|
ret = rsa_pkcs1_mgf1(pad->hash_type, pss.masked_seed,
|
||
|
|
pad->hlen, pss.masked_db, pss.key_len - pad->hlen - 1);
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, rsa_pkcs1_mgf1);
|
||
|
|
|
||
|
|
if (pss.msb_bits)
|
||
|
|
pss.masked_db[0] &= 0xFF >> (8 - pss.msb_bits); /* 8 */
|
||
|
|
|
||
|
|
tmp_len = pss.key_len - pss.slen - pad->hlen - 2; /* 2 */
|
||
|
|
if (tmp_len >= CIPHER_MAX_RSA_KEY_LEN - 1) { /* -1 is for index++, avoid masked_db overflow */
|
||
|
|
gk_err_cipher("operate masked_db maybe overflow %u\n", tmp_len);
|
||
|
|
return GK_ERR_CIPHER_INVALID_PARA;
|
||
|
|
}
|
||
|
|
|
||
|
|
for (index = 0; index < tmp_len; index++) {
|
||
|
|
if (pss.masked_db[index] != 0x00) {
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
pss.slen = pss.key_len - pad->hlen - index - 2;
|
||
|
|
|
||
|
|
rsa_not_equal_return(pss.masked_db[index], 0x01, GK_FAILURE);
|
||
|
|
index++;
|
||
|
|
crypto_memcpy(pss.salt, sizeof(pss.salt), &pss.masked_db[index], pss.slen);
|
||
|
|
|
||
|
|
return rsa_padding_check_pkcs1_pss_hash(pad, mhash, &pss);
|
||
|
|
}
|
||
|
|
|
||
|
|
static gk_s32 rsa_pub_enc_pad_init(rsa_padding_s *pad, const gk_cipher_rsa_pub_encrypt *rsa_enc,
|
||
|
|
gk_cipher_rsa_crypt *rsa_crypt, gk_u8 *arr_em, gk_u32 em_len)
|
||
|
|
{
|
||
|
|
gk_s32 ret;
|
||
|
|
|
||
|
|
if (em_len < rsa_crypt->in_len) {
|
||
|
|
gk_err_cipher("buf len %u < in len %u\n", em_len, rsa_crypt->in_len);
|
||
|
|
return GK_ERR_CIPHER_INVALID_PARA;
|
||
|
|
}
|
||
|
|
|
||
|
|
crypto_memset(pad, sizeof(rsa_padding_s), 0, sizeof(rsa_padding_s));
|
||
|
|
pad->in_data = (gk_u8 *)rsa_crypt->in;
|
||
|
|
pad->in_len = rsa_crypt->in_len;
|
||
|
|
pad->out_data = arr_em;
|
||
|
|
ret = rsa_get_attr(rsa_enc->scheme, rsa_enc->pub_key.n_len, pad);
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, rsa_get_attr);
|
||
|
|
inlet_var_over_max_return(pad->in_len, pad->klen);
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
static gk_s32 rsa_pri_dec_pad_init(rsa_padding_s *pad, const gk_cipher_rsa_private_encrypt *rsa_decrypt,
|
||
|
|
gk_cipher_rsa_crypt *rsa_crypt, gk_u8 *arr_em, gk_u32 em_len)
|
||
|
|
{
|
||
|
|
gk_s32 ret;
|
||
|
|
|
||
|
|
if (em_len < rsa_crypt->in_len) {
|
||
|
|
gk_err_cipher("buf len %u < in len %u\n", em_len, rsa_crypt->in_len);
|
||
|
|
return GK_ERR_CIPHER_INVALID_PARA;
|
||
|
|
}
|
||
|
|
|
||
|
|
crypto_memset(pad, sizeof(rsa_padding_s), 0, sizeof(rsa_padding_s));
|
||
|
|
pad->in_data = arr_em;
|
||
|
|
pad->in_len = rsa_crypt->in_len;
|
||
|
|
pad->out_data = rsa_crypt->out;
|
||
|
|
ret = rsa_get_attr(rsa_decrypt->scheme, rsa_decrypt->private_key.n_len, pad);
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, rsa_get_attr);
|
||
|
|
rsa_not_equal_return(pad->in_len, pad->klen, GK_ERR_CIPHER_INVALID_PARA);
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
static gk_s32 rsa_pri_enc_pad_init(rsa_padding_s *pad, const gk_cipher_rsa_private_encrypt *rsa_encrypt,
|
||
|
|
gk_cipher_rsa_crypt *rsa_crypt, gk_u8 *arr_em, gk_u32 em_len)
|
||
|
|
{
|
||
|
|
gk_s32 ret;
|
||
|
|
|
||
|
|
if (em_len < rsa_crypt->in_len) {
|
||
|
|
gk_err_cipher("buf len %u < in len %u\n", em_len, rsa_crypt->in_len);
|
||
|
|
return GK_ERR_CIPHER_INVALID_PARA;
|
||
|
|
}
|
||
|
|
|
||
|
|
crypto_memset(pad, sizeof(rsa_padding_s), 0, sizeof(rsa_padding_s));
|
||
|
|
pad->in_data = (gk_u8 *)rsa_crypt->in;
|
||
|
|
pad->in_len = rsa_crypt->in_len;
|
||
|
|
pad->out_data = arr_em;
|
||
|
|
ret = rsa_get_attr(rsa_encrypt->scheme, rsa_encrypt->private_key.n_len, pad);
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, rsa_get_attr);
|
||
|
|
inlet_var_over_max_return(pad->in_len, pad->klen);
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
static gk_s32 rsa_pub_dec_pad_init(rsa_padding_s *pad, const gk_cipher_rsa_pub_encrypt *rsa_decrypt,
|
||
|
|
gk_cipher_rsa_crypt *rsa_crypt, gk_u8 *arr_em, gk_u32 em_len)
|
||
|
|
{
|
||
|
|
gk_s32 ret;
|
||
|
|
|
||
|
|
if (em_len < rsa_crypt->in_len) {
|
||
|
|
gk_err_cipher("buf len %u < in len %u\n", em_len, rsa_crypt->in_len);
|
||
|
|
return GK_ERR_CIPHER_INVALID_PARA;
|
||
|
|
}
|
||
|
|
|
||
|
|
crypto_memset(pad, sizeof(rsa_padding_s), 0, sizeof(rsa_padding_s));
|
||
|
|
pad->in_data = arr_em;
|
||
|
|
pad->in_len = rsa_crypt->in_len;
|
||
|
|
pad->out_data = rsa_crypt->out;
|
||
|
|
ret = rsa_get_attr(rsa_decrypt->scheme, rsa_decrypt->pub_key.n_len, pad);
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, rsa_get_attr);
|
||
|
|
rsa_not_equal_return(pad->in_len, pad->klen, GK_FAILURE);
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
static gk_s32 rsa_sign_pad_init(rsa_padding_s *pad,
|
||
|
|
const gk_cipher_rsa_sign *rsa_sign, gk_cipher_sign_data *sign_data, rsa_sign_buf *sign_buf)
|
||
|
|
{
|
||
|
|
gk_s32 ret;
|
||
|
|
gk_cipher_hash_attr hash_attr;
|
||
|
|
gk_handle hash_handle;
|
||
|
|
|
||
|
|
crypto_memset(pad, sizeof(rsa_padding_s), 0, sizeof(rsa_padding_s));
|
||
|
|
ret = rsa_get_attr(rsa_sign->scheme, rsa_sign->private_key.n_len, pad);
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, rsa_get_attr);
|
||
|
|
pad->out_data = sign_buf->arr_em;
|
||
|
|
pad->in_len = pad->hlen;
|
||
|
|
|
||
|
|
/* hash is NULl, need to calc by self */
|
||
|
|
if (sign_data->hash_data != GK_NULL) {
|
||
|
|
pad->in_data = (gk_u8 *)sign_data->hash_data;
|
||
|
|
} else {
|
||
|
|
hash_attr.sha_type = pad->hash_type;
|
||
|
|
ret = gk_api_cipher_hash_init(&hash_attr, &hash_handle) ||
|
||
|
|
gk_api_cipher_hash_update(hash_handle, (gk_u8 *)sign_data->in, sign_data->in_len) ||
|
||
|
|
gk_api_cipher_hash_final(hash_handle, sign_buf->sign_hash);
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, gk_api_cipher_hash_final);
|
||
|
|
pad->in_data = sign_buf->sign_hash;
|
||
|
|
}
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
static gk_s32 rsa_verify_pad_init(rsa_padding_s *pad, const gk_cipher_rsa_verify *rsa_verify,
|
||
|
|
gk_cipher_verify_data *verify_data, rsa_sign_buf *sign_buf)
|
||
|
|
{
|
||
|
|
gk_s32 ret;
|
||
|
|
|
||
|
|
crypto_memset(pad, sizeof(rsa_padding_s), 0, sizeof(rsa_padding_s));
|
||
|
|
ret = rsa_get_attr(rsa_verify->scheme, rsa_verify->pub_key.n_len, pad);
|
||
|
|
pad->in_data = sign_buf->arr_em;
|
||
|
|
pad->in_len = verify_data->sign_len;
|
||
|
|
pad->out_data = sign_buf->sign_hash;
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, rsa_get_attr);
|
||
|
|
rsa_not_equal_return(verify_data->sign_len, pad->klen, GK_FAILURE);
|
||
|
|
|
||
|
|
ret = rsa_public(&rsa_verify->pub_key, verify_data->sign, pad->in_data);
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, rsa_public);
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
static gk_u8 *rsa_verify_get_hash(gk_cipher_verify_data *verify_data,
|
||
|
|
gk_u8 *arr_hash, gk_u32 hash_len, gk_cipher_hash_type hash_type)
|
||
|
|
{
|
||
|
|
gk_u8 *ptr_hash = GK_NULL;
|
||
|
|
gk_cipher_hash_attr hash_attr;
|
||
|
|
gk_handle hash_handle;
|
||
|
|
|
||
|
|
if (verify_data->hash_data != GK_NULL) {
|
||
|
|
ptr_hash = (gk_u8 *)verify_data->hash_data;
|
||
|
|
} else {
|
||
|
|
gk_s32 ret;
|
||
|
|
|
||
|
|
crypto_memset(&hash_attr, sizeof(hash_attr), 0, sizeof(gk_cipher_hash_attr));
|
||
|
|
hash_attr.sha_type = hash_type;
|
||
|
|
ret = gk_api_cipher_hash_init(&hash_attr, &hash_handle) ||
|
||
|
|
gk_api_cipher_hash_update(hash_handle, (gk_u8 *)verify_data->in, verify_data->in_len) ||
|
||
|
|
gk_api_cipher_hash_final(hash_handle, arr_hash);
|
||
|
|
if (ret != GK_SUCCESS) {
|
||
|
|
gk_err_cipher("Calucate hash failed.\n");
|
||
|
|
return GK_NULL;
|
||
|
|
}
|
||
|
|
ptr_hash = arr_hash;
|
||
|
|
}
|
||
|
|
|
||
|
|
return ptr_hash;
|
||
|
|
}
|
||
|
|
|
||
|
|
gk_s32 gk_api_cipher_rsa_pub_encrypt(
|
||
|
|
const gk_cipher_rsa_pub_encrypt *rsa_enc, gk_cipher_rsa_crypt *rsa_crypt)
|
||
|
|
{
|
||
|
|
gk_s32 ret;
|
||
|
|
rsa_padding_s pad;
|
||
|
|
gk_u8 arr_em[CIPHER_MAX_RSA_KEY_LEN] = {0};
|
||
|
|
|
||
|
|
check_cipher_not_open_return();
|
||
|
|
inlet_var_is_null_return(rsa_enc);
|
||
|
|
inlet_var_is_null_return(rsa_crypt);
|
||
|
|
inlet_var_is_null_return(rsa_crypt->in);
|
||
|
|
inlet_var_is_zero_return(rsa_crypt->in_len);
|
||
|
|
inlet_var_is_null_return(rsa_crypt->out);
|
||
|
|
inlet_var_is_null_return(rsa_crypt->out_len);
|
||
|
|
|
||
|
|
ret = rsa_pub_enc_pad_init(&pad, rsa_enc, rsa_crypt, arr_em, sizeof(arr_em));
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, rsa_pub_enc_pad_init);
|
||
|
|
|
||
|
|
switch (rsa_enc->scheme) {
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_NO_PADDING:
|
||
|
|
/* if input_len < klen, padding 0 before input data */
|
||
|
|
pad.out_len = pad.klen;
|
||
|
|
crypto_memcpy(pad.out_data + (pad.klen - pad.in_len),
|
||
|
|
CIPHER_MAX_RSA_KEY_LEN - (pad.klen - pad.in_len), pad.in_data, pad.in_len);
|
||
|
|
break;
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_BLOCK_TYPE_0:
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_BLOCK_TYPE_1:
|
||
|
|
gk_err_cipher("RSA padding mode error, mode = 0x%x.\n", rsa_enc->scheme);
|
||
|
|
gk_err_cipher("For a public key encryption operation, the block type shall be 02.\n");
|
||
|
|
return GK_ERR_CIPHER_INVALID_PARA;
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_BLOCK_TYPE_2:
|
||
|
|
pad.key_bt = (gk_u8)(rsa_enc->scheme - GK_CIPHER_RSA_ENCRYPT_SCHEME_BLOCK_TYPE_0);
|
||
|
|
ret = rsa_padding_add_pkcs1_type(&pad);
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, rsa_padding_add_pkcs1_type);
|
||
|
|
break;
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_RSAES_OAEP_SHA1:
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_RSAES_OAEP_SHA224:
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_RSAES_OAEP_SHA256:
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_RSAES_OAEP_SHA384:
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_RSAES_OAEP_SHA512:
|
||
|
|
ret = rsa_padding_add_pkcs1_oaep(&pad);
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, rsa_padding_add_pkcs1_oaep);
|
||
|
|
break;
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_RSAES_PKCS1_V1_5:
|
||
|
|
ret = rsa_padding_add_pkcs1_v15(&pad);
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, rsa_padding_add_pkcs1_v15);
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
gk_err_cipher("RSA padding mode error, mode = 0x%x.\n", rsa_enc->scheme);
|
||
|
|
return GK_ERR_CIPHER_INVALID_PARA;
|
||
|
|
}
|
||
|
|
|
||
|
|
*rsa_crypt->out_len = pad.out_len;
|
||
|
|
return rsa_public(&rsa_enc->pub_key, pad.out_data, rsa_crypt->out);
|
||
|
|
}
|
||
|
|
|
||
|
|
gk_s32 gk_api_cipher_rsa_private_decrypt(
|
||
|
|
const gk_cipher_rsa_private_encrypt *rsa_decrypt, gk_cipher_rsa_crypt *rsa_crypt)
|
||
|
|
{
|
||
|
|
gk_s32 ret;
|
||
|
|
gk_u8 arr_em[CIPHER_MAX_RSA_KEY_LEN] = {0};
|
||
|
|
rsa_padding_s pad;
|
||
|
|
|
||
|
|
check_cipher_not_open_return();
|
||
|
|
inlet_var_is_null_return(rsa_decrypt);
|
||
|
|
inlet_var_is_null_return(rsa_crypt->in);
|
||
|
|
inlet_var_is_null_return(rsa_crypt->out);
|
||
|
|
inlet_var_is_null_return(rsa_crypt->out_len);
|
||
|
|
|
||
|
|
ret = rsa_pri_dec_pad_init(&pad, rsa_decrypt, rsa_crypt, arr_em, sizeof(arr_em));
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, rsa_pri_dec_pad_init);
|
||
|
|
|
||
|
|
ret = rsa_private(&rsa_decrypt->private_key, rsa_decrypt->ca_type, rsa_crypt->in, pad.in_data);
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, rsa_private);
|
||
|
|
|
||
|
|
switch (rsa_decrypt->scheme) {
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_NO_PADDING:
|
||
|
|
pad.out_len = pad.in_len;
|
||
|
|
crypto_memcpy(pad.out_data, pad.klen, pad.in_data, pad.klen);
|
||
|
|
break;
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_BLOCK_TYPE_0:
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_BLOCK_TYPE_1:
|
||
|
|
gk_err_cipher("RSA padding mode error, mode = 0x%x.\n", rsa_decrypt->scheme);
|
||
|
|
gk_err_cipher("For a private key decryption operation, the block type shall be 02.\n");
|
||
|
|
return GK_ERR_CIPHER_INVALID_PARA;
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_BLOCK_TYPE_2:
|
||
|
|
pad.key_bt = (gk_u8)(rsa_decrypt->scheme - GK_CIPHER_RSA_ENCRYPT_SCHEME_BLOCK_TYPE_0);
|
||
|
|
ret = rsa_padding_check_pkcs1_type(&pad);
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, rsa_padding_check_pkcs1_type);
|
||
|
|
break;
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_RSAES_OAEP_SHA1:
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_RSAES_OAEP_SHA224:
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_RSAES_OAEP_SHA256:
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_RSAES_OAEP_SHA384:
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_RSAES_OAEP_SHA512:
|
||
|
|
ret = rsa_padding_check_pkcs1_oaep(&pad);
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, rsa_padding_check_pkcs1_oaep);
|
||
|
|
break;
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_RSAES_PKCS1_V1_5:
|
||
|
|
ret = rsa_padding_check_pkcs1_v15(&pad);
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, rsa_padding_check_pkcs1_oaep);
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
gk_err_cipher("RSA scheme error, scheme = 0x%x.\n", rsa_decrypt->scheme);
|
||
|
|
return GK_ERR_CIPHER_INVALID_PARA;
|
||
|
|
}
|
||
|
|
|
||
|
|
*rsa_crypt->out_len = pad.out_len;
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
gk_s32 gk_api_cipher_rsa_private_encrypt(
|
||
|
|
const gk_cipher_rsa_private_encrypt *rsa_encrypt, gk_cipher_rsa_crypt *rsa_crypt)
|
||
|
|
{
|
||
|
|
gk_s32 ret;
|
||
|
|
rsa_padding_s pad;
|
||
|
|
gk_u8 arr_em[CIPHER_MAX_RSA_KEY_LEN] = {0};
|
||
|
|
|
||
|
|
check_cipher_not_open_return();
|
||
|
|
inlet_var_is_null_return(rsa_encrypt);
|
||
|
|
inlet_var_is_null_return(rsa_crypt->in);
|
||
|
|
inlet_var_is_zero_return(rsa_crypt->in_len);
|
||
|
|
inlet_var_is_null_return(rsa_crypt->out);
|
||
|
|
inlet_var_is_null_return(rsa_crypt->out_len);
|
||
|
|
|
||
|
|
ret = rsa_pri_enc_pad_init(&pad, rsa_encrypt, rsa_crypt, arr_em, sizeof(arr_em));
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, rsa_pri_enc_pad_init);
|
||
|
|
|
||
|
|
switch (rsa_encrypt->scheme) {
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_NO_PADDING:
|
||
|
|
/* if input_len < klen, padding 0 before input data */
|
||
|
|
pad.out_len = pad.klen;
|
||
|
|
crypto_memcpy(pad.out_data + (pad.klen - pad.in_len),
|
||
|
|
CIPHER_MAX_RSA_KEY_LEN - (pad.klen - pad.in_len), pad.in_data, pad.in_len);
|
||
|
|
break;
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_BLOCK_TYPE_0:
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_BLOCK_TYPE_1:
|
||
|
|
pad.key_bt = (gk_u8)(rsa_encrypt->scheme - GK_CIPHER_RSA_ENCRYPT_SCHEME_BLOCK_TYPE_0);
|
||
|
|
ret = rsa_padding_add_pkcs1_type(&pad);
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, rsa_padding_add_pkcs1_type);
|
||
|
|
break;
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_BLOCK_TYPE_2:
|
||
|
|
gk_err_cipher("RSA padding mode error, mode = 0x%x.\n", rsa_encrypt->scheme);
|
||
|
|
return GK_ERR_CIPHER_INVALID_PARA;
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_RSAES_OAEP_SHA1:
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_RSAES_OAEP_SHA224:
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_RSAES_OAEP_SHA256:
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_RSAES_OAEP_SHA384:
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_RSAES_OAEP_SHA512:
|
||
|
|
ret = rsa_padding_add_pkcs1_oaep(&pad);
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, rsa_padding_add_pkcs1_oaep);
|
||
|
|
break;
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_RSAES_PKCS1_V1_5:
|
||
|
|
pad.key_bt = 0x01;
|
||
|
|
ret = rsa_padding_add_pkcs1_type(&pad);
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, rsa_padding_add_pkcs1_type);
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
gk_err_cipher("RSA padding mode error, mode = 0x%x.\n", rsa_encrypt->scheme);
|
||
|
|
return GK_ERR_CIPHER_INVALID_PARA;
|
||
|
|
}
|
||
|
|
|
||
|
|
rsa_not_equal_return(pad.out_len, pad.klen, GK_FAILURE);
|
||
|
|
*rsa_crypt->out_len = pad.out_len;
|
||
|
|
|
||
|
|
return rsa_private(&rsa_encrypt->private_key, rsa_encrypt->ca_type, pad.out_data, rsa_crypt->out);
|
||
|
|
}
|
||
|
|
|
||
|
|
gk_s32 gk_api_cipher_rsa_pub_decrypt(
|
||
|
|
const gk_cipher_rsa_pub_encrypt *rsa_decrypt, gk_cipher_rsa_crypt *rsa_crypt)
|
||
|
|
{
|
||
|
|
gk_s32 ret;
|
||
|
|
gk_u8 arr_em[CIPHER_MAX_RSA_KEY_LEN] = {0};
|
||
|
|
rsa_padding_s pad;
|
||
|
|
|
||
|
|
check_cipher_not_open_return();
|
||
|
|
inlet_var_is_null_return(rsa_decrypt);
|
||
|
|
inlet_var_is_null_return(rsa_crypt->in);
|
||
|
|
inlet_var_is_zero_return(rsa_crypt->in_len);
|
||
|
|
inlet_var_is_null_return(rsa_crypt->out);
|
||
|
|
inlet_var_is_null_return(rsa_crypt->out_len);
|
||
|
|
|
||
|
|
ret = rsa_pub_dec_pad_init(&pad, rsa_decrypt, rsa_crypt, arr_em, sizeof(arr_em));
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, rsa_pub_dec_pad_init);
|
||
|
|
|
||
|
|
ret = rsa_public(&rsa_decrypt->pub_key, rsa_crypt->in, pad.in_data);
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, rsa_public);
|
||
|
|
|
||
|
|
switch (rsa_decrypt->scheme) {
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_NO_PADDING:
|
||
|
|
pad.out_len = pad.in_len;
|
||
|
|
crypto_memcpy(pad.out_data, pad.klen, pad.in_data, pad.klen);
|
||
|
|
break;
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_BLOCK_TYPE_0:
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_BLOCK_TYPE_1:
|
||
|
|
pad.key_bt = (gk_u8)(rsa_decrypt->scheme - GK_CIPHER_RSA_ENCRYPT_SCHEME_BLOCK_TYPE_0);
|
||
|
|
ret = rsa_padding_check_pkcs1_type(&pad);
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, rsa_padding_check_pkcs1_type);
|
||
|
|
break;
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_BLOCK_TYPE_2:
|
||
|
|
gk_err_cipher("RSA padding mode error, mode = 0x%x.\n", rsa_decrypt->scheme);
|
||
|
|
return GK_ERR_CIPHER_INVALID_PARA;
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_RSAES_OAEP_SHA1:
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_RSAES_OAEP_SHA224:
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_RSAES_OAEP_SHA256:
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_RSAES_OAEP_SHA384:
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_RSAES_OAEP_SHA512:
|
||
|
|
ret = rsa_padding_check_pkcs1_oaep(&pad);
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, rsa_padding_check_pkcs1_oaep);
|
||
|
|
break;
|
||
|
|
case GK_CIPHER_RSA_ENCRYPT_SCHEME_RSAES_PKCS1_V1_5:
|
||
|
|
pad.key_bt = 0x01;
|
||
|
|
ret = rsa_padding_check_pkcs1_type(&pad);
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, rsa_padding_check_pkcs1_type);
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
gk_err_cipher("RSA scheme error, scheme = 0x%x.\n", rsa_decrypt->scheme);
|
||
|
|
return GK_ERR_CIPHER_INVALID_PARA;
|
||
|
|
}
|
||
|
|
|
||
|
|
*rsa_crypt->out_len = pad.out_len;
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
gk_s32 gk_api_cipher_rsa_sign(
|
||
|
|
const gk_cipher_rsa_sign *rsa_sign, gk_cipher_sign_data *sign_data)
|
||
|
|
{
|
||
|
|
gk_s32 ret;
|
||
|
|
rsa_padding_s pad;
|
||
|
|
rsa_sign_buf sign_buf;
|
||
|
|
|
||
|
|
check_cipher_not_open_return();
|
||
|
|
inlet_var_is_null_return(rsa_sign);
|
||
|
|
inlet_var_is_null_return(sign_data->sign);
|
||
|
|
inlet_var_is_null_return(sign_data->sign_len);
|
||
|
|
inlet_var_is_null_return(rsa_sign->private_key.n);
|
||
|
|
|
||
|
|
if ((sign_data->in == GK_NULL || sign_data->in_len == 0) && (sign_data->hash_data == GK_NULL)) {
|
||
|
|
gk_err_cipher("Invalid param\n");
|
||
|
|
return GK_ERR_CIPHER_INVALID_PARA;
|
||
|
|
}
|
||
|
|
|
||
|
|
memset(&sign_buf, 0, sizeof(rsa_sign_buf));
|
||
|
|
ret = rsa_sign_pad_init(&pad, rsa_sign, sign_data, &sign_buf);
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, rsa_sign_pad_init);
|
||
|
|
|
||
|
|
switch (rsa_sign->scheme) {
|
||
|
|
case GK_CIPHER_RSA_SIGN_SCHEME_RSASSA_PKCS1_V15_SHA1:
|
||
|
|
case GK_CIPHER_RSA_SIGN_SCHEME_RSASSA_PKCS1_V15_SHA224:
|
||
|
|
case GK_CIPHER_RSA_SIGN_SCHEME_RSASSA_PKCS1_V15_SHA256:
|
||
|
|
case GK_CIPHER_RSA_SIGN_SCHEME_RSASSA_PKCS1_V15_SHA384:
|
||
|
|
case GK_CIPHER_RSA_SIGN_SCHEME_RSASSA_PKCS1_V15_SHA512:
|
||
|
|
ret = rsa_padding_add_emsa_pkcs1_v15(&pad);
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, rsa_padding_add_emsa_pkcs1_v15);
|
||
|
|
break;
|
||
|
|
case GK_CIPHER_RSA_SIGN_SCHEME_RSASSA_PKCS1_PSS_SHA1:
|
||
|
|
case GK_CIPHER_RSA_SIGN_SCHEME_RSASSA_PKCS1_PSS_SHA224:
|
||
|
|
case GK_CIPHER_RSA_SIGN_SCHEME_RSASSA_PKCS1_PSS_SHA256:
|
||
|
|
case GK_CIPHER_RSA_SIGN_SCHEME_RSASSA_PKCS1_PSS_SHA384:
|
||
|
|
case GK_CIPHER_RSA_SIGN_SCHEME_RSASSA_PKCS1_PSS_SHA512:
|
||
|
|
pad.em_bit = rsa_get_bit_num(rsa_sign->private_key.n, pad.klen);
|
||
|
|
ret = rsa_padding_add_pkcs1_pss(&pad);
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, rsa_padding_add_pkcs1_pss);
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
gk_err_cipher("invalid scheme; 0x%x\n", rsa_sign->scheme);
|
||
|
|
return GK_ERR_CIPHER_INVALID_PARA;
|
||
|
|
}
|
||
|
|
|
||
|
|
rsa_not_equal_return(pad.out_len, pad.klen, GK_FAILURE);
|
||
|
|
*sign_data->sign_len = pad.out_len;
|
||
|
|
|
||
|
|
return rsa_private(&rsa_sign->private_key, rsa_sign->ca_type, pad.out_data, sign_data->sign);
|
||
|
|
}
|
||
|
|
|
||
|
|
gk_s32 gk_api_cipher_rsa_verify(
|
||
|
|
const gk_cipher_rsa_verify *rsa_verify, gk_cipher_verify_data *verify_data)
|
||
|
|
{
|
||
|
|
gk_s32 ret;
|
||
|
|
rsa_padding_s pad;
|
||
|
|
gk_u8 *ptr_hash = GK_NULL;
|
||
|
|
rsa_sign_buf sign_buf;
|
||
|
|
gk_u8 arr_hash[HASH_RESULT_MAX_LEN] = {0};
|
||
|
|
|
||
|
|
check_cipher_not_open_return();
|
||
|
|
inlet_var_is_null_return(rsa_verify);
|
||
|
|
inlet_var_is_null_return(verify_data->sign);
|
||
|
|
|
||
|
|
if ((verify_data->in == GK_NULL || verify_data->in_len == 0) && (verify_data->hash_data == GK_NULL)) {
|
||
|
|
gk_err_cipher("Invalid param\n");
|
||
|
|
return GK_ERR_CIPHER_INVALID_PARA;
|
||
|
|
}
|
||
|
|
|
||
|
|
memset(&sign_buf, 0, sizeof(rsa_sign_buf));
|
||
|
|
ret = rsa_verify_pad_init(&pad, rsa_verify, verify_data, &sign_buf);
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, rsa_verify_pad_init);
|
||
|
|
|
||
|
|
ptr_hash = rsa_verify_get_hash(verify_data, arr_hash, sizeof(arr_hash), pad.hash_type);
|
||
|
|
rsa_func_fail_return(ptr_hash == GK_NULL, GK_ERR_CIPHER_INVALID_POINT, rsa_verify_get_hash);
|
||
|
|
|
||
|
|
switch (rsa_verify->scheme) {
|
||
|
|
case GK_CIPHER_RSA_SIGN_SCHEME_RSASSA_PKCS1_V15_SHA1:
|
||
|
|
case GK_CIPHER_RSA_SIGN_SCHEME_RSASSA_PKCS1_V15_SHA224:
|
||
|
|
case GK_CIPHER_RSA_SIGN_SCHEME_RSASSA_PKCS1_V15_SHA256:
|
||
|
|
case GK_CIPHER_RSA_SIGN_SCHEME_RSASSA_PKCS1_V15_SHA384:
|
||
|
|
case GK_CIPHER_RSA_SIGN_SCHEME_RSASSA_PKCS1_V15_SHA512:
|
||
|
|
ret = rsa_padding_check_emsa_pkcs1_v15(&pad);
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, rsa_padding_check_emsa_pkcs1_v15);
|
||
|
|
ret = memcmp(ptr_hash, pad.out_data, pad.hlen);
|
||
|
|
rsa_func_fail_return(ret != 0, GK_ERR_CIPHER_FAILED_DECRYPT, memcmp);
|
||
|
|
break;
|
||
|
|
case GK_CIPHER_RSA_SIGN_SCHEME_RSASSA_PKCS1_PSS_SHA1:
|
||
|
|
case GK_CIPHER_RSA_SIGN_SCHEME_RSASSA_PKCS1_PSS_SHA224:
|
||
|
|
case GK_CIPHER_RSA_SIGN_SCHEME_RSASSA_PKCS1_PSS_SHA256:
|
||
|
|
case GK_CIPHER_RSA_SIGN_SCHEME_RSASSA_PKCS1_PSS_SHA384:
|
||
|
|
case GK_CIPHER_RSA_SIGN_SCHEME_RSASSA_PKCS1_PSS_SHA512:
|
||
|
|
pad.em_bit = rsa_get_bit_num(rsa_verify->pub_key.n, pad.klen);
|
||
|
|
ret = rsa_padding_check_pkcs1_pss(&pad, ptr_hash);
|
||
|
|
rsa_func_fail_return(ret != GK_SUCCESS, ret, rsa_padding_check_pkcs1_pss);
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
gk_err_cipher("invalid scheme; 0x%x\n", rsa_verify->scheme);
|
||
|
|
return GK_ERR_CIPHER_INVALID_PARA;
|
||
|
|
}
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
}
|