123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358 |
- /* MSP430 example main.c
- *
- * Copyright (C) 2006-2022 wolfSSL Inc.
- *
- * This file is part of wolfSSL.
- *
- * wolfSSL is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * wolfSSL is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
- */
- #include <wolfssl/wolfcrypt/settings.h>
- #include <wolfssl/wolfcrypt/wc_port.h>
- #include <wolfssl/wolfcrypt/types.h>
- #include <wolfssl/wolfcrypt/random.h>
- #include <wolfssl/wolfcrypt/ecc.h>
- #include <wolfssl/wolfcrypt/curve25519.h>
- #include <wolfssl/wolfcrypt/chacha20_poly1305.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdint.h>
- #include <msp430f5659.h>
- /* Without __root on some of the functions, IAR's "Discard Unused Publics"
- will optimze out some of the functions
- */
- #if defined(__IAR_SYSTEMS_ICC__)
- #define IAR_KEEP __root
- #else
- #define IAR_KEEP
- #endif
- #define ECC_256_BIT_FIELD 32 /* 256-bit curve field */
- #define WOLF_GEN_MEM (2*1024)
- #define CHACHA_TEST_LEN 1024
- static byte gWolfMem[WOLF_GEN_MEM];
- static byte generatedCiphertext[CHACHA_TEST_LEN];
- static byte generatedPlaintext[CHACHA_TEST_LEN];
- #define MCLK_FREQ_MHZ 8 /* MCLK = 8MHz */
- static const byte key[] = {
- 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
- 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
- 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
- 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f
- };
- 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";
- static const byte iv[] = {
- 0x07, 0x00, 0x00, 0x00, 0x40, 0x41, 0x42, 0x43,
- 0x44, 0x45, 0x46, 0x47
- };
- static const byte aad[] = { /* additional data */
- 0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3,
- 0xc4, 0xc5, 0xc6, 0xc7
- };
- volatile unsigned int seconds;
- IAR_KEEP unsigned int msp430_time(long *x)
- {
- return seconds;
- }
- static void print_secret(char* who, byte* s, int sLen)
- {
- int i;
- printf("%ss' Secret: ", who);
- for (i = 0; i < sLen; i++) {
- printf("%02x", s[i]);
- }
- printf("\r\n");
- }
- /* This is a very crude RNG, do not use in production */
- IAR_KEEP unsigned int msp430_rnd(void)
- {
- unsigned int result = TA0R ^ TA2R;
- printf("Rand generated: %d\r\n", result);
- return result;
- }
- static void uart_init()
- {
- P8SEL |= BIT3 + BIT2;
- UCA1CTLW0 = UCSWRST; /* Put eUSCI in reset */
- UCA1CTLW0 |= UCSSEL__SMCLK; /* CLK = SMCLK */
- /* Baud Rate calculation
- This was calculated to produce 115200 for a 16MHz clock, so it produces
- 57600 at 8MHz
- 16000000/(16*115200) = 8.6805
- Fractional portion = 0.6805
- Use Table 24-5 in Family User Guide
- */
- UCA1BR0 = 8;
- UCA1BR1 = 0x00;
- UCA1MCTL |= UCOS16 | UCBRF_11 | UCBRS_0;
- UCA1CTLW0 &= ~UCSWRST; /* Initialize eUSCI */
- UCA1IE |= UCRXIE; /* Enable USCI_A0 RX interrupt */
- }
- #if defined(__IAR_SYSTEMS_ICC__)
- IAR_KEEP size_t __write(int fd, const unsigned char *_ptr, size_t len)
- #else
- int write(int fd, const char *_ptr, int len)
- #endif
- {
- size_t i;
- for(i=0 ; i<len ; i++) {
- while(!(UCA1IFG&UCTXIFG));
- UCA1TXBUF = (unsigned char) _ptr[i];
- }
- return len;
- }
- static void SetVcoreUp (unsigned int level)
- {
- /* Change VCORE voltage level */
- PMMCTL0_H = PMMPW_H; /* Open PMM registers for write */
- SVSMHCTL = SVSHE /* Set SVS/SVM high side new level */
- + SVSHRVL0 * level
- + SVMHE
- + SVSMHRRL0 * level;
- SVSMLCTL = SVSLE /* Set SVM low side to new level */
- + SVMLE
- + SVSMLRRL0 * level;
- while ((PMMIFG & SVSMLDLYIFG) == 0); /* Wait till SVM is settled */
- PMMIFG &= ~(SVMLVLRIFG + SVMLIFG); /* Clear already set flags */
- PMMCTL0_L = PMMCOREV0 * level; /* Set VCore to new level */
- if ((PMMIFG & SVMLIFG)) /* Wait till new level reached */
- while ((PMMIFG & SVMLVLRIFG) == 0);
- SVSMLCTL = SVSLE /* Set SVS/SVM low side to new level */
- + SVSLRVL0 * level
- + SVMLE
- + SVSMLRRL0 * level;
- PMMCTL0_H = 0x00; /* Lock PMM registers for write access */
- }
- /* Stop WDT
- We need to do this before main() because when there is ~4K of data to
- initialize the watchdog will fire before initialization completes, sending
- it into an endless loop of nothing.
- See: https://www.iar.com/knowledge/support/technical-notes/general/my-msp430-does-not-start-up/
- */
- #if defined(__IAR_SYSTEMS_ICC__)
- int __low_level_init()
- {
- WDTCTL = WDTPW | WDTHOLD;
- return 1;
- }
- #else
- static void __attribute__((naked, used, section(".crt_0042")))
- disable_watchdog (void)
- {
- WDTCTL = WDTPW | WDTHOLD;
- }
- #endif
- int main(void)
- {
- byte generatedAuthTag[16];
- WOLFSSL_HEAP_HINT* HEAP_HINT = NULL;
- int ret;
- int start;
- /* NOTE: Change core voltage one level at a time.. */
- SetVcoreUp (0x01);
- SetVcoreUp (0x02);
- SetVcoreUp (0x03);
- /* USC module configuration, Fdcoclockdiv = Fmclk = 8MHz */
- UCSCTL8 &= ~SMCLKREQEN; /* disable SMCLK clock requests */
- UCSCTL3 = (0*FLLREFDIV0) /* FLL ref divider 1 */
- + SELREF2; /* set REFOCLK as FLL reference clock source */
- UCSCTL4 = SELA__REFOCLK /* ACLK = REFO */
- + SELM__DCOCLKDIV /* MCLK = DCOCLKDIV */
- + SELS__DCOCLKDIV; /* SMCLK = DCOCLKDIV */
- __bis_SR_register(SCG0); /* disable FLL operation */
- UCSCTL0 = 0x0000; /* lowest possible DCO, MOD */
- UCSCTL1 = DISMOD_L /* modulation disabled */
- + DCORSEL_6; /* DCO range for 8MHz operation */
- UCSCTL2 = FLLD_0 /* D=FLLD=1, so that Fdco=8MHz */
- + 243; /* DCO multiplier for 8MHz */
- /* (N + 1) * FLLRef = Fdcodiv */
- /* (243 + 1) * 32768 = 8MHz (multiplier N = 243) */
- __bic_SR_register(SCG0); /* re-enable FLL operation */
- /* worst-case settling time for the DCO when the DCO range bits have been
- 32 x 32 x 8 MHz / 32,768 Hz = 250000 = MCLK cycles for DCO to settle
- */
- __delay_cycles(250000);
- TA0CCR0 = 32768-1;
- TA0CCTL0 |= CCIE;
- TA0CTL = TASSEL_1 + ID_0 + MC_1;
- TA2CTL = TASSEL_2 | MC_2;
- P1DIR = 1;
- P1OUT = 0;
- uart_init();
- #if defined(__IAR_SYSTEMS_ICC__)
- __enable_interrupt();
- #else
- _enable_interrupts();
- #endif
- printf("START!\r\n");
- #ifdef HAVE_ECC
- WC_RNG rng;
- ecc_key AliceKey, BobKey;
- byte AliceSecret[ECC_256_BIT_FIELD] = {0};
- byte BobSecret[ECC_256_BIT_FIELD] = {0};
- word32 secretLen = 0;
- if (wc_LoadStaticMemory(&HEAP_HINT, gWolfMem, sizeof(gWolfMem),
- WOLFMEM_GENERAL, 10) != 0) {
- printf("unable to load static memory");
- }
- ret = wc_InitRng_ex(&rng, HEAP_HINT, INVALID_DEVID);
- if (ret != 0) {
- printf("RNG init fail: %d\r\n", ret);
- return ret;
- }
- printf("RNG init\r\n");
- ret = wc_ecc_init(&AliceKey);
- if (ret != 0) {
- printf("Alice init fail\r\n");
- goto only_rng;
- }
- printf("Alice init\r\n");
- ret = wc_ecc_init(&BobKey);
- if (ret != 0) {
- printf("Bob init fail\r\n");
- goto alice_and_rng;
- }
- printf("Bob init\r\n");
- start = seconds;
- ret = wc_ecc_make_key(&rng, ECC_256_BIT_FIELD, &AliceKey);
- if (ret != 0) {
- printf("Alice keygen fail\r\n");
- goto all_three;
- }
- printf("Alice keygen %d seconds\r\n", seconds - start);
- start = seconds;
- ret = wc_ecc_make_key(&rng, ECC_256_BIT_FIELD, &BobKey);
- if (ret != 0) {
- printf("Bob keygen fail\r\n");
- goto all_three;
- }
- printf("Bob keygen %d seconds\r\n", seconds - start);
- start = seconds;
- secretLen = ECC_256_BIT_FIELD; /* explicit set */
- ret = wc_ecc_shared_secret(&AliceKey, &BobKey, AliceSecret, &secretLen);
- if (ret != 0) {
- printf("Shared secret fail\r\n");
- goto all_three;
- }
- printf("Bob secret %d seconds\r\n", seconds - start);
- start = seconds;
- secretLen = ECC_256_BIT_FIELD; /* explicit reset for best practice */
- ret = wc_ecc_shared_secret(&BobKey, &AliceKey, BobSecret, &secretLen);
- if (ret == 0) {
- if (XMEMCMP(AliceSecret, BobSecret, secretLen))
- printf("Failed to generate a common secret\n");
- } else {
- goto all_three;
- }
- printf("Alice secret %d seconds\r\n", seconds - start);
- printf("Successfully generated a common secret\r\n");
- print_secret("Alice", AliceSecret, (int) secretLen);
- print_secret("Bob", BobSecret, (int) secretLen);
- all_three:
- wc_ecc_free(&BobKey);
- alice_and_rng:
- wc_ecc_free(&AliceKey);
- only_rng:
- wc_FreeRng(&rng);
- printf(
- "ChaCha20/Poly1305 Encryption Start, 1000 itterations, %d bytes\r\n",
- (int)strlen((const char*)plaintext));
- start = seconds;
- for (int i=0; i <= 1000; i++) {
- ret = wc_ChaCha20Poly1305_Encrypt(key, iv, aad, sizeof(aad), plaintext,
- strlen((const char*)plaintext), generatedCiphertext,
- generatedAuthTag);
- if (ret) {
- printf("ChaCha error: %d\r\n", ret);
- break;
- }
- }
- printf("\r\nEnd %d seconds\r\n", seconds - start);
- start = seconds;
- printf("ChaCha20/Poly1305 Decryption Start, 1000 itterations\r\n");
- start = seconds;
- for (int i=0; i <= 1000; i++) {
- ret = wc_ChaCha20Poly1305_Decrypt(key, iv, aad, sizeof(aad),
- generatedCiphertext, strlen((const char*)plaintext),
- generatedAuthTag, generatedPlaintext);
- if (ret) {
- printf("ChaCha error: %d\r\n", ret);
- break;
- }
- }
- printf("\r\nEnd %d seconds\r\n", seconds - start);
- #else
- printf("Configure wolfSSL with --enable-ecc and try again\n");
- ret = -1;
- #endif
- printf("end\r\n");
- while(1) {
- __delay_cycles(8000000);
- }
- return ret;
- }
- /* Timer ISR */
- #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
- #pragma vector=TIMER0_A0_VECTOR
- __interrupt void TIMER0_A0_ISR(void)
- #elif defined(__GNUC__)
- void __attribute__ ((interrupt(TIMER0_A0_VECTOR))) TIMER0_A0_ISR (void)
- #else
- #error Compiler not supported!
- #endif
- {
- seconds++;
- P1OUT = seconds ^ 2;
- fprintf(stderr, ".");
- }
|