]> git.cryptolib.org Git - avr-crypto-lib.git/blob - rsa/rsa_basic.c
fixing E-Mail-Address & Copyright
[avr-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-2015 Daniel Otte (bg@nerilex.org)
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 <stdio.h>
32 #endif
33
34 void rsa_enc(bigint_t *data, const rsa_publickey_t *key){
35 /*
36         cli_putstr_P(PSTR("\r\n -->rsa_enc()\r\n m = "));
37         bigint_print_hex(data);
38         cli_putstr_P(PSTR("\r\n e = "));
39         bigint_print_hex(key->exponent);
40         cli_putstr_P(PSTR("\r\n n = "));
41         bigint_print_hex(key->modulus);
42 */
43         bigint_expmod_u(data, data, &key->exponent, &key->modulus);
44 }
45
46 /*
47 (p,q,dp,dq,qinv)
48 m1 = c**dp % p
49 m2 = c**dq % q
50 h = (m1 - m2) * qinv % p
51 m = m2 + q * h
52 */
53
54 uint8_t rsa_dec_crt_mono(bigint_t *data, const rsa_privatekey_t *key){
55         bigint_t m1, m2;
56         m1.wordv = malloc((key->components[0].length_W /* + 1 */) * sizeof(bigint_word_t));
57         m2.wordv = malloc((key->components[1].length_W /* + 1 */) * sizeof(bigint_word_t));
58         if(!m1.wordv || !m2.wordv){
59 #if DEBUG
60                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
61 #endif
62                 free(m1.wordv);
63                 free(m2.wordv);
64                 return 1;
65         }
66 #if DEBUG
67         cli_putstr_P(PSTR("\r\nDBG: expmod m1 ..."));
68         cli_putstr_P(PSTR("\r\nexpmod("));
69         bigint_print_hex(data);
70         cli_putc(',');
71         bigint_print_hex(&(key->components[2]));
72         cli_putc(',');
73         bigint_print_hex(&(key->components[0]));
74         cli_putstr_P(PSTR(") = "));
75 #endif
76         bigint_expmod_u(&m1, data, &(key->components[2]), &(key->components[0]));
77 #if DEBUG
78         bigint_print_hex(&m1);
79         cli_putstr_P(PSTR("expmod m2 ..."));
80         cli_putstr_P(PSTR("\r\nexpmod("));
81         bigint_print_hex(data);
82         cli_putc(',');
83         bigint_print_hex(&(key->components[3]));
84         cli_putc(',');
85         bigint_print_hex(&(key->components[1]));
86         cli_putstr_P(PSTR(") = "));
87 #endif
88         bigint_expmod_u(&m2, data, &(key->components[3]), &(key->components[1]));
89 #if DEBUG
90         bigint_print_hex(&m2);
91         cli_putstr_P(PSTR("\r\nDBG: sub ..."));
92         cli_putstr_P(PSTR("\r\nsub("));
93         bigint_print_hex(&m1);
94         cli_putc(',');
95         bigint_print_hex(&m2);
96         cli_putstr_P(PSTR(") = "));
97 #endif
98         bigint_sub_s(&m1, &m1, &m2);
99 #if DEBUG
100         bigint_print_hex(&m1);
101 #endif
102         while(BIGINT_NEG_MASK & m1.info){
103 #if DEBUG
104         cli_putstr_P(PSTR("\r\nDBG: adding "));
105         bigint_print_hex(&key->components[0]);
106         cli_putstr_P(PSTR("\r\nDBG: to "));
107         bigint_print_hex(&m1);
108 #endif
109                 bigint_add_s(&m1, &m1, &(key->components[0]));
110         }
111 #if DEBUG
112         cli_putstr_P(PSTR("\r\nDBG: reduce-mul ..."));
113         cli_putstr_P(PSTR("\r\nreduce("));
114         bigint_print_hex(&m1);
115         cli_putc(',');
116         bigint_print_hex(&(key->components[0]));
117         cli_putstr_P(PSTR(") = "));
118 #endif
119         bigint_reduce(&m1, &(key->components[0]));
120 #if DEBUG
121         bigint_print_hex(&m1);
122         cli_putstr_P(PSTR("\r\nmul("));
123         bigint_print_hex(&m1);
124         cli_putc(',');
125         bigint_print_hex(&(key->components[4]));
126         cli_putstr_P(PSTR(") = "));
127 #endif
128         bigint_mul_u(data, &m1, &(key->components[4]));
129 #if DEBUG
130         bigint_print_hex(data);
131         cli_putstr_P(PSTR("\r\nreduce("));
132         bigint_print_hex(data);
133         cli_putc(',');
134         bigint_print_hex(&(key->components[0]));
135         cli_putstr_P(PSTR(") = "));
136 #endif
137         bigint_reduce(data, &(key->components[0]));
138 #if DEBUG
139         bigint_print_hex(data);
140         cli_putstr_P(PSTR("\r\nmul("));
141         bigint_print_hex(data);
142         cli_putc(',');
143         bigint_print_hex(&(key->components[1]));
144         cli_putstr_P(PSTR(") = "));
145 #endif
146         bigint_mul_u(data, data, &(key->components[1]));
147 #if DEBUG
148         bigint_print_hex(data);
149         cli_putstr_P(PSTR("\r\nadd("));
150         bigint_print_hex(data);
151         cli_putc(',');
152         bigint_print_hex(&m2);
153         cli_putstr_P(PSTR(") = "));
154 #endif
155         bigint_add_u(data, data, &m2);
156 #if DEBUG
157         bigint_print_hex(data);
158 #endif
159         free(m2.wordv);
160         free(m1.wordv);
161         return 0;
162 }
163
164 uint8_t rsa_dec(bigint_t *data, const rsa_privatekey_t *key){
165         if(key->n == 1){
166                 bigint_expmod_u(data, data, &(key->components[0]), &key->modulus);
167                 return 0;
168         }
169         if(key->n == 5){
170                 if (rsa_dec_crt_mono(data, key)){
171                         return 3;
172                 }
173                 return 0;
174         }
175         if(key->n<8 || (key->n-5)%3 != 0){
176                 return 1;
177         }
178         //rsa_dec_crt_multi(data, key, (key->n-5)/3);
179         return 2;
180 }
181
182 void rsa_os2ip(bigint_t *dest, const void *data, uint32_t length_B){
183 #if BIGINT_WORD_SIZE == 8
184         if(data){
185                 memcpy(dest->wordv, data, length_B);
186         }
187         dest->length_W = length_B;
188 #else
189         uint8_t off;
190         off = (sizeof(bigint_word_t) - length_B % sizeof(bigint_word_t)) % sizeof(bigint_word_t);
191 #if DEBUG
192         printf("\r\nDBG: off = 0x%02x", off);
193 #endif
194         if (!data) {
195                 if (off) {
196                         dest->wordv = realloc(dest->wordv, length_B + sizeof(bigint_word_t) - off);
197                         memmove((uint8_t*)dest->wordv + off, dest->wordv, length_B);
198                         memset(dest->wordv, 0, off);
199                 }
200         }else{
201                 memcpy((uint8_t*)dest->wordv + off, data, length_B);
202                 if(off){
203                         memset(dest->wordv, 0, off);
204                 }
205         }
206         dest->length_W = (length_B + off) / sizeof(bigint_word_t);
207 #if DEBUG
208         printf("\r\nDBG: dest->length_W = %u", dest->length_W);
209 #endif
210 #endif
211         dest->info = 0;
212         bigint_changeendianess(dest);
213         bigint_adjust(dest);
214 }
215
216 void rsa_i2osp(void *dest, bigint_t *src, uint16_t *out_length_B){
217 #if BIGINT_WORD_SIZE == 8
218         if(dest){
219                 uint8_t *e = src->wordv + src->length_W;
220                 uint16_t i;
221                 for(i=src->length_W; i>0; --i){
222                         *((uint8_t*)dest) = *--e;
223                         dest = (uint8_t*)dest + 1;
224                 }
225         }else{
226                 bigint_changeendianess(src);
227         }
228
229         *out_length_B = src->length_W;
230 #else
231         *out_length_B = bigint_get_first_set_bit(src) / 8 + 1;
232         if(dest){
233                 uint16_t i;
234                 for(i=*out_length_B; i>0; --i){
235                         *((uint8_t*)dest) = ((uint8_t*)src->wordv)[i-1];
236                         dest = (uint8_t*)dest + 1;
237                 }
238         }else{
239                 uint8_t off;
240                 bigint_changeendianess(src);
241                 bigint_adjust(src);
242
243                 off = bigint_get_last_set_bit(src)/8;
244                 if(off){
245                         memmove(src->wordv, (uint8_t*)src->wordv+off, *out_length_B);
246                 }
247         }
248 #endif
249 }
250