]> git.cryptolib.org Git - avr-crypto-lib.git/blob - bigint/bigint_io.c
some style adjustments
[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) 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 "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         a->length_W = 0;
94         a->wordv = NULL;
95         a->info = 0;
96         for (;;) {
97                 if (allocated - idx < 1) {
98                         bigint_word_t *p;
99                         p = realloc(a->wordv, allocated += BLOCKSIZE);
100                         if (p == NULL) {
101                                 cli_putstr("\r\nERROR: Out of memory!");
102                                 free(a->wordv);
103                                 return 0xff;
104                         }
105                         memset((uint8_t*)p + allocated - BLOCKSIZE, 0, BLOCKSIZE);
106                         a->wordv = p;
107                 }
108                 t = read_byte();
109                 if (idx == 0) {
110                         if (t & 0x0400) {
111                                 /* got minus */
112                                 a->info |= BIGINT_NEG_MASK;
113                                 continue;
114                         } else {
115                                 if (t == 0x0100) {
116                                         free(a->wordv);
117                                         a->wordv = NULL;
118                                         return 1;
119                                 }
120                         }
121                 }
122                 if (t <= 0x00ff) {
123                         ((uint8_t*)(a->wordv))[idx++] = (uint8_t)t;
124                 } else {
125                         if (t & 0x0200) {
126                                 shift4 = 1;
127                                 ((uint8_t*)(a->wordv))[idx++] = (uint8_t)((t & 0x0f) << 4);
128                         }
129                         break;
130                 }
131         }
132         /* we have to reverse the byte array */
133         uint8_t tmp;
134         uint8_t *p, *q;
135         a->length_W = (idx + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t);
136         p = (uint8_t*)(a->wordv);
137         q = (uint8_t*)a->wordv + a->length_W * sizeof(bigint_word_t) - 1;
138         while (q > p) {
139                 tmp = *p;
140                 *p = *q;
141                 *q = tmp;
142                 p++; q--;
143         }
144         bigint_adjust(a);
145         if (shift4) {
146                 bigint_shiftright(a, 4);
147         }
148         if(a->length_W == 1 && a->wordv[0] == 0){
149             a->length_W = 0;
150             a->info = 0;
151         }
152         return 0;
153 }