1*2f1aa25bSmpi /* $OpenBSD: crypto.c,v 1.35 2018/01/15 09:54:48 mpi Exp $ */
2b40edc34Sniklas /* $EOM: crypto.c,v 1.32 2000/03/07 20:08:51 niklas Exp $ */
32040585eSniklas
42040585eSniklas /*
52040585eSniklas * Copyright (c) 1998 Niels Provos. All rights reserved.
605ededd4Sniklas * Copyright (c) 1999, 2000 Niklas Hallqvist. All rights reserved.
72040585eSniklas *
82040585eSniklas * Redistribution and use in source and binary forms, with or without
92040585eSniklas * modification, are permitted provided that the following conditions
102040585eSniklas * are met:
112040585eSniklas * 1. Redistributions of source code must retain the above copyright
122040585eSniklas * notice, this list of conditions and the following disclaimer.
132040585eSniklas * 2. Redistributions in binary form must reproduce the above copyright
142040585eSniklas * notice, this list of conditions and the following disclaimer in the
152040585eSniklas * documentation and/or other materials provided with the distribution.
162040585eSniklas *
172040585eSniklas * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
182040585eSniklas * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
192040585eSniklas * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
202040585eSniklas * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
212040585eSniklas * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
222040585eSniklas * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232040585eSniklas * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242040585eSniklas * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252040585eSniklas * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
262040585eSniklas * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272040585eSniklas */
282040585eSniklas
292040585eSniklas /*
302040585eSniklas * This code was written under funding by Ericsson Radio Systems.
312040585eSniklas */
322040585eSniklas
3382bad92dSderaadt #include <sys/types.h>
342040585eSniklas #include <stdlib.h>
352040585eSniklas #include <string.h>
362040585eSniklas
372040585eSniklas #include "crypto.h"
382040585eSniklas #include "log.h"
392040585eSniklas
402040585eSniklas enum cryptoerr des3_init(struct keystate *, u_int8_t *, u_int16_t);
412040585eSniklas enum cryptoerr blf_init(struct keystate *, u_int8_t *, u_int16_t);
422040585eSniklas enum cryptoerr cast_init(struct keystate *, u_int8_t *, u_int16_t);
4320f38361Smarkus enum cryptoerr aes_init(struct keystate *, u_int8_t *, u_int16_t);
441ad5b6f7Smarkus void des3_encrypt(struct keystate *, u_int8_t *, u_int16_t);
451ad5b6f7Smarkus void des3_decrypt(struct keystate *, u_int8_t *, u_int16_t);
461ad5b6f7Smarkus void blf_encrypt(struct keystate *, u_int8_t *, u_int16_t);
471ad5b6f7Smarkus void blf_decrypt(struct keystate *, u_int8_t *, u_int16_t);
481ad5b6f7Smarkus void cast1_encrypt(struct keystate *, u_int8_t *, u_int16_t);
491ad5b6f7Smarkus void cast1_decrypt(struct keystate *, u_int8_t *, u_int16_t);
5020f38361Smarkus void aes_encrypt(struct keystate *, u_int8_t *, u_int16_t);
5120f38361Smarkus void aes_decrypt(struct keystate *, u_int8_t *, u_int16_t);
522040585eSniklas
532040585eSniklas struct crypto_xf transforms[] = {
542040585eSniklas {
5550eea14cSho TRIPLEDES_CBC, "Triple-DES (CBC-Mode)", 24, 24,
5650eea14cSho BLOCKSIZE, 0,
572040585eSniklas des3_init,
581ad5b6f7Smarkus des3_encrypt, des3_decrypt
592040585eSniklas },
602040585eSniklas {
6150eea14cSho BLOWFISH_CBC, "Blowfish (CBC-Mode)", 12, 56,
6250eea14cSho BLOCKSIZE, 0,
632040585eSniklas blf_init,
641ad5b6f7Smarkus blf_encrypt, blf_decrypt
652040585eSniklas },
662040585eSniklas {
6750eea14cSho CAST_CBC, "CAST (CBC-Mode)", 12, 16,
6850eea14cSho BLOCKSIZE, 0,
692040585eSniklas cast_init,
701ad5b6f7Smarkus cast1_encrypt, cast1_decrypt
712040585eSniklas },
7220f38361Smarkus {
7350eea14cSho AES_CBC, "AES (CBC-Mode)", 16, 32,
7450eea14cSho AES_BLOCK_SIZE, 0,
7520f38361Smarkus aes_init,
7620f38361Smarkus aes_encrypt, aes_decrypt
7720f38361Smarkus },
782040585eSniklas };
792040585eSniklas
802040585eSniklas enum cryptoerr
des3_init(struct keystate * ks,u_int8_t * key,u_int16_t len)812040585eSniklas des3_init(struct keystate *ks, u_int8_t *key, u_int16_t len)
822040585eSniklas {
830456bce5Sjsg DES_set_odd_parity((void *)key);
840456bce5Sjsg DES_set_odd_parity((void *)(key + 8));
850456bce5Sjsg DES_set_odd_parity((void *)(key + 16));
862040585eSniklas
871ad5b6f7Smarkus /* As of the draft Tripe-DES does not check for weak keys */
880456bce5Sjsg DES_set_key((void *)key, &ks->ks_des[0]);
890456bce5Sjsg DES_set_key((void *)(key + 8), &ks->ks_des[1]);
900456bce5Sjsg DES_set_key((void *)(key + 16), &ks->ks_des[2]);
911ad5b6f7Smarkus
921ad5b6f7Smarkus return EOKAY;
932040585eSniklas }
941ad5b6f7Smarkus
951ad5b6f7Smarkus void
des3_encrypt(struct keystate * ks,u_int8_t * data,u_int16_t len)961ad5b6f7Smarkus des3_encrypt(struct keystate *ks, u_int8_t *data, u_int16_t len)
971ad5b6f7Smarkus {
981ad5b6f7Smarkus u_int8_t iv[MAXBLK];
991ad5b6f7Smarkus
1001ad5b6f7Smarkus memcpy(iv, ks->riv, ks->xf->blocksize);
1010456bce5Sjsg DES_ede3_cbc_encrypt((void *)data, (void *)data, len, &ks->ks_des[0],
1020456bce5Sjsg &ks->ks_des[1], &ks->ks_des[2], (void *)iv, DES_ENCRYPT);
1031ad5b6f7Smarkus }
1041ad5b6f7Smarkus
1051ad5b6f7Smarkus void
des3_decrypt(struct keystate * ks,u_int8_t * data,u_int16_t len)1061ad5b6f7Smarkus des3_decrypt(struct keystate *ks, u_int8_t *data, u_int16_t len)
1071ad5b6f7Smarkus {
1081ad5b6f7Smarkus u_int8_t iv[MAXBLK];
1091ad5b6f7Smarkus
1101ad5b6f7Smarkus memcpy(iv, ks->riv, ks->xf->blocksize);
1110456bce5Sjsg DES_ede3_cbc_encrypt((void *)data, (void *)data, len, &ks->ks_des[0],
1120456bce5Sjsg &ks->ks_des[1], &ks->ks_des[2], (void *)iv, DES_DECRYPT);
1131ad5b6f7Smarkus }
1142040585eSniklas
1152040585eSniklas enum cryptoerr
blf_init(struct keystate * ks,u_int8_t * key,u_int16_t len)1162040585eSniklas blf_init(struct keystate *ks, u_int8_t *key, u_int16_t len)
1172040585eSniklas {
1181ad5b6f7Smarkus blf_key(&ks->ks_blf, key, len);
1192040585eSniklas
1201ad5b6f7Smarkus return EOKAY;
1212040585eSniklas }
1221ad5b6f7Smarkus
1231ad5b6f7Smarkus void
blf_encrypt(struct keystate * ks,u_int8_t * data,u_int16_t len)1241ad5b6f7Smarkus blf_encrypt(struct keystate *ks, u_int8_t *data, u_int16_t len)
1251ad5b6f7Smarkus {
1261ad5b6f7Smarkus u_int16_t i, blocksize = ks->xf->blocksize;
1271ad5b6f7Smarkus u_int8_t *iv = ks->liv;
1281ad5b6f7Smarkus u_int32_t xl, xr;
1291ad5b6f7Smarkus
1301ad5b6f7Smarkus memcpy(iv, ks->riv, blocksize);
1311ad5b6f7Smarkus
132fb9475d6Sderaadt for (i = 0; i < len; data += blocksize, i += blocksize) {
1331ad5b6f7Smarkus XOR64(data, iv);
1341ad5b6f7Smarkus xl = GET_32BIT_BIG(data);
1351ad5b6f7Smarkus xr = GET_32BIT_BIG(data + 4);
1361ad5b6f7Smarkus Blowfish_encipher(&ks->ks_blf, &xl, &xr);
1371ad5b6f7Smarkus SET_32BIT_BIG(data, xl);
1381ad5b6f7Smarkus SET_32BIT_BIG(data + 4, xr);
1391ad5b6f7Smarkus SET64(iv, data);
1401ad5b6f7Smarkus }
1411ad5b6f7Smarkus }
1421ad5b6f7Smarkus
1431ad5b6f7Smarkus void
blf_decrypt(struct keystate * ks,u_int8_t * data,u_int16_t len)1441ad5b6f7Smarkus blf_decrypt(struct keystate *ks, u_int8_t *data, u_int16_t len)
1451ad5b6f7Smarkus {
1461ad5b6f7Smarkus u_int16_t i, blocksize = ks->xf->blocksize;
1471ad5b6f7Smarkus u_int32_t xl, xr;
1481ad5b6f7Smarkus
1491ad5b6f7Smarkus data += len - blocksize;
150df915834Shshoexer for (i = len - blocksize; i >= blocksize; data -= blocksize,
151df915834Shshoexer i -= blocksize) {
1521ad5b6f7Smarkus xl = GET_32BIT_BIG(data);
1531ad5b6f7Smarkus xr = GET_32BIT_BIG(data + 4);
1541ad5b6f7Smarkus Blowfish_decipher(&ks->ks_blf, &xl, &xr);
1551ad5b6f7Smarkus SET_32BIT_BIG(data, xl);
1561ad5b6f7Smarkus SET_32BIT_BIG(data + 4, xr);
1571ad5b6f7Smarkus XOR64(data, data - blocksize);
1581ad5b6f7Smarkus
1591ad5b6f7Smarkus }
1601ad5b6f7Smarkus xl = GET_32BIT_BIG(data);
1611ad5b6f7Smarkus xr = GET_32BIT_BIG(data + 4);
1621ad5b6f7Smarkus Blowfish_decipher(&ks->ks_blf, &xl, &xr);
1631ad5b6f7Smarkus SET_32BIT_BIG(data, xl);
1641ad5b6f7Smarkus SET_32BIT_BIG(data + 4, xr);
1651ad5b6f7Smarkus XOR64(data, ks->riv);
1661ad5b6f7Smarkus }
1672040585eSniklas
1682040585eSniklas enum cryptoerr
cast_init(struct keystate * ks,u_int8_t * key,u_int16_t len)1692040585eSniklas cast_init(struct keystate *ks, u_int8_t *key, u_int16_t len)
1702040585eSniklas {
1710ceec575Smikeb CAST_set_key(&ks->ks_cast, len, key);
1722040585eSniklas return EOKAY;
1732040585eSniklas }
1742040585eSniklas
1752040585eSniklas void
cast1_encrypt(struct keystate * ks,u_int8_t * data,u_int16_t len)1761ad5b6f7Smarkus cast1_encrypt(struct keystate *ks, u_int8_t *data, u_int16_t len)
1772040585eSniklas {
1780ceec575Smikeb memcpy(ks->liv, ks->riv, ks->xf->blocksize);
1790ceec575Smikeb CAST_cbc_encrypt(data, data, len, &ks->ks_cast, ks->liv, 1);
1802040585eSniklas }
1812040585eSniklas
1822040585eSniklas void
cast1_decrypt(struct keystate * ks,u_int8_t * data,u_int16_t len)1831ad5b6f7Smarkus cast1_decrypt(struct keystate *ks, u_int8_t *data, u_int16_t len)
1842040585eSniklas {
1850ceec575Smikeb CAST_cbc_encrypt(data, data, len, &ks->ks_cast, ks->riv, 0);
1861ad5b6f7Smarkus }
1872040585eSniklas
18820f38361Smarkus enum cryptoerr
aes_init(struct keystate * ks,u_int8_t * key,u_int16_t len)18920f38361Smarkus aes_init(struct keystate *ks, u_int8_t *key, u_int16_t len)
19020f38361Smarkus {
19120f38361Smarkus AES_set_encrypt_key(key, len << 3, &ks->ks_aes[0]);
19220f38361Smarkus AES_set_decrypt_key(key, len << 3, &ks->ks_aes[1]);
19320f38361Smarkus return EOKAY;
19420f38361Smarkus }
19520f38361Smarkus
19620f38361Smarkus void
aes_encrypt(struct keystate * ks,u_int8_t * data,u_int16_t len)19720f38361Smarkus aes_encrypt(struct keystate *ks, u_int8_t *data, u_int16_t len)
19820f38361Smarkus {
19920f38361Smarkus u_int8_t iv[MAXBLK];
20020f38361Smarkus
20120f38361Smarkus memcpy(iv, ks->riv, ks->xf->blocksize);
20220f38361Smarkus AES_cbc_encrypt(data, data, len, &ks->ks_aes[0], iv, AES_ENCRYPT);
20320f38361Smarkus }
20420f38361Smarkus
20520f38361Smarkus void
aes_decrypt(struct keystate * ks,u_int8_t * data,u_int16_t len)20620f38361Smarkus aes_decrypt(struct keystate *ks, u_int8_t *data, u_int16_t len)
20720f38361Smarkus {
20820f38361Smarkus u_int8_t iv[MAXBLK];
20920f38361Smarkus
21020f38361Smarkus memcpy(iv, ks->riv, ks->xf->blocksize);
21120f38361Smarkus AES_cbc_encrypt(data, data, len, &ks->ks_aes[1], iv, AES_DECRYPT);
21220f38361Smarkus }
21320f38361Smarkus
2142040585eSniklas struct crypto_xf *
crypto_get(enum transform id)2152040585eSniklas crypto_get(enum transform id)
2162040585eSniklas {
217c7c448f9Sho size_t i;
2182040585eSniklas
2192040585eSniklas for (i = 0; i < sizeof transforms / sizeof transforms[0]; i++)
2202040585eSniklas if (id == transforms[i].id)
2212040585eSniklas return &transforms[i];
2222040585eSniklas
2232040585eSniklas return 0;
2242040585eSniklas }
2252040585eSniklas
2262040585eSniklas struct keystate *
crypto_init(struct crypto_xf * xf,u_int8_t * key,u_int16_t len,enum cryptoerr * err)2272040585eSniklas crypto_init(struct crypto_xf *xf, u_int8_t *key, u_int16_t len,
2282040585eSniklas enum cryptoerr *err)
2292040585eSniklas {
230390fe947Sniklas struct keystate *ks;
2312040585eSniklas
232fb9475d6Sderaadt if (len < xf->keymin || len > xf->keymax) {
233df915834Shshoexer LOG_DBG((LOG_CRYPTO, 10, "crypto_init: invalid key length %d",
234df915834Shshoexer len));
2352040585eSniklas *err = EKEYLEN;
236390fe947Sniklas return 0;
2372040585eSniklas }
238390fe947Sniklas ks = calloc(1, sizeof *ks);
239fb9475d6Sderaadt if (!ks) {
2407eb3b581Sderaadt log_error("crypto_init: calloc (1, %lu) failed",
2417eb3b581Sderaadt (unsigned long)sizeof *ks);
2422040585eSniklas *err = ENOCRYPTO;
243390fe947Sniklas return 0;
2442040585eSniklas }
2452040585eSniklas ks->xf = xf;
2462040585eSniklas
247390fe947Sniklas /* Setup the IV. */
2482040585eSniklas ks->riv = ks->iv;
2492040585eSniklas ks->liv = ks->iv2;
2502040585eSniklas
25151ca15aeSniklas LOG_DBG_BUF((LOG_CRYPTO, 40, "crypto_init: key", key, len));
2522040585eSniklas
2532040585eSniklas *err = xf->init(ks, key, len);
254fb9475d6Sderaadt if (*err != EOKAY) {
25551ca15aeSniklas LOG_DBG((LOG_CRYPTO, 30, "crypto_init: weak key found for %s",
25651ca15aeSniklas xf->name));
2572040585eSniklas free(ks);
258390fe947Sniklas return 0;
2592040585eSniklas }
2602040585eSniklas return ks;
2612040585eSniklas }
2622040585eSniklas
2632040585eSniklas void
crypto_update_iv(struct keystate * ks)2642040585eSniklas crypto_update_iv(struct keystate *ks)
2652040585eSniklas {
2662040585eSniklas u_int8_t *tmp;
2672040585eSniklas
2682040585eSniklas tmp = ks->riv;
2692040585eSniklas ks->riv = ks->liv;
2702040585eSniklas ks->liv = tmp;
2712040585eSniklas
27251ca15aeSniklas LOG_DBG_BUF((LOG_CRYPTO, 50, "crypto_update_iv: updated IV", ks->riv,
27351ca15aeSniklas ks->xf->blocksize));
2742040585eSniklas }
2752040585eSniklas
2762040585eSniklas void
crypto_init_iv(struct keystate * ks,u_int8_t * buf,size_t len)2772040585eSniklas crypto_init_iv(struct keystate *ks, u_int8_t *buf, size_t len)
2782040585eSniklas {
2792040585eSniklas memcpy(ks->riv, buf, len);
2802040585eSniklas
28120f38361Smarkus LOG_DBG_BUF((LOG_CRYPTO, 50, "crypto_init_iv: initialized IV", ks->riv,
28251ca15aeSniklas len));
2832040585eSniklas }
2842040585eSniklas
2852040585eSniklas void
crypto_encrypt(struct keystate * ks,u_int8_t * buf,u_int16_t len)2862040585eSniklas crypto_encrypt(struct keystate *ks, u_int8_t *buf, u_int16_t len)
2872040585eSniklas {
288bceabd9cScloder LOG_DBG_BUF((LOG_CRYPTO, 70, "crypto_encrypt: before encryption", buf,
28951ca15aeSniklas len));
2902040585eSniklas ks->xf->encrypt(ks, buf, len);
2912040585eSniklas memcpy(ks->liv, buf + len - ks->xf->blocksize, ks->xf->blocksize);
292bceabd9cScloder LOG_DBG_BUF((LOG_CRYPTO, 70, "crypto_encrypt: after encryption", buf,
29351ca15aeSniklas len));
2942040585eSniklas }
2952040585eSniklas
2962040585eSniklas void
crypto_decrypt(struct keystate * ks,u_int8_t * buf,u_int16_t len)2972040585eSniklas crypto_decrypt(struct keystate *ks, u_int8_t *buf, u_int16_t len)
2982040585eSniklas {
299bceabd9cScloder LOG_DBG_BUF((LOG_CRYPTO, 70, "crypto_decrypt: before decryption", buf,
30051ca15aeSniklas len));
3012040585eSniklas /*
3022040585eSniklas * XXX There is controversy about the correctness of updating the IV
3032040585eSniklas * like this.
3042040585eSniklas */
3052040585eSniklas memcpy(ks->liv, buf + len - ks->xf->blocksize, ks->xf->blocksize);
3067b425235Smillert ks->xf->decrypt(ks, buf, len);
307bceabd9cScloder LOG_DBG_BUF((LOG_CRYPTO, 70, "crypto_decrypt: after decryption", buf,
30851ca15aeSniklas len));
3092040585eSniklas }
3102040585eSniklas
311390fe947Sniklas /* Make a copy of the keystate pointed to by OKS. */
3122040585eSniklas struct keystate *
crypto_clone_keystate(struct keystate * oks)3132040585eSniklas crypto_clone_keystate(struct keystate *oks)
3142040585eSniklas {
3152040585eSniklas struct keystate *ks;
3162040585eSniklas
3172040585eSniklas ks = malloc(sizeof *ks);
318fb9475d6Sderaadt if (!ks) {
3197eb3b581Sderaadt log_error("crypto_clone_keystate: malloc (%lu) failed",
3207eb3b581Sderaadt (unsigned long)sizeof *ks);
3212040585eSniklas return 0;
322390fe947Sniklas }
3232040585eSniklas memcpy(ks, oks, sizeof *ks);
324fb9475d6Sderaadt if (oks->riv == oks->iv) {
3252040585eSniklas ks->riv = ks->iv;
3262040585eSniklas ks->liv = ks->iv2;
327fb9475d6Sderaadt } else {
3282040585eSniklas ks->riv = ks->iv2;
3292040585eSniklas ks->liv = ks->iv;
3302040585eSniklas }
3312040585eSniklas return ks;
3322040585eSniklas }
333