comparison main.c @ 27:ce5097eacf2f

try at adc_random() use interrupts and noise reduction for other sleep 115200, faster crystal
author Matt Johnston <matt@ucc.asn.au>
date Wed, 26 Jun 2013 23:12:37 +0800
parents 292cd17de2a4
children 5d6a841eef82
comparison
equal deleted inserted replaced
26:292cd17de2a4 27:ce5097eacf2f
39 #define NKEYS 10 39 #define NKEYS 10
40 #define HMACLEN 20 40 #define HMACLEN 20
41 #define AESLEN 16 41 #define AESLEN 16
42 #define KEYLEN HMACLEN 42 #define KEYLEN HMACLEN
43 43
44 #define BAUD 38400 44 #define BAUD 115200
45 #define UBRR ((F_CPU)/(16*(BAUD))-1) 45 #define UBRR ((F_CPU)/(16*(BAUD))-1)
46 46
47 #define PORT_PI_BOOT PORTD 47 #define PORT_PI_BOOT PORTD
48 #define DDR_PI_BOOT DDRD 48 #define DDR_PI_BOOT DDRD
49 #define PIN_PI_BOOT PD5 49 #define PIN_PI_BOOT PD5
98 static uint32_t newboot_count; 98 static uint32_t newboot_count;
99 // oneshot counts down 99 // oneshot counts down
100 static uint32_t oneshot_count; 100 static uint32_t oneshot_count;
101 // countdown after the warning. 101 // countdown after the warning.
102 static uint8_t reboot_count; 102 static uint8_t reboot_count;
103 // set by adc completion interrupt
104 static uint8_t adc_done;
103 105
104 // ---- End atomic guards required 106 // ---- End atomic guards required
105 107
106 // boolean flags 108 // boolean flags
107 static uint8_t watchdog_long_hit; 109 static uint8_t watchdog_long_hit;
559 if (memcmp(output, indata, HMACLEN) != 0) { 561 if (memcmp(output, indata, HMACLEN) != 0) {
560 printf_P(PSTR("FAIL: hmac mismatch\n")); 562 printf_P(PSTR("FAIL: hmac mismatch\n"));
561 } 563 }
562 564
563 uint8_t tmpbuf[256]; 565 uint8_t tmpbuf[256];
564 //aesInit(avr_keys[key_index], tmpbuf); 566 aesInit(avr_keys[key_index], tmpbuf);
565 //aesDecrypt(&indata[HMACLEN], NULL); 567 aesDecrypt(&indata[HMACLEN], NULL);
566 568
567 printf_P(PSTR("DECRYPTED: ")); 569 printf_P(PSTR("DECRYPTED: "));
568 printhex(output, AESLEN, stdout); 570 printhex(output, AESLEN, stdout);
569 putchar('\n'); 571 putchar('\n');
570 } 572 }
633 static void 635 static void
634 cmd_vcc() 636 cmd_vcc()
635 { 637 {
636 uint16_t vcc = adc_vcc(); 638 uint16_t vcc = adc_vcc();
637 uint16_t v5 = adc_5v(vcc); 639 uint16_t v5 = adc_5v(vcc);
638 uint16_t r = adc_random();
639 uint16_t temp = adc_temp(); 640 uint16_t temp = adc_temp();
640 // roughly? 641 // roughly?
641 uint16_t temp_deg = temp - 290; 642 uint16_t temp_deg = temp - 290;
642 printf_P(PSTR("vcc: %u mV\n" 643 printf_P(PSTR("vcc: %u mV\n"
643 "5v: %u mV\n" 644 "5v: %u mV\n"
644 "temp: %u mV (%dºC)\n" 645 "temp: %u mV (%dºC)\n"
645 "random: %u\n"
646 ), 646 ),
647 vcc, v5, temp, temp_deg, r); 647 vcc, v5, temp, temp_deg);
648 } 648 }
649 649
650 void(*bootloader)() __attribute__ ((noreturn)) = (void*)0x7e00; 650
651 651 void(*bootloader)() __attribute__ ((noreturn)) = (void*)0x7800;
652 #if 0 652
653 #ifndef PROG_PASSWORD 653 #ifndef PROG_PASSWORD
654 #define PROG_PASSWORD "Y2vvjxO5" 654 #define PROG_PASSWORD "Y2vvjxO5"
655 #endif 655 #endif
656 656
657 static void 657 static void
682 682
683 _delay_ms(20); 683 _delay_ms(20);
684 684
685 bootloader(); 685 bootloader();
686 } 686 }
687 #endif 687
688
689 static void
690 adc_sleep()
691 {
692 set_sleep_mode(SLEEP_MODE_IDLE);
693 sleep_mode();
694 }
695
696 #define BITSET(v, n) (((v) >> (n)) & 1)
697
698 static inline uint8_t
699 popcnt(uint8_t v)
700 {
701 return BITSET(v, 0)
702 + BITSET(v, 1)
703 + BITSET(v, 2)
704 + BITSET(v, 3)
705 + BITSET(v, 4)
706 + BITSET(v, 5)
707 + BITSET(v, 6)
708 + BITSET(v, 7);
709 }
710
711 static uint8_t
712 adc_bit()
713 {
714 ADCSRA |= _BV(ADSC);
715 loop_until_bit_is_clear(ADCSRA, ADSC);
716 uint8_t low = ADCL;
717 uint8_t high = ADCH;
718 return (popcnt(low)&1) ^ (popcnt(high)&1);
719 }
720
721 static void
722 adc_random(uint8_t admux,
723 uint8_t *out, uint16_t num, uint32_t *tries)
724 {
725 uint8_t ret = 0;
726 uint8_t count = 0;
727
728 PRR &= ~_BV(PRADC);
729 // /16 prescaler for 691mhz, no interrupt
730 ADCSRA = _BV(ADEN) | _BV(ADPS2);
731
732 *tries = 0;
733 for (int i = 0; i < num; i++)
734 {
735 while (count <= 7)
736 {
737 (*tries)++;
738
739 // Von Neumann extractor
740 uint8_t one = adc_bit();
741 uint8_t two = adc_bit();
742 if (one == two)
743 {
744 continue;
745 }
746 ret |= one << count;
747 count++;
748 }
749 out[i] = ret;
750 }
751 ADCSRA = 0;
752 PRR |= _BV(PRADC);
753 }
754
755 ISR(ADC_vect)
756 {
757 adc_done = 1;
758 }
759
760 static void
761 adc_generic(uint8_t admux, uint8_t *ret_num, uint16_t *ret_sum)
762 {
763 PRR &= ~_BV(PRADC);
764
765 // /64 prescaler, interrupt
766 ADCSRA = _BV(ADEN) | _BV(ADPS2) | _BV(ADPS1) | _BV(ADIE);
767
768 // set to measure 1.1 reference
769 ADMUX = admux;
770
771 // delay after setting reference etc, allow settling
772 long_delay(300);
773 // average a number of samples
774 uint16_t sum = 0;
775 uint8_t num = 0;
776 for (uint8_t n = 0; n < 20; n++)
777 {
778 while (1)
779 {
780 adc_done = 0;
781 ADCSRA |= _BV(ADSC);
782 adc_sleep();
783
784 uint8_t done;
785 ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
786 {
787 done = adc_done;
788 }
789 if (done)
790 {
791 break;
792 }
793 }
794
795 uint8_t low_11 = ADCL;
796 uint8_t high_11 = ADCH;
797 uint16_t val = low_11 + (high_11 << 8);
798
799 if (n >= 4)
800 {
801 sum += val;
802 num++;
803 }
804 }
805 ADCSRA = 0;
806 PRR |= _BV(PRADC);
807
808 *ret_num = num;
809 *ret_sum = sum;
810 }
811
812 static uint16_t
813 adc_vcc()
814 {
815 const uint8_t mux = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
816 uint16_t sum;
817 uint8_t num;
818
819 adc_generic(mux, &num, &sum);
820
821 //float res_volts = 1.1 * 1024 * num / sum;
822 //return 1000 * res_volts;
823 return ((uint32_t)1100*1024*num) / sum;
824 }
825
826 #define SCALER_5V 2
827
828 static uint16_t
829 adc_5v(uint16_t vcc)
830 {
831 // set to measure ADC4 against AVCC
832 const uint8_t mux = _BV(REFS0) | _BV(MUX2);
833 uint16_t sum;
834 uint8_t num;
835
836 adc_generic(mux, &num, &sum);
837
838 return ((uint32_t)vcc*sum*SCALER_5V/(num*1024));
839 }
840
841 static uint16_t
842 adc_temp()
843 {
844 // set to measure temperature against 1.1v reference.
845 const uint8_t mux = _BV(REFS0) | _BV(REFS1) | _BV(MUX3);
846 uint16_t sum;
847 uint8_t num;
848
849 adc_generic(mux, &num, &sum);
850
851 // return the voltage
852
853 return ((uint32_t)1100*sum) / (num*1024);
854 }
855
856 static void
857 cmd_random(const char* params)
858 {
859 uint8_t admux;
860 uint16_t num;
861 uint8_t buf[100];
862
863 int ret = sscanf_P(params, PSTR("%hhu %u"),
864 &admux, &num);
865 if (!ret)
866 {
867 printf_P(PSTR("Bad arguments\n"));
868 return;
869 }
870 uint32_t tries = 0;
871 printf_P(PSTR("output: "));
872 for (int i = 0; i < num; i+= sizeof(buf))
873 {
874 uint32_t t;
875 uint16_t nr = MIN(num-i, sizeof(buf));
876 adc_random(admux, buf, nr, &t);
877 printhex(buf, nr, stdout);
878 tries += t;
879 }
880 putchar('\n');
881 printf_P(PSTR("%ld tries\n"), tries);
882 }
883
884
688 885
689 static void 886 static void
690 read_handler() 887 read_handler()
691 { 888 {
692 #define LOCAL_PSTR(x) const static char x ## _str[] PROGMEM = #x; 889 #define LOCAL_PSTR(x) const static char x ## _str[] PROGMEM = #x;
701 LOCAL_PSTR(vcc); 898 LOCAL_PSTR(vcc);
702 LOCAL_PSTR(reset); 899 LOCAL_PSTR(reset);
703 LOCAL_PSTR(newboot); 900 LOCAL_PSTR(newboot);
704 LOCAL_PSTR(oldboot); 901 LOCAL_PSTR(oldboot);
705 LOCAL_PSTR(status); 902 LOCAL_PSTR(status);
903 LOCAL_PSTR(random);
904 LOCAL_PSTR(prog);
706 LOCAL_HELP(set_params, "<long_limit> <short_limit> <newboot_limit>"); 905 LOCAL_HELP(set_params, "<long_limit> <short_limit> <newboot_limit>");
707 LOCAL_HELP(set_key, "20_byte_hex>"); 906 LOCAL_HELP(set_key, "20_byte_hex>");
708 LOCAL_HELP(oneshot, "<timeout>"); 907 LOCAL_HELP(oneshot, "<timeout>");
908 LOCAL_HELP(prog, "<password>");
909 LOCAL_HELP(random, "<admux> <nbytes>");
709 LOCAL_HELP(hmac, "<key_index> <20_byte_hex_data>"); 910 LOCAL_HELP(hmac, "<key_index> <20_byte_hex_data>");
710 LOCAL_HELP(decrypt, "<key_index> <20_byte_hmac|16_byte_aes_block>"); 911 LOCAL_HELP(decrypt, "<key_index> <20_byte_hmac|16_byte_aes_block>");
711 912
712 static const struct handler { 913 static const struct handler {
713 PGM_P name; 914 PGM_P name;
723 {status_str, cmd_status, NULL}, 924 {status_str, cmd_status, NULL},
724 {hmac_str, cmd_hmac, hmac_help}, 925 {hmac_str, cmd_hmac, hmac_help},
725 {decrypt_str, cmd_decrypt, decrypt_help}, 926 {decrypt_str, cmd_decrypt, decrypt_help},
726 {set_params_str, cmd_set_params, set_params_help}, 927 {set_params_str, cmd_set_params, set_params_help},
727 {set_key_str, cmd_set_avr_key, set_key_help}, 928 {set_key_str, cmd_set_avr_key, set_key_help},
929 {random_str, cmd_random, random_help},
728 {vcc_str, cmd_vcc, NULL}, 930 {vcc_str, cmd_vcc, NULL},
729 {reset_str, cmd_reset, NULL}, 931 {reset_str, cmd_reset, NULL},
932 {prog_str, cmd_prog, prog_help},
730 }; 933 };
731 934
732 if (readbuf[0] == '\0') 935 if (readbuf[0] == '\0')
733 { 936 {
734 return; 937 return;
880 set_sleep_mode(SLEEP_MODE_IDLE); 1083 set_sleep_mode(SLEEP_MODE_IDLE);
881 sleep_mode(); 1084 sleep_mode();
882 } 1085 }
883 1086
884 static void 1087 static void
885 adc_generic(uint8_t admux, uint8_t *ret_num, uint16_t *ret_sum)
886 {
887 PRR &= ~_BV(PRADC);
888
889 // /16 prescaler
890 ADCSRA = _BV(ADEN) | _BV(ADPS2);
891
892 // set to measure 1.1 reference
893 ADMUX = admux;
894
895 // delay after setting reference etc, allow settling
896 long_delay(300);
897 // average a number of samples
898 uint16_t sum = 0;
899 uint8_t num = 0;
900 for (uint8_t n = 0; n < 20; n++)
901 {
902 ADCSRA |= _BV(ADSC);
903 loop_until_bit_is_clear(ADCSRA, ADSC);
904
905 uint8_t low_11 = ADCL;
906 uint8_t high_11 = ADCH;
907 uint16_t val = low_11 + (high_11 << 8);
908
909 if (n >= 4)
910 {
911 sum += val;
912 num++;
913 }
914 }
915 ADCSRA = 0;
916 PRR |= _BV(PRADC);
917
918 *ret_num = num;
919 *ret_sum = sum;
920 }
921
922 static uint16_t
923 adc_vcc()
924 {
925 const uint8_t mux = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
926 uint16_t sum;
927 uint8_t num;
928
929 adc_generic(mux, &num, &sum);
930
931 //float res_volts = 1.1 * 1024 * num / sum;
932 //return 1000 * res_volts;
933 return ((uint32_t)1100*1024*num) / sum;
934 }
935
936 #define SCALER_5V 2
937
938 static uint16_t
939 adc_5v(uint16_t vcc)
940 {
941 // set to measure ADC4 against AVCC
942 const uint8_t mux = _BV(REFS0) | _BV(MUX2);
943 uint16_t sum;
944 uint8_t num;
945
946 adc_generic(mux, &num, &sum);
947
948 return ((uint32_t)vcc*sum*SCALER_5V/(num*1024));
949 }
950
951 static uint16_t
952 adc_temp()
953 {
954 // set to measure temperature against 1.1v reference.
955 const uint8_t mux = _BV(REFS0) | _BV(REFS1) | _BV(MUX3);
956 uint16_t sum;
957 uint8_t num;
958
959 adc_generic(mux, &num, &sum);
960
961 // return the voltage
962
963 return ((uint32_t)1100*sum) / (num*1024);
964 }
965
966 static void
967 reboot_pi() 1088 reboot_pi()
968 { 1089 {
969 printf_P(PSTR("Real reboot now\n")); 1090 printf_P(PSTR("Real reboot now\n"));
970 // pull it low for 200ms 1091 // pull it low for 200ms
971 PORT_PI_RESET &= ~_BV(PIN_PI_RESET); 1092 PORT_PI_RESET &= ~_BV(PIN_PI_RESET);
972 DDR_PI_RESET |= _BV(PIN_PI_RESET); 1093 DDR_PI_RESET |= _BV(PIN_PI_RESET);
973 _delay_ms(200); 1094 _delay_ms(200);
974 1095
975 PORT_PI_WARNING &= ~_BV(PIN_PI_WARNING); 1096 PORT_PI_WARNING &= ~_BV(PIN_PI_WARNING);
976 DDR_PI_RESET &= ~_BV(PIN_PI_RESET); 1097 DDR_PI_RESET &= ~_BV(PIN_PI_RESET);
977
978 hmac_file("stuff");
979 } 1098 }
980 1099
981 static void 1100 static void
982 wait_reboot_pi() 1101 wait_reboot_pi()
983 { 1102 {