bigint_io.c 3.3 KB

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