]> git.cryptolib.org Git - avr-crypto-lib.git/blob - bigint2/bigint2_io.c
f347688371bbe8249df3b76ec81b0ac1e2cd4ace
[avr-crypto-lib.git] / bigint2 / bigint2_io.c
1 /* bigint_io.c */
2 /*
3     This file is part of the ARM-Crypto-Lib.
4     Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de)
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 "bigint2.h"
23 #include <stdlib.h>
24 #include <string.h>
25 #include <stdio.h>
26
27 void bigint_print_hex(const bigint_t *a) {
28         if (a->length_W == 0) {
29                 putchar('0');
30                 return;
31         }
32         if (a->info & BIGINT_SIGN_MASK) {
33                 putchar('-');
34         }
35         size_t idx;
36         uint8_t print_zero = 0;
37         uint8_t *p, x, y;
38         p = (uint8_t*)&(a->wordv[a->length_W - 1]) + sizeof(bigint_word_t) - 1;
39         for (idx = a->length_W * sizeof(bigint_word_t); idx > 0; --idx) {
40                 x = *p >> 4;
41                 y = *p & 0xf;
42                 if (x != 0 || print_zero != 0) {
43                         putchar(pgm_read_byte(&hexdigit_tab_lc_P[x]));
44                 }
45                 if (x) {
46                         print_zero = 1;
47                 }
48                 if (y != 0 || print_zero != 0) {
49                         putchar(pgm_read_byte(&hexdigit_tab_lc_P[y]));
50                 }
51                 if (y) {
52                         print_zero = 1;
53                 }
54                 --p;
55         }
56         if (!print_zero) {
57             putchar(pgm_read_byte(&hexdigit_tab_lc_P[0]));
58         }
59 }
60
61 #define BLOCKSIZE 32
62
63 static uint8_t char2nibble(char c) {
64         if (c >= '0' && c <= '9') {
65                 return c - '0';
66         }
67         c |= 'A' ^ 'a'; /* to lower case */
68         if ( c >= 'a' && c <= 'f') {
69                 return c - 'a' + 10;
70         }
71         return 0xff;
72 }
73
74 static uint16_t read_byte(void) {
75         uint8_t t1, t2;
76         char c;
77         c = cli_getc_cecho();
78         if (c == '-') {
79                 return 0x0500;
80         }
81         t1 = char2nibble(c);
82         if (t1 == 0xff) {
83                 return 0x0100;
84         }
85         c = cli_getc_cecho();
86         t2 = char2nibble(c);
87         if (t2 == 0xff) {
88                 return 0x0200|t1;
89         }
90         return (t1 << 4)|t2;
91 }
92
93 uint8_t bigint_read_hex_echo(bigint_t *a, bigint_length_t length) {
94         uint8_t  shift4 = 0;
95         uint16_t  t, idx = 0;
96         uint8_t *buf = NULL;
97         memset(a, 0, sizeof(*a));
98         if (length && a->allocated_W < length) {
99             uint8_t *p;
100         p = int_realloc(buf, length * sizeof(bigint_word_t));
101         if (p == NULL) {
102             cli_putstr("\r\nERROR: Out of memory!");
103             return 0xff;
104         }
105         memset((uint8_t*)p, 0, length * sizeof(bigint_word_t));
106         buf = p;
107         a->allocated_W = length;
108         }
109         for (;;) {
110                 if (a->allocated_W - idx < 1) {
111                         uint8_t *p;
112                         if (length) {
113                 if (buf) {
114                     int_realloc(buf, 0);
115                 }
116                             return 0xfe;
117                         }
118                         p = int_realloc(buf, (a->allocated_W += BLOCKSIZE) * sizeof(bigint_word_t));
119                         if (p == NULL) {
120                                 cli_putstr("\r\nERROR: Out of memory!");
121                                 if (buf) {
122                                     int_realloc(buf, 0);
123                                 }
124                                 return 0xff;
125                         }
126                         memset((uint8_t*)p + (a->allocated_W - BLOCKSIZE) * sizeof(bigint_word_t), 0, BLOCKSIZE * sizeof(bigint_word_t));
127                         buf = p;
128                 }
129                 t = read_byte();
130                 if (idx == 0) {
131                         if (t & 0x0400) {
132                                 /* got minus */
133                                 a->info |= BIGINT_SIGN_MASK;
134                                 continue;
135                         } else {
136                                 if (t == 0x0100) {
137                                         free(a->wordv);
138                                         memset(a, 0, sizeof(*a));
139                                         return 1;
140                                 }
141                         }
142                 }
143                 if (t <= 0x00ff) {
144                         buf[idx++] = (uint8_t)t;
145                 } else {
146                         if (t & 0x0200) {
147                                 shift4 = 1;
148                                 buf[idx++] = (uint8_t)((t & 0x0f) << 4);
149                         }
150                         break;
151                 }
152         }
153         /* we have to reverse the byte array */
154         uint8_t tmp;
155         uint8_t *p, *q;
156         a->length_W = (idx + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t);
157         p = buf;
158         q = buf + idx - 1;
159         while (q > p) {
160                 tmp = *p;
161                 *p = *q;
162                 *q = tmp;
163                 p++; q--;
164         }
165         a->wordv = (bigint_word_t*)buf;
166         if (shift4) {
167                 bigint_shiftright_1bit(a);
168         bigint_shiftright_1bit(a);
169         bigint_shiftright_1bit(a);
170         bigint_shiftright_1bit(a);
171         }
172         if(a->length_W == 1 && a->wordv[0] == 0){
173             a->length_W = 0;
174             a->info = 0;
175         }
176         if (length) {
177             a->length_W = length;
178         }
179         return 0;
180 }