2 * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2
6 * as published by the Free Software Foundation
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
26 #if EAD_DEBUGLEVEL >= 1
27 #define DEBUG(n, format, ...) do { \
28 if (EAD_DEBUGLEVEL >= n) \
29 fprintf(stderr, format, ##__VA_ARGS__); \
33 #define DEBUG(n, format, ...) do {} while(0)
37 static uint32_t aes_enc_ctx
[AES_PRIV_SIZE
];
38 static uint32_t aes_dec_ctx
[AES_PRIV_SIZE
];
39 static uint32_t ead_rx_iv
;
40 static uint32_t ead_tx_iv
;
41 static uint32_t ivofs_vec
;
42 static unsigned int ivofs_idx
= 0;
43 static uint32_t W
[80]; /* work space for sha1 */
45 #define EAD_ENC_PAD 64
48 ead_set_key(unsigned char *skey
)
50 uint32_t *ivp
= (uint32_t *)skey
;
52 memset(aes_enc_ctx
, 0, sizeof(aes_enc_ctx
));
53 memset(aes_dec_ctx
, 0, sizeof(aes_dec_ctx
));
55 /* first 32 bytes of skey are used as aes key for
56 * encryption and decryption */
57 rijndaelKeySetupEnc(aes_enc_ctx
, skey
);
58 rijndaelKeySetupDec(aes_dec_ctx
, skey
);
60 /* the following bytes are used as initialization vector for messages
61 * (highest byte cleared to avoid overflow) */
63 ead_rx_iv
= ntohl(*ivp
) & 0x00ffffff;
64 ead_tx_iv
= ead_rx_iv
;
66 /* the last bytes are used to feed the random iv increment */
73 ead_check_rx_iv(uint32_t iv
)
78 if (iv
> ead_rx_iv
+ EAD_MAX_IV_INCR
)
91 ofs
= 1 + ((ivofs_vec
>> 2 * ivofs_idx
) & 0x3);
92 ivofs_idx
= (ivofs_idx
+ 1) % 16;
99 ead_hash_message(struct ead_msg_encrypted
*enc
, uint32_t *hash
, int len
)
101 unsigned char *data
= (unsigned char *) enc
;
103 /* hash the packet with the stored hash part initialized to zero */
105 memset(enc
->hash
, 0, sizeof(enc
->hash
));
107 sha_transform(hash
, data
, W
);
114 ead_encrypt_message(struct ead_msg
*msg
, unsigned int len
)
116 struct ead_msg_encrypted
*enc
= EAD_DATA(msg
, enc
);
117 unsigned char *data
= (unsigned char *) enc
;
121 len
+= sizeof(struct ead_msg_encrypted
);
122 enc
->pad
= (EAD_ENC_PAD
- (len
% EAD_ENC_PAD
)) % EAD_ENC_PAD
;
123 enclen
= len
+ enc
->pad
;
124 msg
->len
= htonl(enclen
);
125 enc
->iv
= htonl(ead_get_tx_iv());
127 ead_hash_message(enc
, hash
, enclen
);
128 for (i
= 0; i
< 5; i
++)
129 enc
->hash
[i
] = htonl(hash
[i
]);
130 DEBUG(2, "SHA1 generate (0x%08x), len=%d\n", enc
->hash
[0], enclen
);
133 rijndaelEncrypt(aes_enc_ctx
, data
, data
);
140 ead_decrypt_message(struct ead_msg
*msg
)
142 struct ead_msg_encrypted
*enc
= EAD_DATA(msg
, enc
);
143 unsigned char *data
= (unsigned char *) enc
;
144 uint32_t hash_old
[5], hash_new
[5];
145 int len
= ntohl(msg
->len
);
148 if (!len
|| (len
% EAD_ENC_PAD
> 0))
152 rijndaelDecrypt(aes_dec_ctx
, data
, data
);
157 data
= (unsigned char *) enc
;
159 if (enc
->pad
>= EAD_ENC_PAD
) {
160 DEBUG(2, "Invalid padding length\n");
164 if (!ead_check_rx_iv(ntohl(enc
->iv
))) {
165 DEBUG(2, "RX IV mismatch (0x%08x <> 0x%08x)\n", ead_rx_iv
, ntohl(enc
->iv
));
169 for (i
= 0; i
< 5; i
++)
170 hash_old
[i
] = ntohl(enc
->hash
[i
]);
171 ead_hash_message(enc
, hash_new
, enclen
);
172 if (memcmp(hash_old
, hash_new
, sizeof(hash_old
)) != 0) {
173 DEBUG(2, "SHA1 mismatch (0x%08x != 0x%08x), len=%d\n", hash_old
[0], hash_new
[0], enclen
);
177 enclen
-= enc
->pad
+ sizeof(struct ead_msg_encrypted
);
This page took 0.053169 seconds and 5 git commands to generate.