main.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. /* MSP430 example main.c
  2. *
  3. * Copyright (C) 2006-2023 wolfSSL Inc.
  4. *
  5. * This file is part of wolfSSL.
  6. *
  7. * wolfSSL is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * wolfSSL is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
  20. */
  21. #include <wolfssl/wolfcrypt/settings.h>
  22. #include <wolfssl/wolfcrypt/wc_port.h>
  23. #include <wolfssl/wolfcrypt/types.h>
  24. #include <wolfssl/wolfcrypt/random.h>
  25. #include <wolfssl/wolfcrypt/ecc.h>
  26. #include <wolfssl/wolfcrypt/curve25519.h>
  27. #include <wolfssl/wolfcrypt/chacha20_poly1305.h>
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30. #include <stdint.h>
  31. #include <msp430f5659.h>
  32. /* Without __root on some of the functions, IAR's "Discard Unused Publics"
  33. will optimize out some of the functions
  34. */
  35. #if defined(__IAR_SYSTEMS_ICC__)
  36. #define IAR_KEEP __root
  37. #else
  38. #define IAR_KEEP
  39. #endif
  40. #define ECC_256_BIT_FIELD 32 /* 256-bit curve field */
  41. #define WOLF_GEN_MEM (2*1024)
  42. #define CHACHA_TEST_LEN 1024
  43. static byte gWolfMem[WOLF_GEN_MEM];
  44. static byte generatedCiphertext[CHACHA_TEST_LEN];
  45. static byte generatedPlaintext[CHACHA_TEST_LEN];
  46. #define MCLK_FREQ_MHZ 8 /* MCLK = 8MHz */
  47. static const byte key[] = {
  48. 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
  49. 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
  50. 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
  51. 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f
  52. };
  53. static const byte plaintext[] = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras lacus odio, pretium vel sagittis ac, facilisis quis diam. Vivamus condimentum velit sed dolor consequat interdum. Etiam eleifend ornare felis, eleifend egestas odio vulputate eu. Sed nec orci nunc. Etiam quis mi augue. Donec ullamcorper suscipit lorem, vel luctus augue cursus fermentum. Etiam a porta arcu, in convallis sem. Integer efficitur elementum diam, vel scelerisque felis posuere placerat. Donec vestibulum sit amet leo sit amet tincidunt. Etiam et vehicula turpis. Phasellus quis finibus sapien. Sed et tristique turpis. Nullam vitae sagittis tortor, et aliquet lorem. Cras a leo scelerisque, convallis lacus ut, fermentum urna. Mauris quis urna diam. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nam aliquam vehicula orci id pulvinar. Proin mollis, libero sollicitudin tempor ultrices, massa augue tincidunt turpis, sit amet aliquam neque nibh nec dui. Fusce finibus massa quis rutrum suscipit cras amet";
  54. static const byte iv[] = {
  55. 0x07, 0x00, 0x00, 0x00, 0x40, 0x41, 0x42, 0x43,
  56. 0x44, 0x45, 0x46, 0x47
  57. };
  58. static const byte aad[] = { /* additional data */
  59. 0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3,
  60. 0xc4, 0xc5, 0xc6, 0xc7
  61. };
  62. volatile unsigned int seconds;
  63. IAR_KEEP unsigned int msp430_time(long *x)
  64. {
  65. return seconds;
  66. }
  67. static void print_secret(char* who, byte* s, int sLen)
  68. {
  69. int i;
  70. printf("%ss' Secret: ", who);
  71. for (i = 0; i < sLen; i++) {
  72. printf("%02x", s[i]);
  73. }
  74. printf("\r\n");
  75. }
  76. /* This is a very crude RNG, do not use in production */
  77. IAR_KEEP unsigned int msp430_rnd(void)
  78. {
  79. unsigned int result = TA0R ^ TA2R;
  80. printf("Rand generated: %d\r\n", result);
  81. return result;
  82. }
  83. static void uart_init()
  84. {
  85. P8SEL |= BIT3 + BIT2;
  86. UCA1CTLW0 = UCSWRST; /* Put eUSCI in reset */
  87. UCA1CTLW0 |= UCSSEL__SMCLK; /* CLK = SMCLK */
  88. /* Baud Rate calculation
  89. This was calculated to produce 115200 for a 16MHz clock, so it produces
  90. 57600 at 8MHz
  91. 16000000/(16*115200) = 8.6805
  92. Fractional portion = 0.6805
  93. Use Table 24-5 in Family User Guide
  94. */
  95. UCA1BR0 = 8;
  96. UCA1BR1 = 0x00;
  97. UCA1MCTL |= UCOS16 | UCBRF_11 | UCBRS_0;
  98. UCA1CTLW0 &= ~UCSWRST; /* Initialize eUSCI */
  99. UCA1IE |= UCRXIE; /* Enable USCI_A0 RX interrupt */
  100. }
  101. #if defined(__IAR_SYSTEMS_ICC__)
  102. IAR_KEEP size_t __write(int fd, const unsigned char *_ptr, size_t len)
  103. #else
  104. int write(int fd, const char *_ptr, int len)
  105. #endif
  106. {
  107. size_t i;
  108. for(i=0 ; i<len ; i++) {
  109. while(!(UCA1IFG&UCTXIFG));
  110. UCA1TXBUF = (unsigned char) _ptr[i];
  111. }
  112. return len;
  113. }
  114. static void SetVcoreUp (unsigned int level)
  115. {
  116. /* Change VCORE voltage level */
  117. PMMCTL0_H = PMMPW_H; /* Open PMM registers for write */
  118. SVSMHCTL = SVSHE /* Set SVS/SVM high side new level */
  119. + SVSHRVL0 * level
  120. + SVMHE
  121. + SVSMHRRL0 * level;
  122. SVSMLCTL = SVSLE /* Set SVM low side to new level */
  123. + SVMLE
  124. + SVSMLRRL0 * level;
  125. while ((PMMIFG & SVSMLDLYIFG) == 0); /* Wait till SVM is settled */
  126. PMMIFG &= ~(SVMLVLRIFG + SVMLIFG); /* Clear already set flags */
  127. PMMCTL0_L = PMMCOREV0 * level; /* Set VCore to new level */
  128. if ((PMMIFG & SVMLIFG)) /* Wait till new level reached */
  129. while ((PMMIFG & SVMLVLRIFG) == 0);
  130. SVSMLCTL = SVSLE /* Set SVS/SVM low side to new level */
  131. + SVSLRVL0 * level
  132. + SVMLE
  133. + SVSMLRRL0 * level;
  134. PMMCTL0_H = 0x00; /* Lock PMM registers for write access */
  135. }
  136. /* Stop WDT
  137. We need to do this before main() because when there is ~4K of data to
  138. initialize the watchdog will fire before initialization completes, sending
  139. it into an endless loop of nothing.
  140. See: https://www.iar.com/knowledge/support/technical-notes/general/my-msp430-does-not-start-up/
  141. */
  142. #if defined(__IAR_SYSTEMS_ICC__)
  143. int __low_level_init()
  144. {
  145. WDTCTL = WDTPW | WDTHOLD;
  146. return 1;
  147. }
  148. #else
  149. static void __attribute__((naked, used, section(".crt_0042")))
  150. disable_watchdog (void)
  151. {
  152. WDTCTL = WDTPW | WDTHOLD;
  153. }
  154. #endif
  155. int main(void)
  156. {
  157. byte generatedAuthTag[16];
  158. WOLFSSL_HEAP_HINT* HEAP_HINT = NULL;
  159. int ret;
  160. int start;
  161. /* NOTE: Change core voltage one level at a time.. */
  162. SetVcoreUp (0x01);
  163. SetVcoreUp (0x02);
  164. SetVcoreUp (0x03);
  165. /* USC module configuration, Fdcoclockdiv = Fmclk = 8MHz */
  166. UCSCTL8 &= ~SMCLKREQEN; /* disable SMCLK clock requests */
  167. UCSCTL3 = (0*FLLREFDIV0) /* FLL ref divider 1 */
  168. + SELREF2; /* set REFOCLK as FLL reference clock source */
  169. UCSCTL4 = SELA__REFOCLK /* ACLK = REFO */
  170. + SELM__DCOCLKDIV /* MCLK = DCOCLKDIV */
  171. + SELS__DCOCLKDIV; /* SMCLK = DCOCLKDIV */
  172. __bis_SR_register(SCG0); /* disable FLL operation */
  173. UCSCTL0 = 0x0000; /* lowest possible DCO, MOD */
  174. UCSCTL1 = DISMOD_L /* modulation disabled */
  175. + DCORSEL_6; /* DCO range for 8MHz operation */
  176. UCSCTL2 = FLLD_0 /* D=FLLD=1, so that Fdco=8MHz */
  177. + 243; /* DCO multiplier for 8MHz */
  178. /* (N + 1) * FLLRef = Fdcodiv */
  179. /* (243 + 1) * 32768 = 8MHz (multiplier N = 243) */
  180. __bic_SR_register(SCG0); /* re-enable FLL operation */
  181. /* worst-case settling time for the DCO when the DCO range bits have been
  182. 32 x 32 x 8 MHz / 32,768 Hz = 250000 = MCLK cycles for DCO to settle
  183. */
  184. __delay_cycles(250000);
  185. TA0CCR0 = 32768-1;
  186. TA0CCTL0 |= CCIE;
  187. TA0CTL = TASSEL_1 + ID_0 + MC_1;
  188. TA2CTL = TASSEL_2 | MC_2;
  189. P1DIR = 1;
  190. P1OUT = 0;
  191. uart_init();
  192. #if defined(__IAR_SYSTEMS_ICC__)
  193. __enable_interrupt();
  194. #else
  195. _enable_interrupts();
  196. #endif
  197. printf("START!\r\n");
  198. #ifdef HAVE_ECC
  199. WC_RNG rng;
  200. ecc_key AliceKey, BobKey;
  201. byte AliceSecret[ECC_256_BIT_FIELD] = {0};
  202. byte BobSecret[ECC_256_BIT_FIELD] = {0};
  203. word32 secretLen = 0;
  204. if (wc_LoadStaticMemory(&HEAP_HINT, gWolfMem, sizeof(gWolfMem),
  205. WOLFMEM_GENERAL, 10) != 0) {
  206. printf("unable to load static memory");
  207. }
  208. ret = wc_InitRng_ex(&rng, HEAP_HINT, INVALID_DEVID);
  209. if (ret != 0) {
  210. printf("RNG init fail: %d\r\n", ret);
  211. return ret;
  212. }
  213. printf("RNG init\r\n");
  214. ret = wc_ecc_init(&AliceKey);
  215. if (ret != 0) {
  216. printf("Alice init fail\r\n");
  217. goto only_rng;
  218. }
  219. printf("Alice init\r\n");
  220. ret = wc_ecc_init(&BobKey);
  221. if (ret != 0) {
  222. printf("Bob init fail\r\n");
  223. goto alice_and_rng;
  224. }
  225. printf("Bob init\r\n");
  226. start = seconds;
  227. ret = wc_ecc_make_key(&rng, ECC_256_BIT_FIELD, &AliceKey);
  228. if (ret != 0) {
  229. printf("Alice keygen fail\r\n");
  230. goto all_three;
  231. }
  232. printf("Alice keygen %d seconds\r\n", seconds - start);
  233. start = seconds;
  234. ret = wc_ecc_make_key(&rng, ECC_256_BIT_FIELD, &BobKey);
  235. if (ret != 0) {
  236. printf("Bob keygen fail\r\n");
  237. goto all_three;
  238. }
  239. printf("Bob keygen %d seconds\r\n", seconds - start);
  240. start = seconds;
  241. secretLen = ECC_256_BIT_FIELD; /* explicit set */
  242. ret = wc_ecc_shared_secret(&AliceKey, &BobKey, AliceSecret, &secretLen);
  243. if (ret != 0) {
  244. printf("Shared secret fail\r\n");
  245. goto all_three;
  246. }
  247. printf("Bob secret %d seconds\r\n", seconds - start);
  248. start = seconds;
  249. secretLen = ECC_256_BIT_FIELD; /* explicit reset for best practice */
  250. ret = wc_ecc_shared_secret(&BobKey, &AliceKey, BobSecret, &secretLen);
  251. if (ret == 0) {
  252. if (XMEMCMP(AliceSecret, BobSecret, secretLen))
  253. printf("Failed to generate a common secret\n");
  254. } else {
  255. goto all_three;
  256. }
  257. printf("Alice secret %d seconds\r\n", seconds - start);
  258. printf("Successfully generated a common secret\r\n");
  259. print_secret("Alice", AliceSecret, (int) secretLen);
  260. print_secret("Bob", BobSecret, (int) secretLen);
  261. all_three:
  262. wc_ecc_free(&BobKey);
  263. alice_and_rng:
  264. wc_ecc_free(&AliceKey);
  265. only_rng:
  266. wc_FreeRng(&rng);
  267. printf(
  268. "ChaCha20/Poly1305 Encryption Start, 1000 iterations, %d bytes\r\n",
  269. (int)strlen((const char*)plaintext));
  270. start = seconds;
  271. for (int i=0; i <= 1000; i++) {
  272. ret = wc_ChaCha20Poly1305_Encrypt(key, iv, aad, sizeof(aad), plaintext,
  273. strlen((const char*)plaintext), generatedCiphertext,
  274. generatedAuthTag);
  275. if (ret) {
  276. printf("ChaCha error: %d\r\n", ret);
  277. break;
  278. }
  279. }
  280. printf("\r\nEnd %d seconds\r\n", seconds - start);
  281. start = seconds;
  282. printf("ChaCha20/Poly1305 Decryption Start, 1000 iterations\r\n");
  283. start = seconds;
  284. for (int i=0; i <= 1000; i++) {
  285. ret = wc_ChaCha20Poly1305_Decrypt(key, iv, aad, sizeof(aad),
  286. generatedCiphertext, strlen((const char*)plaintext),
  287. generatedAuthTag, generatedPlaintext);
  288. if (ret) {
  289. printf("ChaCha error: %d\r\n", ret);
  290. break;
  291. }
  292. }
  293. printf("\r\nEnd %d seconds\r\n", seconds - start);
  294. #else
  295. printf("Configure wolfSSL with --enable-ecc and try again\n");
  296. ret = -1;
  297. #endif
  298. printf("end\r\n");
  299. while(1) {
  300. __delay_cycles(8000000);
  301. }
  302. return ret;
  303. }
  304. /* Timer ISR */
  305. #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
  306. #pragma vector=TIMER0_A0_VECTOR
  307. __interrupt void TIMER0_A0_ISR(void)
  308. #elif defined(__GNUC__)
  309. void __attribute__ ((interrupt(TIMER0_A0_VECTOR))) TIMER0_A0_ISR (void)
  310. #else
  311. #error Compiler not supported!
  312. #endif
  313. {
  314. seconds++;
  315. P1OUT = seconds ^ 2;
  316. fprintf(stderr, ".");
  317. }