2 * Crypto wrapper for internal crypto implementation - Cipher wrappers
3 * Copyright (c) 2006-2009, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
23 struct crypto_cipher
{
24 enum crypto_cipher_alg alg
;
38 struct des3_key_s key
;
50 struct crypto_cipher
* crypto_cipher_init(enum crypto_cipher_alg alg
,
51 const u8
*iv
, const u8
*key
,
54 struct crypto_cipher
*ctx
;
56 ctx
= os_zalloc(sizeof(*ctx
));
63 case CRYPTO_CIPHER_ALG_RC4
:
64 if (key_len
> sizeof(ctx
->u
.rc4
.key
)) {
68 ctx
->u
.rc4
.keylen
= key_len
;
69 os_memcpy(ctx
->u
.rc4
.key
, key
, key_len
);
71 case CRYPTO_CIPHER_ALG_AES
:
72 if (key_len
> sizeof(ctx
->u
.aes
.cbc
)) {
76 ctx
->u
.aes
.ctx_enc
= aes_encrypt_init(key
, key_len
);
77 if (ctx
->u
.aes
.ctx_enc
== NULL
) {
81 ctx
->u
.aes
.ctx_dec
= aes_decrypt_init(key
, key_len
);
82 if (ctx
->u
.aes
.ctx_dec
== NULL
) {
83 aes_encrypt_deinit(ctx
->u
.aes
.ctx_enc
);
87 ctx
->u
.aes
.block_size
= key_len
;
88 os_memcpy(ctx
->u
.aes
.cbc
, iv
, ctx
->u
.aes
.block_size
);
90 case CRYPTO_CIPHER_ALG_3DES
:
95 des3_key_setup(key
, &ctx
->u
.des3
.key
);
96 os_memcpy(ctx
->u
.des3
.cbc
, iv
, 8);
98 case CRYPTO_CIPHER_ALG_DES
:
103 des_key_setup(key
, ctx
->u
.des
.ek
, ctx
->u
.des
.dk
);
104 os_memcpy(ctx
->u
.des
.cbc
, iv
, 8);
115 int crypto_cipher_encrypt(struct crypto_cipher
*ctx
, const u8
*plain
,
116 u8
*crypt
, size_t len
)
121 case CRYPTO_CIPHER_ALG_RC4
:
123 os_memcpy(crypt
, plain
, len
);
124 rc4_skip(ctx
->u
.rc4
.key
, ctx
->u
.rc4
.keylen
,
125 ctx
->u
.rc4
.used_bytes
, crypt
, len
);
126 ctx
->u
.rc4
.used_bytes
+= len
;
128 case CRYPTO_CIPHER_ALG_AES
:
129 if (len
% ctx
->u
.aes
.block_size
)
131 blocks
= len
/ ctx
->u
.aes
.block_size
;
132 for (i
= 0; i
< blocks
; i
++) {
133 for (j
= 0; j
< ctx
->u
.aes
.block_size
; j
++)
134 ctx
->u
.aes
.cbc
[j
] ^= plain
[j
];
135 aes_encrypt(ctx
->u
.aes
.ctx_enc
, ctx
->u
.aes
.cbc
,
137 os_memcpy(crypt
, ctx
->u
.aes
.cbc
,
138 ctx
->u
.aes
.block_size
);
139 plain
+= ctx
->u
.aes
.block_size
;
140 crypt
+= ctx
->u
.aes
.block_size
;
143 case CRYPTO_CIPHER_ALG_3DES
:
147 for (i
= 0; i
< blocks
; i
++) {
148 for (j
= 0; j
< 8; j
++)
149 ctx
->u
.des3
.cbc
[j
] ^= plain
[j
];
150 des3_encrypt(ctx
->u
.des3
.cbc
, &ctx
->u
.des3
.key
,
152 os_memcpy(crypt
, ctx
->u
.des3
.cbc
, 8);
157 case CRYPTO_CIPHER_ALG_DES
:
161 for (i
= 0; i
< blocks
; i
++) {
162 for (j
= 0; j
< 8; j
++)
163 ctx
->u
.des3
.cbc
[j
] ^= plain
[j
];
164 des_block_encrypt(ctx
->u
.des
.cbc
, ctx
->u
.des
.ek
,
166 os_memcpy(crypt
, ctx
->u
.des
.cbc
, 8);
179 int crypto_cipher_decrypt(struct crypto_cipher
*ctx
, const u8
*crypt
,
180 u8
*plain
, size_t len
)
186 case CRYPTO_CIPHER_ALG_RC4
:
188 os_memcpy(plain
, crypt
, len
);
189 rc4_skip(ctx
->u
.rc4
.key
, ctx
->u
.rc4
.keylen
,
190 ctx
->u
.rc4
.used_bytes
, plain
, len
);
191 ctx
->u
.rc4
.used_bytes
+= len
;
193 case CRYPTO_CIPHER_ALG_AES
:
194 if (len
% ctx
->u
.aes
.block_size
)
196 blocks
= len
/ ctx
->u
.aes
.block_size
;
197 for (i
= 0; i
< blocks
; i
++) {
198 os_memcpy(tmp
, crypt
, ctx
->u
.aes
.block_size
);
199 aes_decrypt(ctx
->u
.aes
.ctx_dec
, crypt
, plain
);
200 for (j
= 0; j
< ctx
->u
.aes
.block_size
; j
++)
201 plain
[j
] ^= ctx
->u
.aes
.cbc
[j
];
202 os_memcpy(ctx
->u
.aes
.cbc
, tmp
, ctx
->u
.aes
.block_size
);
203 plain
+= ctx
->u
.aes
.block_size
;
204 crypt
+= ctx
->u
.aes
.block_size
;
207 case CRYPTO_CIPHER_ALG_3DES
:
211 for (i
= 0; i
< blocks
; i
++) {
212 os_memcpy(tmp
, crypt
, 8);
213 des3_decrypt(crypt
, &ctx
->u
.des3
.key
, plain
);
214 for (j
= 0; j
< 8; j
++)
215 plain
[j
] ^= ctx
->u
.des3
.cbc
[j
];
216 os_memcpy(ctx
->u
.des3
.cbc
, tmp
, 8);
221 case CRYPTO_CIPHER_ALG_DES
:
225 for (i
= 0; i
< blocks
; i
++) {
226 os_memcpy(tmp
, crypt
, 8);
227 des_block_decrypt(crypt
, ctx
->u
.des
.dk
, plain
);
228 for (j
= 0; j
< 8; j
++)
229 plain
[j
] ^= ctx
->u
.des
.cbc
[j
];
230 os_memcpy(ctx
->u
.des
.cbc
, tmp
, 8);
243 void crypto_cipher_deinit(struct crypto_cipher
*ctx
)
246 case CRYPTO_CIPHER_ALG_AES
:
247 aes_encrypt_deinit(ctx
->u
.aes
.ctx_enc
);
248 aes_decrypt_deinit(ctx
->u
.aes
.ctx_dec
);
250 case CRYPTO_CIPHER_ALG_3DES
: