tizen 2.4 release
[external/nettle.git] / rsa-compat.c
1 /* rsa-compat.c
2  *
3  * The RSA publickey algorithm, RSAREF compatible interface.
4  */
5
6 /* nettle, low-level cryptographics library
7  *
8  * Copyright (C) 2001 Niels Möller
9  *  
10  * The nettle library is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU Lesser General Public License as published by
12  * the Free Software Foundation; either version 2.1 of the License, or (at your
13  * option) any later version.
14  * 
15  * The nettle library is distributed in the hope that it will be useful, but
16  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
18  * License for more details.
19  * 
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with the nettle library; see the file COPYING.LIB.  If not, write to
22  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
23  * MA 02111-1301, USA.
24  */
25
26 #if HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #include "rsa-compat.h"
31
32 #include "bignum.h"
33 #include "md5.h"
34
35 int
36 R_SignInit(R_SIGNATURE_CTX *ctx,
37            int digestAlgorithm)
38 {
39   if (digestAlgorithm != DA_MD5)
40     return RE_DIGEST_ALGORITHM;
41
42   md5_init(&ctx->hash);
43
44   return 0;
45 }
46
47 int
48 R_SignUpdate(R_SIGNATURE_CTX *ctx,
49              const uint8_t *data,
50              /* Length is an unsigned char according to rsaref.txt,
51               * but that must be a typo. */
52              unsigned length)
53 {
54   md5_update(&ctx->hash, length, data);
55
56   return RE_SUCCESS;
57 }
58
59 int
60 R_SignFinal(R_SIGNATURE_CTX *ctx,
61             uint8_t *signature,
62             unsigned *length,
63             R_RSA_PRIVATE_KEY *key)
64 {
65   struct rsa_private_key k;
66   int res;
67   
68   nettle_mpz_init_set_str_256_u(k.p,
69                                 MAX_RSA_MODULUS_LEN, key->prime[0]);
70   nettle_mpz_init_set_str_256_u(k.q,
71                                 MAX_RSA_MODULUS_LEN, key->prime[1]);
72   nettle_mpz_init_set_str_256_u(k.a,
73                                 MAX_RSA_MODULUS_LEN, key->primeExponent[0]);
74   nettle_mpz_init_set_str_256_u(k.b,
75                                 MAX_RSA_MODULUS_LEN, key->primeExponent[1]);
76   nettle_mpz_init_set_str_256_u(k.c,
77                                 MAX_RSA_MODULUS_LEN, key->coefficient);
78
79   if (rsa_private_key_prepare(&k) && (k.size <= MAX_RSA_MODULUS_LEN))
80     {
81       mpz_t s;
82       mpz_init(s);
83
84       if (rsa_md5_sign(&k, &ctx->hash, s))
85         {
86           nettle_mpz_get_str_256(k.size, signature, s);
87           *length = k.size;
88
89           res = RE_SUCCESS;
90         }
91       else
92         res = RE_PRIVATE_KEY;
93
94       mpz_clear(s);
95     }
96   else
97     res = RE_PRIVATE_KEY;
98   
99   mpz_clear(k.p);
100   mpz_clear(k.q);
101   mpz_clear(k.a);
102   mpz_clear(k.b);
103   mpz_clear(k.c);
104
105   return res;
106 }
107
108 int
109 R_VerifyInit(R_SIGNATURE_CTX *ctx,
110              int digestAlgorithm)
111 {
112   return R_SignInit(ctx, digestAlgorithm);
113 }
114
115 int
116 R_VerifyUpdate(R_SIGNATURE_CTX *ctx,
117                const uint8_t *data,
118                /* Length is an unsigned char according to rsaref.txt,
119                 * but that must be a typo. */
120                unsigned length)
121 {
122   return R_SignUpdate(ctx, data, length);
123 }
124
125 int
126 R_VerifyFinal(R_SIGNATURE_CTX *ctx,
127               uint8_t *signature,
128               unsigned length,
129               R_RSA_PUBLIC_KEY *key)
130 {
131   struct rsa_public_key k;
132   int res;
133
134   nettle_mpz_init_set_str_256_u(k.n,
135                                 MAX_RSA_MODULUS_LEN, key->modulus);
136   nettle_mpz_init_set_str_256_u(k.e,
137                                 MAX_RSA_MODULUS_LEN, key->exponent);
138   
139   if (rsa_public_key_prepare(&k) && (k.size == length))
140     {
141       mpz_t s;
142   
143       nettle_mpz_init_set_str_256_u(s,
144                                     k.size, signature);
145       res = rsa_md5_verify(&k, &ctx->hash, s)
146         ? RE_SUCCESS : RE_SIGNATURE;
147
148       mpz_clear(s);
149     }
150   else
151     res = RE_PUBLIC_KEY;
152
153   mpz_clear(k.n);
154   mpz_clear(k.e);
155
156   return res;
157 }