| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511 |
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "core_804.h"
- #include "wm_irq.h"
- #include "wm_regs.h"
- #include "wm_debug.h"
- #include "wm_crypto_hard.h"
- #include "wm_internal_flash.h"
- #include "wm_pmu.h"
- //#define TEST_ALL_CRYPTO
- #undef DIGIT_BIT
- #define DIGIT_BIT 28//32
- #define SOFT_RESET_RC4 25
- #define SOFT_RESET_AES 26
- #define SOFT_RESET_DES 27
- #define RNG_SWITCH 28
- #define RNG_LOAD_SEED 29
- #define RNG_START 30
- #define TRNG_EN 0
- #define TRNG_SEL 1
- #define TRNG_DIG_BYPASS 2
- #define TRNG_CP 3
- #define TRNG_INT_MASK 6
- #define USE_TRNG 1
- #define DES_KEY_LEN 8
- #define DES3_KEY_LEN 24
- #define DES3_IV_LEN 8
- #define SHA1_HASH_SIZE 20
- #define MD5_HASH_SIZE 16
- #define STORE32H(x, y) { \
- (y)[0] = (unsigned char)(((x)>>24)&255); \
- (y)[1] = (unsigned char)(((x)>>16)&255); \
- (y)[2] = (unsigned char)(((x)>>8)&255); \
- (y)[3] = (unsigned char)((x)&255); \
- }
- #define STORE32L(x, y) { \
- unsigned long __t = (x); memcpy(y, &__t, 4); \
- }
- //#define CRYPTO_LOG printf
- #define CRYPTO_LOG(...)
- //extern volatile uint32_t sys_count;
- #define sys_count tls_os_get_time()
- extern void delay_cnt(int count);
- struct wm_crypto_ctx g_crypto_ctx = {0,0
- #ifndef CONFIG_KERNEL_NONE
- ,NULL
- #endif
- };
- #if 1
- typedef s32 psPool_t;
- #include "libtommath.h"
- extern int wpa_mp_init (mp_int * a);
- #define pstm_set(a, b) mp_set((mp_int *)a, b)
- #define pstm_init(pool, a) wpa_mp_init((mp_int *)a)
- #define pstm_count_bits(a) mp_count_bits((mp_int *)a)
- #define pstm_init_for_read_unsigned_bin(pool, a, len) mp_init_for_read_unsigned_bin((mp_int *)a, len)
- #define pstm_read_unsigned_bin(a, b, c) mp_read_unsigned_bin((mp_int *)a, b, c)
- #define pstm_copy(a, b) mp_copy((mp_int *)a, (mp_int *)b)
- #define pstm_clear(a) mp_clear((mp_int *)a)
- #define pstm_clamp(a) mp_clamp((mp_int *)a)
- #define pstm_mulmod(pool, a, b, c, d) mp_mulmod((mp_int *)a, (mp_int *)b, (mp_int *)c, (mp_int *)d)
- #define pstm_exptmod(pool, G, X, P, Y) mp_exptmod((mp_int *)G, (mp_int *)X, (mp_int *)P, (mp_int *)Y)
- #define pstm_reverse mp_reverse
- #define pstm_cmp mp_cmp
- #define pstm_to_unsigned_bin_nr(pool, a, b) mp_to_unsigned_bin_nr((mp_int *)a, (unsigned char *)b)
- #define pstm_2expt(a, b) mp_2expt((mp_int *)a, b)
- #define pstm_mod(pool, a, b, c) mp_mod((mp_int *)a, (mp_int *)b, (mp_int *)c)
- #endif
- void RSA_F_IRQHandler(void)
- {
- RSACON = 0x00;
- g_crypto_ctx.rsa_complete = 1;
- }
- void CRYPTION_IRQHandler(void)
- {
- tls_reg_write32(HR_CRYPTO_SEC_STS, 0x10000);
- g_crypto_ctx.gpsec_complete = 1;
- }
- #if 1
- static int16 pstm_get_bit (hstm_int *a, int16 idx)
- {
- int16 r;
- int16 n = idx / DIGIT_BIT;
- int16 m = idx % DIGIT_BIT;
- if (a->used <= 0)
- {
- return 0;
- }
- r = (a->dp[n] >> m) & 0x01;
- return r;
- }
- #endif
- u32 Reflect(u32 ref, u8 ch)
- {
- int i;
- u32 value = 0;
- for( i = 1; i < ( ch + 1 ); i++ )
- {
- if( ref & 1 )
- value |= 1 << ( ch - i );
- ref >>= 1;
- }
- return value;
- }
- #ifndef CONFIG_KERNEL_NONE
- void tls_crypto_sem_lock(void)
- {
- if (g_crypto_ctx.gpsec_lock == NULL)
- {
- return;
- }
- tls_os_sem_acquire(g_crypto_ctx.gpsec_lock, 0);
- }
- void tls_crypto_sem_unlock(void)
- {
- if (g_crypto_ctx.gpsec_lock == NULL)
- {
- return;
- }
- tls_os_sem_release(g_crypto_ctx.gpsec_lock);
- }
- #else
- #define tls_crypto_sem_lock
- #define tls_crypto_sem_unlock
- #endif
- void tls_crypto_set_key(void *key, int keylen)
- {
- uint32_t *key32 = (uint32_t *)key;
- int i = 0;
- for(i = 0; i < keylen / 4 && i < 6; i++)
- {
- M32(HR_CRYPTO_KEY0 + (4 * i)) = key32[i];
- }
- if(keylen == 32)
- {
- M32(HR_CRYPTO_KEY6) = key32[6];
- M32(HR_CRYPTO_KEY7) = key32[7];
- }
- }
- void tls_crypto_set_iv(void *iv, int ivlen)
- {
- uint32_t *IV32 = (uint32_t *)iv;
- if(ivlen >= 8)
- {
- M32(HR_CRYPTO_IV0) = IV32[0];
- M32(HR_CRYPTO_IV0 + 4) = IV32[1];
- }
- if(ivlen == 16)
- {
- M32(HR_CRYPTO_IV1) = IV32[2];
- M32(HR_CRYPTO_IV1 + 4) = IV32[3];
- }
- }
- /**
- * @brief This function is used to stop random produce.
- *
- * @param[in] None
- *
- * @retval 0 success
- * @retval other failed
- *
- * @note None
- */
- int tls_crypto_random_stop(void)
- {
- unsigned int sec_cfg;
- #if USE_TRNG
- #else
- unsigned int val;
- #endif
- tls_open_peripheral_clock(TLS_PERIPHERAL_TYPE_GPSEC);
- #if USE_TRNG
- sec_cfg = 0x40;
- tls_reg_write32(HR_CRYPTO_TRNG_CR, sec_cfg);
- g_crypto_ctx.gpsec_complete = 0;
- #else
- val = tls_reg_read32(HR_CRYPTO_SEC_CFG);
- sec_cfg = val & ~(1 << RNG_START);
- tls_reg_write32(HR_CRYPTO_SEC_CFG, sec_cfg);
- #endif
- tls_close_peripheral_clock(TLS_PERIPHERAL_TYPE_GPSEC);
- tls_crypto_sem_unlock();
- return ERR_CRY_OK;
- }
- /**
- * @brief This function initializes random digit seed and BIT number.
- *
- * @param[in] seed The random digit seed.
- * @param[in] rng_switch The random digit bit number. (0: 16bit 1:32bit)
- *
- * @retval 0 success
- * @retval other failed
- *
- * @note None
- */
- int tls_crypto_random_init(u32 seed, CRYPTO_RNG_SWITCH rng_switch)
- {
- unsigned int sec_cfg;
- tls_crypto_sem_lock();
- tls_open_peripheral_clock(TLS_PERIPHERAL_TYPE_GPSEC);
- #if USE_TRNG
- sec_cfg = (1 << TRNG_INT_MASK) | (4 << TRNG_CP) | (1 << TRNG_SEL) | (1 << TRNG_EN);
- sec_cfg &= ~(1 << TRNG_INT_MASK);
- g_crypto_ctx.gpsec_complete = 0;
- tls_reg_write32(HR_CRYPTO_TRNG_CR, sec_cfg);
- #else
- tls_reg_write32(HR_CRYPTO_KEY0, seed);
- sec_cfg = (rng_switch << RNG_SWITCH) | (1 << RNG_LOAD_SEED) | (1 << RNG_START);
- tls_reg_write32(HR_CRYPTO_SEC_CFG, sec_cfg);
- #endif
- return ERR_CRY_OK;
- }
- /**
- * @brief This function is used to get random digit content.
- *
- * @param[in] out Pointer to the output of random digit.
- * @param[in] len The random digit bit number will output.
- *
- * @retval 0 success
- * @retval other failed
- *
- * @note None
- */
- int tls_crypto_random_bytes(unsigned char *out, u32 len)
- {
- unsigned int val;
- uint32 inLen = len;
- int randomBytes = 2;
- #if USE_TRNG
- delay_cnt(1000);
- randomBytes = 4;
- #else
- val = tls_reg_read32(HR_CRYPTO_SEC_CFG);
- randomBytes = val & (1 << RNG_SWITCH) ? 4 : 2;
- #endif
- while(inLen > 0)
- {
- #if USE_TRNG
- while (!g_crypto_ctx.gpsec_complete)
- {
- }
- g_crypto_ctx.gpsec_complete = 0;
- #endif
- val = tls_reg_read32(HR_CRYPTO_RNG_RESULT);
- if(inLen >= randomBytes)
- {
- memcpy(out, (char *)&val, randomBytes);
- out += randomBytes;
- inLen -= randomBytes;
- }
- else
- {
- memcpy(out, (char *)&val, inLen);
- inLen = 0;
- }
- }
- //tls_close_peripheral_clock(TLS_PERIPHERAL_TYPE_GPSEC);
- return ERR_CRY_OK;
- }
- /**
- * @brief This function is used to generate true random number.
- *
- * @param[in] out Pointer to the output of random number.
- * @param[in] len The random number length.
- *
- * @retval 0 success
- * @retval other failed
- *
- * @note None
- */
- int tls_crypto_trng(unsigned char *out, u32 len)
- {
- unsigned int sec_cfg, val;
- uint32 inLen = len;
- int randomBytes = 4;
- tls_crypto_sem_lock();
- tls_open_peripheral_clock(TLS_PERIPHERAL_TYPE_GPSEC);
- sec_cfg = (1 << TRNG_INT_MASK) | (4 << TRNG_CP) | (1 << TRNG_SEL) | (1 << TRNG_EN);
- tls_reg_write32(HR_CRYPTO_TRNG_CR, sec_cfg);
- sec_cfg &= ~(1 << TRNG_INT_MASK);
- tls_reg_write32(HR_CRYPTO_TRNG_CR, sec_cfg);
- delay_cnt(1000);
- while(inLen > 0)
- {
- g_crypto_ctx.gpsec_complete = 0;
- while (!g_crypto_ctx.gpsec_complete)
- {
- }
- g_crypto_ctx.gpsec_complete = 0;
- val = tls_reg_read32(HR_CRYPTO_RNG_RESULT);
- if(inLen >= randomBytes)
- {
- memcpy(out, (char *)&val, randomBytes);
- out += randomBytes;
- inLen -= randomBytes;
- }
- else
- {
- memcpy(out, (char *)&val, inLen);
- inLen = 0;
- }
- }
- tls_reg_write32(HR_CRYPTO_TRNG_CR, 0x40);
- tls_close_peripheral_clock(TLS_PERIPHERAL_TYPE_GPSEC);
- tls_crypto_sem_unlock();
- return ERR_CRY_OK;
- }
- int tls_crypto_random_bytes_range(unsigned char *out, u32 len, u32 range)
- {
- unsigned int val, i;
- val = tls_reg_read32(HR_CRYPTO_SEC_CFG);
- for(i = 0; i< len; i++) {
- val = tls_reg_read32(HR_CRYPTO_RNG_RESULT);
- out[i] = val % range;
- // printf("rand val:%d, val:%d\r\n", val, out[i]);
- }
- return ERR_CRY_OK;
- }
- /**
- * @brief This function initializes a RC4 encryption algorithm,
- * i.e. fills the psCipherContext_t structure pointed to by ctx with necessary data.
- *
- * @param[in] ctx Pointer to the Cipher Context.
- * @param[in] key Pointer to the key.
- * @param[in] keylen the length of key.
- *
- * @retval 0 success
- * @retval other failed
- *
- * @note The first parameter ctx must be a structure which is allocated externally.
- * And all of Context parameters in the initializing methods should be allocated externally too.
- */
- int tls_crypto_rc4_init(psCipherContext_t *ctx, const unsigned char *key, u32 keylen)
- {
- if(keylen != 16 && keylen != 32)
- {
- return ERR_FAILURE;
- }
- memcpy(ctx->arc4.state, key, keylen);
- ctx->arc4.byteCount = keylen;
- return ERR_CRY_OK;
- }
- /**
- * @brief This function encrypts a variable length data stream according to RC4.
- * The RC4 algorithm it generates a "keystream" which is simply XORed with the plaintext to produce the ciphertext stream.
- * Decryption is exactly the same as encryption. This function also decrypts a variable length data stream according to RC4.
- *
- * @param[in] ctx Pointer to the Cipher Context.
- * @param[in] in Pointer to the input plaintext data stream(or the encrypted text data stream) of variable length.
- * @param[in] out Pointer to the resulting ciphertext data stream.
- * @param[in] len Length of the plaintext data stream in octets.
- *
- * @retval 0 success
- * @retval other failed
- *
- * @note None
- */
- int tls_crypto_rc4(psCipherContext_t *ctx, unsigned char *in, unsigned char *out, u32 len)
- {
- unsigned int sec_cfg;
- unsigned char *key = ctx->arc4.state;
- u32 keylen = ctx->arc4.byteCount;
- tls_crypto_sem_lock();
- tls_open_peripheral_clock(TLS_PERIPHERAL_TYPE_GPSEC);
- tls_crypto_set_key(key, keylen);
- tls_reg_write32(HR_CRYPTO_SRC_ADDR, (unsigned int)in);
- tls_reg_write32(HR_CRYPTO_DEST_ADDR, (unsigned int)out);
- sec_cfg = (CRYPTO_METHOD_RC4 << 16) | (1 << SOFT_RESET_RC4) | (len & 0xFFFF);
- if(keylen == 32)
- {
- sec_cfg |= (1 << 31);
- }
- tls_reg_write32(HR_CRYPTO_SEC_CFG, sec_cfg);
- CRYPTO_LOG("[%d]:rc4[%d] start\n", sys_count, len);
- g_crypto_ctx.gpsec_complete = 0;
- tls_reg_write32(HR_CRYPTO_SEC_CTRL, 0x1);//start crypto
- while (!g_crypto_ctx.gpsec_complete)
- {
- }
- g_crypto_ctx.gpsec_complete = 0;
- CRYPTO_LOG("[%d]:rc4 end status: %x\n", sys_count, tls_reg_read32(HR_CRYPTO_SEC_STS));
- tls_close_peripheral_clock(TLS_PERIPHERAL_TYPE_GPSEC);
- tls_crypto_sem_unlock();
- return ERR_CRY_OK;
- }
- /**
- * @brief This function initializes a AES encryption algorithm, i.e. fills the psCipherContext_t structure pointed to by ctx with necessary data.
- *
- * @param[in] ctx Pointer to the Cipher Context.
- * @param[in] IV Pointer to the Initialization Vector
- * @param[in] key Pointer to the key.
- * @param[in] keylen the length of key.
- * @param[in] cbc the encryption mode, AES supports ECB/CBC/CTR modes.
- *
- * @retval 0 success
- * @retval other failed
- *
- * @note None
- */
- int tls_crypto_aes_init(psCipherContext_t *ctx, const unsigned char *IV, const unsigned char *key, u32 keylen, CRYPTO_MODE cbc)
- {
- int x = 0;
- if (keylen != 16)
- return ERR_FAILURE;
- memcpy(ctx->aes.key.skey, key, keylen);
- ctx->aes.key.type = cbc;
- ctx->aes.key.rounds = 16;
- if(IV)
- {
- for (x = 0; x < ctx->aes.key.rounds; x++)
- {
- ctx->aes.IV[x] = IV[x];
- }
- }
- return ERR_CRY_OK;
- }
- /**
- * @brief This function encrypts or decrypts a variable length data stream according to AES.
- *
- * @param[in] ctx Pointer to the Cipher Context.
- * @param[in] in Pointer to the input plaintext data stream(or the encrypted text data stream) of variable length.
- * @param[in] out Pointer to the resulting ciphertext data stream.
- * @param[in] len Length of the plaintext data stream in octets.
- * @param[in] dec The cryption way which indicates encryption or decryption.
- *
- * @retval 0 success
- * @retval other failed
- *
- * @note None
- */
- int tls_crypto_aes_encrypt_decrypt(psCipherContext_t *ctx, unsigned char *in, unsigned char *out, u32 len, CRYPTO_WAY dec)
- {
- unsigned int sec_cfg;
- u32 keylen = 16;
- unsigned char *key = (unsigned char *)ctx->aes.key.skey;
- unsigned char *IV = ctx->aes.IV;
- CRYPTO_MODE cbc = (CRYPTO_MODE)(ctx->aes.key.type & 0xFF);
- tls_crypto_sem_lock();
- tls_open_peripheral_clock(TLS_PERIPHERAL_TYPE_GPSEC);
- tls_crypto_set_key(key, keylen);
- tls_crypto_set_iv(IV, 16);
- tls_reg_write32(HR_CRYPTO_SRC_ADDR, (unsigned int)in);
- tls_reg_write32(HR_CRYPTO_DEST_ADDR, (unsigned int)out);
- sec_cfg = (CRYPTO_METHOD_AES << 16) | (1 << SOFT_RESET_AES) | (dec << 20) | (cbc << 21) | (len & 0xFFFF);
- tls_reg_write32(HR_CRYPTO_SEC_CFG, sec_cfg);
- CRYPTO_LOG("[%d]:aes[%d] %s %s start\n", sys_count, len, dec == CRYPTO_WAY_ENCRYPT ? "ENCRYPT" : "DECRYPT",
- cbc == CRYPTO_MODE_ECB ? "ECB" : (cbc == CRYPTO_MODE_CBC ? "CBC" : (cbc == CRYPTO_MODE_CTR ? "CTR" : "MAC")));
- g_crypto_ctx.gpsec_complete = 0;
- tls_reg_write32(HR_CRYPTO_SEC_CTRL, 0x1);//start crypto
- while (!g_crypto_ctx.gpsec_complete)
- {
- }
- g_crypto_ctx.gpsec_complete = 0;
- CRYPTO_LOG("[%d]:aes end %d\n", sys_count, tls_reg_read32(HR_CRYPTO_SEC_STS) & 0xFFFF);
- tls_close_peripheral_clock(TLS_PERIPHERAL_TYPE_GPSEC);
- tls_crypto_sem_unlock();
- return ERR_CRY_OK;
- }
- /**
- * @brief This function initializes a 3DES encryption algorithm, i.e. fills the psCipherContext_t structure pointed to by ctx with necessary data.
- *
- * @param[in] ctx Pointer to the Cipher Context.
- * @param[in] IV Pointer to the Initialization Vector
- * @param[in] key Pointer to the key.
- * @param[in] keylen the length of key.
- * @param[in] cbc the encryption mode, 3DES supports ECB/CBC modes.
- *
- * @retval 0 success
- * @retval other failed
- *
- * @note None
- */
- int tls_crypto_3des_init(psCipherContext_t *ctx, const unsigned char *IV, const unsigned char *key, u32 keylen, CRYPTO_MODE cbc)
- {
- unsigned int x;
- if (keylen != DES3_KEY_LEN)
- return ERR_FAILURE;
- memcpy(ctx->des3.key.ek[0], key, keylen);
- ctx->des3.key.ek[1][0] = cbc;
- ctx->des3.blocklen = DES3_IV_LEN;
- if(IV)
- {
- for (x = 0; x < ctx->des3.blocklen; x++)
- {
- ctx->des3.IV[x] = IV[x];
- }
- }
- return ERR_CRY_OK;
- }
- /**
- * @brief This function encrypts or decrypts a variable length data stream according to 3DES.
- *
- * @param[in] ctx Pointer to the Cipher Context.
- * @param[in] in Pointer to the input plaintext data stream(or the encrypted text data stream) of variable length.
- * @param[in] out Pointer to the resulting ciphertext data stream.
- * @param[in] len Length of the plaintext data stream in octets.
- * @param[in] dec The cryption way which indicates encryption or decryption.
- *
- * @retval 0 success
- * @retval other failed
- *
- * @note None
- */
- int tls_crypto_3des_encrypt_decrypt(psCipherContext_t *ctx, unsigned char *in, unsigned char *out, u32 len, CRYPTO_WAY dec)
- {
- unsigned int sec_cfg;
- u32 keylen = DES3_KEY_LEN;
- unsigned char *key = (unsigned char *)(unsigned char *)ctx->des3.key.ek[0];
- unsigned char *IV = ctx->des3.IV;
- CRYPTO_MODE cbc = (CRYPTO_MODE)(ctx->des3.key.ek[1][0] & 0xFF);
- tls_crypto_sem_lock();
- tls_open_peripheral_clock(TLS_PERIPHERAL_TYPE_GPSEC);
- tls_crypto_set_key(key, keylen);
- tls_crypto_set_iv(IV, DES3_IV_LEN);
- tls_reg_write32(HR_CRYPTO_SRC_ADDR, (unsigned int)in);
- tls_reg_write32(HR_CRYPTO_DEST_ADDR, (unsigned int)out);
- sec_cfg = (CRYPTO_METHOD_3DES << 16) | (1 << SOFT_RESET_DES) | (dec << 20) | (cbc << 21) | (len & 0xFFFF);
- tls_reg_write32(HR_CRYPTO_SEC_CFG, sec_cfg);
- CRYPTO_LOG("[%d]:3des[%d] %s %s start\n", sys_count, len, dec == CRYPTO_WAY_ENCRYPT ? "ENCRYPT" : "DECRYPT",
- cbc == CRYPTO_MODE_ECB ? "ECB" : "CBC");
- g_crypto_ctx.gpsec_complete = 0;
- tls_reg_write32(HR_CRYPTO_SEC_CTRL, 0x1);//start crypto
- while (!g_crypto_ctx.gpsec_complete)
- {
- }
- g_crypto_ctx.gpsec_complete = 0;
- CRYPTO_LOG("[%d]:3des end %d\n", sys_count, tls_reg_read32(HR_CRYPTO_SEC_STS) & 0xFFFF);
- tls_close_peripheral_clock(TLS_PERIPHERAL_TYPE_GPSEC);
- tls_crypto_sem_unlock();
- return ERR_CRY_OK;
- }
- /**
- * @brief This function initializes a DES encryption algorithm, i.e. fills the psCipherContext_t structure pointed to by ctx with necessary data.
- *
- * @param[in] ctx Pointer to the Cipher Context.
- * @param[in] IV Pointer to the Initialization Vector
- * @param[in] key Pointer to the key.
- * @param[in] keylen the length of key.
- * @param[in] cbc the encryption mode, DES supports ECB/CBC modes.
- *
- * @retval 0 success
- * @retval other failed
- *
- * @note None
- */
- int tls_crypto_des_init(psCipherContext_t *ctx, const unsigned char *IV, const unsigned char *key, u32 keylen, CRYPTO_MODE cbc)
- {
- unsigned int x;
- if (keylen != DES_KEY_LEN)
- return ERR_FAILURE;
- memcpy(ctx->des3.key.ek[0], key, keylen);
- ctx->des3.key.ek[1][0] = cbc;
- ctx->des3.blocklen = DES3_IV_LEN;
- if(IV)
- {
- for (x = 0; x < ctx->des3.blocklen; x++)
- {
- ctx->des3.IV[x] = IV[x];
- }
- }
- return ERR_CRY_OK;
- }
- /**
- * @brief This function encrypts or decrypts a variable length data stream according to DES.
- *
- * @param[in] ctx Pointer to the Cipher Context.
- * @param[in] in Pointer to the input plaintext data stream(or the encrypted text data stream) of variable length.
- * @param[in] out Pointer to the resulting ciphertext data stream.
- * @param[in] len Length of the plaintext data stream in octets.
- * @param[in] dec The cryption way which indicates encryption or decryption.
- *
- * @retval 0 success
- * @retval other failed
- *
- * @note None
- */
- int tls_crypto_des_encrypt_decrypt(psCipherContext_t *ctx, unsigned char *in, unsigned char *out, u32 len, CRYPTO_WAY dec)
- {
- unsigned int sec_cfg;
- u32 keylen = DES_KEY_LEN;
- unsigned char *key = (unsigned char *)ctx->des3.key.ek[0];
- unsigned char *IV = ctx->des3.IV;
- CRYPTO_MODE cbc = (CRYPTO_MODE)(ctx->des3.key.ek[1][0] & 0xFF);
- //uint32_t *IV32 = (uint32_t *)IV;
- tls_crypto_sem_lock();
- tls_open_peripheral_clock(TLS_PERIPHERAL_TYPE_GPSEC);
- tls_crypto_set_key(key, keylen);
- tls_crypto_set_iv(IV, DES3_IV_LEN);
- tls_reg_write32(HR_CRYPTO_SRC_ADDR, (unsigned int)in);
- tls_reg_write32(HR_CRYPTO_DEST_ADDR, (unsigned int)out);
- sec_cfg = (CRYPTO_METHOD_DES << 16) | (1 << SOFT_RESET_DES) | (dec << 20) | (cbc << 21) | (len & 0xFFFF);
- tls_reg_write32(HR_CRYPTO_SEC_CFG, sec_cfg);
- CRYPTO_LOG("[%d]:des[%d] %s %s start\n", sys_count, len, dec == CRYPTO_WAY_ENCRYPT ? "ENCRYPT" : "DECRYPT",
- cbc == CRYPTO_MODE_ECB ? "ECB" : "CBC");
- g_crypto_ctx.gpsec_complete = 0;
- tls_reg_write32(HR_CRYPTO_SEC_CTRL, 0x1);//start crypto
- while (!g_crypto_ctx.gpsec_complete)
- {
- }
- g_crypto_ctx.gpsec_complete = 0;
- CRYPTO_LOG("[%d]:des end %d\n", sys_count, tls_reg_read32(HR_CRYPTO_SEC_STS) & 0xFFFF);
- tls_close_peripheral_clock(TLS_PERIPHERAL_TYPE_GPSEC);
- tls_crypto_sem_unlock();
- return ERR_CRY_OK;
- }
- /**
- * @brief This function initializes a CRC algorithm, i.e. fills the psCrcContext_t structure pointed to by ctx with necessary data.
- *
- * @param[in] ctx Pointer to the CRC Context.
- * @param[in] key The initialization key.
- * @param[in] crc_type The CRC type, supports CRC8/CRC16 MODBUS/CRC16 CCITT/CRC32
- * @param[in] mode Set input or outpu reflect.
- * @param[in] dec The cryption way which indicates encryption or decryption.
- * see OUTPUT_REFLECT
- * see INPUT_REFLECT
- *
- * @retval 0 success
- * @retval other failed
- *
- * @note None
- */
- int tls_crypto_crc_init(psCrcContext_t *ctx, u32 key, CRYPTO_CRC_TYPE crc_type, u8 mode)
- {
- ctx->state = key;
- ctx->type = crc_type;
- ctx->mode = mode;
- return ERR_CRY_OK;
- }
- /**
- * @brief This function updates the CRC value with a variable length bytes.
- * This function may be called as many times as necessary, so the message may be processed in blocks.
- *
- * @param[in] ctx Pointer to the CRC Context.
- * @param[in] in Pointer to a variable length bytes
- * @param[in] len The bytes 's length
- *
- * @retval 0 success
- * @retval other failed
- *
- * @note None
- */
- int tls_crypto_crc_update(psCrcContext_t *ctx, unsigned char *in, u32 len)
- {
- unsigned int sec_cfg;
- tls_crypto_sem_lock();
- tls_open_peripheral_clock(TLS_PERIPHERAL_TYPE_GPSEC);
- sec_cfg = (CRYPTO_METHOD_CRC << 16) | (ctx->type << 21) | (ctx->mode << 23) | (len & 0xFFFF);
- tls_reg_write32(HR_CRYPTO_SEC_CFG, sec_cfg);
- if(ctx->mode & OUTPUT_REFLECT)
- {
- u8 ch_crc = 16;
- u32 state = 0;
- switch(ctx->type)
- {
- case CRYPTO_CRC_TYPE_8:
- ch_crc = 8;
- break;
- case CRYPTO_CRC_TYPE_16_MODBUS:
- ch_crc = 16;
- break;
- case CRYPTO_CRC_TYPE_16_CCITT:
- ch_crc = 16;
- break;
- case CRYPTO_CRC_TYPE_32:
- ch_crc = 32;
- break;
- default:
- break;
- }
- state = Reflect(ctx->state, ch_crc);
- tls_reg_write32(HR_CRYPTO_CRC_KEY, state);
- }
- else
- tls_reg_write32(HR_CRYPTO_CRC_KEY, ctx->state);
- tls_reg_write32(HR_CRYPTO_SRC_ADDR, (unsigned int)in);
- g_crypto_ctx.gpsec_complete = 0;
- tls_reg_write32(HR_CRYPTO_SEC_CTRL, 0x1);//start crypto
- while (!g_crypto_ctx.gpsec_complete)
- {
- }
- g_crypto_ctx.gpsec_complete = 0;
- ctx->state = tls_reg_read32(HR_CRYPTO_CRC_RESULT);
- tls_reg_write32(HR_CRYPTO_SEC_CTRL, 0x4);//clear crc fifo
- tls_close_peripheral_clock(TLS_PERIPHERAL_TYPE_GPSEC);
- tls_crypto_sem_unlock();
- return ERR_CRY_OK;
- }
- /**
- * @brief This function ends a CRC operation and produces a CRC value.
- *
- * @param[in] ctx Pointer to the CRC Context.
- * @param[in] crc_val Pointer to the CRC value.
- *
- * @retval 0 success
- * @retval other failed
- *
- * @note None
- */
- int tls_crypto_crc_final(psCrcContext_t *ctx, u32 *crc_val)
- {
- *crc_val = ctx->state;
- return ERR_CRY_OK;
- }
- static void hd_sha1_compress(psDigestContext_t *md)
- {
- unsigned int sec_cfg, val;
- int i = 0;
- tls_crypto_sem_lock();
- tls_open_peripheral_clock(TLS_PERIPHERAL_TYPE_GPSEC);
- tls_reg_write32(HR_CRYPTO_SRC_ADDR, (unsigned int)md->u.sha1.buf);
- sec_cfg = (CRYPTO_METHOD_SHA1 << 16) | (64 & 0xFFFF); // TODO
- tls_reg_write32(HR_CRYPTO_SEC_CFG, sec_cfg);
- tls_reg_write32(HR_CRYPTO_SHA1_DIGEST0, md->u.sha1.state[0]);
- tls_reg_write32(HR_CRYPTO_SHA1_DIGEST1, md->u.sha1.state[1]);
- tls_reg_write32(HR_CRYPTO_SHA1_DIGEST2, md->u.sha1.state[2]);
- tls_reg_write32(HR_CRYPTO_SHA1_DIGEST3, md->u.sha1.state[3]);
- tls_reg_write32(HR_CRYPTO_SHA1_DIGEST4, md->u.sha1.state[4]);
- g_crypto_ctx.gpsec_complete = 0;
- tls_reg_write32(HR_CRYPTO_SEC_CTRL, 0x1);//start crypto
- while (!g_crypto_ctx.gpsec_complete)
- {
- }
- g_crypto_ctx.gpsec_complete = 0;
- for (i = 0; i < 5; i++)
- {
- val = tls_reg_read32(HR_CRYPTO_SHA1_DIGEST0 + (4 * i));
- md->u.sha1.state[i] = val;
- }
- tls_close_peripheral_clock(TLS_PERIPHERAL_TYPE_GPSEC);
- tls_crypto_sem_unlock();
- }
- /**
- * @brief This function initializes Message-Diggest context for usage in SHA1 algorithm, starts a new SHA1 operation and writes a new Digest Context.
- *
- * @param[in] md Pointer to the SHA1 Digest Context.
- *
- * @retval 0 success
- * @retval other failed
- *
- * @note None
- */
- void tls_crypto_sha1_init(psDigestContext_t *md)
- {
- md->u.sha1.state[0] = 0x67452301UL;
- md->u.sha1.state[1] = 0xefcdab89UL;
- md->u.sha1.state[2] = 0x98badcfeUL;
- md->u.sha1.state[3] = 0x10325476UL;
- md->u.sha1.state[4] = 0xc3d2e1f0UL;
- md->u.sha1.curlen = 0;
- #ifdef HAVE_NATIVE_INT64
- md->u.sha1.length = 0;
- #else
- md->u.sha1.lengthHi = 0;
- md->u.sha1.lengthLo = 0;
- #endif /* HAVE_NATIVE_INT64 */
- }
- /**
- * @brief Process a message block using SHA1 algorithm.
- * This function performs a SHA1 block update operation. It continues an SHA1 message-digest operation,
- * by processing InputLen-byte length message block pointed to by buf, and by updating the SHA1 context pointed to by md.
- * This function may be called as many times as necessary, so the message may be processed in blocks.
- *
- * @param[in] md Pointer to the SHA1 Digest Context.
- * @param[in] buf InputLen-byte length message block
- * @param[in] len The buf 's length
- *
- * @returnl None
- *
- * @note None
- */
- void tls_crypto_sha1_update(psDigestContext_t *md, const unsigned char *buf, u32 len)
- {
- u32 n;
- while (len > 0)
- {
- n = min(len, (64 - md->u.sha1.curlen));
- memcpy(md->u.sha1.buf + md->u.sha1.curlen, buf, (size_t)n);
- md->u.sha1.curlen += n;
- buf += n;
- len -= n;
- /* is 64 bytes full? */
- if (md->u.sha1.curlen == 64)
- {
- hd_sha1_compress(md);
- #ifdef HAVE_NATIVE_INT64
- md->u.sha1.length += 512;
- #else
- n = (md->u.sha1.lengthLo + 512) & 0xFFFFFFFFL;
- if (n < md->u.sha1.lengthLo)
- {
- md->u.sha1.lengthHi++;
- }
- md->u.sha1.lengthLo = n;
- #endif /* HAVE_NATIVE_INT64 */
- md->u.sha1.curlen = 0;
- }
- }
- }
- /**
- * @brief This function ends a SHA1 operation and produces a Message-Digest.
- * This function finalizes SHA1 algorithm, i.e. ends an SHA1 Message-Digest operation,
- * writing the Message-Digest in the 20-byte buffer pointed to by hash in according to the information stored in context.
- *
- * @param[in] md Pointer to the SHA1 Digest Context.
- * @param[in] hash Pointer to the Message-Digest
- *
- * @retval 20 success, return the hash size.
- * @retval <0 failed
- *
- * @note None
- */
- int tls_crypto_sha1_final(psDigestContext_t *md, unsigned char *hash)
- {
- s32 i;
- u32 val;
- #ifndef HAVE_NATIVE_INT64
- u32 n;
- #endif
- if (md->u.sha1.curlen >= sizeof(md->u.sha1.buf) || hash == NULL)
- {
- return ERR_ARG_FAIL;
- }
- /*
- increase the length of the message
- */
- #ifdef HAVE_NATIVE_INT64
- md->u.sha1.length += md->u.sha1.curlen << 3;
- #else
- n = (md->u.sha1.lengthLo + (md->u.sha1.curlen << 3)) & 0xFFFFFFFFL;
- if (n < md->u.sha1.lengthLo)
- {
- md->u.sha1.lengthHi++;
- }
- md->u.sha1.lengthHi += (md->u.sha1.curlen >> 29);
- md->u.sha1.lengthLo = n;
- #endif /* HAVE_NATIVE_INT64 */
- /*
- append the '1' bit
- */
- md->u.sha1.buf[md->u.sha1.curlen++] = (unsigned char)0x80;
- /*
- if the length is currently above 56 bytes we append zeros then compress.
- Then we can fall back to padding zeros and length encoding like normal.
- */
- if (md->u.sha1.curlen > 56)
- {
- while (md->u.sha1.curlen < 64)
- {
- md->u.sha1.buf[md->u.sha1.curlen++] = (unsigned char)0;
- }
- hd_sha1_compress(md);
- md->u.sha1.curlen = 0;
- }
- /*
- pad upto 56 bytes of zeroes
- */
- while (md->u.sha1.curlen < 56)
- {
- md->u.sha1.buf[md->u.sha1.curlen++] = (unsigned char)0;
- }
- /*
- store length
- */
- #ifdef HAVE_NATIVE_INT64
- STORE64H(md->u.sha1.length, md->u.sha1.buf + 56);
- #else
- STORE32H(md->u.sha1.lengthHi, md->u.sha1.buf + 56);
- STORE32H(md->u.sha1.lengthLo, md->u.sha1.buf + 60);
- #endif /* HAVE_NATIVE_INT64 */
- hd_sha1_compress(md);
- /*
- copy output
- */
- for (i = 0; i < 5; i++)
- {
- val = tls_reg_read32(HR_CRYPTO_SHA1_DIGEST0 + (4 * i));
- STORE32H(val, hash + (4 * i));
- }
- memset(md, 0x0, sizeof(psSha1_t));
- return SHA1_HASH_SIZE;
- }
- static void hd_md5_compress(psDigestContext_t *md)
- {
- unsigned int sec_cfg, val, i;
- tls_crypto_sem_lock();
- tls_open_peripheral_clock(TLS_PERIPHERAL_TYPE_GPSEC);
- tls_reg_write32(HR_CRYPTO_SRC_ADDR, (unsigned int)md->u.md5.buf);
- sec_cfg = (CRYPTO_METHOD_MD5 << 16) | (64 & 0xFFFF);
- tls_reg_write32(HR_CRYPTO_SEC_CFG, sec_cfg);
- tls_reg_write32(HR_CRYPTO_SHA1_DIGEST0, md->u.md5.state[0]);
- tls_reg_write32(HR_CRYPTO_SHA1_DIGEST1, md->u.md5.state[1]);
- tls_reg_write32(HR_CRYPTO_SHA1_DIGEST2, md->u.md5.state[2]);
- tls_reg_write32(HR_CRYPTO_SHA1_DIGEST3, md->u.md5.state[3]);
- g_crypto_ctx.gpsec_complete = 0;
- tls_reg_write32(HR_CRYPTO_SEC_CTRL, 0x1);//start crypto
- while (!g_crypto_ctx.gpsec_complete)
- {
- }
- g_crypto_ctx.gpsec_complete = 0;
- for (i = 0; i < 4; i++)
- {
- val = tls_reg_read32(HR_CRYPTO_SHA1_DIGEST0 + (4 * i));
- md->u.md5.state[i] = val;
- }
- tls_close_peripheral_clock(TLS_PERIPHERAL_TYPE_GPSEC);
- tls_crypto_sem_unlock();
- }
- /**
- * @brief This function initializes Message-Diggest context for usage in MD5 algorithm, starts a new MD5 operation and writes a new Digest Context.
- * This function begins a MD5 Message-Diggest Algorithm, i.e. fills the psDigestContext_t structure pointed to by md with necessary data.
- * MD5 is the algorithm which takes as input a message of arbitrary length and produces as output a 128-bit "fingerprint" or "message digest" of the input.
- * It is conjectured that it is computationally infeasible to produce two messages having the same message digest,
- * or to produce any message having a given prespecified target message digest.
- *
- * @param[in] md MD5 Digest Context.
- *
- * @return None
- *
- * @note None
- */
- void tls_crypto_md5_init(psDigestContext_t *md)
- {
- md->u.md5.state[0] = 0x67452301UL;
- md->u.md5.state[1] = 0xefcdab89UL;
- md->u.md5.state[2] = 0x98badcfeUL;
- md->u.md5.state[3] = 0x10325476UL;
- md->u.md5.curlen = 0;
- #ifdef HAVE_NATIVE_INT64
- md->u.md5.length = 0;
- #else
- md->u.md5.lengthHi = 0;
- md->u.md5.lengthLo = 0;
- #endif /* HAVE_NATIVE_INT64 */
- }
- /**
- * @brief Process a message block using MD5 algorithm.
- * This function performs a MD5 block update operation. It continues an MD5 message-digest operation,
- * by processing InputLen-byte length message block pointed to by buf, and by updating the MD5 context pointed to by md.
- * This function may be called as many times as necessary, so the message may be processed in blocks.
- *
- * @param[in] md MD5 Digest Context.
- * @param[in] buf InputLen-byte length message block
- * @param[in] len The buf 's length
- *
- * @return None
- *
- * @note None
- */
- void tls_crypto_md5_update(psDigestContext_t *md, const unsigned char *buf, u32 len)
- {
- u32 n;
- while (len > 0)
- {
- n = min(len, (64 - md->u.md5.curlen));
- memcpy(md->u.md5.buf + md->u.md5.curlen, buf, (size_t)n);
- md->u.md5.curlen += n;
- buf += n;
- len -= n;
- /*
- is 64 bytes full?
- */
- if (md->u.md5.curlen == 64)
- {
- hd_md5_compress(md);
- #ifdef HAVE_NATIVE_INT64
- md->u.md5.length += 512;
- #else
- n = (md->u.md5.lengthLo + 512) & 0xFFFFFFFFL;
- if (n < md->u.md5.lengthLo)
- {
- md->u.md5.lengthHi++;
- }
- md->u.md5.lengthLo = n;
- #endif /* HAVE_NATIVE_INT64 */
- md->u.md5.curlen = 0;
- }
- }
- }
- /**
- * @brief This function ends a MD5 operation and produces a Message-Digest.
- * This function finalizes MD5 algorithm, i.e. ends an MD5 Message-Digest operation,
- * writing the Message-Digest in the 16-byte buffer pointed to by hash in according to the information stored in context.
- *
- * @param[in] md MD5 Digest Context.
- * @param[in] hash the Message-Digest
- *
- * @retval 16 success, return the hash size.
- * @retval <0 failed
- *
- * @note None
- */
- s32 tls_crypto_md5_final(psDigestContext_t *md, unsigned char *hash)
- {
- s32 i;
- u32 val;
- #ifndef HAVE_NATIVE_INT64
- u32 n;
- #endif
- // psAssert(md != NULL);
- if (hash == NULL)
- {
- CRYPTO_LOG("NULL hash storage passed to psMd5Final\n");
- return PS_ARG_FAIL;
- }
- /*
- increase the length of the message
- */
- #ifdef HAVE_NATIVE_INT64
- md->u.md5.length += md->u.md5.curlen << 3;
- #else
- n = (md->u.md5.lengthLo + (md->u.md5.curlen << 3)) & 0xFFFFFFFFL;
- if (n < md->u.md5.lengthLo)
- {
- md->u.md5.lengthHi++;
- }
- md->u.md5.lengthHi += (md->u.md5.curlen >> 29);
- md->u.md5.lengthLo = n;
- #endif /* HAVE_NATIVE_INT64 */
- /*
- append the '1' bit
- */
- md->u.md5.buf[md->u.md5.curlen++] = (unsigned char)0x80;
- /*
- if the length is currently above 56 bytes we append zeros then compress.
- Then we can fall back to padding zeros and length encoding like normal.
- */
- if (md->u.md5.curlen > 56)
- {
- while (md->u.md5.curlen < 64)
- {
- md->u.md5.buf[md->u.md5.curlen++] = (unsigned char)0;
- }
- hd_md5_compress(md);
- md->u.md5.curlen = 0;
- }
- /*
- pad upto 56 bytes of zeroes
- */
- while (md->u.md5.curlen < 56)
- {
- md->u.md5.buf[md->u.md5.curlen++] = (unsigned char)0;
- }
- /*
- store length
- */
- #ifdef HAVE_NATIVE_INT64
- STORE64L(md->u.md5.length, md->u.md5.buf + 56);
- #else
- STORE32L(md->u.md5.lengthLo, md->u.md5.buf + 56);
- STORE32L(md->u.md5.lengthHi, md->u.md5.buf + 60);
- #endif /* HAVE_NATIVE_INT64 */
- hd_md5_compress(md);
- /*
- copy output
- */
- for (i = 0; i < 4; i++)
- {
- val = tls_reg_read32(HR_CRYPTO_SHA1_DIGEST0 + (4 * i));
- STORE32L(val, hash + (4 * i));
- }
- memset(md, 0x0, sizeof(psMd5_t));
- return MD5_HASH_SIZE;
- }
- static void rsaMonMulSetLen(const u32 len)
- {
- RSAN = len;
- }
- static void rsaMonMulWriteMc(const u32 mc)
- {
- u32 val = 0;
- RSAMC = mc;
- val = RSAMC;
- if(val == mc)
- {
- val = 1;
- return;
- }
- }
- static void rsaMonMulWriteA(const u32 *const in)
- {
- memcpy((u32 *)&RSAXBUF, in, RSAN * sizeof(u32));
- }
- static void rsaMonMulWriteB(const u32 *const in)
- {
- memcpy((u32 *)&RSAYBUF, in, RSAN * sizeof(u32));
- }
- static void rsaMonMulWriteM(const u32 *const in)
- {
- memcpy((u32 *)&RSAMBUF, in, RSAN * sizeof(u32));
- }
- static void rsaMonMulReadA(u32 *const in)
- {
- memcpy(in, (u32 *)&RSAXBUF, RSAN * sizeof(u32));
- }
- static void rsaMonMulReadB(u32 *const in)
- {
- memcpy(in, (u32 *)&RSAYBUF, RSAN * sizeof(u32));
- }
- static void rsaMonMulReadD(u32 *const in)
- {
- memcpy(in, (u32 *)&RSADBUF, RSAN * sizeof(u32));
- }
- static int rsaMulModRead(unsigned char w, hstm_int *a)
- {
- u32 in[64];
- int err = 0;
- memset(in, 0, 64 * sizeof(u32));
- switch(w)
- {
- case 'A':
- rsaMonMulReadA(in);
- break;
- case 'B':
- rsaMonMulReadB(in);
- break;
- case 'D':
- rsaMonMulReadD(in);
- break;
- }
- pstm_reverse((unsigned char *)in, RSAN * sizeof(u32));
- /* this a should be initialized outside. */
- //if ((err = pstm_init_for_read_unsigned_bin(NULL, a, RSAN * sizeof(u32) + sizeof(hstm_int))) != ERR_CRY_OK){
- // return err;
- //}
- if ((err = pstm_read_unsigned_bin(a, (unsigned char *)in, RSAN * sizeof(u32))) != ERR_CRY_OK)
- {
- pstm_clear(a);
- return err;
- }
- return 0;
- }
- #if 0
- static void rsaMulModDump(unsigned char w)
- {
- extern void dumpUint32(char *name, uint32_t* buffer, int len);
- int addr = 0;
- switch(w)
- {
- case 'A':
- addr = 0;
- break;
- case 'B':
- addr = 0x100;
- break;
- case 'D':
- addr = 0x300;
- break;
- }
- printf("%c", w);
- dumpUint32(" Val:",((volatile u32*) (RSA_BASE_ADDRESS + addr )), RSAN);
- }
- #endif
- static void rsaMulModWrite(unsigned char w, hstm_int *a)
- {
- u32 in[64];
- memset(in, 0, 64 * sizeof(u32));
- pstm_to_unsigned_bin_nr(NULL, a, (unsigned char *)in);
- switch(w)
- {
- case 'A':
- rsaMonMulWriteA(in);
- break;
- case 'B':
- rsaMonMulWriteB(in);
- break;
- case 'M':
- rsaMonMulWriteM(in);
- break;
- }
- }
- static void rsaMonMulAA(void)
- {
- g_crypto_ctx.rsa_complete = 0;
- RSACON = 0x2c;
- while (!g_crypto_ctx.rsa_complete)
- {
- }
- g_crypto_ctx.rsa_complete = 0;
- }
- static void rsaMonMulDD(void)
- {
- g_crypto_ctx.rsa_complete = 0;
- RSACON = 0x20;
- while (!g_crypto_ctx.rsa_complete)
- {
- }
- g_crypto_ctx.rsa_complete = 0;
- }
- static void rsaMonMulAB(void)
- {
- g_crypto_ctx.rsa_complete = 0;
- RSACON = 0x24;
- while (!g_crypto_ctx.rsa_complete)
- {
- }
- g_crypto_ctx.rsa_complete = 0;
- }
- static void rsaMonMulBD(void)
- {
- g_crypto_ctx.rsa_complete = 0;
- RSACON = 0x28;
- while (!g_crypto_ctx.rsa_complete)
- {
- }
- g_crypto_ctx.rsa_complete = 0;
- }
- /******************************************************************************
- compute mc, s.t. mc * in = 0xffffffff
- ******************************************************************************/
- static void rsaCalMc(u32 *mc, const u32 in)
- {
- u32 y = 1;
- u32 i = 31;
- u32 left = 1;
- u32 right = 0;
- for(i = 31; i != 0; i--)
- {
- left <<= 1; /* 2^(i-1) */
- right = (in * y) & left; /* (n*y) mod 2^i */
- if( right )
- {
- y += left;
- }
- }
- *mc = ~y + 1;
- }
- /**
- * @brief This function implements the large module power multiplication algorithm.
- * res = a**e (mod n)
- *
- * @param[in] a Pointer to a bignumber.
- * @param[in] e Pointer to a bignumber.
- * @param[in] n Pointer to a bignumber.
- * @param[out] res Pointer to the result bignumber.
- *
- * @retval 0 success
- * @retval other failed
- *
- * @note None
- */
- int tls_crypto_exptmod(hstm_int *a, hstm_int *e, hstm_int *n, hstm_int *res)
- {
- int i = 0;
- u32 k = 0, mc = 0, dp0;
- volatile u8 monmulFlag = 0;
- hstm_int R, X, Y;
- tls_open_peripheral_clock(TLS_PERIPHERAL_TYPE_RSA);
- #ifndef CONFIG_KERNEL_NONE
- tls_fls_sem_lock();
- #endif
- pstm_init(NULL, &X);
- pstm_init(NULL, &Y);
- pstm_init(NULL, &R);
- k = pstm_count_bits(n);//n->used * DIGIT_BIT;//pstm_count_bits(n);
- k = ((k / 32) + (k % 32 > 0 ? 1 : 0)) * 32;
- #if 0
- pstm_set(&Y, k);
- pstm_set(&X, 2);
- pstm_exptmod(NULL, &X, &Y, n, &R); //R = 2^k % n
- #else
- pstm_2expt(&X, (int16)k); //X = 2^k
- pstm_mod(NULL, &X, n, &R); //R = 2^k % n
- #endif
- //pstm_set(&Y, 1);
- pstm_mulmod(NULL, a, &R, n, &X); //X = A * R
- pstm_copy(&R, &Y);
- if(n->used > 1)
- {
- #if (DIGIT_BIT < 32)
- dp0 = 0xFFFFFFFF & ((n->dp[0]) | (u32)(n->dp[1] << DIGIT_BIT));
- #else
- dp0 = (n->dp[0]);
- #endif
- }
- else
- dp0 = n->dp[0];
- rsaCalMc(&mc, dp0);
- k = pstm_count_bits(n);
- rsaMonMulSetLen(k / 32 + (k % 32 == 0 ? 0 : 1));
- rsaMonMulWriteMc(mc);
- rsaMulModWrite('M', n);
- rsaMulModWrite('B', &X);
- rsaMulModWrite('A', &Y);
- k = pstm_count_bits(e);
- for(i = k - 1; i >= 0; i--)
- {
- //montMulMod(&Y, &Y, n, &Y);
- //if(pstm_get_bit(e, i))
- // montMulMod(&Y, &X, n, &Y);
- if(monmulFlag == 0)
- {
- rsaMonMulAA();
- monmulFlag = 1;
- //rsaMulModDump('D');
- }
- else
- {
- rsaMonMulDD();
- monmulFlag = 0;
- //rsaMulModDump('A');
- }
- if(pstm_get_bit(e, i))
- {
- if(monmulFlag == 0)
- {
- rsaMonMulAB();
- monmulFlag = 1;
- //rsaMulModDump('D');
- }
- else
- {
- rsaMonMulBD();
- monmulFlag = 0;
- //rsaMulModDump('A');
- }
- }
- }
- pstm_set(&R, 1);
- rsaMulModWrite('B', &R);
- //montMulMod(&Y, &R, n, res);
- if(monmulFlag == 0)
- {
- rsaMonMulAB();
- rsaMulModRead('D', res);
- }
- else
- {
- rsaMonMulBD();
- rsaMulModRead('A', res);
- }
- pstm_clamp(res);
- pstm_clear(&X);
- pstm_clear(&Y);
- pstm_clear(&R);
- #ifndef CONFIG_KERNEL_NONE
- tls_fls_sem_unlock();
- #endif
- tls_close_peripheral_clock(TLS_PERIPHERAL_TYPE_RSA);
- return 0;
- }
- /**
- * @brief This function initializes the encryption module.
- *
- * @param None
- *
- * @return None
- *
- * @note None
- */
- int tls_crypto_init(void)
- {
- #ifndef CONFIG_KERNEL_NONE
- int err = 0;
- if(g_crypto_ctx.gpsec_lock != NULL)
- {
- return 0;
- }
- err = tls_os_sem_create(&g_crypto_ctx.gpsec_lock, 1);
- if (err != TLS_OS_SUCCESS)
- {
- TLS_DBGPRT_ERR("create semaphore @gpsec_lock fail!\n");
- return -1;
- }
- #endif
- tls_irq_enable(RSA_IRQn);
- tls_irq_enable(CRYPTION_IRQn);
- return 0;
- }
- /**
- * @brief This function is used to generate true random number seed.
- *
- * @param[in] None
- *
- * @retval random number
- *
- * @note None
- */
- unsigned int tls_random_seed_generation(void)
- {
- #if 0
- extern void delay_cnt(int count);
- unsigned int val;
- unsigned int seed;
- val = tls_reg_read32(HR_CRYPTO_TRNG_CR);
- tls_reg_write32(HR_CRYPTO_TRNG_CR, val|(1 << TRNG_SEL));
- delay_cnt(2000);
- seed = tls_reg_read32(HR_CRYPTO_RNG_RESULT);
- tls_reg_write32(HR_CRYPTO_TRNG_CR, val);
- return seed;
- #else
- return csi_coret_get_value();
- #endif
- }
|