/* * Copyright (c) XMEDIA. All rights reserved. */ #include "xmedia_cipher_osal.h" //#include "safety.h" /************************************************************/ static xmedia_void *g_rsa_reg_base = XMEDIA_NULL; static xmedia_void *g_rsa_reg_crg = XMEDIA_NULL; static xmedia_u32 rsa_init_flag = 0; /************************************************************/ #define RSA_REG_BASE_RSA g_rsa_reg_base #define SEC_RSA_BUSY_REG (RSA_REG_BASE_RSA + 0x010C) #define SEC_RSA_MOD_REG (RSA_REG_BASE_RSA + 0x0110) #define SEC_RSA_WSEC_REG (RSA_REG_BASE_RSA + 0x0104) #define SEC_RSA_WDAT_REG (RSA_REG_BASE_RSA + 0x0108) #define SEC_RSA_RRSLT_REG (RSA_REG_BASE_RSA + 0x0120) #define SEC_RSA_START_REG (RSA_REG_BASE_RSA + 0x0114) #define SEC_RSA_ERROR_REG (RSA_REG_BASE_RSA + 0x0124) #define RSA_DATA_CLR_KEY (1 << 2) #define RSA_DATA_CLR_INPUT (2 << 2) #define RSA_DATA_CLR_OUTPUT (4 << 2) #define RSA_MOD_SEL (3 << 0) #define RSA_MOD_SEL_OPT (0 << 0) #define RSA_MOD_SEL_RAM_CLAER (2 << 0) #define RSA_BUSY (1 << 0) #define RSA_START (1 << 0) #define RSA_MAX_KEY_LEN 512 #define CRC16_POLYNOMIAL 0x1021 #define RSA_PKCS1_PSS_MGF1_SHA256_MALLOC_SIZE 0x44 #define RSA_PKCS1_PSS_PADDING_CHECK_MALLOC_SIZE 0x48 #define ASN1_HASH_SHA256 "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20" #define SHA256_DATA_BYTE_LEN 32 typedef enum { RSA_DATA_TYPE_CONTEXT, RSA_DATA_TYPE_MODULE, RSA_DATA_TYPE_KEY, } rsa_data_type_e; typedef enum { RSA_KEY_WIDTH_1K = 0x00, RSA_KEY_WIDTH_2K = 0x01, RSA_KEY_WIDTH_4K = 0x02, RSA_KEY_WIDTH_3K = 0x03, RSA_KEY_WIDTH_BUTT = 0xff, } rsa_key_width_e; typedef struct { xmedia_u32 hlen; xmedia_u32 klen; xmedia_u32 em_bit; xmedia_u8 *in_data; xmedia_u32 in_len; } rsa_padding_s; typedef struct { xmedia_u8 *masked_db; xmedia_u8 *masked_seed; xmedia_u8 salt[RSA_MAX_KEY_LEN]; xmedia_u32 msb_bits; xmedia_u32 slen; xmedia_u32 key_len; } rsa_pkcs1_pss_s; typedef struct { xmedia_u8 *input_data; xmedia_u8 *output_data; xmedia_u32 data_len; xmedia_u8 *rsa_n; xmedia_u8 *rsa_k; xmedia_u16 rsa_n_len; xmedia_u16 rsa_k_len; } rsa_data_s; static xmedia_void hal_rsa_start(xmedia_void) { hal_cipher_write_reg(SEC_RSA_START_REG, 0x01); } static xmedia_s32 hal_rsa_wait_free(xmedia_void) { xmedia_u32 value; xmedia_u32 try_count = 0; do { value = hal_cipher_read_reg(SEC_RSA_BUSY_REG); if ((value & RSA_BUSY) == 0) return XMEDIA_SUCCESS; try_count++; cipher_usleep(10); } while (try_count < RSA_TIMEOUT_CNT); return XMEDIA_FAILURE; } static xmedia_void hal_rsa_clear_ram(xmedia_void) { xmedia_u32 value; value = hal_cipher_read_reg(SEC_RSA_MOD_REG); value &= 0x60; value |= RSA_DATA_CLR_INPUT | RSA_DATA_CLR_OUTPUT | RSA_DATA_CLR_KEY | RSA_MOD_SEL_RAM_CLAER; hal_cipher_write_reg(SEC_RSA_MOD_REG, value); } static xmedia_void hal_rsa_config_mode(rsa_key_width_e ken_width) { xmedia_u32 value; value = ((xmedia_u32)ken_width << 5) | RSA_MOD_SEL_OPT; /* 5 left shift */ hal_cipher_write_reg(SEC_RSA_MOD_REG, value); } static xmedia_void hal_rsa_write_data(rsa_data_type_e data_type, xmedia_u8 *data, xmedia_u32 data_len, xmedia_u32 length, xmedia_u32 random[2]) /* 2 random size */ { xmedia_u32 *reg = XMEDIA_NULL; xmedia_u8 *pos = XMEDIA_NULL; xmedia_u32 i, value; xmedia_bool id = 0; if (data_type == RSA_DATA_TYPE_CONTEXT) reg = SEC_RSA_WDAT_REG; else reg = SEC_RSA_WSEC_REG; pos = data; for (i = 0; i < length; i += 4) { /* 4 groups */ value = (xmedia_u32)pos[0]; value |= ((xmedia_u32)pos[1]) << 8; /* 1 index, 8 left shift */ value |= ((xmedia_u32)pos[2]) << 16; /* 2 index, 16 left shift */ value |= ((xmedia_u32)pos[3]) << 24; /* 3 index, 24 left shift */ if (data_type != RSA_DATA_TYPE_CONTEXT) value ^= random[id]; hal_cipher_write_reg(reg, value); pos += 4; /* 4 groups */ id = (xmedia_u32)id ^ 0x01; } } static xmedia_void hal_rsa_read_data(xmedia_u8 *data, xmedia_u32 data_len, xmedia_u32 klen) { xmedia_u32 value; xmedia_u8 *pos = XMEDIA_NULL; xmedia_u32 i; pos = data; for (i = 0; i < klen; i += 4) { /* 4 groups */ value = hal_cipher_read_reg(SEC_RSA_RRSLT_REG); pos[0] = (xmedia_u8)(value & 0xFF); pos[1] = (xmedia_u8)((value >> 8) & 0xFF); /* 1 index, 8 right shift */ pos[2] = (xmedia_u8)((value >> 16) & 0xFF); /* 2 index, 16 right shift */ pos[3] = (xmedia_u8)((value >> 24) & 0xFF); /* 3 index, 24 right shift */ pos += 4; /* 4 groups */ } } static xmedia_u32 hal_rsa_get_error_code(xmedia_void) { xmedia_u32 value; value = hal_cipher_read_reg(SEC_RSA_ERROR_REG); return value; } static xmedia_void hal_rsa_enable(xmedia_void) { xmedia_u32 value; value = hal_cipher_read_reg(g_rsa_reg_crg); hal_set_bit(value, 5); /* 5bit clock opened */ hal_cipher_write_reg(g_rsa_reg_crg, value); cipher_usleep(10); hal_clear_bit(value, 4); /* 4bit cancel reset */ hal_cipher_write_reg(g_rsa_reg_crg, value); cipher_usleep(10); //enable_rsa_safety(); } static xmedia_void hal_rsa_disable(xmedia_void) { xmedia_u32 value; value = hal_cipher_read_reg(g_rsa_reg_crg); hal_set_bit(value, 4); /* 4bit reset */ hal_cipher_write_reg(g_rsa_reg_crg, value); cipher_usleep(10); hal_clear_bit(value, 5); /* 5bit clock closed */ hal_cipher_write_reg(g_rsa_reg_crg, value); cipher_usleep(10); } static xmedia_u32 rsa_get_bit_num(xmedia_u8 *big_num, xmedia_u32 num_len) { static const xmedia_s8 bits[16] = {0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4}; /* 16 bits size */ xmedia_u32 i; for (i = 0; i < num_len; i++) { xmedia_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; } static xmedia_s32 rsa_pkcs1_mgf1(xmedia_u8 *seed, xmedia_u32 seed_len, xmedia_u8 *mask, xmedia_u32 mask_len) { xmedia_s32 ret = XMEDIA_FAILURE; xmedia_u32 i, out_len; xmedia_u8 *ptr_cnt = XMEDIA_NULL; xmedia_u8 *ptr_md = XMEDIA_NULL; xmedia_u8 *ptr_seed = XMEDIA_NULL; xmedia_u8 *ptr_malloc = XMEDIA_NULL; ptr_malloc = (xmedia_u8 *)cipher_malloc(RSA_PKCS1_PSS_MGF1_SHA256_MALLOC_SIZE); if (ptr_malloc == XMEDIA_NULL) { cipher_debug_log(CIPHER_ERR_RSA_MALLOC); return XMEDIA_FAILURE; } crypto_memset(ptr_malloc, RSA_PKCS1_PSS_MGF1_SHA256_MALLOC_SIZE, 0, RSA_PKCS1_PSS_MGF1_SHA256_MALLOC_SIZE); ptr_cnt = ptr_malloc; ptr_md = ptr_malloc + 4; ptr_seed = (ptr_malloc + 4 + SHA256_RESULT_SIZE); crypto_memcpy(ptr_seed, (RSA_PKCS1_PSS_MGF1_SHA256_MALLOC_SIZE - SHA256_RESULT_SIZE - 4), seed, seed_len); /* PKCS#1 V2.1*/ for (i = 0, out_len = 0; out_len < mask_len; i++) { xmedia_u32 j, md_len; //sha256 fixed md_len = 32; ptr_cnt[0] = (xmedia_u8)((i >> 24) & 0xFF); /* 0 ptr_cnt index, 24 right shift */ ptr_cnt[1] = (xmedia_u8)((i >> 16) & 0xFF); /* 1 ptr_cnt index, 16 right shift */ ptr_cnt[2] = (xmedia_u8)((i >> 8) & 0xFF); /* 2 ptr_cnt index, 8 right shift */ ptr_cnt[3] = (xmedia_u8)(i & 0xFF); /* 3 ptr_cnt index */ ret = xmedia_cipher_sha256_init(); ret |= xmedia_cipher_sha256_update(ptr_seed, seed_len); ret |= xmedia_cipher_sha256_update(ptr_cnt, 4); /* 4 ptr_cnt size */ ret |= xmedia_cipher_sha256_final(ptr_md); if(ret != XMEDIA_SUCCESS) { cipher_debug_log(CIPHER_ERR_RSA_SHA256); /*sha256 failed*/ goto free_ptr; } for (j = 0; (j < md_len) && (out_len < mask_len); j++) mask[out_len++] ^= ptr_md[j]; } free_ptr: cipher_free(ptr_malloc); ptr_malloc = XMEDIA_NULL; return ret; } static xmedia_s32 rsa_padding_check_pkcs1_pss_hash(rsa_padding_s *pad, xmedia_u8 *mhash, rsa_pkcs1_pss_s *pss) { xmedia_s32 ret; xmedia_u32 mlen; xmedia_u8 *ptr_m = XMEDIA_NULL; xmedia_u8 arr_h[SHA256_RESULT_SIZE]; /*8+32+32*/ mlen = pss->slen + pad->hlen + 8; /* 8 */ ptr_m = (xmedia_u8 *)cipher_malloc(RSA_PKCS1_PSS_PADDING_CHECK_MALLOC_SIZE); if(ptr_m == XMEDIA_NULL) { return XMEDIA_FAILURE; } crypto_memset(arr_h, SHA256_RESULT_SIZE, 0, SHA256_RESULT_SIZE); crypto_memset(ptr_m, RSA_PKCS1_PSS_PADDING_CHECK_MALLOC_SIZE, 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 */ ret = xmedia_cipher_sha256_init(); ret |= xmedia_cipher_sha256_update(ptr_m, mlen); ret |= xmedia_cipher_sha256_final(arr_h); cipher_free(ptr_m); /* Must free ptr_m befort return */ ptr_m = XMEDIA_NULL; if(ret != XMEDIA_SUCCESS) { cipher_debug_log(CIPHER_ERR_RSA_SHA256); /*sha256 failed*/ return XMEDIA_FAILURE; } if(crypto_memcmp(arr_h, pss->masked_seed, pad->hlen) != XMEDIA_SUCCESS) { cipher_debug_log(CIPHER_ERR_RSA_VERIFY_HASH_CMP); /*masked_seed cmp failed*/ return XMEDIA_FAILURE; } return XMEDIA_SUCCESS; } static xmedia_s32 rsa_padding_check_pkcs1_pss(rsa_padding_s *pad, xmedia_u8 *mhash) { xmedia_u32 ret; xmedia_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 */ cipher_debug_log(CIPHER_ERR_RSA_VERIFY_M_LEN); /*message too long*/ return XMEDIA_FAILURE; } if (pad->in_data[0] & (0xFF << pss.msb_bits)) { cipher_debug_log(CIPHER_ERR_RSA_VERIFY_EM0); /*inconsistent, EM[0] invalid*/ return XMEDIA_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) { cipher_debug_log(CIPHER_ERR_RSA_VERIFY_BC); /*inconsistent, EM[key_len - 1] != 0xBC*/ return XMEDIA_FAILURE; } /* formula: maskedDB = DB xor dbMask, DB = PS || 0x01 || salt */ ret = rsa_pkcs1_mgf1(pss.masked_seed, pad->hlen, pss.masked_db, pss.key_len - pad->hlen - 1); if(ret != XMEDIA_SUCCESS) { cipher_debug_log(CIPHER_ERR_RSA_MGF1); /*rsa_pkcs1_mgf1 failed*/ return XMEDIA_FAILURE; } 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 >= RSA_MAX_KEY_LEN - 1) { /* -1 is for index++, avoid masked_db overflow */ cipher_debug_log(CIPHER_ERR_RSA_VERIFY_MASKEDDB_LEN); /*operate masked_db maybe overflow*/ return XMEDIA_FAILURE; } for (index = 0; index < tmp_len; index++) { if (pss.masked_db[index] != 0x00) { break; } } pss.slen = pss.key_len - pad->hlen - index - 2; if(pss.masked_db[index] != 0x1) { cipher_debug_log(CIPHER_ERR_RSA_VERIFY_DB_1); /*check masked_db failed*/ return XMEDIA_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 xmedia_s32 rsa_padding_check_pkcs1_v15(xmedia_u8 *mhash, xmedia_u32 hash_len, xmedia_u8 *em, xmedia_u32 key_len) { xmedia_u8 *data_hash[32]; xmedia_u8 *p; xmedia_u32 t_len; if (hash_len != SHA256_DATA_BYTE_LEN) { cipher_debug_log(CIPHER_ERR_RSA_VERIFY_SHA256_DATA_LEN); /* only support sha256 */ return XMEDIA_FAILURE; } /* EM = 0x00 || 0x01 || PS || 0x00 || T */ p = em; if (*p++ != 0x0) { cipher_debug_log(CIPHER_ERR_RSA_VERIFY_EM_FIRSTBYTE); /* EM's first byte must be 0 */ return XMEDIA_FAILURE; } if (*p++ != 0x1) { cipher_debug_log(CIPHER_ERR_RSA_VERIFY_EM_SECONDBYTE); /* EM's second byte must be 1 */ return XMEDIA_FAILURE; } while (*p != 0) { if ((p >= em + key_len - 1) || (*p != 0xFF)) { cipher_debug_log(CIPHER_ERR_RSA_VERIFY_EM_PS); /* PS's every byte is 0xff */ return XMEDIA_FAILURE; } p++; } p++; // skip 0x0 before T t_len = key_len- (xmedia_u32)(p - em); if (t_len != (19 + hash_len)) { cipher_debug_log(CIPHER_ERR_RSA_VERIFY_EM_T_LEN); /* T length must be 51 (19 + 32), just for sha256 */ return XMEDIA_FAILURE; } if (memcmp(p, ASN1_HASH_SHA256, 19)) { cipher_debug_log(CIPHER_ERR_RSA_VERIFY_ASN1_SHA256); /* just for sha256 */ return XMEDIA_FAILURE; } if (memcmp(p + 19, mhash, hash_len)) { cipher_debug_log(CIPHER_ERR_RSA_VERIFY_SHA256_DATA); /* sha256 data invalid */ return XMEDIA_FAILURE; } return XMEDIA_SUCCESS; } static xmedia_s32 drv_cipher_calc_rsa(rsa_data_s *rsa_data); static xmedia_s32 rsa_public(const cipher_rsa_pub_key *pub_key, const xmedia_u8 *input, xmedia_u8 *output) { rsa_data_s rsa_data; 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 = (xmedia_u8 *)input; rsa_data.output_data = output; rsa_data.data_len = pub_key->n_len; return drv_cipher_calc_rsa(&rsa_data); } static xmedia_s32 rsa_verify_pad_init(rsa_padding_s *pad, const cipher_rsa_verify *rsa_verify, cipher_verify_data *verify_data, xmedia_u8 *arr_em) { /*fix here: only support sha256*/ pad->hlen = SHA256_RESULT_SIZE; /* 32 pad hlen */ pad->klen = rsa_verify->pub_key.n_len; pad->in_data = arr_em; pad->in_len = verify_data->sign_len; if(verify_data->sign_len != pad->klen) { return XMEDIA_FAILURE; } return rsa_public(&rsa_verify->pub_key, verify_data->sign, pad->in_data); } static xmedia_s32 drv_rsa_init(xmedia_void) { g_rsa_reg_crg = cipher_ioremap_nocache(CIPHER_RSA_CRG_ADDR_PHY, 16); /* 16 */ g_rsa_reg_base = cipher_ioremap_nocache(CIPHER_RSA_REG_BASE_ADDR_PHY, 0x1000); return XMEDIA_SUCCESS; } static xmedia_void drv_rsa_deinit(xmedia_void) { if (g_rsa_reg_base != XMEDIA_NULL) { cipher_iounmap(g_rsa_reg_base); g_rsa_reg_base = XMEDIA_NULL; } if (g_rsa_reg_crg != XMEDIA_NULL) { cipher_iounmap(g_rsa_reg_crg); g_rsa_reg_crg = XMEDIA_NULL; } } static xmedia_s32 drv_rsa_wait_done(xmedia_void) { return hal_rsa_wait_free(); } static xmedia_s32 drv_cipher_check_rsa_data(xmedia_u8 *rsa_n, xmedia_u8 *rsa_e, xmedia_u8 *rsa_mc, xmedia_u32 length) { xmedia_u32 i; /* formula: rsa_mc > 0 */ for (i = 0; i < length; i++) { if (rsa_mc[i] > 0) break; } if (i >= length) { cipher_debug_log(CIPHER_ERR_RSA_M_ZERO); /*RSA M/C is zero, error*/ return XMEDIA_FAILURE; } /* formula: rsa_mc < rsa_n */ for (i = 0; i < length; i++) { if(rsa_mc[i] < rsa_n[i]) break; if(rsa_mc[i] == rsa_n[i]) continue; if (rsa_mc[i] > rsa_n[i]) { cipher_debug_log(CIPHER_ERR_RSA_M_LARGER_N); /*RSA M/C is larger than rsa_n, error!*/ return XMEDIA_FAILURE; } } if (i >= length) { cipher_debug_log(CIPHER_ERR_RSA_M_LARGER_N); /*RSA M/C is larger than rsa_n, error!*/ return XMEDIA_FAILURE; } /* formula: rsa_e > 1 */ for (i = 0; i < length; i++) { if (rsa_e[i] > 0) break; } if ((i == length -1) && (rsa_e[i] == 1)) { cipher_debug_log(CIPHER_ERR_RSA_E_EQUAL_1); /*RSA D/rsa_e is 1, error!*/ return XMEDIA_FAILURE; } if (i >= length) { cipher_debug_log(CIPHER_ERR_RSA_E_EQUAL_0); /*RSA D/rsa_e is zero, error!*/ return XMEDIA_FAILURE; } return XMEDIA_SUCCESS; } static xmedia_s32 drv_cipher_clear_rsa_ram(xmedia_void) { if (hal_rsa_wait_free() != XMEDIA_SUCCESS) { cipher_debug_log(CIPHER_ERR_RSA_BUSY_TIMEOUT); /*RSA is busy and timeout,error!*/ return XMEDIA_FAILURE; } hal_rsa_clear_ram(); hal_rsa_start(); if (drv_rsa_wait_done() != XMEDIA_SUCCESS) { cipher_debug_log(CIPHER_ERR_RSA_BUSY_TIMEOUT); /*RSA is busy and timeout,error!*/ return XMEDIA_FAILURE; } return XMEDIA_SUCCESS; } static xmedia_void drv_rsa_rand_mask(rsa_data_s *rsa_data, xmedia_u32 key_len, xmedia_u32 *random) { return; } static void drv_rsa_cipher_klad(rsa_data_s *rsa_data, xmedia_u32 key_len, xmedia_u32 *random) { hal_rsa_write_data(RSA_DATA_TYPE_KEY, rsa_data->rsa_k, rsa_data->rsa_n_len, key_len, random); return; } static xmedia_s32 drv_rsa_key_info(rsa_data_s *rsa_data, xmedia_u32 *key_len, rsa_key_width_e *key_width) { /* Only support the key width of 1024, 2048 and 4096 */ if (rsa_data->rsa_n_len <= 128) { /* key n size 128 */ *key_len = 128; /* key n size 128 */ *key_width = RSA_KEY_WIDTH_1K; } else if (rsa_data->rsa_n_len <= 256) { /* key n size 256 */ *key_len = 256; /* key n size 256 */ *key_width = RSA_KEY_WIDTH_2K; } else if (rsa_data->rsa_n_len <= 384) { /* key n size 384 */ *key_len = 384; /* key n size 384 */ *key_width = RSA_KEY_WIDTH_3K; } else if (rsa_data->rsa_n_len <= 512) { /* key n size 512 */ *key_len = 512; /* key n size 512 */ *key_width = RSA_KEY_WIDTH_4K; } else { cipher_debug_log(CIPHER_ERR_RSA_KEY_LEN); return XMEDIA_FAILURE; } return XMEDIA_SUCCESS; } static xmedia_s32 drv_cipher_calc_rsa_ex(rsa_data_s *rsa_data, xmedia_u32 key_len, rsa_key_width_e key_width) { xmedia_s32 ret = XMEDIA_FAILURE; xmedia_u32 err_code = 0; xmedia_u64 random = 0; ret = drv_cipher_check_rsa_data(rsa_data->rsa_n, rsa_data->rsa_k, rsa_data->input_data, key_len); if (ret != XMEDIA_SUCCESS) { return ret; } hal_rsa_enable(); ret = hal_rsa_wait_free(); if (ret != XMEDIA_SUCCESS) { cipher_debug_log(CIPHER_ERR_RSA_BUSY_TIMEOUT); /*RSA is busy!*/ goto exit; } /* Config Mode */ hal_rsa_config_mode(key_width); //V500 not support,reserved! drv_rsa_rand_mask(rsa_data, key_len, (xmedia_u32 *)&random); /* Write rsa_n, rsa_e, rsa_m */ hal_rsa_write_data(RSA_DATA_TYPE_MODULE, rsa_data->rsa_n, rsa_data->rsa_n_len, key_len, (xmedia_u32 *)&random); /* V500 not support rand mask,random reserved! */ drv_rsa_cipher_klad(rsa_data, key_len, (xmedia_u32 *)&random); hal_rsa_write_data(RSA_DATA_TYPE_CONTEXT, rsa_data->input_data, rsa_data->rsa_n_len, key_len, (xmedia_u32 *)&random); /* Sart */ hal_rsa_start(); ret = drv_rsa_wait_done(); if (ret != XMEDIA_SUCCESS) { cipher_debug_log(CIPHER_ERR_RSA_BUSY_TIMEOUT); /*RSA is busy and timeout,error!*/ goto exit; } /* Get result */ hal_rsa_read_data(rsa_data->output_data, rsa_data->rsa_n_len, key_len); err_code = hal_rsa_get_error_code(); if (err_code == 0) { ret = XMEDIA_SUCCESS; } else { cipher_debug_log(CIPHER_ERR_RSA_ERRORCODE); /*RSA is err!*/ ret = XMEDIA_FAILURE; } exit: (void)drv_cipher_clear_rsa_ram(); hal_rsa_disable(); return ret; } static xmedia_s32 drv_cipher_calc_rsa(rsa_data_s *rsa_data) { xmedia_s32 ret; xmedia_u32 key_len = 0; rsa_data_s cipher_rsa_data; rsa_key_width_e key_width = RSA_KEY_WIDTH_BUTT; ret = drv_rsa_key_info(rsa_data, &key_len, &key_width); if (ret != XMEDIA_SUCCESS) return ret; crypto_memset(&cipher_rsa_data, sizeof(rsa_data_s), 0, sizeof(rsa_data_s)); cipher_rsa_data.rsa_n = rsa_data->rsa_n; cipher_rsa_data.rsa_k = rsa_data->rsa_k; cipher_rsa_data.rsa_n_len = key_len; cipher_rsa_data.rsa_k_len = key_len; cipher_rsa_data.input_data = rsa_data->input_data; cipher_rsa_data.data_len = key_len; cipher_rsa_data.output_data = rsa_data->output_data; ret = drv_cipher_calc_rsa_ex(&cipher_rsa_data, key_len, key_width); return ret; } xmedia_s32 xmedia_cipher_rsa_deinit(xmedia_void) { if (rsa_init_flag == 1) { drv_rsa_deinit(); rsa_init_flag = 0; } return XMEDIA_SUCCESS; } xmedia_s32 xmedia_cipher_rsa_verify(const cipher_rsa_verify *rsa_verify, cipher_verify_data *verify_data) { xmedia_s32 ret; rsa_padding_s pad; xmedia_u8 arr_em[RSA_MAX_KEY_LEN]; if (rsa_init_flag == 0) { if (drv_rsa_init() != XMEDIA_SUCCESS) { return XMEDIA_FAILURE; } rsa_init_flag = 1; } crypto_memset(arr_em, sizeof(arr_em), 0, sizeof(arr_em)); crypto_memset(&pad, sizeof(rsa_padding_s), 0, sizeof(rsa_padding_s)); ret = rsa_verify_pad_init(&pad, rsa_verify, verify_data, arr_em); if (ret != XMEDIA_SUCCESS) { cipher_debug_log(CIPHER_ERR_RSA_DEC); return XMEDIA_FAILURE; } if (rsa_verify->scheme == XMEDIA_CIPHER_RSA_SIGN_SCHEME_RSASSA_PKCS1_V15_SHA256) { ret = rsa_padding_check_pkcs1_v15(verify_data->hash_data, SHA256_DATA_BYTE_LEN, arr_em, rsa_verify->pub_key.n_len); if (ret != XMEDIA_SUCCESS) { cipher_debug_log(CIPHER_ERR_RSA_CHECK_PADDING); return XMEDIA_FAILURE; } } else { pad.em_bit = rsa_get_bit_num(rsa_verify->pub_key.n, pad.klen); ret = rsa_padding_check_pkcs1_pss(&pad, verify_data->hash_data); if (ret != XMEDIA_SUCCESS) { cipher_debug_log(CIPHER_ERR_RSA_CHECK_PADDING); return XMEDIA_FAILURE; } } return XMEDIA_SUCCESS; }