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