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.18 2010/11/07 08:39:59 agc 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 #include "crypto.h"
86 #include "netpgpdefs.h"
87 
88 
89 static void
std_set_iv(pgp_crypt_t * crypt,const uint8_t * iv)90 std_set_iv(pgp_crypt_t *crypt, const uint8_t *iv)
91 {
92 	(void) memcpy(crypt->iv, iv, crypt->blocksize);
93 	crypt->num = 0;
94 }
95 
96 static void
std_set_key(pgp_crypt_t * crypt,const uint8_t * key)97 std_set_key(pgp_crypt_t *crypt, const uint8_t *key)
98 {
99 	(void) memcpy(crypt->key, key, crypt->keysize);
100 }
101 
102 static void
std_resync(pgp_crypt_t * decrypt)103 std_resync(pgp_crypt_t *decrypt)
104 {
105 	if ((size_t) decrypt->num == decrypt->blocksize) {
106 		return;
107 	}
108 
109 	memmove(decrypt->civ + decrypt->blocksize - decrypt->num, decrypt->civ,
110 		(unsigned)decrypt->num);
111 	(void) memcpy(decrypt->civ, decrypt->siv + decrypt->num,
112 	       decrypt->blocksize - decrypt->num);
113 	decrypt->num = 0;
114 }
115 
116 static void
std_finish(pgp_crypt_t * crypt)117 std_finish(pgp_crypt_t *crypt)
118 {
119 	if (crypt->encrypt_key) {
120 		free(crypt->encrypt_key);
121 		crypt->encrypt_key = NULL;
122 	}
123 	if (crypt->decrypt_key) {
124 		free(crypt->decrypt_key);
125 		crypt->decrypt_key = NULL;
126 	}
127 }
128 
129 static int
cast5_init(pgp_crypt_t * crypt)130 cast5_init(pgp_crypt_t *crypt)
131 {
132 	if (crypt->encrypt_key) {
133 		free(crypt->encrypt_key);
134 	}
135 	if ((crypt->encrypt_key = calloc(1, sizeof(CAST_KEY))) == NULL) {
136 		(void) fprintf(stderr, "cast5_init: alloc failure\n");
137 		return 0;
138 	}
139 	CAST_set_key(crypt->encrypt_key, (int)crypt->keysize, crypt->key);
140 	if ((crypt->decrypt_key = calloc(1, sizeof(CAST_KEY))) == NULL) {
141 		(void) fprintf(stderr, "cast5_init: alloc failure\n");
142 		return 0;
143 	}
144 	CAST_set_key(crypt->decrypt_key, (int)crypt->keysize, crypt->key);
145 	return 1;
146 }
147 
148 static void
cast5_block_encrypt(pgp_crypt_t * crypt,void * out,const void * in)149 cast5_block_encrypt(pgp_crypt_t *crypt, void *out, const void *in)
150 {
151 	CAST_ecb_encrypt(in, out, crypt->encrypt_key, CAST_ENCRYPT);
152 }
153 
154 static void
cast5_block_decrypt(pgp_crypt_t * crypt,void * out,const void * in)155 cast5_block_decrypt(pgp_crypt_t *crypt, void *out, const void *in)
156 {
157 	CAST_ecb_encrypt(in, out, crypt->encrypt_key, CAST_DECRYPT);
158 }
159 
160 static void
cast5_cfb_encrypt(pgp_crypt_t * crypt,void * out,const void * in,size_t count)161 cast5_cfb_encrypt(pgp_crypt_t *crypt, void *out, const void *in, size_t count)
162 {
163 	CAST_cfb64_encrypt(in, out, (long)count,
164 			   crypt->encrypt_key, crypt->iv, &crypt->num,
165 			   CAST_ENCRYPT);
166 }
167 
168 static void
cast5_cfb_decrypt(pgp_crypt_t * crypt,void * out,const void * in,size_t count)169 cast5_cfb_decrypt(pgp_crypt_t *crypt, void *out, const void *in, size_t count)
170 {
171 	CAST_cfb64_encrypt(in, out, (long)count,
172 			   crypt->encrypt_key, crypt->iv, &crypt->num,
173 			   CAST_DECRYPT);
174 }
175 
176 #define TRAILER		"","","","",0,NULL,NULL
177 
178 static pgp_crypt_t cast5 =
179 {
180 	PGP_SA_CAST5,
181 	CAST_BLOCK,
182 	CAST_KEY_LENGTH,
183 	std_set_iv,
184 	std_set_key,
185 	cast5_init,
186 	std_resync,
187 	cast5_block_encrypt,
188 	cast5_block_decrypt,
189 	cast5_cfb_encrypt,
190 	cast5_cfb_decrypt,
191 	std_finish,
192 	TRAILER
193 };
194 
195 #ifndef OPENSSL_NO_IDEA
196 static int
idea_init(pgp_crypt_t * crypt)197 idea_init(pgp_crypt_t *crypt)
198 {
199 	if (crypt->keysize != IDEA_KEY_LENGTH) {
200 		(void) fprintf(stderr, "idea_init: keysize wrong\n");
201 		return 0;
202 	}
203 
204 	if (crypt->encrypt_key) {
205 		free(crypt->encrypt_key);
206 	}
207 	if ((crypt->encrypt_key = calloc(1, sizeof(IDEA_KEY_SCHEDULE))) == NULL) {
208 		(void) fprintf(stderr, "idea_init: alloc failure\n");
209 		return 0;
210 	}
211 
212 	/* note that we don't invert the key when decrypting for CFB mode */
213 	idea_set_encrypt_key(crypt->key, crypt->encrypt_key);
214 
215 	if (crypt->decrypt_key) {
216 		free(crypt->decrypt_key);
217 	}
218 	if ((crypt->decrypt_key = calloc(1, sizeof(IDEA_KEY_SCHEDULE))) == NULL) {
219 		(void) fprintf(stderr, "idea_init: alloc failure\n");
220 		return 0;
221 	}
222 
223 	idea_set_decrypt_key(crypt->encrypt_key, crypt->decrypt_key);
224 	return 1;
225 }
226 
227 static void
idea_block_encrypt(pgp_crypt_t * crypt,void * out,const void * in)228 idea_block_encrypt(pgp_crypt_t *crypt, void *out, const void *in)
229 {
230 	idea_ecb_encrypt(in, out, crypt->encrypt_key);
231 }
232 
233 static void
idea_block_decrypt(pgp_crypt_t * crypt,void * out,const void * in)234 idea_block_decrypt(pgp_crypt_t *crypt, void *out, const void *in)
235 {
236 	idea_ecb_encrypt(in, out, crypt->decrypt_key);
237 }
238 
239 static void
idea_cfb_encrypt(pgp_crypt_t * crypt,void * out,const void * in,size_t count)240 idea_cfb_encrypt(pgp_crypt_t *crypt, void *out, const void *in, size_t count)
241 {
242 	idea_cfb64_encrypt(in, out, (long)count,
243 			   crypt->encrypt_key, crypt->iv, &crypt->num,
244 			   CAST_ENCRYPT);
245 }
246 
247 static void
idea_cfb_decrypt(pgp_crypt_t * crypt,void * out,const void * in,size_t count)248 idea_cfb_decrypt(pgp_crypt_t *crypt, void *out, const void *in, size_t count)
249 {
250 	idea_cfb64_encrypt(in, out, (long)count,
251 			   crypt->decrypt_key, crypt->iv, &crypt->num,
252 			   CAST_DECRYPT);
253 }
254 
255 static const pgp_crypt_t idea =
256 {
257 	PGP_SA_IDEA,
258 	IDEA_BLOCK,
259 	IDEA_KEY_LENGTH,
260 	std_set_iv,
261 	std_set_key,
262 	idea_init,
263 	std_resync,
264 	idea_block_encrypt,
265 	idea_block_decrypt,
266 	idea_cfb_encrypt,
267 	idea_cfb_decrypt,
268 	std_finish,
269 	TRAILER
270 };
271 #endif				/* OPENSSL_NO_IDEA */
272 
273 /* AES with 128-bit key (AES) */
274 
275 #define KEYBITS_AES128 128
276 
277 static int
aes128_init(pgp_crypt_t * crypt)278 aes128_init(pgp_crypt_t *crypt)
279 {
280 	if (crypt->encrypt_key) {
281 		free(crypt->encrypt_key);
282 	}
283 	if ((crypt->encrypt_key = calloc(1, sizeof(AES_KEY))) == NULL) {
284 		(void) fprintf(stderr, "aes128_init: alloc failure\n");
285 		return 0;
286 	}
287 	if (AES_set_encrypt_key(crypt->key, KEYBITS_AES128,
288 			crypt->encrypt_key)) {
289 		fprintf(stderr, "aes128_init: Error setting encrypt_key\n");
290 	}
291 
292 	if (crypt->decrypt_key) {
293 		free(crypt->decrypt_key);
294 	}
295 	if ((crypt->decrypt_key = calloc(1, sizeof(AES_KEY))) == NULL) {
296 		(void) fprintf(stderr, "aes128_init: alloc failure\n");
297 		return 0;
298 	}
299 	if (AES_set_decrypt_key(crypt->key, KEYBITS_AES128,
300 				crypt->decrypt_key)) {
301 		fprintf(stderr, "aes128_init: Error setting decrypt_key\n");
302 	}
303 	return 1;
304 }
305 
306 static void
aes_block_encrypt(pgp_crypt_t * crypt,void * out,const void * in)307 aes_block_encrypt(pgp_crypt_t *crypt, void *out, const void *in)
308 {
309 	AES_encrypt(in, out, crypt->encrypt_key);
310 }
311 
312 static void
aes_block_decrypt(pgp_crypt_t * crypt,void * out,const void * in)313 aes_block_decrypt(pgp_crypt_t *crypt, void *out, const void *in)
314 {
315 	AES_decrypt(in, out, crypt->decrypt_key);
316 }
317 
318 static void
aes_cfb_encrypt(pgp_crypt_t * crypt,void * out,const void * in,size_t count)319 aes_cfb_encrypt(pgp_crypt_t *crypt, void *out, const void *in, size_t count)
320 {
321 	AES_cfb128_encrypt(in, out, (unsigned)count,
322 			   crypt->encrypt_key, crypt->iv, &crypt->num,
323 			   AES_ENCRYPT);
324 }
325 
326 static void
aes_cfb_decrypt(pgp_crypt_t * crypt,void * out,const void * in,size_t count)327 aes_cfb_decrypt(pgp_crypt_t *crypt, void *out, const void *in, size_t count)
328 {
329 	AES_cfb128_encrypt(in, out, (unsigned)count,
330 			   crypt->encrypt_key, crypt->iv, &crypt->num,
331 			   AES_DECRYPT);
332 }
333 
334 static const pgp_crypt_t aes128 =
335 {
336 	PGP_SA_AES_128,
337 	AES_BLOCK_SIZE,
338 	KEYBITS_AES128 / 8,
339 	std_set_iv,
340 	std_set_key,
341 	aes128_init,
342 	std_resync,
343 	aes_block_encrypt,
344 	aes_block_decrypt,
345 	aes_cfb_encrypt,
346 	aes_cfb_decrypt,
347 	std_finish,
348 	TRAILER
349 };
350 
351 /* AES with 256-bit key */
352 
353 #define KEYBITS_AES256 256
354 
355 static int
aes256_init(pgp_crypt_t * crypt)356 aes256_init(pgp_crypt_t *crypt)
357 {
358 	if (crypt->encrypt_key) {
359 		free(crypt->encrypt_key);
360 	}
361 	if ((crypt->encrypt_key = calloc(1, sizeof(AES_KEY))) == NULL) {
362 		(void) fprintf(stderr, "aes256_init: alloc failure\n");
363 		return 0;
364 	}
365 	if (AES_set_encrypt_key(crypt->key, KEYBITS_AES256,
366 			crypt->encrypt_key)) {
367 		fprintf(stderr, "aes256_init: Error setting encrypt_key\n");
368 		free(crypt->encrypt_key);
369 		crypt->encrypt_key = NULL;
370 		return 0;
371 	}
372 	if (crypt->decrypt_key) {
373 		free(crypt->decrypt_key);
374 	}
375 	if ((crypt->decrypt_key = calloc(1, sizeof(AES_KEY))) == NULL) {
376 		(void) fprintf(stderr, "aes256_init: alloc failure\n");
377 		free(crypt->encrypt_key);
378 		crypt->encrypt_key = NULL;
379 		return 0;
380 	}
381 	if (AES_set_decrypt_key(crypt->key, KEYBITS_AES256,
382 			crypt->decrypt_key)) {
383 		fprintf(stderr, "aes256_init: Error setting decrypt_key\n");
384 		free(crypt->encrypt_key);
385 		crypt->encrypt_key = NULL;
386 		free(crypt->decrypt_key);
387 		crypt->decrypt_key = NULL;
388 		return 0;
389 	}
390 	return 1;
391 }
392 
393 static const pgp_crypt_t aes256 =
394 {
395 	PGP_SA_AES_256,
396 	AES_BLOCK_SIZE,
397 	KEYBITS_AES256 / 8,
398 	std_set_iv,
399 	std_set_key,
400 	aes256_init,
401 	std_resync,
402 	aes_block_encrypt,
403 	aes_block_decrypt,
404 	aes_cfb_encrypt,
405 	aes_cfb_decrypt,
406 	std_finish,
407 	TRAILER
408 };
409 
410 /* Triple DES */
411 
412 static int
tripledes_init(pgp_crypt_t * crypt)413 tripledes_init(pgp_crypt_t *crypt)
414 {
415 	DES_key_schedule *keys;
416 	int             n;
417 
418 	if (crypt->encrypt_key) {
419 		free(crypt->encrypt_key);
420 	}
421 	if ((keys = crypt->encrypt_key = calloc(1, 3 * sizeof(DES_key_schedule))) == NULL) {
422 		(void) fprintf(stderr, "tripledes_init: alloc failure\n");
423 		return 0;
424 	}
425 	for (n = 0; n < 3; ++n) {
426 		DES_set_key((DES_cblock *)(void *)(crypt->key + n * 8),
427 			&keys[n]);
428 	}
429 	return 1;
430 }
431 
432 static void
tripledes_block_encrypt(pgp_crypt_t * crypt,void * out,const void * in)433 tripledes_block_encrypt(pgp_crypt_t *crypt, void *out, const void *in)
434 {
435 	DES_key_schedule *keys = crypt->encrypt_key;
436 
437 	DES_ecb3_encrypt(__UNCONST(in), out, &keys[0], &keys[1], &keys[2],
438 			DES_ENCRYPT);
439 }
440 
441 static void
tripledes_block_decrypt(pgp_crypt_t * crypt,void * out,const void * in)442 tripledes_block_decrypt(pgp_crypt_t *crypt, void *out, const void *in)
443 {
444 	DES_key_schedule *keys = crypt->encrypt_key;
445 
446 	DES_ecb3_encrypt(__UNCONST(in), out, &keys[0], &keys[1], &keys[2],
447 			DES_DECRYPT);
448 }
449 
450 static void
tripledes_cfb_encrypt(pgp_crypt_t * crypt,void * out,const void * in,size_t count)451 tripledes_cfb_encrypt(pgp_crypt_t *crypt, void *out, const void *in,
452 			size_t count)
453 {
454 	DES_key_schedule *keys = crypt->encrypt_key;
455 
456 	DES_ede3_cfb64_encrypt(in, out, (long)count,
457 		&keys[0], &keys[1], &keys[2], (DES_cblock *)(void *)crypt->iv,
458 		&crypt->num, DES_ENCRYPT);
459 }
460 
461 static void
tripledes_cfb_decrypt(pgp_crypt_t * crypt,void * out,const void * in,size_t count)462 tripledes_cfb_decrypt(pgp_crypt_t *crypt, void *out, const void *in,
463 			size_t count)
464 {
465 	DES_key_schedule *keys = crypt->encrypt_key;
466 
467 	DES_ede3_cfb64_encrypt(in, out, (long)count,
468 		&keys[0], &keys[1], &keys[2], (DES_cblock *)(void *)crypt->iv,
469 		&crypt->num, DES_DECRYPT);
470 }
471 
472 static const pgp_crypt_t tripledes =
473 {
474 	PGP_SA_TRIPLEDES,
475 	8,
476 	24,
477 	std_set_iv,
478 	std_set_key,
479 	tripledes_init,
480 	std_resync,
481 	tripledes_block_encrypt,
482 	tripledes_block_decrypt,
483 	tripledes_cfb_encrypt,
484 	tripledes_cfb_decrypt,
485 	std_finish,
486 	TRAILER
487 };
488 
489 #if defined(HAVE_OPENSSL_CAMELLIA_H) && !defined(OPENSSL_NO_CAMELLIA)
490 /* Camellia with 128-bit key (CAMELLIA) */
491 
492 #define KEYBITS_CAMELLIA128 128
493 
494 static int
camellia128_init(pgp_crypt_t * crypt)495 camellia128_init(pgp_crypt_t *crypt)
496 {
497 	if (crypt->encrypt_key) {
498 		free(crypt->encrypt_key);
499 	}
500 	if ((crypt->encrypt_key = calloc(1, sizeof(CAMELLIA_KEY))) == NULL) {
501 		(void) fprintf(stderr, "camellia128_init: alloc failure\n");
502 		return 0;
503 	}
504 	if (Camellia_set_key(crypt->key, KEYBITS_CAMELLIA128, crypt->encrypt_key)) {
505 		fprintf(stderr, "camellia128_init: Error setting encrypt_key\n");
506 	}
507 	if (crypt->decrypt_key) {
508 		free(crypt->decrypt_key);
509 	}
510 	if ((crypt->decrypt_key = calloc(1, sizeof(CAMELLIA_KEY))) == NULL) {
511 		(void) fprintf(stderr, "camellia128_init: alloc failure\n");
512 		return 0;
513 	}
514 	if (Camellia_set_key(crypt->key, KEYBITS_CAMELLIA128, crypt->decrypt_key)) {
515 		fprintf(stderr, "camellia128_init: Error setting decrypt_key\n");
516 	}
517 	return 1;
518 }
519 
520 static void
camellia_block_encrypt(pgp_crypt_t * crypt,void * out,const void * in)521 camellia_block_encrypt(pgp_crypt_t *crypt, void *out, const void *in)
522 {
523 	Camellia_encrypt(in, out, crypt->encrypt_key);
524 }
525 
526 static void
camellia_block_decrypt(pgp_crypt_t * crypt,void * out,const void * in)527 camellia_block_decrypt(pgp_crypt_t *crypt, void *out, const void *in)
528 {
529 	Camellia_decrypt(in, out, crypt->decrypt_key);
530 }
531 
532 static void
camellia_cfb_encrypt(pgp_crypt_t * crypt,void * out,const void * in,size_t count)533 camellia_cfb_encrypt(pgp_crypt_t *crypt, void *out, const void *in, size_t count)
534 {
535 	Camellia_cfb128_encrypt(in, out, (unsigned)count,
536 			   crypt->encrypt_key, crypt->iv, &crypt->num,
537 			   CAMELLIA_ENCRYPT);
538 }
539 
540 static void
camellia_cfb_decrypt(pgp_crypt_t * crypt,void * out,const void * in,size_t count)541 camellia_cfb_decrypt(pgp_crypt_t *crypt, void *out, const void *in, size_t count)
542 {
543 	Camellia_cfb128_encrypt(in, out, (unsigned)count,
544 			   crypt->encrypt_key, crypt->iv, &crypt->num,
545 			   CAMELLIA_DECRYPT);
546 }
547 
548 static const pgp_crypt_t camellia128 =
549 {
550 	PGP_SA_CAMELLIA_128,
551 	CAMELLIA_BLOCK_SIZE,
552 	KEYBITS_CAMELLIA128 / 8,
553 	std_set_iv,
554 	std_set_key,
555 	camellia128_init,
556 	std_resync,
557 	camellia_block_encrypt,
558 	camellia_block_decrypt,
559 	camellia_cfb_encrypt,
560 	camellia_cfb_decrypt,
561 	std_finish,
562 	TRAILER
563 };
564 
565 /* Camellia with 256-bit key (CAMELLIA) */
566 
567 #define KEYBITS_CAMELLIA256 256
568 
569 static int
camellia256_init(pgp_crypt_t * crypt)570 camellia256_init(pgp_crypt_t *crypt)
571 {
572 	if (crypt->encrypt_key) {
573 		free(crypt->encrypt_key);
574 	}
575 	if ((crypt->encrypt_key = calloc(1, sizeof(CAMELLIA_KEY))) == NULL) {
576 		(void) fprintf(stderr, "camellia256_init: alloc failure\n");
577 		return 0;
578 	}
579 	if (Camellia_set_key(crypt->key, KEYBITS_CAMELLIA256, crypt->encrypt_key)) {
580 		fprintf(stderr, "camellia256_init: Error setting encrypt_key\n");
581 	}
582 	if (crypt->decrypt_key) {
583 		free(crypt->decrypt_key);
584 	}
585 	if ((crypt->decrypt_key = calloc(1, sizeof(CAMELLIA_KEY))) == NULL) {
586 		(void) fprintf(stderr, "camellia256_init: alloc failure\n");
587 		return 0;
588 	}
589 	if (Camellia_set_key(crypt->key, KEYBITS_CAMELLIA256, crypt->decrypt_key)) {
590 		fprintf(stderr, "camellia256_init: Error setting decrypt_key\n");
591 	}
592 	return 1;
593 }
594 
595 static const pgp_crypt_t camellia256 =
596 {
597 	PGP_SA_CAMELLIA_256,
598 	CAMELLIA_BLOCK_SIZE,
599 	KEYBITS_CAMELLIA256 / 8,
600 	std_set_iv,
601 	std_set_key,
602 	camellia256_init,
603 	std_resync,
604 	camellia_block_encrypt,
605 	camellia_block_decrypt,
606 	camellia_cfb_encrypt,
607 	camellia_cfb_decrypt,
608 	std_finish,
609 	TRAILER
610 };
611 #endif
612 
613 
614 static const pgp_crypt_t *
get_proto(pgp_symm_alg_t alg)615 get_proto(pgp_symm_alg_t alg)
616 {
617 	switch (alg) {
618 	case PGP_SA_CAST5:
619 		return &cast5;
620 #ifndef OPENSSL_NO_IDEA
621 	case PGP_SA_IDEA:
622 		return &idea;
623 #endif				/* OPENSSL_NO_IDEA */
624 	case PGP_SA_AES_128:
625 		return &aes128;
626 	case PGP_SA_AES_256:
627 		return &aes256;
628 #if defined(HAVE_OPENSSL_CAMELLIA_H) && !defined(OPENSSL_NO_CAMELLIA)
629 	case PGP_SA_CAMELLIA_128:
630 		return &camellia128;
631 	case PGP_SA_CAMELLIA_256:
632 		return &camellia256;
633 #endif
634 	case PGP_SA_TRIPLEDES:
635 		return &tripledes;
636 	default:
637 		(void) fprintf(stderr, "Unknown algorithm: %d (%s)\n",
638 			alg, pgp_show_symm_alg(alg));
639 	}
640 	return NULL;
641 }
642 
643 int
pgp_crypt_any(pgp_crypt_t * crypt,pgp_symm_alg_t alg)644 pgp_crypt_any(pgp_crypt_t *crypt, pgp_symm_alg_t alg)
645 {
646 	const pgp_crypt_t *ptr = get_proto(alg);
647 
648 	if (ptr) {
649 		*crypt = *ptr;
650 		return 1;
651 	} else {
652 		(void) memset(crypt, 0x0, sizeof(*crypt));
653 		return 0;
654 	}
655 }
656 
657 unsigned
pgp_block_size(pgp_symm_alg_t alg)658 pgp_block_size(pgp_symm_alg_t alg)
659 {
660 	const pgp_crypt_t *p = get_proto(alg);
661 
662 	return (p == NULL) ? 0 : (unsigned)p->blocksize;
663 }
664 
665 unsigned
pgp_key_size(pgp_symm_alg_t alg)666 pgp_key_size(pgp_symm_alg_t alg)
667 {
668 	const pgp_crypt_t *p = get_proto(alg);
669 
670 	return (p == NULL) ? 0 : (unsigned)p->keysize;
671 }
672 
673 void
pgp_encrypt_init(pgp_crypt_t * encrypt)674 pgp_encrypt_init(pgp_crypt_t *encrypt)
675 {
676 	/* \todo should there be a separate pgp_encrypt_init? */
677 	pgp_decrypt_init(encrypt);
678 }
679 
680 void
pgp_decrypt_init(pgp_crypt_t * decrypt)681 pgp_decrypt_init(pgp_crypt_t *decrypt)
682 {
683 	decrypt->base_init(decrypt);
684 	decrypt->block_encrypt(decrypt, decrypt->siv, decrypt->iv);
685 	(void) memcpy(decrypt->civ, decrypt->siv, decrypt->blocksize);
686 	decrypt->num = 0;
687 }
688 
689 size_t
pgp_decrypt_se(pgp_crypt_t * decrypt,void * outvoid,const void * invoid,size_t count)690 pgp_decrypt_se(pgp_crypt_t *decrypt, void *outvoid, const void *invoid,
691 		size_t count)
692 {
693 	const uint8_t	*in = invoid;
694 	uint8_t		*out = outvoid;
695 	int              saved = (int)count;
696 
697 	/*
698 	 * in order to support v3's weird resyncing we have to implement CFB
699 	 * mode ourselves
700 	 */
701 	while (count-- > 0) {
702 		uint8_t   t;
703 
704 		if ((size_t) decrypt->num == decrypt->blocksize) {
705 			(void) memcpy(decrypt->siv, decrypt->civ,
706 					decrypt->blocksize);
707 			decrypt->block_decrypt(decrypt, decrypt->civ,
708 					decrypt->civ);
709 			decrypt->num = 0;
710 		}
711 		t = decrypt->civ[decrypt->num];
712 		*out++ = t ^ (decrypt->civ[decrypt->num++] = *in++);
713 	}
714 
715 	return (size_t)saved;
716 }
717 
718 size_t
pgp_encrypt_se(pgp_crypt_t * encrypt,void * outvoid,const void * invoid,size_t count)719 pgp_encrypt_se(pgp_crypt_t *encrypt, void *outvoid, const void *invoid,
720 	       size_t count)
721 {
722 	const uint8_t	*in = invoid;
723 	uint8_t		*out = outvoid;
724 	int              saved = (int)count;
725 
726 	/*
727 	 * in order to support v3's weird resyncing we have to implement CFB
728 	 * mode ourselves
729 	 */
730 	while (count-- > 0) {
731 		if ((size_t) encrypt->num == encrypt->blocksize) {
732 			(void) memcpy(encrypt->siv, encrypt->civ,
733 					encrypt->blocksize);
734 			encrypt->block_encrypt(encrypt, encrypt->civ,
735 					encrypt->civ);
736 			encrypt->num = 0;
737 		}
738 		encrypt->civ[encrypt->num] = *out++ =
739 				encrypt->civ[encrypt->num] ^ *in++;
740 		++encrypt->num;
741 	}
742 
743 	return (size_t)saved;
744 }
745 
746 /**
747 \ingroup HighLevel_Supported
748 \brief Is this Symmetric Algorithm supported?
749 \param alg Symmetric Algorithm to check
750 \return 1 if supported; else 0
751 */
752 unsigned
pgp_is_sa_supported(pgp_symm_alg_t alg)753 pgp_is_sa_supported(pgp_symm_alg_t alg)
754 {
755 	switch (alg) {
756 	case PGP_SA_AES_128:
757 	case PGP_SA_AES_256:
758 	case PGP_SA_CAST5:
759 	case PGP_SA_TRIPLEDES:
760 #if defined(HAVE_OPENSSL_CAMELLIA_H) && !defined(OPENSSL_NO_CAMELLIA)
761 	case PGP_SA_CAMELLIA_128:
762 	case PGP_SA_CAMELLIA_256:
763 #endif
764 #ifndef OPENSSL_NO_IDEA
765 	case PGP_SA_IDEA:
766 #endif
767 		return 1;
768 
769 	default:
770 		fprintf(stderr, "\nWarning: %s not supported\n",
771 			pgp_show_symm_alg(alg));
772 		return 0;
773 	}
774 }
775 
776 size_t
pgp_encrypt_se_ip(pgp_crypt_t * crypt,void * out,const void * in,size_t count)777 pgp_encrypt_se_ip(pgp_crypt_t *crypt, void *out, const void *in,
778 		  size_t count)
779 {
780 	if (!pgp_is_sa_supported(crypt->alg)) {
781 		return 0;
782 	}
783 
784 	crypt->cfb_encrypt(crypt, out, in, count);
785 
786 	/* \todo test this number was encrypted */
787 	return count;
788 }
789 
790 size_t
pgp_decrypt_se_ip(pgp_crypt_t * crypt,void * out,const void * in,size_t count)791 pgp_decrypt_se_ip(pgp_crypt_t *crypt, void *out, const void *in,
792 		  size_t count)
793 {
794 	if (!pgp_is_sa_supported(crypt->alg)) {
795 		return 0;
796 	}
797 
798 	crypt->cfb_decrypt(crypt, out, in, count);
799 
800 	/* \todo check this number was in fact decrypted */
801 	return count;
802 }
803