]> git.cryptolib.org Git - arm-crypto-lib.git/blob - rsa/rsassa_pkcs1v15.c
improving present
[arm-crypto-lib.git] / rsa / rsassa_pkcs1v15.c
1 /* rsassa_pkcs1v15.c */
2 /*
3     This file is part of the ARM-Crypto-Lib.
4     Copyright (C) 2006-2012 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 <stdlib.h>
21 #include <stdint.h>
22 #include <string.h>
23 #include "rsa_basic.h"
24 #include "bigint.h"
25 #include "rsassa_pkcs1v15.h"
26
27 #include "cli.h"
28
29 const uint8_t md5_prefix[] =
30 { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,
31   0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00,
32   0x04, 0x10
33 };
34
35 const pkcs1v15_algo_prefix_t pkcs1v15_md5_prefix = {
36         18, md5_prefix
37 };
38
39 const uint8_t sha1_prefix[] =
40 { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e,
41   0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14
42 };
43
44 const pkcs1v15_algo_prefix_t pkcs1v15_sha1_prefix = {
45         15, sha1_prefix
46 };
47
48 const uint8_t sha224_prefix[] =
49 { 0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
50   0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05,
51   0x00, 0x04, 0x1c
52 };
53
54 const pkcs1v15_algo_prefix_t pkcs1v15_sha224_prefix = {
55         19, sha224_prefix
56 };
57
58 const uint8_t sha256_prefix[] =
59 { 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
60   0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
61   0x00, 0x04, 0x20
62 };
63
64 const pkcs1v15_algo_prefix_t pkcs1v15_sha256_prefix = {
65         19, sha256_prefix
66 };
67
68 const uint8_t sha384_prefix[] =
69 { 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
70   0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05,
71   0x00, 0x04, 0x30
72 };
73
74 const pkcs1v15_algo_prefix_t pkcs1v15_sha384_prefix = {
75         19, sha384_prefix
76 };
77
78 const uint8_t sha512_prefix[] =
79 { 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
80   0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
81   0x00, 0x04, 0x40
82 };
83
84 const pkcs1v15_algo_prefix_t pkcs1v15_sha512_prefix = {
85         19, sha512_prefix
86 };
87 /*
88
89 MD2:     (0x)30 20 30 0c 06 08 2a 86 48 86 f7 0d 02 02 05 00 04 10
90 MD5:     (0x)30 20 30 0c 06 08 2a 86 48 86 f7 0d 02 05 05 00 04 10
91 SHA-1:   (0x)30 21 30 09 06 05 2b 0e 03 02 1a 05 00 04 14
92 SHA-224: (0x)30 2d 30 0d 06 09 60 86 48 01 65 03 04 02 04 05 00 04 1c
93 SHA-256: (0x)30 51 30 0d 06 09 60 86 48 01 65 03 04 02 01 05 00 04 20
94 SHA-384: (0x)30 51 30 0d 06 09 60 86 48 01 65 03 04 02 02 05 00 04 30
95 SHA-512: (0x)30 51 30 0d 06 09 60 86 48 01 65 03 04 02 03 05 00 04 40
96
97 */
98
99 static
100 uint8_t emsa_pkcs1v15_encode(void* dest, uint16_t dest_length_B, const void* hash,
101                 uint16_t hash_length_B, const pkcs1v15_algo_prefix_t* algo_prefix){
102         uint16_t ps_length;
103
104         if(dest_length_B < algo_prefix->length + hash_length_B + 3 + 8){
105                 return 1;
106         }
107         ps_length = dest_length_B - (algo_prefix->length + hash_length_B + 3);
108         ((uint8_t*)dest)[0] = 0x00;
109         ((uint8_t*)dest)[1] = 0x01;
110         ((uint8_t*)dest)[2 + ps_length] = 0x00;
111         memset((uint8_t*)dest + 2, 0xff, ps_length);
112         memcpy((uint8_t*)dest + 3 + ps_length, algo_prefix->data, algo_prefix->length);
113         memcpy((uint8_t*)dest + 3 + ps_length + algo_prefix->length, hash, hash_length_B);
114         return 0;
115 }
116
117 uint8_t rsa_sign_pkcs1v15(void* dest, uint16_t* out_length_B, const void* hash,
118                 uint16_t hash_length_B, const rsa_privatekey_t* key,
119                 const pkcs1v15_algo_prefix_t* algo_prefix){
120         uint8_t r;
121         uint16_t modulus_length;
122         bigint_t x;
123         modulus_length = bigint_get_first_set_bit(&key->modulus) / 8 + 1;
124         r = emsa_pkcs1v15_encode(dest, modulus_length, hash, hash_length_B, algo_prefix);
125         if(r){
126                 return r;
127         }
128         x.wordv = dest;
129         rsa_os2ip(&x, NULL, modulus_length);
130         rsa_dec(&x, key);
131         rsa_i2osp(NULL, &x, out_length_B);
132
133         return 0;
134 }
135
136
137 uint8_t rsa_verify_pkcs1v15(const void* signature, uint16_t signature_length_B,
138                 const void* hash, uint16_t hash_length_B, const rsa_publickey_t* key,
139                 const pkcs1v15_algo_prefix_t* algo_prefix){
140         uint16_t modulus_length;
141         uint16_t signature_em_length, ps_length;
142         bigint_t x;
143
144         modulus_length = bigint_get_first_set_bit(&key->modulus) / 8 + 1;
145 #if PREFERE_HEAP
146         uint8_t *buffer;
147         buffer = malloc(bigint_length_B(&key->modulus));
148         if(!buffer){
149                 return 0x80;
150         }
151 #else
152         uint8_t buffer[bigint_length_B(&key->modulus)];
153 #endif
154 /*
155         cli_putstr("\r\nDBG: signature_length_B: 0x");
156         cli_hexdump_rev(&signature_length_B, 2);
157         cli_putstr("\r\nDBG: modulus_length_B: 0x");
158         cli_hexdump_rev(&modulus_length, 2);
159 */
160         x.wordv = (bigint_word_t*)buffer;
161         rsa_os2ip(&x, signature, signature_length_B);
162         rsa_enc(&x, key);
163         rsa_i2osp(NULL, &x, &signature_em_length);
164 /*
165         cli_putstr("\r\nDBG: signature_em_length_B: 0x");
166         cli_hexdump_rev(&signature_em_length, 2);
167 */
168         if(signature_em_length + 1 != modulus_length){
169                 return 1;
170         }
171         if(memcmp(buffer + modulus_length - hash_length_B - 1, hash, hash_length_B)){
172                 return 2;
173         }
174         ps_length = modulus_length - (algo_prefix->length + hash_length_B + 3);
175         if((int16_t)ps_length < 8){
176                 return 3;
177         }
178         if(memcmp(buffer + 2 + ps_length, algo_prefix->data, algo_prefix->length)){
179                 return 4;
180         }
181         if(buffer[0] != 1){
182                 return 6;
183         }
184         if(buffer[1 + ps_length] != 0){
185                 return 7;
186         }
187         do{
188                 if(buffer[ps_length] != 0xff){
189                         return 8;
190                 }
191         }while(--ps_length);
192 #if PREFERE_HEAP
193         free(buffer);
194 #endif
195
196         return 0;
197 }