xref: /netbsd-src/crypto/external/bsd/netpgp/dist/src/lib/symmetric.c (revision 3fba244ae402394f46c5bc009243eb3244ff5585)
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