]> git.cryptolib.org Git - arm-crypto-lib.git/blob - rsa/rsa_basic.c
fixing bugs reported by Christian Dernehl
[arm-crypto-lib.git] / rsa / rsa_basic.c
1 /* rsa_basic.c */
2 /*
3     This file is part of the ARM-Crypto-Lib.
4     Copyright (C) 2006-2011 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 <stdint.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include "bigint.h"
24 #include "bigint_io.h"
25 #include "rsa_basic.h"
26
27 #define DEBUG 0
28
29 #if DEBUG
30 #include "cli.h"
31 #include "uart_lowlevel.h"
32 #include "string-extras.h"
33 #endif
34
35 void rsa_enc(bigint_t* data, const rsa_publickey_t* key){
36 /*
37         cli_putstr("\r\n -->rsa_enc()\r\n m = ");
38         bigint_print_hex(data);
39         cli_putstr("\r\n e = ");
40         bigint_print_hex(key->exponent);
41         cli_putstr("\r\n n = ");
42         bigint_print_hex(key->modulus);
43 */
44         bigint_expmod_u(data, data, &key->exponent, &key->modulus);
45 }
46
47 /*
48 (p,q,dp,dq,qinv)
49 m1 = c**dp % p
50 m2 = c**dq % q
51 h = (m1 - m2) * qinv % p
52 m = m2 + q * h
53 */
54
55 uint8_t rsa_dec_crt_mono(bigint_t* data, const rsa_privatekey_t* key){
56         bigint_t m1, m2;
57         m1.wordv = malloc(key->components[0].length_W * sizeof(bigint_word_t));
58         m2.wordv = malloc(key->components[1].length_W * sizeof(bigint_word_t));
59         if(!m1.wordv || !m2.wordv){
60 #if DEBUG
61                 cli_putstr("\r\nERROR: OOM!");
62 #endif
63                 free(m2.wordv);
64                 free(m1.wordv);
65                 return 1;
66         }
67 #if DEBUG
68         cli_putstr("\r\nDBG: expmod m1 ...");
69 #endif
70         bigint_expmod_u(&m1, data, &key->components[2], &key->components[0]);
71 #if DEBUG
72         cli_putstr("expmod m2 ...");
73 #endif
74         bigint_expmod_u(&m2, data, &key->components[3], &key->components[1]);
75         bigint_sub_s(&m1, &m1, &m2);
76         while(BIGINT_NEG_MASK & m1.info){
77                 bigint_add_s(&m1, &m1, &key->components[0]);
78         }
79
80 #if DEBUG
81         cli_putstr("\r\nDBG: reduce-mul ...");
82 #endif
83         bigint_reduce(&m1, &key->components[0]);
84         bigint_mul_u(data, &m1, &key->components[4]);
85         bigint_reduce(data, &key->components[0]);
86         bigint_mul_u(data, data, &key->components[1]);
87         bigint_add_u(data, data, &m2);
88         free(m2.wordv);
89         free(m1.wordv);
90         return 0;
91 }
92
93 uint8_t rsa_dec(bigint_t* data, const rsa_privatekey_t* key){
94         if(key->n == 1){
95                 bigint_expmod_u(data, data, &key->components[0], &key->modulus);
96                 return 0;
97         }
98         if(key->n == 5){
99                 if (rsa_dec_crt_mono(data, key)){
100                         return 3;
101                 }
102                 return 0;
103         }
104         if(key->n<8 || (key->n-5)%3 != 0){
105                 return 1;
106         }
107         //rsa_dec_crt_multi(data, key, (key->n-5)/3);
108         return 2;
109 }
110
111 void rsa_os2ip(bigint_t* dest, const void* data, uint32_t length_B){
112 #if BIGINT_WORD_SIZE == 8
113         if(data){
114                 memcpy(dest->wordv, data, length_B)
115         }
116         dest->length_W = length_B;
117 #else
118         uint8_t off;
119         off = (sizeof(bigint_word_t) - length_B % sizeof(bigint_word_t)) % sizeof(bigint_word_t);
120 #if DEBUG
121         cli_putstr("\r\nDBG: off = 0x");
122         cli_hexdump_byte(off);
123 #endif
124         if(!data){
125                 if(off){
126                         dest->wordv = realloc(dest->wordv, length_B + sizeof(bigint_word_t) - off);
127                         memmove((uint8_t*)dest->wordv+off, dest->wordv, length_B);
128                         memset(dest->wordv, 0, off);
129                 }
130         }else{
131                 memcpy((uint8_t*)dest->wordv + off, data, length_B);
132                 if(off){
133                         memset(dest->wordv, 0, off);
134                 }
135         }
136         dest->length_W = (length_B + off) / sizeof(bigint_word_t);
137 #if DEBUG
138         cli_putstr("\r\nDBG: dest->length_W = 0x");
139         cli_hexdump_rev(&(dest->length_W), 2);
140 #endif
141 #endif
142         dest->info = 0;
143         bigint_changeendianess(dest);
144         bigint_adjust(dest);
145 }
146
147 void rsa_i2osp(void* dest, bigint_t* src, uint16_t* out_length_B){
148 #if BIGINT_WORD_SIZE == 8
149         if(dest){
150                 uint8_t *e = src->wordv + src->length_W;
151                 uint16_t i;
152                 for(i=src->length_W; i>0; --i){
153                         *((uint8_t*)dest) = *--e;
154                         dest = (uint8_t*)dest + 1;
155                 }
156         }else{
157                 bigint_changeendianess(src);
158         }
159
160         *out_length_B = src->length_W;
161 #else
162         *out_length_B = bigint_get_first_set_bit(src) / 8 + 1;
163         if(dest){
164                 uint16_t i;
165                 for(i=*out_length_B; i>0; --i){
166                         *((uint8_t*)dest) = ((uint8_t*)src->wordv)[i-1];
167                         dest = (uint8_t*)dest + 1;
168                 }
169         }else{
170                 uint8_t off;
171                 bigint_changeendianess(src);
172                 bigint_adjust(src);
173
174                 off = bigint_get_last_set_bit(src)/8;
175                 if(off){
176                         memmove(src->wordv, (uint8_t*)src->wordv+off, *out_length_B);
177                 }
178         }
179 #endif
180 }
181