2 * Crypto wrapper for internal crypto implementation - Cipher wrappers
3 * Copyright (c) 2006-2009, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
17 struct crypto_cipher {
18 enum crypto_cipher_alg alg;
32 struct des3_key_s key;
44 struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg,
45 const u8 *iv, const u8 *key,
48 struct crypto_cipher *ctx;
50 ctx = os_zalloc(sizeof(*ctx));
57 case CRYPTO_CIPHER_ALG_RC4:
58 if (key_len > sizeof(ctx->u.rc4.key)) {
62 ctx->u.rc4.keylen = key_len;
63 os_memcpy(ctx->u.rc4.key, key, key_len);
65 case CRYPTO_CIPHER_ALG_AES:
66 if (key_len > sizeof(ctx->u.aes.cbc)) {
70 ctx->u.aes.ctx_enc = aes_encrypt_init(key, key_len);
71 if (ctx->u.aes.ctx_enc == NULL) {
75 ctx->u.aes.ctx_dec = aes_decrypt_init(key, key_len);
76 if (ctx->u.aes.ctx_dec == NULL) {
77 aes_encrypt_deinit(ctx->u.aes.ctx_enc);
81 ctx->u.aes.block_size = key_len;
82 os_memcpy(ctx->u.aes.cbc, iv, ctx->u.aes.block_size);
84 case CRYPTO_CIPHER_ALG_3DES:
89 des3_key_setup(key, &ctx->u.des3.key);
90 os_memcpy(ctx->u.des3.cbc, iv, 8);
92 case CRYPTO_CIPHER_ALG_DES:
97 des_key_setup(key, ctx->u.des.ek, ctx->u.des.dk);
98 os_memcpy(ctx->u.des.cbc, iv, 8);
109 int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain,
110 u8 *crypt, size_t len)
115 case CRYPTO_CIPHER_ALG_RC4:
117 os_memcpy(crypt, plain, len);
118 rc4_skip(ctx->u.rc4.key, ctx->u.rc4.keylen,
119 ctx->u.rc4.used_bytes, crypt, len);
120 ctx->u.rc4.used_bytes += len;
122 case CRYPTO_CIPHER_ALG_AES:
123 if (len % ctx->u.aes.block_size)
125 blocks = len / ctx->u.aes.block_size;
126 for (i = 0; i < blocks; i++) {
127 for (j = 0; j < ctx->u.aes.block_size; j++)
128 ctx->u.aes.cbc[j] ^= plain[j];
129 aes_encrypt(ctx->u.aes.ctx_enc, ctx->u.aes.cbc,
131 os_memcpy(crypt, ctx->u.aes.cbc,
132 ctx->u.aes.block_size);
133 plain += ctx->u.aes.block_size;
134 crypt += ctx->u.aes.block_size;
137 case CRYPTO_CIPHER_ALG_3DES:
141 for (i = 0; i < blocks; i++) {
142 for (j = 0; j < 8; j++)
143 ctx->u.des3.cbc[j] ^= plain[j];
144 des3_encrypt(ctx->u.des3.cbc, &ctx->u.des3.key,
146 os_memcpy(crypt, ctx->u.des3.cbc, 8);
151 case CRYPTO_CIPHER_ALG_DES:
155 for (i = 0; i < blocks; i++) {
156 for (j = 0; j < 8; j++)
157 ctx->u.des3.cbc[j] ^= plain[j];
158 des_block_encrypt(ctx->u.des.cbc, ctx->u.des.ek,
160 os_memcpy(crypt, ctx->u.des.cbc, 8);
173 int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt,
174 u8 *plain, size_t len)
180 case CRYPTO_CIPHER_ALG_RC4:
182 os_memcpy(plain, crypt, len);
183 rc4_skip(ctx->u.rc4.key, ctx->u.rc4.keylen,
184 ctx->u.rc4.used_bytes, plain, len);
185 ctx->u.rc4.used_bytes += len;
187 case CRYPTO_CIPHER_ALG_AES:
188 if (len % ctx->u.aes.block_size)
190 blocks = len / ctx->u.aes.block_size;
191 for (i = 0; i < blocks; i++) {
192 os_memcpy(tmp, crypt, ctx->u.aes.block_size);
193 aes_decrypt(ctx->u.aes.ctx_dec, crypt, plain);
194 for (j = 0; j < ctx->u.aes.block_size; j++)
195 plain[j] ^= ctx->u.aes.cbc[j];
196 os_memcpy(ctx->u.aes.cbc, tmp, ctx->u.aes.block_size);
197 plain += ctx->u.aes.block_size;
198 crypt += ctx->u.aes.block_size;
201 case CRYPTO_CIPHER_ALG_3DES:
205 for (i = 0; i < blocks; i++) {
206 os_memcpy(tmp, crypt, 8);
207 des3_decrypt(crypt, &ctx->u.des3.key, plain);
208 for (j = 0; j < 8; j++)
209 plain[j] ^= ctx->u.des3.cbc[j];
210 os_memcpy(ctx->u.des3.cbc, tmp, 8);
215 case CRYPTO_CIPHER_ALG_DES:
219 for (i = 0; i < blocks; i++) {
220 os_memcpy(tmp, crypt, 8);
221 des_block_decrypt(crypt, ctx->u.des.dk, plain);
222 for (j = 0; j < 8; j++)
223 plain[j] ^= ctx->u.des.cbc[j];
224 os_memcpy(ctx->u.des.cbc, tmp, 8);
237 void crypto_cipher_deinit(struct crypto_cipher *ctx)
240 case CRYPTO_CIPHER_ALG_AES:
241 aes_encrypt_deinit(ctx->u.aes.ctx_enc);
242 aes_decrypt_deinit(ctx->u.aes.ctx_dec);
244 case CRYPTO_CIPHER_ALG_3DES: