9d40e3e50c9d303c23fc77df2524aa9bc4ec9055
[strongswan.git] / src / pluto / alg / ike_alg_twofish.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <stddef.h>
4 #include <sys/types.h>
5 #include <freeswan.h>
6
7 #include "constants.h"
8 #include "defs.h"
9 #include "log.h"
10 #include "libtwofish/twofish_cbc.h"
11 #include "alg_info.h"
12 #include "ike_alg.h"
13
14 #define TWOFISH_CBC_BLOCK_SIZE (128/BITS_PER_BYTE)
15 #define TWOFISH_KEY_MIN_LEN 128
16 #define TWOFISH_KEY_DEF_LEN 128
17 #define TWOFISH_KEY_MAX_LEN 256
18
19 static void
20 do_twofish(u_int8_t *buf, size_t buf_size, u_int8_t *key, size_t key_size, u_int8_t *iv, bool enc)
21 {
22 twofish_context twofish_ctx;
23 char iv_bak[TWOFISH_CBC_BLOCK_SIZE];
24 char *new_iv = NULL; /* logic will avoid copy to NULL */
25
26 twofish_set_key(&twofish_ctx, key, key_size);
27 /*
28 * my TWOFISH cbc does not touch passed IV (optimization for
29 * ESP handling), so I must "emulate" des-like IV
30 * crunching
31 */
32 if (!enc)
33 memcpy(new_iv=iv_bak,
34 (char*) buf + buf_size-TWOFISH_CBC_BLOCK_SIZE,
35 TWOFISH_CBC_BLOCK_SIZE);
36
37 twofish_cbc_encrypt(&twofish_ctx, buf, buf, buf_size, iv, enc);
38
39 if (enc)
40 new_iv = (char*) buf + buf_size-TWOFISH_CBC_BLOCK_SIZE;
41
42 memcpy(iv, new_iv, TWOFISH_CBC_BLOCK_SIZE);
43 }
44
45 struct encrypt_desc encrypt_desc_twofish =
46 {
47 algo_type: IKE_ALG_ENCRYPT,
48 algo_id: OAKLEY_TWOFISH_CBC,
49 algo_next: NULL,
50 enc_ctxsize: sizeof(twofish_context),
51 enc_blocksize: TWOFISH_CBC_BLOCK_SIZE,
52 keydeflen: TWOFISH_KEY_MIN_LEN,
53 keyminlen: TWOFISH_KEY_DEF_LEN,
54 keymaxlen: TWOFISH_KEY_MAX_LEN,
55 do_crypt: do_twofish,
56 enc_testvectors: NULL
57 };
58
59 struct encrypt_desc encrypt_desc_twofish_ssh =
60 {
61 algo_type: IKE_ALG_ENCRYPT,
62 algo_id: OAKLEY_TWOFISH_CBC_SSH,
63 algo_next: NULL,
64 enc_ctxsize: sizeof(twofish_context),
65 enc_blocksize: TWOFISH_CBC_BLOCK_SIZE,
66 keydeflen: TWOFISH_KEY_MIN_LEN,
67 keyminlen: TWOFISH_KEY_DEF_LEN,
68 keymaxlen: TWOFISH_KEY_MAX_LEN,
69 do_crypt: do_twofish,
70 };
71
72 int ike_alg_twofish_init(void);
73
74 int
75 ike_alg_twofish_init(void)
76 {
77 int ret = ike_alg_register_enc(&encrypt_desc_twofish);
78
79 if (ike_alg_register_enc(&encrypt_desc_twofish_ssh) < 0)
80 plog("ike_alg_twofish_init(): Experimental OAKLEY_TWOFISH_CBC_SSH activation failed");
81
82 return ret;
83 }
84 /*
85 IKE_ALG_INIT_NAME: ike_alg_twofish_init
86 */