/* 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 "bigint.h" #include #include void bigint_print_hex(const bigint_t* a){ if(a->length_B==0){ cli_putc('0'); return; } if(a->info&BIGINT_NEG_MASK){ cli_putc('-'); } // cli_putc((a->info&BIGINT_NEG_MASK)?'-':'+'); /* print sign */ /* if(a->wordv[a->length_B-1]<0x10){ cli_putc(hexdigit_tab_uc[a->wordv[a->length_B-1]]); cli_hexdump_rev(a->wordv, a->length_B-1); } else { */ // cli_hexdump_rev(a->wordv, a->length_B*sizeof(bigint_word_t)); // } uint32_t idx; uint8_t print_zero=0; uint8_t *p,x,y; p = (uint8_t*)&(a->wordv[a->length_B-1])+sizeof(bigint_word_t)-1; for(idx=a->length_B*sizeof(bigint_word_t); idx>0; --idx){ x = *p >> 4; y = *p & 0xf; if(x!=0 || print_zero!=0){ cli_putc(hexdigit_tab_lc[x]); } if(x){ print_zero = 1; } if(y!=0 || print_zero!=0){ cli_putc(hexdigit_tab_lc[y]); } if(y){ print_zero = 1; } --p; } } #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){ uint16_t allocated=0; uint8_t shift4=0; uint16_t t; a->length_B = 0; a->wordv = NULL; a->info = 0; for(;;){ if(allocated-a->length_B < 1){ bigint_word_t *p; p = realloc(a->wordv, allocated+=BLOCKSIZE); if(p==NULL){ cli_putstr("\r\nERROR: Out of memory!"); free(a->wordv); return 0xff; } memset((uint8_t*)p+allocated-BLOCKSIZE, 0, BLOCKSIZE); a->wordv=p; } t = read_byte(); if(a->length_B==0){ if(t&0x0400){ /* got minus */ a->info |= BIGINT_NEG_MASK; continue; }else{ if(t==0x0100){ free(a->wordv); a->wordv=NULL; return 1; } } } if(t<=0x00ff){ ((uint8_t*)(a->wordv))[a->length_B++] = (uint8_t)t; }else{ if(t&0x0200){ shift4 = 1; ((uint8_t*)(a->wordv))[a->length_B++] = (uint8_t)((t&0x0f)<<4); } break; } } /* we have to reverse the byte array */ uint8_t tmp; uint8_t *p, *q; p = (uint8_t*)(a->wordv); q = (uint8_t*)a->wordv+a->length_B-1; while(q>p){ tmp = *p; *p = *q; *q = tmp; p++; q--; } a->length_B = (a->length_B+sizeof(bigint_word_t)-1)/sizeof(bigint_word_t); if(shift4){ bigint_adjust(a); bigint_shiftright(a, 4); }else{ bigint_adjust(a); } return 0; }