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: