Correct PPTP server firewall rules chain.
[tomato/davidwu.git] / release / src / router / nettle / examples / rsa-decrypt.c
blobd5ca80125bf24d3c361e00b3a5e174aab7724fb3
1 /* rsa-decrypt.c
3 */
5 /* nettle, low-level cryptographics library
7 * Copyright (C) 2002 Niels Möller
8 *
9 * The nettle library is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation; either version 2.1 of the License, or (at your
12 * option) any later version.
14 * The nettle library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17 * License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with the nettle library; see the file COPYING.LIB. If not, write to
21 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22 * MA 02111-1301, USA.
25 #if HAVE_CONFIG_H
26 # include "config.h"
27 #endif
29 #include <ctype.h>
30 #include <errno.h>
31 #include <stdlib.h>
32 #include <stdio.h>
33 #include <string.h>
34 #ifdef WIN32
35 #include <fcntl.h>
36 #endif
38 /* string.h must be included before gmp.h */
39 #include "aes.h"
40 #include "bignum.h"
41 #include "buffer.h"
42 #include "cbc.h"
43 #include "hmac.h"
44 #include "macros.h"
45 #include "rsa.h"
46 #include "yarrow.h"
48 #include "io.h"
49 #include "rsa-session.h"
51 void
52 rsa_session_set_decrypt_key(struct rsa_session *ctx,
53 const struct rsa_session_info *key)
55 const uint8_t *aes_key = SESSION_AES_KEY(key);
56 const uint8_t *iv = SESSION_IV(key);
57 const uint8_t *hmac_key = SESSION_HMAC_KEY(key);
59 aes_set_decrypt_key(&ctx->aes.ctx, AES_KEY_SIZE, aes_key);
60 CBC_SET_IV(&ctx->aes, iv);
61 hmac_sha1_set_key(&ctx->hmac, SHA1_DIGEST_SIZE, hmac_key);
64 static int
65 read_uint32(FILE *f, uint32_t *n)
67 uint8_t buf[4];
68 if (fread(buf, 1, sizeof(buf), f) != sizeof(buf))
69 return 0;
71 *n = READ_UINT32(buf);
72 return 1;
75 static int
76 read_version(FILE *f)
78 uint32_t version;
79 return read_uint32(f, &version) && version == RSA_VERSION;
82 static int
83 read_bignum(FILE *f, mpz_t x)
85 uint32_t size;
86 if (read_uint32(f, &size)
87 && size < 1000)
89 uint8_t *p = xalloc(size);
90 if (fread(p, 1, size, f) != size)
92 free(p);
93 return 0;
96 nettle_mpz_set_str_256_u(x, size, p);
97 free(p);
99 return 1;
101 return 0;
104 struct process_ctx
106 struct CBC_CTX(struct aes_ctx, AES_BLOCK_SIZE) aes;
107 struct hmac_sha1_ctx hmac;
108 struct yarrow256_ctx yarrow;
111 #define BUF_SIZE (100 * AES_BLOCK_SIZE)
113 /* Trailing data that needs special processing */
114 #define BUF_FINAL (AES_BLOCK_SIZE + SHA1_DIGEST_SIZE)
116 static int
117 process_file(struct rsa_session *ctx,
118 FILE *in, FILE *out)
120 uint8_t buffer[BUF_SIZE + BUF_FINAL];
121 uint8_t digest[SHA1_DIGEST_SIZE];
122 size_t size;
123 unsigned padding;
125 size = fread(buffer, 1, BUF_FINAL, in);
126 if (size < BUF_FINAL)
128 if (ferror(in))
129 werror("Reading input failed: %s\n", strerror(errno));
130 else
131 werror("Unexpected EOF on input.\n");
132 return 0;
137 size = fread(buffer + BUF_FINAL, 1, BUF_SIZE, in);
139 if (size < BUF_SIZE && ferror(in))
141 werror("Reading input failed: %s\n", strerror(errno));
142 return 0;
145 if (size % AES_BLOCK_SIZE != 0)
147 werror("Unexpected EOF on input.\n");
148 return 0;
151 if (size)
153 CBC_DECRYPT(&ctx->aes, aes_decrypt, size, buffer, buffer);
154 hmac_sha1_update(&ctx->hmac, size, buffer);
155 if (!write_string(out, size, buffer))
157 werror("Writing output failed: %s\n", strerror(errno));
158 return 0;
160 memmove(buffer, buffer + size, BUF_FINAL);
163 while (size == BUF_SIZE);
165 /* Decrypt final block */
166 CBC_DECRYPT(&ctx->aes, aes_decrypt, AES_BLOCK_SIZE, buffer, buffer);
167 padding = buffer[AES_BLOCK_SIZE - 1];
168 if (padding > AES_BLOCK_SIZE)
170 werror("Decryption failed: Invalid padding.\n");
171 return 0;
174 if (padding < AES_BLOCK_SIZE)
176 unsigned leftover = AES_BLOCK_SIZE - padding;
177 hmac_sha1_update(&ctx->hmac, leftover, buffer);
178 if (!write_string(out, leftover, buffer))
180 werror("Writing output failed: %s\n", strerror(errno));
181 return 0;
184 hmac_sha1_digest(&ctx->hmac, SHA1_DIGEST_SIZE, digest);
185 if (memcmp(digest, buffer + AES_BLOCK_SIZE, SHA1_DIGEST_SIZE) != 0)
187 werror("Decryption failed: Invalid mac.\n");
188 return 0;
191 return 1;
195 main(int argc, char **argv)
197 struct rsa_private_key key;
198 struct rsa_session ctx;
199 struct rsa_session_info session;
201 unsigned length;
202 mpz_t x;
204 mpz_init(x);
206 if (argc != 2)
208 werror("Usage: rsa-decrypt PRIVATE-KEY < ciphertext\n");
209 return EXIT_FAILURE;
212 rsa_private_key_init(&key);
214 if (!read_rsa_key(argv[1], NULL, &key))
216 werror("Invalid key\n");
217 return EXIT_FAILURE;
220 #ifdef WIN32
221 _setmode(0, O_BINARY);
222 _setmode(1, O_BINARY);
223 #endif
225 if (!read_version(stdin))
227 werror("Bad version number in input file.\n");
228 return EXIT_FAILURE;
231 if (!read_bignum(stdin, x))
233 werror("Bad rsa header in input file.\n");
234 return EXIT_FAILURE;
237 length = sizeof(session.key);
238 if (!rsa_decrypt(&key, &length, session.key, x) || length != sizeof(session.key))
240 werror("Failed to decrypt rsa header in input file.\n");
241 return EXIT_FAILURE;
243 mpz_clear(x);
245 rsa_session_set_decrypt_key(&ctx, &session);
247 if (!process_file(&ctx,
248 stdin, stdout))
249 return EXIT_FAILURE;
251 rsa_private_key_clear(&key);
253 return EXIT_SUCCESS;