]> git.cryptolib.org Git - avr-crypto-lib.git/blob - bigint/bigint_io.c
fixing E-Mail-Address & Copyright
[avr-crypto-lib.git] / bigint / bigint_io.c
1 /* bigint_io.c */
2 /*
3     This file is part of the ARM-Crypto-Lib.
4     Copyright (C) 2006-2015 Daniel Otte (bg@nerilex.org)
5
6     This program is free software: you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation, either version 3 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "cli.h"
21 #include "hexdigit_tab.h"
22 #include "bigint.h"
23 #include <stdlib.h>
24 #include <string.h>
25
26 void bigint_print_hex(const bigint_t *a) {
27         if (a->length_W == 0) {
28                 cli_putc('0');
29                 return;
30         }
31         if (a->info&BIGINT_NEG_MASK) {
32                 cli_putc('-');
33         }
34         size_t idx;
35         uint8_t print_zero = 0;
36         uint8_t *p, x, y;
37         p = (uint8_t*)&(a->wordv[a->length_W - 1]) + sizeof(bigint_word_t) - 1;
38         for (idx = a->length_W * sizeof(bigint_word_t); idx > 0; --idx) {
39                 x = *p >> 4;
40                 y = *p & 0xf;
41                 if (x != 0 || print_zero != 0) {
42                         cli_putc(pgm_read_byte(&hexdigit_tab_lc_P[x]));
43                 }
44                 if (x) {
45                         print_zero = 1;
46                 }
47                 if (y != 0 || print_zero != 0) {
48                         cli_putc(pgm_read_byte(&hexdigit_tab_lc_P[y]));
49                 }
50                 if (y) {
51                         print_zero = 1;
52                 }
53                 --p;
54         }
55 }
56
57 #define BLOCKSIZE 32
58
59 static uint8_t char2nibble(char c) {
60         if (c >= '0' && c <= '9') {
61                 return c - '0';
62         }
63         c |= 'A' ^ 'a'; /* to lower case */
64         if ( c>= 'a' && c <= 'f') {
65                 return c - 'a' + 10;
66         }
67         return 0xff;
68 }
69
70 static uint16_t read_byte(void) {
71         uint8_t t1, t2;
72         char c;
73         c = cli_getc_cecho();
74         if (c == '-') {
75                 return 0x0500;
76         }
77         t1 = char2nibble(c);
78         if (t1 == 0xff) {
79                 return 0x0100;
80         }
81         c = cli_getc_cecho();
82         t2 = char2nibble(c);
83         if (t2 == 0xff) {
84                 return 0x0200|t1;
85         }
86         return (t1 << 4)|t2;
87 }
88
89 uint8_t bigint_read_hex_echo(bigint_t *a) {
90         uint16_t allocated = 0;
91         uint8_t  shift4 = 0;
92         uint16_t  t, idx = 0;
93         uint8_t *buf = NULL;
94         a->length_W = 0;
95         a->wordv = NULL;
96         a->info = 0;
97         for (;;) {
98                 if (allocated - idx < 1) {
99                         uint8_t *p;
100                         p = realloc(buf, (allocated += BLOCKSIZE) * sizeof(bigint_word_t));
101                         if (p == NULL) {
102                                 cli_putstr("\r\nERROR: Out of memory!");
103                                 free(buf);
104                                 return 0xff;
105                         }
106                         memset((uint8_t*)p + (allocated - BLOCKSIZE) * sizeof(bigint_word_t), 0, BLOCKSIZE * sizeof(bigint_word_t));
107                         buf = p;
108                 }
109                 t = read_byte();
110                 if (idx == 0) {
111                         if (t & 0x0400) {
112                                 /* got minus */
113                                 a->info |= BIGINT_NEG_MASK;
114                                 continue;
115                         } else {
116                                 if (t == 0x0100) {
117                                         free(a->wordv);
118                                         a->wordv = NULL;
119                                         return 1;
120                                 }
121                         }
122                 }
123                 if (t <= 0x00ff) {
124                         buf[idx++] = (uint8_t)t;
125                 } else {
126                         if (t & 0x0200) {
127                                 shift4 = 1;
128                                 buf[idx++] = (uint8_t)((t & 0x0f) << 4);
129                         }
130                         break;
131                 }
132         }
133         /* we have to reverse the byte array */
134         uint8_t tmp;
135         uint8_t *p, *q;
136         a->length_W = (idx + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t);
137         p = buf;
138         q = buf + idx - 1;
139         while (q > p) {
140                 tmp = *p;
141                 *p = *q;
142                 *q = tmp;
143                 p++; q--;
144         }
145         a->wordv = (bigint_word_t*)buf;
146         bigint_adjust(a);
147         if (shift4) {
148                 bigint_shiftright(a, 4);
149         }
150         if(a->length_W == 1 && a->wordv[0] == 0){
151             a->length_W = 0;
152             a->info = 0;
153         }
154         return 0;
155 }