5 /* nettle, low-level cryptographics library
7 * Copyright (C) 2002 Niels Möller
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,
38 /* string.h must be included before gmp.h */
49 #include "rsa-session.h"
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
);
65 read_uint32(FILE *f
, uint32_t *n
)
68 if (fread(buf
, 1, sizeof(buf
), f
) != sizeof(buf
))
71 *n
= READ_UINT32(buf
);
79 return read_uint32(f
, &version
) && version
== RSA_VERSION
;
83 read_bignum(FILE *f
, mpz_t x
)
86 if (read_uint32(f
, &size
)
89 uint8_t *p
= xalloc(size
);
90 if (fread(p
, 1, size
, f
) != size
)
96 nettle_mpz_set_str_256_u(x
, size
, p
);
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)
117 process_file(struct rsa_session
*ctx
,
120 uint8_t buffer
[BUF_SIZE
+ BUF_FINAL
];
121 uint8_t digest
[SHA1_DIGEST_SIZE
];
125 size
= fread(buffer
, 1, BUF_FINAL
, in
);
126 if (size
< BUF_FINAL
)
129 werror("Reading input failed: %s\n", strerror(errno
));
131 werror("Unexpected EOF on input.\n");
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
));
145 if (size
% AES_BLOCK_SIZE
!= 0)
147 werror("Unexpected EOF on input.\n");
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
));
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");
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
));
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");
195 main(int argc
, char **argv
)
197 struct rsa_private_key key
;
198 struct rsa_session ctx
;
199 struct rsa_session_info session
;
208 werror("Usage: rsa-decrypt PRIVATE-KEY < ciphertext\n");
212 rsa_private_key_init(&key
);
214 if (!read_rsa_key(argv
[1], NULL
, &key
))
216 werror("Invalid key\n");
221 _setmode(0, O_BINARY
);
222 _setmode(1, O_BINARY
);
225 if (!read_version(stdin
))
227 werror("Bad version number in input file.\n");
231 if (!read_bignum(stdin
, x
))
233 werror("Bad rsa header in input file.\n");
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");
245 rsa_session_set_decrypt_key(&ctx
, &session
);
247 if (!process_file(&ctx
,
251 rsa_private_key_clear(&key
);