always enable keygen
[gnuk/gnuk.git] / src / call-rsa.c
1 /*
2  * call-rsa.c -- Glue code between RSA computation and OpenPGP card protocol
3  *
4  * Copyright (C) 2010, 2011, 2012, 2013, 2014
5  *               Free Software Initiative of Japan
6  * Author: NIIBE Yutaka <gniibe@fsij.org>
7  *
8  * This file is a part of Gnuk, a GnuPG USB Token implementation.
9  *
10  * Gnuk is free software: you can redistribute it and/or modify it
11  * under the terms of the GNU General Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * Gnuk is distributed in the hope that it will be useful, but WITHOUT
16  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
18  * License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22  *
23  */
24
25 #include <stdint.h>
26 #include <string.h>
27 #include <stdlib.h>
28 #include "config.h"
29
30 #include "gnuk.h"
31 #include "openpgp.h"
32 #include "random.h"
33 #include "polarssl/config.h"
34 #include "polarssl/rsa.h"
35
36 static rsa_context rsa_ctx;
37
38 int
39 rsa_sign (const uint8_t *raw_message, uint8_t *output, int msg_len,
40           struct key_data *kd, int pubkey_len)
41 {
42   mpi P1, Q1, H;
43   int ret = 0;
44   unsigned char temp[pubkey_len];
45
46   rsa_init (&rsa_ctx, RSA_PKCS_V15, 0);
47
48   mpi_init (&P1);  mpi_init (&Q1);  mpi_init (&H);
49
50   rsa_ctx.len = pubkey_len;
51   MPI_CHK( mpi_lset (&rsa_ctx.E, 0x10001) );
52   MPI_CHK( mpi_read_binary (&rsa_ctx.P, &kd->data[0], pubkey_len / 2) );
53   MPI_CHK( mpi_read_binary (&rsa_ctx.Q, &kd->data[pubkey_len / 2],
54                             pubkey_len / 2) );
55 #if 0
56   MPI_CHK( mpi_mul_mpi (&rsa_ctx.N, &rsa_ctx.P, &rsa_ctx.Q) );
57 #endif
58   MPI_CHK( mpi_sub_int (&P1, &rsa_ctx.P, 1) );
59   MPI_CHK( mpi_sub_int (&Q1, &rsa_ctx.Q, 1) );
60   MPI_CHK( mpi_mul_mpi (&H, &P1, &Q1) );
61   MPI_CHK( mpi_inv_mod (&rsa_ctx.D , &rsa_ctx.E, &H) );
62   MPI_CHK( mpi_mod_mpi (&rsa_ctx.DP, &rsa_ctx.D, &P1) );
63   MPI_CHK( mpi_mod_mpi (&rsa_ctx.DQ, &rsa_ctx.D, &Q1) );
64   MPI_CHK( mpi_inv_mod (&rsa_ctx.QP, &rsa_ctx.Q, &rsa_ctx.P) );
65  cleanup:
66   mpi_free (&P1);  mpi_free (&Q1);  mpi_free (&H);
67   if (ret == 0)
68     {
69       DEBUG_INFO ("RSA sign...");
70
71       ret = rsa_rsassa_pkcs1_v15_sign (&rsa_ctx, NULL, NULL,
72                                        RSA_PRIVATE, SIG_RSA_RAW,
73                                        msg_len, raw_message, temp);
74       memcpy (output, temp, pubkey_len);
75     }
76
77   rsa_free (&rsa_ctx);
78   if (ret != 0)
79     {
80       DEBUG_INFO ("fail:");
81       DEBUG_SHORT (ret);
82       return -1;
83     }
84   else
85     {
86       DEBUG_INFO ("done.\r\n");
87       GPG_SUCCESS ();
88       return 0;
89     }
90 }
91
92 /*
93  * LEN: length in byte
94  */
95 uint8_t *
96 modulus_calc (const uint8_t *p, int len)
97 {
98   mpi P, Q, N;
99   uint8_t *modulus;
100   int ret;
101
102   modulus = malloc (len);
103   if (modulus == NULL)
104     return NULL;
105
106   mpi_init (&P);  mpi_init (&Q);  mpi_init (&N);
107   MPI_CHK( mpi_read_binary (&P, p, len / 2) );
108   MPI_CHK( mpi_read_binary (&Q, p + len / 2, len / 2) );
109   MPI_CHK( mpi_mul_mpi (&N, &P, &Q) );
110   MPI_CHK( mpi_write_binary (&N, modulus, len) );
111  cleanup:
112   mpi_free (&P);  mpi_free (&Q);  mpi_free (&N);
113   if (ret != 0)
114     return NULL;
115   else
116     return modulus;
117 }
118
119
120 int
121 rsa_decrypt (const uint8_t *input, uint8_t *output, int msg_len,
122              struct key_data *kd, unsigned int *output_len_p)
123 {
124   mpi P1, Q1, H;
125   int ret;
126
127   DEBUG_INFO ("RSA decrypt:");
128   DEBUG_WORD ((uint32_t)&ret);
129
130   rsa_init (&rsa_ctx, RSA_PKCS_V15, 0);
131   mpi_init (&P1);  mpi_init (&Q1);  mpi_init (&H);
132
133   rsa_ctx.len = msg_len;
134   DEBUG_WORD (msg_len);
135
136   MPI_CHK( mpi_lset (&rsa_ctx.E, 0x10001) );
137   MPI_CHK( mpi_read_binary (&rsa_ctx.P, &kd->data[0], msg_len / 2) );
138   MPI_CHK( mpi_read_binary (&rsa_ctx.Q, &kd->data[msg_len / 2], msg_len / 2) );
139 #if 0
140   MPI_CHK( mpi_mul_mpi (&rsa_ctx.N, &rsa_ctx.P, &rsa_ctx.Q) );
141 #endif
142   MPI_CHK( mpi_sub_int (&P1, &rsa_ctx.P, 1) );
143   MPI_CHK( mpi_sub_int (&Q1, &rsa_ctx.Q, 1) );
144   MPI_CHK( mpi_mul_mpi (&H, &P1, &Q1) );
145   MPI_CHK( mpi_inv_mod (&rsa_ctx.D , &rsa_ctx.E, &H) );
146   MPI_CHK( mpi_mod_mpi (&rsa_ctx.DP, &rsa_ctx.D, &P1) );
147   MPI_CHK( mpi_mod_mpi (&rsa_ctx.DQ, &rsa_ctx.D, &Q1) );
148   MPI_CHK( mpi_inv_mod (&rsa_ctx.QP, &rsa_ctx.Q, &rsa_ctx.P) );
149  cleanup:
150   mpi_free (&P1);  mpi_free (&Q1);  mpi_free (&H);
151   if (ret == 0)
152     {
153       DEBUG_INFO ("RSA decrypt ...");
154       ret = rsa_rsaes_pkcs1_v15_decrypt (&rsa_ctx, NULL, NULL,
155                                          RSA_PRIVATE, output_len_p, input,
156                                          output, MAX_RES_APDU_DATA_SIZE);
157     }
158
159   rsa_free (&rsa_ctx);
160   if (ret != 0)
161     {
162       DEBUG_INFO ("fail:");
163       DEBUG_SHORT (ret);
164       return -1;
165     }
166   else
167     {
168       DEBUG_INFO ("done.\r\n");
169       GPG_SUCCESS ();
170       return 0;
171     }
172 }
173
174 int
175 rsa_verify (const uint8_t *pubkey, int pubkey_len,
176             const uint8_t *hash, const uint8_t *sig)
177 {
178   int ret;
179
180   rsa_init (&rsa_ctx, RSA_PKCS_V15, 0);
181   rsa_ctx.len = pubkey_len;
182   MPI_CHK( mpi_lset (&rsa_ctx.E, 0x10001) );
183   MPI_CHK( mpi_read_binary (&rsa_ctx.N, pubkey, pubkey_len) );
184
185   DEBUG_INFO ("RSA verify...");
186
187   MPI_CHK( rsa_rsassa_pkcs1_v15_verify (&rsa_ctx, NULL, NULL,
188                                         RSA_PUBLIC, SIG_RSA_SHA256, 32,
189                                         hash, sig) );
190  cleanup:
191   rsa_free (&rsa_ctx);
192   if (ret != 0)
193     {
194       DEBUG_INFO ("fail:");
195       DEBUG_SHORT (ret);
196       return -1;
197     }
198   else
199     {
200       DEBUG_INFO ("verified.\r\n");
201       return 0;
202     }
203 }
204
205 #define RSA_EXPONENT 0x10001
206
207 uint8_t *
208 rsa_genkey (int pubkey_len)
209 {
210   int ret;
211   uint8_t index = 0;
212   uint8_t *p_q_modulus = (uint8_t *)malloc (pubkey_len * 2);
213   uint8_t *p = p_q_modulus;
214   uint8_t *q = p_q_modulus + pubkey_len / 2;
215   uint8_t *modulus = p_q_modulus + pubkey_len;
216   extern int prng_seed (int (*f_rng)(void *, unsigned char *, size_t),
217                         void *p_rng);
218   extern void neug_flush (void);
219
220   if (p_q_modulus == NULL)
221     return NULL;
222
223   neug_flush ();
224   prng_seed (random_gen, &index);
225
226   rsa_init (&rsa_ctx, RSA_PKCS_V15, 0);
227   MPI_CHK( rsa_gen_key (&rsa_ctx, random_gen, &index, pubkey_len * 8,
228                         RSA_EXPONENT) );
229   if (ret != 0)
230     {
231       free (p_q_modulus);
232       rsa_free (&rsa_ctx);
233       return NULL;
234     }
235
236   MPI_CHK( mpi_write_binary (&rsa_ctx.P, p, pubkey_len / 2) );
237   MPI_CHK( mpi_write_binary (&rsa_ctx.Q, q, pubkey_len / 2) );
238   MPI_CHK( mpi_write_binary (&rsa_ctx.N, modulus, pubkey_len) );
239
240  cleanup:
241   rsa_free (&rsa_ctx);
242   if (ret != 0)
243       return NULL;
244   else
245     return p_q_modulus;
246 }