1 /*-
2 * Copyright (c) 2009 The NetBSD Foundation, Inc.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to The NetBSD Foundation
6 * by Alistair Crooks (agc@NetBSD.org)
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 */
29 /*
30 * Copyright (c) 2005-2008 Nominet UK (www.nic.uk)
31 * All rights reserved.
32 * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted
33 * their moral rights under the UK Copyright Design and Patents Act 1988 to
34 * be recorded as the authors of this copyright work.
35 *
36 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
37 * use this file except in compliance with the License.
38 *
39 * You may obtain a copy of the License at
40 * http://www.apache.org/licenses/LICENSE-2.0
41 *
42 * Unless required by applicable law or agreed to in writing, software
43 * distributed under the License is distributed on an "AS IS" BASIS,
44 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
45 *
46 * See the License for the specific language governing permissions and
47 * limitations under the License.
48 */
49 #include "config.h"
50
51 #ifdef HAVE_SYS_CDEFS_H
52 #include <sys/cdefs.h>
53 #endif
54
55 #if defined(__NetBSD__)
56 __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
57 __RCSID("$NetBSD: symmetric.c,v 1.19 2020/04/18 19:27:48 jhigh Exp $");
58 #endif
59
60 #include "crypto.h"
61 #include "packet-show.h"
62
63 #include <string.h>
64
65 #ifdef HAVE_OPENSSL_CAST_H
66 #include <openssl/cast.h>
67 #endif
68
69 #ifdef HAVE_OPENSSL_IDEA_H
70 #include <openssl/idea.h>
71 #endif
72
73 #ifdef HAVE_OPENSSL_AES_H
74 #include <openssl/aes.h>
75 #endif
76
77 #ifdef HAVE_OPENSSL_DES_H
78 #include <openssl/des.h>
79 #endif
80
81 #ifdef HAVE_OPENSSL_CAMELLIA_H
82 #include <openssl/camellia.h>
83 #endif
84
85 #ifdef HAVE_OPENSSL_BLOWFISH_H
86 #include <openssl/blowfish.h>
87 #endif
88
89 #include "crypto.h"
90 #include "netpgpdefs.h"
91
92
93 static void
std_set_iv(pgp_crypt_t * crypt,const uint8_t * iv)94 std_set_iv(pgp_crypt_t *crypt, const uint8_t *iv)
95 {
96 (void) memcpy(crypt->iv, iv, crypt->blocksize);
97 crypt->num = 0;
98 }
99
100 static void
std_set_key(pgp_crypt_t * crypt,const uint8_t * key)101 std_set_key(pgp_crypt_t *crypt, const uint8_t *key)
102 {
103 (void) memcpy(crypt->key, key, crypt->keysize);
104 }
105
106 static void
std_resync(pgp_crypt_t * decrypt)107 std_resync(pgp_crypt_t *decrypt)
108 {
109 if ((size_t) decrypt->num == decrypt->blocksize) {
110 return;
111 }
112
113 memmove(decrypt->civ + decrypt->blocksize - decrypt->num, decrypt->civ,
114 (unsigned)decrypt->num);
115 (void) memcpy(decrypt->civ, decrypt->siv + decrypt->num,
116 decrypt->blocksize - decrypt->num);
117 decrypt->num = 0;
118 }
119
120 static void
std_finish(pgp_crypt_t * crypt)121 std_finish(pgp_crypt_t *crypt)
122 {
123 if (crypt->encrypt_key) {
124 free(crypt->encrypt_key);
125 crypt->encrypt_key = NULL;
126 }
127 if (crypt->decrypt_key) {
128 free(crypt->decrypt_key);
129 crypt->decrypt_key = NULL;
130 }
131 }
132
133 static int
cast5_init(pgp_crypt_t * crypt)134 cast5_init(pgp_crypt_t *crypt)
135 {
136 if (crypt->encrypt_key) {
137 free(crypt->encrypt_key);
138 }
139 if ((crypt->encrypt_key = calloc(1, sizeof(CAST_KEY))) == NULL) {
140 (void) fprintf(stderr, "cast5_init: alloc failure\n");
141 return 0;
142 }
143 CAST_set_key(crypt->encrypt_key, (int)crypt->keysize, crypt->key);
144 if ((crypt->decrypt_key = calloc(1, sizeof(CAST_KEY))) == NULL) {
145 (void) fprintf(stderr, "cast5_init: alloc failure\n");
146 return 0;
147 }
148 CAST_set_key(crypt->decrypt_key, (int)crypt->keysize, crypt->key);
149 return 1;
150 }
151
152 static void
cast5_block_encrypt(pgp_crypt_t * crypt,void * out,const void * in)153 cast5_block_encrypt(pgp_crypt_t *crypt, void *out, const void *in)
154 {
155 CAST_ecb_encrypt(in, out, crypt->encrypt_key, CAST_ENCRYPT);
156 }
157
158 static void
cast5_block_decrypt(pgp_crypt_t * crypt,void * out,const void * in)159 cast5_block_decrypt(pgp_crypt_t *crypt, void *out, const void *in)
160 {
161 CAST_ecb_encrypt(in, out, crypt->encrypt_key, CAST_DECRYPT);
162 }
163
164 static void
cast5_cfb_encrypt(pgp_crypt_t * crypt,void * out,const void * in,size_t count)165 cast5_cfb_encrypt(pgp_crypt_t *crypt, void *out, const void *in, size_t count)
166 {
167 CAST_cfb64_encrypt(in, out, (long)count,
168 crypt->encrypt_key, crypt->iv, &crypt->num,
169 CAST_ENCRYPT);
170 }
171
172 static void
cast5_cfb_decrypt(pgp_crypt_t * crypt,void * out,const void * in,size_t count)173 cast5_cfb_decrypt(pgp_crypt_t *crypt, void *out, const void *in, size_t count)
174 {
175 CAST_cfb64_encrypt(in, out, (long)count,
176 crypt->encrypt_key, crypt->iv, &crypt->num,
177 CAST_DECRYPT);
178 }
179
180 #define TRAILER "","","","",0,NULL,NULL
181
182 static pgp_crypt_t cast5 =
183 {
184 PGP_SA_CAST5,
185 CAST_BLOCK,
186 CAST_KEY_LENGTH,
187 std_set_iv,
188 std_set_key,
189 cast5_init,
190 std_resync,
191 cast5_block_encrypt,
192 cast5_block_decrypt,
193 cast5_cfb_encrypt,
194 cast5_cfb_decrypt,
195 std_finish,
196 TRAILER
197 };
198
199 #ifdef HAVE_OPENSSL_BLOWFISH_H
200
201 /* RFC 4880 9.2 Blowfish 128 */
202 #define BLOWFISH_KEY_LENGTH 16
203
204 static int
blowfish_init(pgp_crypt_t * crypt)205 blowfish_init(pgp_crypt_t *crypt)
206 {
207 if (crypt->encrypt_key) {
208 free(crypt->encrypt_key);
209 }
210 if (crypt->keysize != BLOWFISH_KEY_LENGTH) {
211 (void) fprintf(stderr, "blowfish_init: keysize wrong\n");
212 return 0;
213 }
214 if ((crypt->encrypt_key = calloc(1, sizeof(BF_KEY))) == NULL) {
215 (void) fprintf(stderr, "blowfish_init: alloc failure\n");
216 return 0;
217 }
218 BF_set_key(crypt->encrypt_key, (int)crypt->keysize, crypt->key);
219 if ((crypt->decrypt_key = calloc(1, sizeof(BF_KEY))) == NULL) {
220 (void) fprintf(stderr, "blowfish_init: alloc failure\n");
221 return 0;
222 }
223 BF_set_key(crypt->decrypt_key, (int)crypt->keysize, crypt->key);
224 return 1;
225 }
226
227 static void
blowfish_block_encrypt(pgp_crypt_t * crypt,void * out,const void * in)228 blowfish_block_encrypt(pgp_crypt_t *crypt, void *out, const void *in)
229 {
230 BF_ecb_encrypt(in, out, crypt->encrypt_key, BF_ENCRYPT);
231 }
232
233 static void
blowfish_block_decrypt(pgp_crypt_t * crypt,void * out,const void * in)234 blowfish_block_decrypt(pgp_crypt_t *crypt, void *out, const void *in)
235 {
236 BF_ecb_encrypt(in, out, crypt->encrypt_key, BF_DECRYPT);
237 }
238
239 static void
blowfish_cfb_encrypt(pgp_crypt_t * crypt,void * out,const void * in,size_t count)240 blowfish_cfb_encrypt(pgp_crypt_t *crypt, void *out, const void *in, size_t count)
241 {
242 BF_cfb64_encrypt(in, out, (long)count,
243 crypt->encrypt_key, crypt->iv, &crypt->num,
244 BF_ENCRYPT);
245 }
246
247 static void
blowfish_cfb_decrypt(pgp_crypt_t * crypt,void * out,const void * in,size_t count)248 blowfish_cfb_decrypt(pgp_crypt_t *crypt, void *out, const void *in, size_t count)
249 {
250 BF_cfb64_encrypt(in, out, (long)count,
251 crypt->encrypt_key, crypt->iv, &crypt->num,
252 BF_DECRYPT);
253 }
254
255 static pgp_crypt_t blowfish =
256 {
257 PGP_SA_BLOWFISH,
258 BF_BLOCK,
259 BLOWFISH_KEY_LENGTH,
260 std_set_iv,
261 std_set_key,
262 blowfish_init,
263 std_resync,
264 blowfish_block_encrypt,
265 blowfish_block_decrypt,
266 blowfish_cfb_encrypt,
267 blowfish_cfb_decrypt,
268 std_finish,
269 TRAILER
270 };
271
272 #endif /* HAVE_OPENSSL_BLOWFISH_H */
273
274 #ifndef OPENSSL_NO_IDEA
275 static int
idea_init(pgp_crypt_t * crypt)276 idea_init(pgp_crypt_t *crypt)
277 {
278 if (crypt->keysize != IDEA_KEY_LENGTH) {
279 (void) fprintf(stderr, "idea_init: keysize wrong\n");
280 return 0;
281 }
282
283 if (crypt->encrypt_key) {
284 free(crypt->encrypt_key);
285 }
286 if ((crypt->encrypt_key = calloc(1, sizeof(IDEA_KEY_SCHEDULE))) == NULL) {
287 (void) fprintf(stderr, "idea_init: alloc failure\n");
288 return 0;
289 }
290
291 /* note that we don't invert the key when decrypting for CFB mode */
292 idea_set_encrypt_key(crypt->key, crypt->encrypt_key);
293
294 if (crypt->decrypt_key) {
295 free(crypt->decrypt_key);
296 }
297 if ((crypt->decrypt_key = calloc(1, sizeof(IDEA_KEY_SCHEDULE))) == NULL) {
298 (void) fprintf(stderr, "idea_init: alloc failure\n");
299 return 0;
300 }
301
302 idea_set_decrypt_key(crypt->encrypt_key, crypt->decrypt_key);
303 return 1;
304 }
305
306 static void
idea_block_encrypt(pgp_crypt_t * crypt,void * out,const void * in)307 idea_block_encrypt(pgp_crypt_t *crypt, void *out, const void *in)
308 {
309 idea_ecb_encrypt(in, out, crypt->encrypt_key);
310 }
311
312 static void
idea_block_decrypt(pgp_crypt_t * crypt,void * out,const void * in)313 idea_block_decrypt(pgp_crypt_t *crypt, void *out, const void *in)
314 {
315 idea_ecb_encrypt(in, out, crypt->decrypt_key);
316 }
317
318 static void
idea_cfb_encrypt(pgp_crypt_t * crypt,void * out,const void * in,size_t count)319 idea_cfb_encrypt(pgp_crypt_t *crypt, void *out, const void *in, size_t count)
320 {
321 idea_cfb64_encrypt(in, out, (long)count,
322 crypt->encrypt_key, crypt->iv, &crypt->num,
323 CAST_ENCRYPT);
324 }
325
326 static void
idea_cfb_decrypt(pgp_crypt_t * crypt,void * out,const void * in,size_t count)327 idea_cfb_decrypt(pgp_crypt_t *crypt, void *out, const void *in, size_t count)
328 {
329 idea_cfb64_encrypt(in, out, (long)count,
330 crypt->decrypt_key, crypt->iv, &crypt->num,
331 CAST_DECRYPT);
332 }
333
334 static const pgp_crypt_t idea =
335 {
336 PGP_SA_IDEA,
337 IDEA_BLOCK,
338 IDEA_KEY_LENGTH,
339 std_set_iv,
340 std_set_key,
341 idea_init,
342 std_resync,
343 idea_block_encrypt,
344 idea_block_decrypt,
345 idea_cfb_encrypt,
346 idea_cfb_decrypt,
347 std_finish,
348 TRAILER
349 };
350 #endif /* OPENSSL_NO_IDEA */
351
352 /* AES with 128-bit key (AES) */
353
354 #define KEYBITS_AES128 128
355
356 static int
aes128_init(pgp_crypt_t * crypt)357 aes128_init(pgp_crypt_t *crypt)
358 {
359 if (crypt->encrypt_key) {
360 free(crypt->encrypt_key);
361 }
362 if ((crypt->encrypt_key = calloc(1, sizeof(AES_KEY))) == NULL) {
363 (void) fprintf(stderr, "aes128_init: alloc failure\n");
364 return 0;
365 }
366 if (AES_set_encrypt_key(crypt->key, KEYBITS_AES128,
367 crypt->encrypt_key)) {
368 fprintf(stderr, "aes128_init: Error setting encrypt_key\n");
369 }
370
371 if (crypt->decrypt_key) {
372 free(crypt->decrypt_key);
373 }
374 if ((crypt->decrypt_key = calloc(1, sizeof(AES_KEY))) == NULL) {
375 (void) fprintf(stderr, "aes128_init: alloc failure\n");
376 return 0;
377 }
378 if (AES_set_decrypt_key(crypt->key, KEYBITS_AES128,
379 crypt->decrypt_key)) {
380 fprintf(stderr, "aes128_init: Error setting decrypt_key\n");
381 }
382 return 1;
383 }
384
385 static void
aes_block_encrypt(pgp_crypt_t * crypt,void * out,const void * in)386 aes_block_encrypt(pgp_crypt_t *crypt, void *out, const void *in)
387 {
388 AES_encrypt(in, out, crypt->encrypt_key);
389 }
390
391 static void
aes_block_decrypt(pgp_crypt_t * crypt,void * out,const void * in)392 aes_block_decrypt(pgp_crypt_t *crypt, void *out, const void *in)
393 {
394 AES_decrypt(in, out, crypt->decrypt_key);
395 }
396
397 static void
aes_cfb_encrypt(pgp_crypt_t * crypt,void * out,const void * in,size_t count)398 aes_cfb_encrypt(pgp_crypt_t *crypt, void *out, const void *in, size_t count)
399 {
400 AES_cfb128_encrypt(in, out, (unsigned)count,
401 crypt->encrypt_key, crypt->iv, &crypt->num,
402 AES_ENCRYPT);
403 }
404
405 static void
aes_cfb_decrypt(pgp_crypt_t * crypt,void * out,const void * in,size_t count)406 aes_cfb_decrypt(pgp_crypt_t *crypt, void *out, const void *in, size_t count)
407 {
408 AES_cfb128_encrypt(in, out, (unsigned)count,
409 crypt->encrypt_key, crypt->iv, &crypt->num,
410 AES_DECRYPT);
411 }
412
413 static const pgp_crypt_t aes128 =
414 {
415 PGP_SA_AES_128,
416 AES_BLOCK_SIZE,
417 KEYBITS_AES128 / 8,
418 std_set_iv,
419 std_set_key,
420 aes128_init,
421 std_resync,
422 aes_block_encrypt,
423 aes_block_decrypt,
424 aes_cfb_encrypt,
425 aes_cfb_decrypt,
426 std_finish,
427 TRAILER
428 };
429
430 /* AES with 256-bit key */
431
432 #define KEYBITS_AES256 256
433
434 static int
aes256_init(pgp_crypt_t * crypt)435 aes256_init(pgp_crypt_t *crypt)
436 {
437 if (crypt->encrypt_key) {
438 free(crypt->encrypt_key);
439 }
440 if ((crypt->encrypt_key = calloc(1, sizeof(AES_KEY))) == NULL) {
441 (void) fprintf(stderr, "aes256_init: alloc failure\n");
442 return 0;
443 }
444 if (AES_set_encrypt_key(crypt->key, KEYBITS_AES256,
445 crypt->encrypt_key)) {
446 fprintf(stderr, "aes256_init: Error setting encrypt_key\n");
447 free(crypt->encrypt_key);
448 crypt->encrypt_key = NULL;
449 return 0;
450 }
451 if (crypt->decrypt_key) {
452 free(crypt->decrypt_key);
453 }
454 if ((crypt->decrypt_key = calloc(1, sizeof(AES_KEY))) == NULL) {
455 (void) fprintf(stderr, "aes256_init: alloc failure\n");
456 free(crypt->encrypt_key);
457 crypt->encrypt_key = NULL;
458 return 0;
459 }
460 if (AES_set_decrypt_key(crypt->key, KEYBITS_AES256,
461 crypt->decrypt_key)) {
462 fprintf(stderr, "aes256_init: Error setting decrypt_key\n");
463 free(crypt->encrypt_key);
464 crypt->encrypt_key = NULL;
465 free(crypt->decrypt_key);
466 crypt->decrypt_key = NULL;
467 return 0;
468 }
469 return 1;
470 }
471
472 static const pgp_crypt_t aes256 =
473 {
474 PGP_SA_AES_256,
475 AES_BLOCK_SIZE,
476 KEYBITS_AES256 / 8,
477 std_set_iv,
478 std_set_key,
479 aes256_init,
480 std_resync,
481 aes_block_encrypt,
482 aes_block_decrypt,
483 aes_cfb_encrypt,
484 aes_cfb_decrypt,
485 std_finish,
486 TRAILER
487 };
488
489 /* Triple DES */
490
491 static int
tripledes_init(pgp_crypt_t * crypt)492 tripledes_init(pgp_crypt_t *crypt)
493 {
494 DES_key_schedule *keys;
495 int n;
496
497 if (crypt->encrypt_key) {
498 free(crypt->encrypt_key);
499 }
500 if ((keys = crypt->encrypt_key = calloc(1, 3 * sizeof(DES_key_schedule))) == NULL) {
501 (void) fprintf(stderr, "tripledes_init: alloc failure\n");
502 return 0;
503 }
504 for (n = 0; n < 3; ++n) {
505 DES_set_key((DES_cblock *)(void *)(crypt->key + n * 8),
506 &keys[n]);
507 }
508 return 1;
509 }
510
511 static void
tripledes_block_encrypt(pgp_crypt_t * crypt,void * out,const void * in)512 tripledes_block_encrypt(pgp_crypt_t *crypt, void *out, const void *in)
513 {
514 DES_key_schedule *keys = crypt->encrypt_key;
515
516 DES_ecb3_encrypt(__UNCONST(in), out, &keys[0], &keys[1], &keys[2],
517 DES_ENCRYPT);
518 }
519
520 static void
tripledes_block_decrypt(pgp_crypt_t * crypt,void * out,const void * in)521 tripledes_block_decrypt(pgp_crypt_t *crypt, void *out, const void *in)
522 {
523 DES_key_schedule *keys = crypt->encrypt_key;
524
525 DES_ecb3_encrypt(__UNCONST(in), out, &keys[0], &keys[1], &keys[2],
526 DES_DECRYPT);
527 }
528
529 static void
tripledes_cfb_encrypt(pgp_crypt_t * crypt,void * out,const void * in,size_t count)530 tripledes_cfb_encrypt(pgp_crypt_t *crypt, void *out, const void *in,
531 size_t count)
532 {
533 DES_key_schedule *keys = crypt->encrypt_key;
534
535 DES_ede3_cfb64_encrypt(in, out, (long)count,
536 &keys[0], &keys[1], &keys[2], (DES_cblock *)(void *)crypt->iv,
537 &crypt->num, DES_ENCRYPT);
538 }
539
540 static void
tripledes_cfb_decrypt(pgp_crypt_t * crypt,void * out,const void * in,size_t count)541 tripledes_cfb_decrypt(pgp_crypt_t *crypt, void *out, const void *in,
542 size_t count)
543 {
544 DES_key_schedule *keys = crypt->encrypt_key;
545
546 DES_ede3_cfb64_encrypt(in, out, (long)count,
547 &keys[0], &keys[1], &keys[2], (DES_cblock *)(void *)crypt->iv,
548 &crypt->num, DES_DECRYPT);
549 }
550
551 static const pgp_crypt_t tripledes =
552 {
553 PGP_SA_TRIPLEDES,
554 8,
555 24,
556 std_set_iv,
557 std_set_key,
558 tripledes_init,
559 std_resync,
560 tripledes_block_encrypt,
561 tripledes_block_decrypt,
562 tripledes_cfb_encrypt,
563 tripledes_cfb_decrypt,
564 std_finish,
565 TRAILER
566 };
567
568 #if defined(HAVE_OPENSSL_CAMELLIA_H) && !defined(OPENSSL_NO_CAMELLIA)
569 /* Camellia with 128-bit key (CAMELLIA) */
570
571 #define KEYBITS_CAMELLIA128 128
572
573 static int
camellia128_init(pgp_crypt_t * crypt)574 camellia128_init(pgp_crypt_t *crypt)
575 {
576 if (crypt->encrypt_key) {
577 free(crypt->encrypt_key);
578 }
579 if ((crypt->encrypt_key = calloc(1, sizeof(CAMELLIA_KEY))) == NULL) {
580 (void) fprintf(stderr, "camellia128_init: alloc failure\n");
581 return 0;
582 }
583 if (Camellia_set_key(crypt->key, KEYBITS_CAMELLIA128, crypt->encrypt_key)) {
584 fprintf(stderr, "camellia128_init: Error setting encrypt_key\n");
585 }
586 if (crypt->decrypt_key) {
587 free(crypt->decrypt_key);
588 }
589 if ((crypt->decrypt_key = calloc(1, sizeof(CAMELLIA_KEY))) == NULL) {
590 (void) fprintf(stderr, "camellia128_init: alloc failure\n");
591 return 0;
592 }
593 if (Camellia_set_key(crypt->key, KEYBITS_CAMELLIA128, crypt->decrypt_key)) {
594 fprintf(stderr, "camellia128_init: Error setting decrypt_key\n");
595 }
596 return 1;
597 }
598
599 static void
camellia_block_encrypt(pgp_crypt_t * crypt,void * out,const void * in)600 camellia_block_encrypt(pgp_crypt_t *crypt, void *out, const void *in)
601 {
602 Camellia_encrypt(in, out, crypt->encrypt_key);
603 }
604
605 static void
camellia_block_decrypt(pgp_crypt_t * crypt,void * out,const void * in)606 camellia_block_decrypt(pgp_crypt_t *crypt, void *out, const void *in)
607 {
608 Camellia_decrypt(in, out, crypt->decrypt_key);
609 }
610
611 static void
camellia_cfb_encrypt(pgp_crypt_t * crypt,void * out,const void * in,size_t count)612 camellia_cfb_encrypt(pgp_crypt_t *crypt, void *out, const void *in, size_t count)
613 {
614 Camellia_cfb128_encrypt(in, out, (unsigned)count,
615 crypt->encrypt_key, crypt->iv, &crypt->num,
616 CAMELLIA_ENCRYPT);
617 }
618
619 static void
camellia_cfb_decrypt(pgp_crypt_t * crypt,void * out,const void * in,size_t count)620 camellia_cfb_decrypt(pgp_crypt_t *crypt, void *out, const void *in, size_t count)
621 {
622 Camellia_cfb128_encrypt(in, out, (unsigned)count,
623 crypt->encrypt_key, crypt->iv, &crypt->num,
624 CAMELLIA_DECRYPT);
625 }
626
627 static const pgp_crypt_t camellia128 =
628 {
629 PGP_SA_CAMELLIA_128,
630 CAMELLIA_BLOCK_SIZE,
631 KEYBITS_CAMELLIA128 / 8,
632 std_set_iv,
633 std_set_key,
634 camellia128_init,
635 std_resync,
636 camellia_block_encrypt,
637 camellia_block_decrypt,
638 camellia_cfb_encrypt,
639 camellia_cfb_decrypt,
640 std_finish,
641 TRAILER
642 };
643
644 /* Camellia with 256-bit key (CAMELLIA) */
645
646 #define KEYBITS_CAMELLIA256 256
647
648 static int
camellia256_init(pgp_crypt_t * crypt)649 camellia256_init(pgp_crypt_t *crypt)
650 {
651 if (crypt->encrypt_key) {
652 free(crypt->encrypt_key);
653 }
654 if ((crypt->encrypt_key = calloc(1, sizeof(CAMELLIA_KEY))) == NULL) {
655 (void) fprintf(stderr, "camellia256_init: alloc failure\n");
656 return 0;
657 }
658 if (Camellia_set_key(crypt->key, KEYBITS_CAMELLIA256, crypt->encrypt_key)) {
659 fprintf(stderr, "camellia256_init: Error setting encrypt_key\n");
660 }
661 if (crypt->decrypt_key) {
662 free(crypt->decrypt_key);
663 }
664 if ((crypt->decrypt_key = calloc(1, sizeof(CAMELLIA_KEY))) == NULL) {
665 (void) fprintf(stderr, "camellia256_init: alloc failure\n");
666 return 0;
667 }
668 if (Camellia_set_key(crypt->key, KEYBITS_CAMELLIA256, crypt->decrypt_key)) {
669 fprintf(stderr, "camellia256_init: Error setting decrypt_key\n");
670 }
671 return 1;
672 }
673
674 static const pgp_crypt_t camellia256 =
675 {
676 PGP_SA_CAMELLIA_256,
677 CAMELLIA_BLOCK_SIZE,
678 KEYBITS_CAMELLIA256 / 8,
679 std_set_iv,
680 std_set_key,
681 camellia256_init,
682 std_resync,
683 camellia_block_encrypt,
684 camellia_block_decrypt,
685 camellia_cfb_encrypt,
686 camellia_cfb_decrypt,
687 std_finish,
688 TRAILER
689 };
690 #endif
691
692
693 static const pgp_crypt_t *
get_proto(pgp_symm_alg_t alg)694 get_proto(pgp_symm_alg_t alg)
695 {
696 switch (alg) {
697 case PGP_SA_CAST5:
698 return &cast5;
699 #ifndef OPENSSL_NO_IDEA
700 case PGP_SA_IDEA:
701 return &idea;
702 #endif /* OPENSSL_NO_IDEA */
703 case PGP_SA_AES_128:
704 return &aes128;
705 case PGP_SA_AES_256:
706 return &aes256;
707 #if defined(HAVE_OPENSSL_CAMELLIA_H) && !defined(OPENSSL_NO_CAMELLIA)
708 case PGP_SA_CAMELLIA_128:
709 return &camellia128;
710 case PGP_SA_CAMELLIA_256:
711 return &camellia256;
712 #endif
713 case PGP_SA_TRIPLEDES:
714 return &tripledes;
715 #if defined HAVE_OPENSSL_BLOWFISH_H
716 case PGP_SA_BLOWFISH:
717 return &blowfish;
718 #endif
719
720 default:
721 (void) fprintf(stderr, "Unknown algorithm: %d (%s)\n",
722 alg, pgp_show_symm_alg(alg));
723 }
724 return NULL;
725 }
726
727 int
pgp_crypt_any(pgp_crypt_t * crypt,pgp_symm_alg_t alg)728 pgp_crypt_any(pgp_crypt_t *crypt, pgp_symm_alg_t alg)
729 {
730 const pgp_crypt_t *ptr = get_proto(alg);
731
732 if (ptr) {
733 *crypt = *ptr;
734 return 1;
735 } else {
736 (void) memset(crypt, 0x0, sizeof(*crypt));
737 return 0;
738 }
739 }
740
741 unsigned
pgp_block_size(pgp_symm_alg_t alg)742 pgp_block_size(pgp_symm_alg_t alg)
743 {
744 const pgp_crypt_t *p = get_proto(alg);
745
746 return (p == NULL) ? 0 : (unsigned)p->blocksize;
747 }
748
749 unsigned
pgp_key_size(pgp_symm_alg_t alg)750 pgp_key_size(pgp_symm_alg_t alg)
751 {
752 const pgp_crypt_t *p = get_proto(alg);
753
754 return (p == NULL) ? 0 : (unsigned)p->keysize;
755 }
756
757 void
pgp_encrypt_init(pgp_crypt_t * encrypt)758 pgp_encrypt_init(pgp_crypt_t *encrypt)
759 {
760 /* \todo should there be a separate pgp_encrypt_init? */
761 pgp_decrypt_init(encrypt);
762 }
763
764 void
pgp_decrypt_init(pgp_crypt_t * decrypt)765 pgp_decrypt_init(pgp_crypt_t *decrypt)
766 {
767 decrypt->base_init(decrypt);
768 decrypt->block_encrypt(decrypt, decrypt->siv, decrypt->iv);
769 (void) memcpy(decrypt->civ, decrypt->siv, decrypt->blocksize);
770 decrypt->num = 0;
771 }
772
773 size_t
pgp_decrypt_se(pgp_crypt_t * decrypt,void * outvoid,const void * invoid,size_t count)774 pgp_decrypt_se(pgp_crypt_t *decrypt, void *outvoid, const void *invoid,
775 size_t count)
776 {
777 const uint8_t *in = invoid;
778 uint8_t *out = outvoid;
779 int saved = (int)count;
780
781 /*
782 * in order to support v3's weird resyncing we have to implement CFB
783 * mode ourselves
784 */
785 while (count-- > 0) {
786 uint8_t t;
787
788 if ((size_t) decrypt->num == decrypt->blocksize) {
789 (void) memcpy(decrypt->siv, decrypt->civ,
790 decrypt->blocksize);
791 decrypt->block_decrypt(decrypt, decrypt->civ,
792 decrypt->civ);
793 decrypt->num = 0;
794 }
795 t = decrypt->civ[decrypt->num];
796 *out++ = t ^ (decrypt->civ[decrypt->num++] = *in++);
797 }
798
799 return (size_t)saved;
800 }
801
802 size_t
pgp_encrypt_se(pgp_crypt_t * encrypt,void * outvoid,const void * invoid,size_t count)803 pgp_encrypt_se(pgp_crypt_t *encrypt, void *outvoid, const void *invoid,
804 size_t count)
805 {
806 const uint8_t *in = invoid;
807 uint8_t *out = outvoid;
808 int saved = (int)count;
809
810 /*
811 * in order to support v3's weird resyncing we have to implement CFB
812 * mode ourselves
813 */
814 while (count-- > 0) {
815 if ((size_t) encrypt->num == encrypt->blocksize) {
816 (void) memcpy(encrypt->siv, encrypt->civ,
817 encrypt->blocksize);
818 encrypt->block_encrypt(encrypt, encrypt->civ,
819 encrypt->civ);
820 encrypt->num = 0;
821 }
822 encrypt->civ[encrypt->num] = *out++ =
823 encrypt->civ[encrypt->num] ^ *in++;
824 ++encrypt->num;
825 }
826
827 return (size_t)saved;
828 }
829
830 /**
831 \ingroup HighLevel_Supported
832 \brief Is this Symmetric Algorithm supported?
833 \param alg Symmetric Algorithm to check
834 \return 1 if supported; else 0
835 */
836 unsigned
pgp_is_sa_supported(pgp_symm_alg_t alg)837 pgp_is_sa_supported(pgp_symm_alg_t alg)
838 {
839 switch (alg) {
840 case PGP_SA_AES_128:
841 case PGP_SA_AES_256:
842 case PGP_SA_CAST5:
843 #if defined(HAVE_OPENSSL_BLOWFISH_H)
844 case PGP_SA_BLOWFISH:
845 #endif
846 case PGP_SA_TRIPLEDES:
847 #if defined(HAVE_OPENSSL_CAMELLIA_H) && !defined(OPENSSL_NO_CAMELLIA)
848 case PGP_SA_CAMELLIA_128:
849 case PGP_SA_CAMELLIA_256:
850 #endif
851 #ifndef OPENSSL_NO_IDEA
852 case PGP_SA_IDEA:
853 #endif
854 return 1;
855
856 default:
857 fprintf(stderr, "\nWarning: %s not supported\n",
858 pgp_show_symm_alg(alg));
859 return 0;
860 }
861 }
862
863 size_t
pgp_encrypt_se_ip(pgp_crypt_t * crypt,void * out,const void * in,size_t count)864 pgp_encrypt_se_ip(pgp_crypt_t *crypt, void *out, const void *in,
865 size_t count)
866 {
867 if (!pgp_is_sa_supported(crypt->alg)) {
868 return 0;
869 }
870
871 crypt->cfb_encrypt(crypt, out, in, count);
872
873 /* \todo test this number was encrypted */
874 return count;
875 }
876
877 size_t
pgp_decrypt_se_ip(pgp_crypt_t * crypt,void * out,const void * in,size_t count)878 pgp_decrypt_se_ip(pgp_crypt_t *crypt, void *out, const void *in,
879 size_t count)
880 {
881 if (!pgp_is_sa_supported(crypt->alg)) {
882 return 0;
883 }
884
885 crypt->cfb_decrypt(crypt, out, in, count);
886
887 /* \todo check this number was in fact decrypted */
888 return count;
889 }
890