X-Git-Url: https://git.cryptolib.org/?p=avr-crypto-lib.git;a=blobdiff_plain;f=bigint2%2Fbigint2_io.c;fp=bigint2%2Fbigint2_io.c;h=f347688371bbe8249df3b76ec81b0ac1e2cd4ace;hp=0000000000000000000000000000000000000000;hb=cda2e9d578a68a57f3bd95c3ddbc5db78c7e3b36;hpb=55113fbb49edbc607a5ea5657be14e35296102c4 diff --git a/bigint2/bigint2_io.c b/bigint2/bigint2_io.c new file mode 100644 index 0000000..f347688 --- /dev/null +++ b/bigint2/bigint2_io.c @@ -0,0 +1,180 @@ +/* bigint_io.c */ +/* + This file is part of the ARM-Crypto-Lib. + Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de) + + This program 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 3 of the License, or + (at your option) any later version. + + This program 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, see . +*/ + +#include "cli.h" +#include "hexdigit_tab.h" +#include "bigint2.h" +#include +#include +#include + +void bigint_print_hex(const bigint_t *a) { + if (a->length_W == 0) { + putchar('0'); + return; + } + if (a->info & BIGINT_SIGN_MASK) { + putchar('-'); + } + size_t idx; + uint8_t print_zero = 0; + uint8_t *p, x, y; + p = (uint8_t*)&(a->wordv[a->length_W - 1]) + sizeof(bigint_word_t) - 1; + for (idx = a->length_W * sizeof(bigint_word_t); idx > 0; --idx) { + x = *p >> 4; + y = *p & 0xf; + if (x != 0 || print_zero != 0) { + putchar(pgm_read_byte(&hexdigit_tab_lc_P[x])); + } + if (x) { + print_zero = 1; + } + if (y != 0 || print_zero != 0) { + putchar(pgm_read_byte(&hexdigit_tab_lc_P[y])); + } + if (y) { + print_zero = 1; + } + --p; + } + if (!print_zero) { + putchar(pgm_read_byte(&hexdigit_tab_lc_P[0])); + } +} + +#define BLOCKSIZE 32 + +static uint8_t char2nibble(char c) { + if (c >= '0' && c <= '9') { + return c - '0'; + } + c |= 'A' ^ 'a'; /* to lower case */ + if ( c >= 'a' && c <= 'f') { + return c - 'a' + 10; + } + return 0xff; +} + +static uint16_t read_byte(void) { + uint8_t t1, t2; + char c; + c = cli_getc_cecho(); + if (c == '-') { + return 0x0500; + } + t1 = char2nibble(c); + if (t1 == 0xff) { + return 0x0100; + } + c = cli_getc_cecho(); + t2 = char2nibble(c); + if (t2 == 0xff) { + return 0x0200|t1; + } + return (t1 << 4)|t2; +} + +uint8_t bigint_read_hex_echo(bigint_t *a, bigint_length_t length) { + uint8_t shift4 = 0; + uint16_t t, idx = 0; + uint8_t *buf = NULL; + memset(a, 0, sizeof(*a)); + if (length && a->allocated_W < length) { + uint8_t *p; + p = int_realloc(buf, length * sizeof(bigint_word_t)); + if (p == NULL) { + cli_putstr("\r\nERROR: Out of memory!"); + return 0xff; + } + memset((uint8_t*)p, 0, length * sizeof(bigint_word_t)); + buf = p; + a->allocated_W = length; + } + for (;;) { + if (a->allocated_W - idx < 1) { + uint8_t *p; + if (length) { + if (buf) { + int_realloc(buf, 0); + } + return 0xfe; + } + p = int_realloc(buf, (a->allocated_W += BLOCKSIZE) * sizeof(bigint_word_t)); + if (p == NULL) { + cli_putstr("\r\nERROR: Out of memory!"); + if (buf) { + int_realloc(buf, 0); + } + return 0xff; + } + memset((uint8_t*)p + (a->allocated_W - BLOCKSIZE) * sizeof(bigint_word_t), 0, BLOCKSIZE * sizeof(bigint_word_t)); + buf = p; + } + t = read_byte(); + if (idx == 0) { + if (t & 0x0400) { + /* got minus */ + a->info |= BIGINT_SIGN_MASK; + continue; + } else { + if (t == 0x0100) { + free(a->wordv); + memset(a, 0, sizeof(*a)); + return 1; + } + } + } + if (t <= 0x00ff) { + buf[idx++] = (uint8_t)t; + } else { + if (t & 0x0200) { + shift4 = 1; + buf[idx++] = (uint8_t)((t & 0x0f) << 4); + } + break; + } + } + /* we have to reverse the byte array */ + uint8_t tmp; + uint8_t *p, *q; + a->length_W = (idx + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t); + p = buf; + q = buf + idx - 1; + while (q > p) { + tmp = *p; + *p = *q; + *q = tmp; + p++; q--; + } + a->wordv = (bigint_word_t*)buf; + if (shift4) { + bigint_shiftright_1bit(a); + bigint_shiftright_1bit(a); + bigint_shiftright_1bit(a); + bigint_shiftright_1bit(a); + } + if(a->length_W == 1 && a->wordv[0] == 0){ + a->length_W = 0; + a->info = 0; + } + if (length) { + a->length_W = length; + } + return 0; +}