blob: 75134f09a403fdfd2e73f44a34d4f2100fa218e3 [file] [log] [blame]
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001/*
2 * Crypto wrapper for internal crypto implementation - Cipher wrappers
3 * Copyright (c) 2006-2009, Jouni Malinen <j@w1.fi>
4 *
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.
8 *
9 * Alternatively, this software may be distributed under the terms of BSD
10 * license.
11 *
12 * See README and COPYING for more details.
13 */
14
15#include "includes.h"
16
17#include "common.h"
18#include "crypto.h"
19#include "aes.h"
20#include "des_i.h"
21
22
23struct crypto_cipher {
24 enum crypto_cipher_alg alg;
25 union {
26 struct {
27 size_t used_bytes;
28 u8 key[16];
29 size_t keylen;
30 } rc4;
31 struct {
32 u8 cbc[32];
33 size_t block_size;
34 void *ctx_enc;
35 void *ctx_dec;
36 } aes;
37 struct {
38 struct des3_key_s key;
39 u8 cbc[8];
40 } des3;
41 struct {
42 u32 ek[32];
43 u32 dk[32];
44 u8 cbc[8];
45 } des;
46 } u;
47};
48
49
50struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg,
51 const u8 *iv, const u8 *key,
52 size_t key_len)
53{
54 struct crypto_cipher *ctx;
55
56 ctx = os_zalloc(sizeof(*ctx));
57 if (ctx == NULL)
58 return NULL;
59
60 ctx->alg = alg;
61
62 switch (alg) {
63 case CRYPTO_CIPHER_ALG_RC4:
64 if (key_len > sizeof(ctx->u.rc4.key)) {
65 os_free(ctx);
66 return NULL;
67 }
68 ctx->u.rc4.keylen = key_len;
69 os_memcpy(ctx->u.rc4.key, key, key_len);
70 break;
71 case CRYPTO_CIPHER_ALG_AES:
72 if (key_len > sizeof(ctx->u.aes.cbc)) {
73 os_free(ctx);
74 return NULL;
75 }
76 ctx->u.aes.ctx_enc = aes_encrypt_init(key, key_len);
77 if (ctx->u.aes.ctx_enc == NULL) {
78 os_free(ctx);
79 return NULL;
80 }
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);
84 os_free(ctx);
85 return NULL;
86 }
87 ctx->u.aes.block_size = key_len;
88 os_memcpy(ctx->u.aes.cbc, iv, ctx->u.aes.block_size);
89 break;
90 case CRYPTO_CIPHER_ALG_3DES:
91 if (key_len != 24) {
92 os_free(ctx);
93 return NULL;
94 }
95 des3_key_setup(key, &ctx->u.des3.key);
96 os_memcpy(ctx->u.des3.cbc, iv, 8);
97 break;
98 case CRYPTO_CIPHER_ALG_DES:
99 if (key_len != 8) {
100 os_free(ctx);
101 return NULL;
102 }
103 des_key_setup(key, ctx->u.des.ek, ctx->u.des.dk);
104 os_memcpy(ctx->u.des.cbc, iv, 8);
105 break;
106 default:
107 os_free(ctx);
108 return NULL;
109 }
110
111 return ctx;
112}
113
114
115int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain,
116 u8 *crypt, size_t len)
117{
118 size_t i, j, blocks;
119
120 switch (ctx->alg) {
121 case CRYPTO_CIPHER_ALG_RC4:
122 if (plain != crypt)
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;
127 break;
128 case CRYPTO_CIPHER_ALG_AES:
129 if (len % ctx->u.aes.block_size)
130 return -1;
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,
136 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;
141 }
142 break;
143 case CRYPTO_CIPHER_ALG_3DES:
144 if (len % 8)
145 return -1;
146 blocks = len / 8;
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,
151 ctx->u.des3.cbc);
152 os_memcpy(crypt, ctx->u.des3.cbc, 8);
153 plain += 8;
154 crypt += 8;
155 }
156 break;
157 case CRYPTO_CIPHER_ALG_DES:
158 if (len % 8)
159 return -1;
160 blocks = len / 8;
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,
165 ctx->u.des.cbc);
166 os_memcpy(crypt, ctx->u.des.cbc, 8);
167 plain += 8;
168 crypt += 8;
169 }
170 break;
171 default:
172 return -1;
173 }
174
175 return 0;
176}
177
178
179int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt,
180 u8 *plain, size_t len)
181{
182 size_t i, j, blocks;
183 u8 tmp[32];
184
185 switch (ctx->alg) {
186 case CRYPTO_CIPHER_ALG_RC4:
187 if (plain != crypt)
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;
192 break;
193 case CRYPTO_CIPHER_ALG_AES:
194 if (len % ctx->u.aes.block_size)
195 return -1;
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;
205 }
206 break;
207 case CRYPTO_CIPHER_ALG_3DES:
208 if (len % 8)
209 return -1;
210 blocks = len / 8;
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);
217 plain += 8;
218 crypt += 8;
219 }
220 break;
221 case CRYPTO_CIPHER_ALG_DES:
222 if (len % 8)
223 return -1;
224 blocks = len / 8;
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);
231 plain += 8;
232 crypt += 8;
233 }
234 break;
235 default:
236 return -1;
237 }
238
239 return 0;
240}
241
242
243void crypto_cipher_deinit(struct crypto_cipher *ctx)
244{
245 switch (ctx->alg) {
246 case CRYPTO_CIPHER_ALG_AES:
247 aes_encrypt_deinit(ctx->u.aes.ctx_enc);
248 aes_decrypt_deinit(ctx->u.aes.ctx_dec);
249 break;
250 case CRYPTO_CIPHER_ALG_3DES:
251 break;
252 default:
253 break;
254 }
255 os_free(ctx);
256}