wm_crypto_hard.c 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include "core_804.h"
  5. #include "wm_irq.h"
  6. #include "wm_regs.h"
  7. #include "wm_debug.h"
  8. #include "wm_crypto_hard.h"
  9. #include "wm_internal_flash.h"
  10. #include "wm_pmu.h"
  11. //#define TEST_ALL_CRYPTO
  12. #undef DIGIT_BIT
  13. #define DIGIT_BIT 28//32
  14. #define SOFT_RESET_RC4 25
  15. #define SOFT_RESET_AES 26
  16. #define SOFT_RESET_DES 27
  17. #define RNG_SWITCH 28
  18. #define RNG_LOAD_SEED 29
  19. #define RNG_START 30
  20. #define TRNG_EN 0
  21. #define TRNG_SEL 1
  22. #define TRNG_DIG_BYPASS 2
  23. #define TRNG_CP 3
  24. #define TRNG_INT_MASK 6
  25. #define USE_TRNG 1
  26. #define DES_KEY_LEN 8
  27. #define DES3_KEY_LEN 24
  28. #define DES3_IV_LEN 8
  29. #define SHA1_HASH_SIZE 20
  30. #define MD5_HASH_SIZE 16
  31. #define STORE32H(x, y) { \
  32. (y)[0] = (unsigned char)(((x)>>24)&255); \
  33. (y)[1] = (unsigned char)(((x)>>16)&255); \
  34. (y)[2] = (unsigned char)(((x)>>8)&255); \
  35. (y)[3] = (unsigned char)((x)&255); \
  36. }
  37. #define STORE32L(x, y) { \
  38. unsigned long __t = (x); memcpy(y, &__t, 4); \
  39. }
  40. //#define CRYPTO_LOG printf
  41. #define CRYPTO_LOG(...)
  42. //extern volatile uint32_t sys_count;
  43. #define sys_count tls_os_get_time()
  44. struct wm_crypto_ctx g_crypto_ctx = {0,0
  45. #ifndef CONFIG_KERNEL_NONE
  46. ,NULL
  47. #endif
  48. };
  49. #if 1
  50. typedef s32 psPool_t;
  51. #include "libtommath.h"
  52. #define pstm_set(a, b) mp_set((mp_int *)a, b)
  53. #define pstm_init(pool, a) wpa_mp_init((mp_int *)a)
  54. #define pstm_count_bits(a) mp_count_bits((mp_int *)a)
  55. #define pstm_init_for_read_unsigned_bin(pool, a, len) mp_init_for_read_unsigned_bin((mp_int *)a, len)
  56. #define pstm_read_unsigned_bin(a, b, c) mp_read_unsigned_bin((mp_int *)a, b, c)
  57. #define pstm_copy(a, b) mp_copy((mp_int *)a, (mp_int *)b)
  58. #define pstm_clear(a) mp_clear((mp_int *)a)
  59. #define pstm_clamp(a) mp_clamp((mp_int *)a)
  60. #define pstm_mulmod(pool, a, b, c, d) mp_mulmod((mp_int *)a, (mp_int *)b, (mp_int *)c, (mp_int *)d)
  61. #define pstm_exptmod(pool, G, X, P, Y) mp_exptmod((mp_int *)G, (mp_int *)X, (mp_int *)P, (mp_int *)Y)
  62. #define pstm_reverse mp_reverse
  63. #define pstm_cmp mp_cmp
  64. #define pstm_to_unsigned_bin_nr(pool, a, b) mp_to_unsigned_bin_nr((mp_int *)a, (unsigned char *)b)
  65. #define pstm_2expt(a, b) mp_2expt((mp_int *)a, b)
  66. #define pstm_mod(pool, a, b, c) mp_mod((mp_int *)a, (mp_int *)b, (mp_int *)c)
  67. #endif
  68. void RSA_F_IRQHandler(void)
  69. {
  70. RSACON = 0x00;
  71. g_crypto_ctx.rsa_complete = 1;
  72. }
  73. void CRYPTION_IRQHandler(void)
  74. {
  75. tls_reg_write32(HR_CRYPTO_SEC_STS, 0x10000);
  76. g_crypto_ctx.gpsec_complete = 1;
  77. }
  78. #if 1
  79. static int16 pstm_get_bit (hstm_int *a, int16 idx)
  80. {
  81. int16 r;
  82. int16 n = idx / DIGIT_BIT;
  83. int16 m = idx % DIGIT_BIT;
  84. if (a->used <= 0)
  85. {
  86. return 0;
  87. }
  88. r = (a->dp[n] >> m) & 0x01;
  89. return r;
  90. }
  91. #endif
  92. u32 Reflect(u32 ref, u8 ch)
  93. {
  94. int i;
  95. u32 value = 0;
  96. for( i = 1; i < ( ch + 1 ); i++ )
  97. {
  98. if( ref & 1 )
  99. value |= 1 << ( ch - i );
  100. ref >>= 1;
  101. }
  102. return value;
  103. }
  104. #ifndef CONFIG_KERNEL_NONE
  105. void tls_crypto_sem_lock(void)
  106. {
  107. if (g_crypto_ctx.gpsec_lock == NULL)
  108. {
  109. return;
  110. }
  111. tls_os_sem_acquire(g_crypto_ctx.gpsec_lock, 0);
  112. }
  113. void tls_crypto_sem_unlock(void)
  114. {
  115. if (g_crypto_ctx.gpsec_lock == NULL)
  116. {
  117. return;
  118. }
  119. tls_os_sem_release(g_crypto_ctx.gpsec_lock);
  120. }
  121. #else
  122. #define tls_crypto_sem_lock
  123. #define tls_crypto_sem_unlock
  124. #endif
  125. void tls_crypto_set_key(void *key, int keylen)
  126. {
  127. uint32_t *key32 = (uint32_t *)key;
  128. int i = 0;
  129. for(i = 0; i < keylen / 4 && i < 6; i++)
  130. {
  131. M32(HR_CRYPTO_KEY0 + (4 * i)) = key32[i];
  132. }
  133. if(keylen == 32)
  134. {
  135. M32(HR_CRYPTO_KEY6) = key32[6];
  136. M32(HR_CRYPTO_KEY7) = key32[7];
  137. }
  138. }
  139. void tls_crypto_set_iv(void *iv, int ivlen)
  140. {
  141. uint32_t *IV32 = (uint32_t *)iv;
  142. if(ivlen >= 8)
  143. {
  144. M32(HR_CRYPTO_IV0) = IV32[0];
  145. M32(HR_CRYPTO_IV0 + 4) = IV32[1];
  146. }
  147. if(ivlen == 16)
  148. {
  149. M32(HR_CRYPTO_IV1) = IV32[2];
  150. M32(HR_CRYPTO_IV1 + 4) = IV32[3];
  151. }
  152. }
  153. /**
  154. * @brief This function is used to stop random produce.
  155. *
  156. * @param[in] None
  157. *
  158. * @retval 0 success
  159. * @retval other failed
  160. *
  161. * @note None
  162. */
  163. int tls_crypto_random_stop(void)
  164. {
  165. unsigned int sec_cfg;
  166. #if USE_TRNG
  167. #else
  168. unsigned int val;
  169. #endif
  170. tls_open_peripheral_clock(TLS_PERIPHERAL_TYPE_GPSEC);
  171. #if USE_TRNG
  172. sec_cfg = 0x40;
  173. tls_reg_write32(HR_CRYPTO_TRNG_CR, sec_cfg);
  174. g_crypto_ctx.gpsec_complete = 0;
  175. #else
  176. val = tls_reg_read32(HR_CRYPTO_SEC_CFG);
  177. sec_cfg = val & ~(1 << RNG_START);
  178. tls_reg_write32(HR_CRYPTO_SEC_CFG, sec_cfg);
  179. #endif
  180. tls_close_peripheral_clock(TLS_PERIPHERAL_TYPE_GPSEC);
  181. tls_crypto_sem_unlock();
  182. return ERR_CRY_OK;
  183. }
  184. /**
  185. * @brief This function initializes random digit seed and BIT number.
  186. *
  187. * @param[in] seed The random digit seed.
  188. * @param[in] rng_switch The random digit bit number. (0: 16bit 1:32bit)
  189. *
  190. * @retval 0 success
  191. * @retval other failed
  192. *
  193. * @note None
  194. */
  195. int tls_crypto_random_init(u32 seed, CRYPTO_RNG_SWITCH rng_switch)
  196. {
  197. unsigned int sec_cfg;
  198. tls_crypto_sem_lock();
  199. tls_open_peripheral_clock(TLS_PERIPHERAL_TYPE_GPSEC);
  200. #if USE_TRNG
  201. sec_cfg = (1 << TRNG_INT_MASK) | (4 << TRNG_CP) | (1 << TRNG_SEL) | (1 << TRNG_EN);
  202. sec_cfg &= ~(1 << TRNG_INT_MASK);
  203. g_crypto_ctx.gpsec_complete = 0;
  204. tls_reg_write32(HR_CRYPTO_TRNG_CR, sec_cfg);
  205. #else
  206. tls_reg_write32(HR_CRYPTO_KEY0, seed);
  207. sec_cfg = (rng_switch << RNG_SWITCH) | (1 << RNG_LOAD_SEED) | (1 << RNG_START);
  208. tls_reg_write32(HR_CRYPTO_SEC_CFG, sec_cfg);
  209. #endif
  210. return ERR_CRY_OK;
  211. }
  212. /**
  213. * @brief This function is used to get random digit content.
  214. *
  215. * @param[in] out Pointer to the output of random digit.
  216. * @param[in] len The random digit bit number will output.
  217. *
  218. * @retval 0 success
  219. * @retval other failed
  220. *
  221. * @note None
  222. */
  223. int tls_crypto_random_bytes(unsigned char *out, u32 len)
  224. {
  225. unsigned int val;
  226. uint32 inLen = len;
  227. int randomBytes = 2;
  228. #if USE_TRNG
  229. randomBytes = 4;
  230. #else
  231. val = tls_reg_read32(HR_CRYPTO_SEC_CFG);
  232. randomBytes = val & (1 << RNG_SWITCH) ? 4 : 2;
  233. #endif
  234. while(inLen > 0)
  235. {
  236. #if USE_TRNG
  237. while (!g_crypto_ctx.gpsec_complete)
  238. {
  239. }
  240. g_crypto_ctx.gpsec_complete = 0;
  241. #endif
  242. val = tls_reg_read32(HR_CRYPTO_RNG_RESULT);
  243. if(inLen >= randomBytes)
  244. {
  245. memcpy(out, (char *)&val, randomBytes);
  246. out += randomBytes;
  247. inLen -= randomBytes;
  248. }
  249. else
  250. {
  251. memcpy(out, (char *)&val, inLen);
  252. inLen = 0;
  253. }
  254. }
  255. tls_close_peripheral_clock(TLS_PERIPHERAL_TYPE_GPSEC);
  256. return ERR_CRY_OK;
  257. }
  258. /**
  259. * @brief This function is used to generate true random number.
  260. *
  261. * @param[in] out Pointer to the output of random number.
  262. * @param[in] len The random number length.
  263. *
  264. * @retval 0 success
  265. * @retval other failed
  266. *
  267. * @note None
  268. */
  269. int tls_crypto_trng(unsigned char *out, u32 len)
  270. {
  271. unsigned int sec_cfg, val;
  272. uint32 inLen = len;
  273. int randomBytes = 4;
  274. tls_crypto_sem_lock();
  275. tls_open_peripheral_clock(TLS_PERIPHERAL_TYPE_GPSEC);
  276. sec_cfg = (1 << TRNG_INT_MASK) | (4 << TRNG_CP) | (1 << TRNG_SEL) | (1 << TRNG_EN);
  277. sec_cfg &= ~(1 << TRNG_INT_MASK);
  278. tls_reg_write32(HR_CRYPTO_TRNG_CR, sec_cfg);
  279. delay_cnt(1000);
  280. while(inLen > 0)
  281. {
  282. g_crypto_ctx.gpsec_complete = 0;
  283. while (!g_crypto_ctx.gpsec_complete)
  284. {
  285. }
  286. g_crypto_ctx.gpsec_complete = 0;
  287. val = tls_reg_read32(HR_CRYPTO_RNG_RESULT);
  288. if(inLen >= randomBytes)
  289. {
  290. memcpy(out, (char *)&val, randomBytes);
  291. out += randomBytes;
  292. inLen -= randomBytes;
  293. }
  294. else
  295. {
  296. memcpy(out, (char *)&val, inLen);
  297. inLen = 0;
  298. }
  299. }
  300. tls_reg_write32(HR_CRYPTO_TRNG_CR, 0x40);
  301. tls_close_peripheral_clock(TLS_PERIPHERAL_TYPE_GPSEC);
  302. tls_crypto_sem_unlock();
  303. return ERR_CRY_OK;
  304. }
  305. int tls_crypto_random_bytes_range(unsigned char *out, u32 len, u32 range)
  306. {
  307. unsigned int val, i;
  308. val = tls_reg_read32(HR_CRYPTO_SEC_CFG);
  309. for(i = 0; i< len; i++) {
  310. val = tls_reg_read32(HR_CRYPTO_RNG_RESULT);
  311. out[i] = val % range;
  312. // printf("rand val:%d, val:%d\r\n", val, out[i]);
  313. }
  314. return ERR_CRY_OK;
  315. }
  316. /**
  317. * @brief This function initializes a RC4 encryption algorithm,
  318. * i.e. fills the psCipherContext_t structure pointed to by ctx with necessary data.
  319. *
  320. * @param[in] ctx Pointer to the Cipher Context.
  321. * @param[in] key Pointer to the key.
  322. * @param[in] keylen the length of key.
  323. *
  324. * @retval 0 success
  325. * @retval other failed
  326. *
  327. * @note The first parameter ctx must be a structure which is allocated externally.
  328. * And all of Context parameters in the initializing methods should be allocated externally too.
  329. */
  330. int tls_crypto_rc4_init(psCipherContext_t *ctx, const unsigned char *key, u32 keylen)
  331. {
  332. if(keylen != 16 && keylen != 32)
  333. {
  334. return ERR_FAILURE;
  335. }
  336. memcpy(ctx->arc4.state, key, keylen);
  337. ctx->arc4.byteCount = keylen;
  338. return ERR_CRY_OK;
  339. }
  340. /**
  341. * @brief This function encrypts a variable length data stream according to RC4.
  342. * The RC4 algorithm it generates a "keystream" which is simply XORed with the plaintext to produce the ciphertext stream.
  343. * Decryption is exactly the same as encryption. This function also decrypts a variable length data stream according to RC4.
  344. *
  345. * @param[in] ctx Pointer to the Cipher Context.
  346. * @param[in] in Pointer to the input plaintext data stream(or the encrypted text data stream) of variable length.
  347. * @param[in] out Pointer to the resulting ciphertext data stream.
  348. * @param[in] len Length of the plaintext data stream in octets.
  349. *
  350. * @retval 0 success
  351. * @retval other failed
  352. *
  353. * @note None
  354. */
  355. int tls_crypto_rc4(psCipherContext_t *ctx, unsigned char *in, unsigned char *out, u32 len)
  356. {
  357. unsigned int sec_cfg;
  358. unsigned char *key = ctx->arc4.state;
  359. u32 keylen = ctx->arc4.byteCount;
  360. tls_crypto_sem_lock();
  361. tls_open_peripheral_clock(TLS_PERIPHERAL_TYPE_GPSEC);
  362. tls_crypto_set_key(key, keylen);
  363. tls_reg_write32(HR_CRYPTO_SRC_ADDR, (unsigned int)in);
  364. tls_reg_write32(HR_CRYPTO_DEST_ADDR, (unsigned int)out);
  365. sec_cfg = (CRYPTO_METHOD_RC4 << 16) | (1 << SOFT_RESET_RC4) | (len & 0xFFFF);
  366. if(keylen == 32)
  367. {
  368. sec_cfg |= (1 << 31);
  369. }
  370. tls_reg_write32(HR_CRYPTO_SEC_CFG, sec_cfg);
  371. CRYPTO_LOG("[%d]:rc4[%d] start\n", sys_count, len);
  372. g_crypto_ctx.gpsec_complete = 0;
  373. tls_reg_write32(HR_CRYPTO_SEC_CTRL, 0x1);//start crypto
  374. while (!g_crypto_ctx.gpsec_complete)
  375. {
  376. }
  377. g_crypto_ctx.gpsec_complete = 0;
  378. CRYPTO_LOG("[%d]:rc4 end status: %x\n", sys_count, tls_reg_read32(HR_CRYPTO_SEC_STS));
  379. tls_close_peripheral_clock(TLS_PERIPHERAL_TYPE_GPSEC);
  380. tls_crypto_sem_unlock();
  381. return ERR_CRY_OK;
  382. }
  383. /**
  384. * @brief This function initializes a AES encryption algorithm, i.e. fills the psCipherContext_t structure pointed to by ctx with necessary data.
  385. *
  386. * @param[in] ctx Pointer to the Cipher Context.
  387. * @param[in] IV Pointer to the Initialization Vector
  388. * @param[in] key Pointer to the key.
  389. * @param[in] keylen the length of key.
  390. * @param[in] cbc the encryption mode, AES supports ECB/CBC/CTR modes.
  391. *
  392. * @retval 0 success
  393. * @retval other failed
  394. *
  395. * @note None
  396. */
  397. int tls_crypto_aes_init(psCipherContext_t *ctx, const unsigned char *IV, const unsigned char *key, u32 keylen, CRYPTO_MODE cbc)
  398. {
  399. int x = 0;
  400. if (keylen != 16)
  401. return ERR_FAILURE;
  402. memcpy(ctx->aes.key.skey, key, keylen);
  403. ctx->aes.key.type = cbc;
  404. ctx->aes.key.rounds = 16;
  405. if(IV)
  406. {
  407. for (x = 0; x < ctx->aes.key.rounds; x++)
  408. {
  409. ctx->aes.IV[x] = IV[x];
  410. }
  411. }
  412. return ERR_CRY_OK;
  413. }
  414. /**
  415. * @brief This function encrypts or decrypts a variable length data stream according to AES.
  416. *
  417. * @param[in] ctx Pointer to the Cipher Context.
  418. * @param[in] in Pointer to the input plaintext data stream(or the encrypted text data stream) of variable length.
  419. * @param[in] out Pointer to the resulting ciphertext data stream.
  420. * @param[in] len Length of the plaintext data stream in octets.
  421. * @param[in] dec The cryption way which indicates encryption or decryption.
  422. *
  423. * @retval 0 success
  424. * @retval other failed
  425. *
  426. * @note None
  427. */
  428. int tls_crypto_aes_encrypt_decrypt(psCipherContext_t *ctx, unsigned char *in, unsigned char *out, u32 len, CRYPTO_WAY dec)
  429. {
  430. unsigned int sec_cfg;
  431. u32 keylen = 16;
  432. unsigned char *key = (unsigned char *)ctx->aes.key.skey;
  433. unsigned char *IV = ctx->aes.IV;
  434. CRYPTO_MODE cbc = (CRYPTO_MODE)(ctx->aes.key.type & 0xFF);
  435. tls_crypto_sem_lock();
  436. tls_open_peripheral_clock(TLS_PERIPHERAL_TYPE_GPSEC);
  437. tls_crypto_set_key(key, keylen);
  438. tls_crypto_set_iv(IV, 16);
  439. tls_reg_write32(HR_CRYPTO_SRC_ADDR, (unsigned int)in);
  440. tls_reg_write32(HR_CRYPTO_DEST_ADDR, (unsigned int)out);
  441. sec_cfg = (CRYPTO_METHOD_AES << 16) | (1 << SOFT_RESET_AES) | (dec << 20) | (cbc << 21) | (len & 0xFFFF);
  442. tls_reg_write32(HR_CRYPTO_SEC_CFG, sec_cfg);
  443. CRYPTO_LOG("[%d]:aes[%d] %s %s start\n", sys_count, len, dec == CRYPTO_WAY_ENCRYPT ? "ENCRYPT" : "DECRYPT",
  444. cbc == CRYPTO_MODE_ECB ? "ECB" : (cbc == CRYPTO_MODE_CBC ? "CBC" : (cbc == CRYPTO_MODE_CTR ? "CTR" : "MAC")));
  445. g_crypto_ctx.gpsec_complete = 0;
  446. tls_reg_write32(HR_CRYPTO_SEC_CTRL, 0x1);//start crypto
  447. while (!g_crypto_ctx.gpsec_complete)
  448. {
  449. }
  450. g_crypto_ctx.gpsec_complete = 0;
  451. CRYPTO_LOG("[%d]:aes end %d\n", sys_count, tls_reg_read32(HR_CRYPTO_SEC_STS) & 0xFFFF);
  452. tls_close_peripheral_clock(TLS_PERIPHERAL_TYPE_GPSEC);
  453. tls_crypto_sem_unlock();
  454. return ERR_CRY_OK;
  455. }
  456. /**
  457. * @brief This function initializes a 3DES encryption algorithm, i.e. fills the psCipherContext_t structure pointed to by ctx with necessary data.
  458. *
  459. * @param[in] ctx Pointer to the Cipher Context.
  460. * @param[in] IV Pointer to the Initialization Vector
  461. * @param[in] key Pointer to the key.
  462. * @param[in] keylen the length of key.
  463. * @param[in] cbc the encryption mode, 3DES supports ECB/CBC modes.
  464. *
  465. * @retval 0 success
  466. * @retval other failed
  467. *
  468. * @note None
  469. */
  470. int tls_crypto_3des_init(psCipherContext_t *ctx, const unsigned char *IV, const unsigned char *key, u32 keylen, CRYPTO_MODE cbc)
  471. {
  472. unsigned int x;
  473. if (keylen != DES3_KEY_LEN)
  474. return ERR_FAILURE;
  475. memcpy(ctx->des3.key.ek[0], key, keylen);
  476. ctx->des3.key.ek[1][0] = cbc;
  477. ctx->des3.blocklen = DES3_IV_LEN;
  478. if(IV)
  479. {
  480. for (x = 0; x < ctx->des3.blocklen; x++)
  481. {
  482. ctx->des3.IV[x] = IV[x];
  483. }
  484. }
  485. return ERR_CRY_OK;
  486. }
  487. /**
  488. * @brief This function encrypts or decrypts a variable length data stream according to 3DES.
  489. *
  490. * @param[in] ctx Pointer to the Cipher Context.
  491. * @param[in] in Pointer to the input plaintext data stream(or the encrypted text data stream) of variable length.
  492. * @param[in] out Pointer to the resulting ciphertext data stream.
  493. * @param[in] len Length of the plaintext data stream in octets.
  494. * @param[in] dec The cryption way which indicates encryption or decryption.
  495. *
  496. * @retval 0 success
  497. * @retval other failed
  498. *
  499. * @note None
  500. */
  501. int tls_crypto_3des_encrypt_decrypt(psCipherContext_t *ctx, unsigned char *in, unsigned char *out, u32 len, CRYPTO_WAY dec)
  502. {
  503. unsigned int sec_cfg;
  504. u32 keylen = DES3_KEY_LEN;
  505. unsigned char *key = (unsigned char *)(unsigned char *)ctx->des3.key.ek[0];
  506. unsigned char *IV = ctx->des3.IV;
  507. CRYPTO_MODE cbc = (CRYPTO_MODE)(ctx->des3.key.ek[1][0] & 0xFF);
  508. tls_crypto_sem_lock();
  509. tls_open_peripheral_clock(TLS_PERIPHERAL_TYPE_GPSEC);
  510. tls_crypto_set_key(key, keylen);
  511. tls_crypto_set_iv(IV, DES3_IV_LEN);
  512. tls_reg_write32(HR_CRYPTO_SRC_ADDR, (unsigned int)in);
  513. tls_reg_write32(HR_CRYPTO_DEST_ADDR, (unsigned int)out);
  514. sec_cfg = (CRYPTO_METHOD_3DES << 16) | (1 << SOFT_RESET_DES) | (dec << 20) | (cbc << 21) | (len & 0xFFFF);
  515. tls_reg_write32(HR_CRYPTO_SEC_CFG, sec_cfg);
  516. CRYPTO_LOG("[%d]:3des[%d] %s %s start\n", sys_count, len, dec == CRYPTO_WAY_ENCRYPT ? "ENCRYPT" : "DECRYPT",
  517. cbc == CRYPTO_MODE_ECB ? "ECB" : "CBC");
  518. g_crypto_ctx.gpsec_complete = 0;
  519. tls_reg_write32(HR_CRYPTO_SEC_CTRL, 0x1);//start crypto
  520. while (!g_crypto_ctx.gpsec_complete)
  521. {
  522. }
  523. g_crypto_ctx.gpsec_complete = 0;
  524. CRYPTO_LOG("[%d]:3des end %d\n", sys_count, tls_reg_read32(HR_CRYPTO_SEC_STS) & 0xFFFF);
  525. tls_close_peripheral_clock(TLS_PERIPHERAL_TYPE_GPSEC);
  526. tls_crypto_sem_unlock();
  527. return ERR_CRY_OK;
  528. }
  529. /**
  530. * @brief This function initializes a DES encryption algorithm, i.e. fills the psCipherContext_t structure pointed to by ctx with necessary data.
  531. *
  532. * @param[in] ctx Pointer to the Cipher Context.
  533. * @param[in] IV Pointer to the Initialization Vector
  534. * @param[in] key Pointer to the key.
  535. * @param[in] keylen the length of key.
  536. * @param[in] cbc the encryption mode, DES supports ECB/CBC modes.
  537. *
  538. * @retval 0 success
  539. * @retval other failed
  540. *
  541. * @note None
  542. */
  543. int tls_crypto_des_init(psCipherContext_t *ctx, const unsigned char *IV, const unsigned char *key, u32 keylen, CRYPTO_MODE cbc)
  544. {
  545. unsigned int x;
  546. if (keylen != DES_KEY_LEN)
  547. return ERR_FAILURE;
  548. memcpy(ctx->des3.key.ek[0], key, keylen);
  549. ctx->des3.key.ek[1][0] = cbc;
  550. ctx->des3.blocklen = DES3_IV_LEN;
  551. if(IV)
  552. {
  553. for (x = 0; x < ctx->des3.blocklen; x++)
  554. {
  555. ctx->des3.IV[x] = IV[x];
  556. }
  557. }
  558. return ERR_CRY_OK;
  559. }
  560. /**
  561. * @brief This function encrypts or decrypts a variable length data stream according to DES.
  562. *
  563. * @param[in] ctx Pointer to the Cipher Context.
  564. * @param[in] in Pointer to the input plaintext data stream(or the encrypted text data stream) of variable length.
  565. * @param[in] out Pointer to the resulting ciphertext data stream.
  566. * @param[in] len Length of the plaintext data stream in octets.
  567. * @param[in] dec The cryption way which indicates encryption or decryption.
  568. *
  569. * @retval 0 success
  570. * @retval other failed
  571. *
  572. * @note None
  573. */
  574. int tls_crypto_des_encrypt_decrypt(psCipherContext_t *ctx, unsigned char *in, unsigned char *out, u32 len, CRYPTO_WAY dec)
  575. {
  576. unsigned int sec_cfg;
  577. u32 keylen = DES_KEY_LEN;
  578. unsigned char *key = (unsigned char *)ctx->des3.key.ek[0];
  579. unsigned char *IV = ctx->des3.IV;
  580. CRYPTO_MODE cbc = (CRYPTO_MODE)(ctx->des3.key.ek[1][0] & 0xFF);
  581. //uint32_t *IV32 = (uint32_t *)IV;
  582. tls_crypto_sem_lock();
  583. tls_open_peripheral_clock(TLS_PERIPHERAL_TYPE_GPSEC);
  584. tls_crypto_set_key(key, keylen);
  585. tls_crypto_set_iv(IV, DES3_IV_LEN);
  586. tls_reg_write32(HR_CRYPTO_SRC_ADDR, (unsigned int)in);
  587. tls_reg_write32(HR_CRYPTO_DEST_ADDR, (unsigned int)out);
  588. sec_cfg = (CRYPTO_METHOD_DES << 16) | (1 << SOFT_RESET_DES) | (dec << 20) | (cbc << 21) | (len & 0xFFFF);
  589. tls_reg_write32(HR_CRYPTO_SEC_CFG, sec_cfg);
  590. CRYPTO_LOG("[%d]:des[%d] %s %s start\n", sys_count, len, dec == CRYPTO_WAY_ENCRYPT ? "ENCRYPT" : "DECRYPT",
  591. cbc == CRYPTO_MODE_ECB ? "ECB" : "CBC");
  592. g_crypto_ctx.gpsec_complete = 0;
  593. tls_reg_write32(HR_CRYPTO_SEC_CTRL, 0x1);//start crypto
  594. while (!g_crypto_ctx.gpsec_complete)
  595. {
  596. }
  597. g_crypto_ctx.gpsec_complete = 0;
  598. CRYPTO_LOG("[%d]:des end %d\n", sys_count, tls_reg_read32(HR_CRYPTO_SEC_STS) & 0xFFFF);
  599. tls_close_peripheral_clock(TLS_PERIPHERAL_TYPE_GPSEC);
  600. tls_crypto_sem_unlock();
  601. return ERR_CRY_OK;
  602. }
  603. /**
  604. * @brief This function initializes a CRC algorithm, i.e. fills the psCrcContext_t structure pointed to by ctx with necessary data.
  605. *
  606. * @param[in] ctx Pointer to the CRC Context.
  607. * @param[in] key The initialization key.
  608. * @param[in] crc_type The CRC type, supports CRC8/CRC16 MODBUS/CRC16 CCITT/CRC32
  609. * @param[in] mode Set input or outpu reflect.
  610. * @param[in] dec The cryption way which indicates encryption or decryption.
  611. * see OUTPUT_REFLECT
  612. * see INPUT_REFLECT
  613. *
  614. * @retval 0 success
  615. * @retval other failed
  616. *
  617. * @note None
  618. */
  619. int tls_crypto_crc_init(psCrcContext_t *ctx, u32 key, CRYPTO_CRC_TYPE crc_type, u8 mode)
  620. {
  621. ctx->state = key;
  622. ctx->type = crc_type;
  623. ctx->mode = mode;
  624. return ERR_CRY_OK;
  625. }
  626. /**
  627. * @brief This function updates the CRC value with a variable length bytes.
  628. * This function may be called as many times as necessary, so the message may be processed in blocks.
  629. *
  630. * @param[in] ctx Pointer to the CRC Context.
  631. * @param[in] in Pointer to a variable length bytes
  632. * @param[in] len The bytes 's length
  633. *
  634. * @retval 0 success
  635. * @retval other failed
  636. *
  637. * @note None
  638. */
  639. int tls_crypto_crc_update(psCrcContext_t *ctx, unsigned char *in, u32 len)
  640. {
  641. unsigned int sec_cfg;
  642. tls_crypto_sem_lock();
  643. tls_open_peripheral_clock(TLS_PERIPHERAL_TYPE_GPSEC);
  644. sec_cfg = (CRYPTO_METHOD_CRC << 16) | (ctx->type << 21) | (ctx->mode << 23) | (len & 0xFFFF);
  645. tls_reg_write32(HR_CRYPTO_SEC_CFG, sec_cfg);
  646. if(ctx->mode & OUTPUT_REFLECT)
  647. {
  648. u8 ch_crc = 16;
  649. u32 state = 0;
  650. switch(ctx->type)
  651. {
  652. case CRYPTO_CRC_TYPE_8:
  653. ch_crc = 8;
  654. break;
  655. case CRYPTO_CRC_TYPE_16_MODBUS:
  656. ch_crc = 16;
  657. break;
  658. case CRYPTO_CRC_TYPE_16_CCITT:
  659. ch_crc = 16;
  660. break;
  661. case CRYPTO_CRC_TYPE_32:
  662. ch_crc = 32;
  663. break;
  664. default:
  665. break;
  666. }
  667. state = Reflect(ctx->state, ch_crc);
  668. tls_reg_write32(HR_CRYPTO_CRC_KEY, state);
  669. }
  670. else
  671. tls_reg_write32(HR_CRYPTO_CRC_KEY, ctx->state);
  672. tls_reg_write32(HR_CRYPTO_SRC_ADDR, (unsigned int)in);
  673. g_crypto_ctx.gpsec_complete = 0;
  674. tls_reg_write32(HR_CRYPTO_SEC_CTRL, 0x1);//start crypto
  675. while (!g_crypto_ctx.gpsec_complete)
  676. {
  677. }
  678. g_crypto_ctx.gpsec_complete = 0;
  679. ctx->state = tls_reg_read32(HR_CRYPTO_CRC_RESULT);
  680. tls_reg_write32(HR_CRYPTO_SEC_CTRL, 0x4);//clear crc fifo
  681. tls_close_peripheral_clock(TLS_PERIPHERAL_TYPE_GPSEC);
  682. tls_crypto_sem_unlock();
  683. return ERR_CRY_OK;
  684. }
  685. /**
  686. * @brief This function ends a CRC operation and produces a CRC value.
  687. *
  688. * @param[in] ctx Pointer to the CRC Context.
  689. * @param[in] crc_val Pointer to the CRC value.
  690. *
  691. * @retval 0 success
  692. * @retval other failed
  693. *
  694. * @note None
  695. */
  696. int tls_crypto_crc_final(psCrcContext_t *ctx, u32 *crc_val)
  697. {
  698. *crc_val = ctx->state;
  699. return ERR_CRY_OK;
  700. }
  701. static void hd_sha1_compress(psDigestContext_t *md)
  702. {
  703. unsigned int sec_cfg, val;
  704. int i = 0;
  705. tls_crypto_sem_lock();
  706. tls_open_peripheral_clock(TLS_PERIPHERAL_TYPE_GPSEC);
  707. tls_reg_write32(HR_CRYPTO_SRC_ADDR, (unsigned int)md->u.sha1.buf);
  708. sec_cfg = (CRYPTO_METHOD_SHA1 << 16) | (64 & 0xFFFF); // TODO
  709. tls_reg_write32(HR_CRYPTO_SEC_CFG, sec_cfg);
  710. tls_reg_write32(HR_CRYPTO_SHA1_DIGEST0, md->u.sha1.state[0]);
  711. tls_reg_write32(HR_CRYPTO_SHA1_DIGEST1, md->u.sha1.state[1]);
  712. tls_reg_write32(HR_CRYPTO_SHA1_DIGEST2, md->u.sha1.state[2]);
  713. tls_reg_write32(HR_CRYPTO_SHA1_DIGEST3, md->u.sha1.state[3]);
  714. tls_reg_write32(HR_CRYPTO_SHA1_DIGEST4, md->u.sha1.state[4]);
  715. g_crypto_ctx.gpsec_complete = 0;
  716. tls_reg_write32(HR_CRYPTO_SEC_CTRL, 0x1);//start crypto
  717. while (!g_crypto_ctx.gpsec_complete)
  718. {
  719. }
  720. g_crypto_ctx.gpsec_complete = 0;
  721. for (i = 0; i < 5; i++)
  722. {
  723. val = tls_reg_read32(HR_CRYPTO_SHA1_DIGEST0 + (4 * i));
  724. md->u.sha1.state[i] = val;
  725. }
  726. tls_close_peripheral_clock(TLS_PERIPHERAL_TYPE_GPSEC);
  727. tls_crypto_sem_unlock();
  728. }
  729. /**
  730. * @brief This function initializes Message-Diggest context for usage in SHA1 algorithm, starts a new SHA1 operation and writes a new Digest Context.
  731. *
  732. * @param[in] md Pointer to the SHA1 Digest Context.
  733. *
  734. * @retval 0 success
  735. * @retval other failed
  736. *
  737. * @note None
  738. */
  739. void tls_crypto_sha1_init(psDigestContext_t *md)
  740. {
  741. md->u.sha1.state[0] = 0x67452301UL;
  742. md->u.sha1.state[1] = 0xefcdab89UL;
  743. md->u.sha1.state[2] = 0x98badcfeUL;
  744. md->u.sha1.state[3] = 0x10325476UL;
  745. md->u.sha1.state[4] = 0xc3d2e1f0UL;
  746. md->u.sha1.curlen = 0;
  747. #ifdef HAVE_NATIVE_INT64
  748. md->u.sha1.length = 0;
  749. #else
  750. md->u.sha1.lengthHi = 0;
  751. md->u.sha1.lengthLo = 0;
  752. #endif /* HAVE_NATIVE_INT64 */
  753. }
  754. /**
  755. * @brief Process a message block using SHA1 algorithm.
  756. * This function performs a SHA1 block update operation. It continues an SHA1 message-digest operation,
  757. * by processing InputLen-byte length message block pointed to by buf, and by updating the SHA1 context pointed to by md.
  758. * This function may be called as many times as necessary, so the message may be processed in blocks.
  759. *
  760. * @param[in] md Pointer to the SHA1 Digest Context.
  761. * @param[in] buf InputLen-byte length message block
  762. * @param[in] len The buf 's length
  763. *
  764. * @returnl None
  765. *
  766. * @note None
  767. */
  768. void tls_crypto_sha1_update(psDigestContext_t *md, const unsigned char *buf, u32 len)
  769. {
  770. u32 n;
  771. while (len > 0)
  772. {
  773. n = min(len, (64 - md->u.sha1.curlen));
  774. memcpy(md->u.sha1.buf + md->u.sha1.curlen, buf, (size_t)n);
  775. md->u.sha1.curlen += n;
  776. buf += n;
  777. len -= n;
  778. /* is 64 bytes full? */
  779. if (md->u.sha1.curlen == 64)
  780. {
  781. hd_sha1_compress(md);
  782. #ifdef HAVE_NATIVE_INT64
  783. md->u.sha1.length += 512;
  784. #else
  785. n = (md->u.sha1.lengthLo + 512) & 0xFFFFFFFFL;
  786. if (n < md->u.sha1.lengthLo)
  787. {
  788. md->u.sha1.lengthHi++;
  789. }
  790. md->u.sha1.lengthLo = n;
  791. #endif /* HAVE_NATIVE_INT64 */
  792. md->u.sha1.curlen = 0;
  793. }
  794. }
  795. }
  796. /**
  797. * @brief This function ends a SHA1 operation and produces a Message-Digest.
  798. * This function finalizes SHA1 algorithm, i.e. ends an SHA1 Message-Digest operation,
  799. * writing the Message-Digest in the 20-byte buffer pointed to by hash in according to the information stored in context.
  800. *
  801. * @param[in] md Pointer to the SHA1 Digest Context.
  802. * @param[in] hash Pointer to the Message-Digest
  803. *
  804. * @retval 20 success, return the hash size.
  805. * @retval <0 failed
  806. *
  807. * @note None
  808. */
  809. int tls_crypto_sha1_final(psDigestContext_t *md, unsigned char *hash)
  810. {
  811. s32 i;
  812. u32 val;
  813. #ifndef HAVE_NATIVE_INT64
  814. u32 n;
  815. #endif
  816. if (md->u.sha1.curlen >= sizeof(md->u.sha1.buf) || hash == NULL)
  817. {
  818. return ERR_ARG_FAIL;
  819. }
  820. /*
  821. increase the length of the message
  822. */
  823. #ifdef HAVE_NATIVE_INT64
  824. md->u.sha1.length += md->u.sha1.curlen << 3;
  825. #else
  826. n = (md->u.sha1.lengthLo + (md->u.sha1.curlen << 3)) & 0xFFFFFFFFL;
  827. if (n < md->u.sha1.lengthLo)
  828. {
  829. md->u.sha1.lengthHi++;
  830. }
  831. md->u.sha1.lengthHi += (md->u.sha1.curlen >> 29);
  832. md->u.sha1.lengthLo = n;
  833. #endif /* HAVE_NATIVE_INT64 */
  834. /*
  835. append the '1' bit
  836. */
  837. md->u.sha1.buf[md->u.sha1.curlen++] = (unsigned char)0x80;
  838. /*
  839. if the length is currently above 56 bytes we append zeros then compress.
  840. Then we can fall back to padding zeros and length encoding like normal.
  841. */
  842. if (md->u.sha1.curlen > 56)
  843. {
  844. while (md->u.sha1.curlen < 64)
  845. {
  846. md->u.sha1.buf[md->u.sha1.curlen++] = (unsigned char)0;
  847. }
  848. hd_sha1_compress(md);
  849. md->u.sha1.curlen = 0;
  850. }
  851. /*
  852. pad upto 56 bytes of zeroes
  853. */
  854. while (md->u.sha1.curlen < 56)
  855. {
  856. md->u.sha1.buf[md->u.sha1.curlen++] = (unsigned char)0;
  857. }
  858. /*
  859. store length
  860. */
  861. #ifdef HAVE_NATIVE_INT64
  862. STORE64H(md->u.sha1.length, md->u.sha1.buf + 56);
  863. #else
  864. STORE32H(md->u.sha1.lengthHi, md->u.sha1.buf + 56);
  865. STORE32H(md->u.sha1.lengthLo, md->u.sha1.buf + 60);
  866. #endif /* HAVE_NATIVE_INT64 */
  867. hd_sha1_compress(md);
  868. /*
  869. copy output
  870. */
  871. for (i = 0; i < 5; i++)
  872. {
  873. val = tls_reg_read32(HR_CRYPTO_SHA1_DIGEST0 + (4 * i));
  874. STORE32H(val, hash + (4 * i));
  875. }
  876. memset(md, 0x0, sizeof(psSha1_t));
  877. return SHA1_HASH_SIZE;
  878. }
  879. static void hd_md5_compress(psDigestContext_t *md)
  880. {
  881. unsigned int sec_cfg, val, i;
  882. tls_crypto_sem_lock();
  883. tls_open_peripheral_clock(TLS_PERIPHERAL_TYPE_GPSEC);
  884. tls_reg_write32(HR_CRYPTO_SRC_ADDR, (unsigned int)md->u.md5.buf);
  885. sec_cfg = (CRYPTO_METHOD_MD5 << 16) | (64 & 0xFFFF);
  886. tls_reg_write32(HR_CRYPTO_SEC_CFG, sec_cfg);
  887. tls_reg_write32(HR_CRYPTO_SHA1_DIGEST0, md->u.md5.state[0]);
  888. tls_reg_write32(HR_CRYPTO_SHA1_DIGEST1, md->u.md5.state[1]);
  889. tls_reg_write32(HR_CRYPTO_SHA1_DIGEST2, md->u.md5.state[2]);
  890. tls_reg_write32(HR_CRYPTO_SHA1_DIGEST3, md->u.md5.state[3]);
  891. g_crypto_ctx.gpsec_complete = 0;
  892. tls_reg_write32(HR_CRYPTO_SEC_CTRL, 0x1);//start crypto
  893. while (!g_crypto_ctx.gpsec_complete)
  894. {
  895. }
  896. g_crypto_ctx.gpsec_complete = 0;
  897. for (i = 0; i < 4; i++)
  898. {
  899. val = tls_reg_read32(HR_CRYPTO_SHA1_DIGEST0 + (4 * i));
  900. md->u.md5.state[i] = val;
  901. }
  902. tls_close_peripheral_clock(TLS_PERIPHERAL_TYPE_GPSEC);
  903. tls_crypto_sem_unlock();
  904. }
  905. /**
  906. * @brief This function initializes Message-Diggest context for usage in MD5 algorithm, starts a new MD5 operation and writes a new Digest Context.
  907. * This function begins a MD5 Message-Diggest Algorithm, i.e. fills the psDigestContext_t structure pointed to by md with necessary data.
  908. * 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.
  909. * It is conjectured that it is computationally infeasible to produce two messages having the same message digest,
  910. * or to produce any message having a given prespecified target message digest.
  911. *
  912. * @param[in] md MD5 Digest Context.
  913. *
  914. * @return None
  915. *
  916. * @note None
  917. */
  918. void tls_crypto_md5_init(psDigestContext_t *md)
  919. {
  920. md->u.md5.state[0] = 0x67452301UL;
  921. md->u.md5.state[1] = 0xefcdab89UL;
  922. md->u.md5.state[2] = 0x98badcfeUL;
  923. md->u.md5.state[3] = 0x10325476UL;
  924. md->u.md5.curlen = 0;
  925. #ifdef HAVE_NATIVE_INT64
  926. md->u.md5.length = 0;
  927. #else
  928. md->u.md5.lengthHi = 0;
  929. md->u.md5.lengthLo = 0;
  930. #endif /* HAVE_NATIVE_INT64 */
  931. }
  932. /**
  933. * @brief Process a message block using MD5 algorithm.
  934. * This function performs a MD5 block update operation. It continues an MD5 message-digest operation,
  935. * by processing InputLen-byte length message block pointed to by buf, and by updating the MD5 context pointed to by md.
  936. * This function may be called as many times as necessary, so the message may be processed in blocks.
  937. *
  938. * @param[in] md MD5 Digest Context.
  939. * @param[in] buf InputLen-byte length message block
  940. * @param[in] len The buf 's length
  941. *
  942. * @return None
  943. *
  944. * @note None
  945. */
  946. void tls_crypto_md5_update(psDigestContext_t *md, const unsigned char *buf, u32 len)
  947. {
  948. u32 n;
  949. while (len > 0)
  950. {
  951. n = min(len, (64 - md->u.md5.curlen));
  952. memcpy(md->u.md5.buf + md->u.md5.curlen, buf, (size_t)n);
  953. md->u.md5.curlen += n;
  954. buf += n;
  955. len -= n;
  956. /*
  957. is 64 bytes full?
  958. */
  959. if (md->u.md5.curlen == 64)
  960. {
  961. hd_md5_compress(md);
  962. #ifdef HAVE_NATIVE_INT64
  963. md->u.md5.length += 512;
  964. #else
  965. n = (md->u.md5.lengthLo + 512) & 0xFFFFFFFFL;
  966. if (n < md->u.md5.lengthLo)
  967. {
  968. md->u.md5.lengthHi++;
  969. }
  970. md->u.md5.lengthLo = n;
  971. #endif /* HAVE_NATIVE_INT64 */
  972. md->u.md5.curlen = 0;
  973. }
  974. }
  975. }
  976. /**
  977. * @brief This function ends a MD5 operation and produces a Message-Digest.
  978. * This function finalizes MD5 algorithm, i.e. ends an MD5 Message-Digest operation,
  979. * writing the Message-Digest in the 16-byte buffer pointed to by hash in according to the information stored in context.
  980. *
  981. * @param[in] md MD5 Digest Context.
  982. * @param[in] hash the Message-Digest
  983. *
  984. * @retval 16 success, return the hash size.
  985. * @retval <0 failed
  986. *
  987. * @note None
  988. */
  989. s32 tls_crypto_md5_final(psDigestContext_t *md, unsigned char *hash)
  990. {
  991. s32 i;
  992. u32 val;
  993. #ifndef HAVE_NATIVE_INT64
  994. u32 n;
  995. #endif
  996. // psAssert(md != NULL);
  997. if (hash == NULL)
  998. {
  999. CRYPTO_LOG("NULL hash storage passed to psMd5Final\n");
  1000. return PS_ARG_FAIL;
  1001. }
  1002. /*
  1003. increase the length of the message
  1004. */
  1005. #ifdef HAVE_NATIVE_INT64
  1006. md->u.md5.length += md->u.md5.curlen << 3;
  1007. #else
  1008. n = (md->u.md5.lengthLo + (md->u.md5.curlen << 3)) & 0xFFFFFFFFL;
  1009. if (n < md->u.md5.lengthLo)
  1010. {
  1011. md->u.md5.lengthHi++;
  1012. }
  1013. md->u.md5.lengthHi += (md->u.md5.curlen >> 29);
  1014. md->u.md5.lengthLo = n;
  1015. #endif /* HAVE_NATIVE_INT64 */
  1016. /*
  1017. append the '1' bit
  1018. */
  1019. md->u.md5.buf[md->u.md5.curlen++] = (unsigned char)0x80;
  1020. /*
  1021. if the length is currently above 56 bytes we append zeros then compress.
  1022. Then we can fall back to padding zeros and length encoding like normal.
  1023. */
  1024. if (md->u.md5.curlen > 56)
  1025. {
  1026. while (md->u.md5.curlen < 64)
  1027. {
  1028. md->u.md5.buf[md->u.md5.curlen++] = (unsigned char)0;
  1029. }
  1030. hd_md5_compress(md);
  1031. md->u.md5.curlen = 0;
  1032. }
  1033. /*
  1034. pad upto 56 bytes of zeroes
  1035. */
  1036. while (md->u.md5.curlen < 56)
  1037. {
  1038. md->u.md5.buf[md->u.md5.curlen++] = (unsigned char)0;
  1039. }
  1040. /*
  1041. store length
  1042. */
  1043. #ifdef HAVE_NATIVE_INT64
  1044. STORE64L(md->u.md5.length, md->u.md5.buf + 56);
  1045. #else
  1046. STORE32L(md->u.md5.lengthLo, md->u.md5.buf + 56);
  1047. STORE32L(md->u.md5.lengthHi, md->u.md5.buf + 60);
  1048. #endif /* HAVE_NATIVE_INT64 */
  1049. hd_md5_compress(md);
  1050. /*
  1051. copy output
  1052. */
  1053. for (i = 0; i < 4; i++)
  1054. {
  1055. val = tls_reg_read32(HR_CRYPTO_SHA1_DIGEST0 + (4 * i));
  1056. STORE32L(val, hash + (4 * i));
  1057. }
  1058. memset(md, 0x0, sizeof(psMd5_t));
  1059. return MD5_HASH_SIZE;
  1060. }
  1061. static void rsaMonMulSetLen(const u32 len)
  1062. {
  1063. RSAN = len;
  1064. }
  1065. static void rsaMonMulWriteMc(const u32 mc)
  1066. {
  1067. u32 val = 0;
  1068. RSAMC = mc;
  1069. val = RSAMC;
  1070. if(val == mc)
  1071. {
  1072. val = 1;
  1073. return;
  1074. }
  1075. }
  1076. static void rsaMonMulWriteA(const u32 *const in)
  1077. {
  1078. memcpy((u32 *)&RSAXBUF, in, RSAN * sizeof(u32));
  1079. }
  1080. static void rsaMonMulWriteB(const u32 *const in)
  1081. {
  1082. memcpy((u32 *)&RSAYBUF, in, RSAN * sizeof(u32));
  1083. }
  1084. static void rsaMonMulWriteM(const u32 *const in)
  1085. {
  1086. memcpy((u32 *)&RSAMBUF, in, RSAN * sizeof(u32));
  1087. }
  1088. static void rsaMonMulReadA(u32 *const in)
  1089. {
  1090. memcpy(in, (u32 *)&RSAXBUF, RSAN * sizeof(u32));
  1091. }
  1092. static void rsaMonMulReadB(u32 *const in)
  1093. {
  1094. memcpy(in, (u32 *)&RSAYBUF, RSAN * sizeof(u32));
  1095. }
  1096. static void rsaMonMulReadD(u32 *const in)
  1097. {
  1098. memcpy(in, (u32 *)&RSADBUF, RSAN * sizeof(u32));
  1099. }
  1100. static int rsaMulModRead(unsigned char w, hstm_int *a)
  1101. {
  1102. u32 in[64];
  1103. int err = 0;
  1104. memset(in, 0, 64 * sizeof(u32));
  1105. switch(w)
  1106. {
  1107. case 'A':
  1108. rsaMonMulReadA(in);
  1109. break;
  1110. case 'B':
  1111. rsaMonMulReadB(in);
  1112. break;
  1113. case 'D':
  1114. rsaMonMulReadD(in);
  1115. break;
  1116. }
  1117. pstm_reverse((unsigned char *)in, RSAN * sizeof(u32));
  1118. /* this a should be initialized outside. */
  1119. //if ((err = pstm_init_for_read_unsigned_bin(NULL, a, RSAN * sizeof(u32) + sizeof(hstm_int))) != ERR_CRY_OK){
  1120. // return err;
  1121. //}
  1122. if ((err = pstm_read_unsigned_bin(a, (unsigned char *)in, RSAN * sizeof(u32))) != ERR_CRY_OK)
  1123. {
  1124. pstm_clear(a);
  1125. return err;
  1126. }
  1127. return 0;
  1128. }
  1129. static void rsaMulModDump(unsigned char w)
  1130. {
  1131. int addr = 0;
  1132. switch(w)
  1133. {
  1134. case 'A':
  1135. addr = 0;
  1136. break;
  1137. case 'B':
  1138. addr = 0x100;
  1139. break;
  1140. case 'D':
  1141. addr = 0x300;
  1142. break;
  1143. }
  1144. printf("%c", w);
  1145. dumpUint32(" Val:",((volatile u32*) (RSA_BASE_ADDRESS + addr )), RSAN);
  1146. }
  1147. static void rsaMulModWrite(unsigned char w, hstm_int *a)
  1148. {
  1149. u32 in[64];
  1150. memset(in, 0, 64 * sizeof(u32));
  1151. pstm_to_unsigned_bin_nr(NULL, a, (unsigned char *)in);
  1152. switch(w)
  1153. {
  1154. case 'A':
  1155. rsaMonMulWriteA(in);
  1156. break;
  1157. case 'B':
  1158. rsaMonMulWriteB(in);
  1159. break;
  1160. case 'M':
  1161. rsaMonMulWriteM(in);
  1162. break;
  1163. }
  1164. }
  1165. static void rsaMonMulAA(void)
  1166. {
  1167. g_crypto_ctx.rsa_complete = 0;
  1168. RSACON = 0x2c;
  1169. while (!g_crypto_ctx.rsa_complete)
  1170. {
  1171. }
  1172. g_crypto_ctx.rsa_complete = 0;
  1173. }
  1174. static void rsaMonMulDD(void)
  1175. {
  1176. g_crypto_ctx.rsa_complete = 0;
  1177. RSACON = 0x20;
  1178. while (!g_crypto_ctx.rsa_complete)
  1179. {
  1180. }
  1181. g_crypto_ctx.rsa_complete = 0;
  1182. }
  1183. static void rsaMonMulAB(void)
  1184. {
  1185. g_crypto_ctx.rsa_complete = 0;
  1186. RSACON = 0x24;
  1187. while (!g_crypto_ctx.rsa_complete)
  1188. {
  1189. }
  1190. g_crypto_ctx.rsa_complete = 0;
  1191. }
  1192. static void rsaMonMulBD(void)
  1193. {
  1194. g_crypto_ctx.rsa_complete = 0;
  1195. RSACON = 0x28;
  1196. while (!g_crypto_ctx.rsa_complete)
  1197. {
  1198. }
  1199. g_crypto_ctx.rsa_complete = 0;
  1200. }
  1201. /******************************************************************************
  1202. compute mc, s.t. mc * in = 0xffffffff
  1203. ******************************************************************************/
  1204. static void rsaCalMc(u32 *mc, const u32 in)
  1205. {
  1206. u32 y = 1;
  1207. u32 i = 31;
  1208. u32 left = 1;
  1209. u32 right = 0;
  1210. for(i = 31; i != 0; i--)
  1211. {
  1212. left <<= 1; /* 2^(i-1) */
  1213. right = (in * y) & left; /* (n*y) mod 2^i */
  1214. if( right )
  1215. {
  1216. y += left;
  1217. }
  1218. }
  1219. *mc = ~y + 1;
  1220. }
  1221. /**
  1222. * @brief This function implements the large module power multiplication algorithm.
  1223. * res = a**e (mod n)
  1224. *
  1225. * @param[in] a Pointer to a bignumber.
  1226. * @param[in] e Pointer to a bignumber.
  1227. * @param[in] n Pointer to a bignumber.
  1228. * @param[out] res Pointer to the result bignumber.
  1229. *
  1230. * @retval 0 success
  1231. * @retval other failed
  1232. *
  1233. * @note None
  1234. */
  1235. int tls_crypto_exptmod(hstm_int *a, hstm_int *e, hstm_int *n, hstm_int *res)
  1236. {
  1237. int i = 0;
  1238. u32 k = 0, mc = 0, dp0;
  1239. volatile u8 monmulFlag = 0;
  1240. hstm_int R, X, Y;
  1241. tls_open_peripheral_clock(TLS_PERIPHERAL_TYPE_RSA);
  1242. #ifndef CONFIG_KERNEL_NONE
  1243. tls_fls_sem_lock();
  1244. #endif
  1245. pstm_init(NULL, &X);
  1246. pstm_init(NULL, &Y);
  1247. pstm_init(NULL, &R);
  1248. k = pstm_count_bits(n);//n->used * DIGIT_BIT;//pstm_count_bits(n);
  1249. k = ((k / 32) + (k % 32 > 0 ? 1 : 0)) * 32;
  1250. #if 0
  1251. pstm_set(&Y, k);
  1252. pstm_set(&X, 2);
  1253. pstm_exptmod(NULL, &X, &Y, n, &R); //R = 2^k % n
  1254. #else
  1255. pstm_2expt(&X, (int16)k); //X = 2^k
  1256. pstm_mod(NULL, &X, n, &R); //R = 2^k % n
  1257. #endif
  1258. //pstm_set(&Y, 1);
  1259. pstm_mulmod(NULL, a, &R, n, &X); //X = A * R
  1260. pstm_copy(&R, &Y);
  1261. if(n->used > 1)
  1262. {
  1263. #if (DIGIT_BIT < 32)
  1264. dp0 = 0xFFFFFFFF & ((n->dp[0]) | (u32)(n->dp[1] << DIGIT_BIT));
  1265. #else
  1266. dp0 = (n->dp[0]);
  1267. #endif
  1268. }
  1269. else
  1270. dp0 = n->dp[0];
  1271. rsaCalMc(&mc, dp0);
  1272. k = pstm_count_bits(n);
  1273. rsaMonMulSetLen(k / 32 + (k % 32 == 0 ? 0 : 1));
  1274. rsaMonMulWriteMc(mc);
  1275. rsaMulModWrite('M', n);
  1276. rsaMulModWrite('B', &X);
  1277. rsaMulModWrite('A', &Y);
  1278. k = pstm_count_bits(e);
  1279. for(i = k - 1; i >= 0; i--)
  1280. {
  1281. //montMulMod(&Y, &Y, n, &Y);
  1282. //if(pstm_get_bit(e, i))
  1283. // montMulMod(&Y, &X, n, &Y);
  1284. if(monmulFlag == 0)
  1285. {
  1286. rsaMonMulAA();
  1287. monmulFlag = 1;
  1288. //rsaMulModDump('D');
  1289. }
  1290. else
  1291. {
  1292. rsaMonMulDD();
  1293. monmulFlag = 0;
  1294. //rsaMulModDump('A');
  1295. }
  1296. if(pstm_get_bit(e, i))
  1297. {
  1298. if(monmulFlag == 0)
  1299. {
  1300. rsaMonMulAB();
  1301. monmulFlag = 1;
  1302. //rsaMulModDump('D');
  1303. }
  1304. else
  1305. {
  1306. rsaMonMulBD();
  1307. monmulFlag = 0;
  1308. //rsaMulModDump('A');
  1309. }
  1310. }
  1311. }
  1312. pstm_set(&R, 1);
  1313. rsaMulModWrite('B', &R);
  1314. //montMulMod(&Y, &R, n, res);
  1315. if(monmulFlag == 0)
  1316. {
  1317. rsaMonMulAB();
  1318. rsaMulModRead('D', res);
  1319. }
  1320. else
  1321. {
  1322. rsaMonMulBD();
  1323. rsaMulModRead('A', res);
  1324. }
  1325. pstm_clamp(res);
  1326. pstm_clear(&X);
  1327. pstm_clear(&Y);
  1328. pstm_clear(&R);
  1329. #ifndef CONFIG_KERNEL_NONE
  1330. tls_fls_sem_unlock();
  1331. #endif
  1332. tls_close_peripheral_clock(TLS_PERIPHERAL_TYPE_RSA);
  1333. return 0;
  1334. }
  1335. /**
  1336. * @brief This function initializes the encryption module.
  1337. *
  1338. * @param None
  1339. *
  1340. * @return None
  1341. *
  1342. * @note None
  1343. */
  1344. int tls_crypto_init(void)
  1345. {
  1346. #ifndef CONFIG_KERNEL_NONE
  1347. int err = 0;
  1348. if(g_crypto_ctx.gpsec_lock != NULL)
  1349. {
  1350. return 0;
  1351. }
  1352. err = tls_os_sem_create(&g_crypto_ctx.gpsec_lock, 1);
  1353. if (err != TLS_OS_SUCCESS)
  1354. {
  1355. TLS_DBGPRT_ERR("create semaphore @gpsec_lock fail!\n");
  1356. return -1;
  1357. }
  1358. #endif
  1359. tls_irq_enable(RSA_IRQn);
  1360. tls_irq_enable(CRYPTION_IRQn);
  1361. return 0;
  1362. }