00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "includes.h"
00016
00017 #include "common.h"
00018 #include "crypto.h"
00019 #include "aes.h"
00020 #include "des_i.h"
00021
00022
00023 struct crypto_cipher {
00024 enum crypto_cipher_alg alg;
00025 union {
00026 struct {
00027 size_t used_bytes;
00028 u8 key[16];
00029 size_t keylen;
00030 } rc4;
00031 struct {
00032 u8 cbc[32];
00033 size_t block_size;
00034 void *ctx_enc;
00035 void *ctx_dec;
00036 } aes;
00037 struct {
00038 struct des3_key_s key;
00039 u8 cbc[8];
00040 } des3;
00041 struct {
00042 u32 ek[32];
00043 u32 dk[32];
00044 u8 cbc[8];
00045 } des;
00046 } u;
00047 };
00048
00049
00050 struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg,
00051 const u8 *iv, const u8 *key,
00052 size_t key_len)
00053 {
00054 struct crypto_cipher *ctx;
00055
00056 ctx = os_zalloc(sizeof(*ctx));
00057 if (ctx == NULL)
00058 return NULL;
00059
00060 ctx->alg = alg;
00061
00062 switch (alg) {
00063 case CRYPTO_CIPHER_ALG_RC4:
00064 if (key_len > sizeof(ctx->u.rc4.key)) {
00065 os_free(ctx);
00066 return NULL;
00067 }
00068 ctx->u.rc4.keylen = key_len;
00069 os_memcpy(ctx->u.rc4.key, key, key_len);
00070 break;
00071 case CRYPTO_CIPHER_ALG_AES:
00072 if (key_len > sizeof(ctx->u.aes.cbc)) {
00073 os_free(ctx);
00074 return NULL;
00075 }
00076 ctx->u.aes.ctx_enc = aes_encrypt_init(key, key_len);
00077 if (ctx->u.aes.ctx_enc == NULL) {
00078 os_free(ctx);
00079 return NULL;
00080 }
00081 ctx->u.aes.ctx_dec = aes_decrypt_init(key, key_len);
00082 if (ctx->u.aes.ctx_dec == NULL) {
00083 aes_encrypt_deinit(ctx->u.aes.ctx_enc);
00084 os_free(ctx);
00085 return NULL;
00086 }
00087 ctx->u.aes.block_size = key_len;
00088 os_memcpy(ctx->u.aes.cbc, iv, ctx->u.aes.block_size);
00089 break;
00090 case CRYPTO_CIPHER_ALG_3DES:
00091 if (key_len != 24) {
00092 os_free(ctx);
00093 return NULL;
00094 }
00095 des3_key_setup(key, &ctx->u.des3.key);
00096 os_memcpy(ctx->u.des3.cbc, iv, 8);
00097 break;
00098 case CRYPTO_CIPHER_ALG_DES:
00099 if (key_len != 8) {
00100 os_free(ctx);
00101 return NULL;
00102 }
00103 des_key_setup(key, ctx->u.des.ek, ctx->u.des.dk);
00104 os_memcpy(ctx->u.des.cbc, iv, 8);
00105 break;
00106 default:
00107 os_free(ctx);
00108 return NULL;
00109 }
00110
00111 return ctx;
00112 }
00113
00114
00115 int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain,
00116 u8 *crypt, size_t len)
00117 {
00118 size_t i, j, blocks;
00119
00120 switch (ctx->alg) {
00121 case CRYPTO_CIPHER_ALG_RC4:
00122 if (plain != crypt)
00123 os_memcpy(crypt, plain, len);
00124 rc4_skip(ctx->u.rc4.key, ctx->u.rc4.keylen,
00125 ctx->u.rc4.used_bytes, crypt, len);
00126 ctx->u.rc4.used_bytes += len;
00127 break;
00128 case CRYPTO_CIPHER_ALG_AES:
00129 if (len % ctx->u.aes.block_size)
00130 return -1;
00131 blocks = len / ctx->u.aes.block_size;
00132 for (i = 0; i < blocks; i++) {
00133 for (j = 0; j < ctx->u.aes.block_size; j++)
00134 ctx->u.aes.cbc[j] ^= plain[j];
00135 aes_encrypt(ctx->u.aes.ctx_enc, ctx->u.aes.cbc,
00136 ctx->u.aes.cbc);
00137 os_memcpy(crypt, ctx->u.aes.cbc,
00138 ctx->u.aes.block_size);
00139 plain += ctx->u.aes.block_size;
00140 crypt += ctx->u.aes.block_size;
00141 }
00142 break;
00143 case CRYPTO_CIPHER_ALG_3DES:
00144 if (len % 8)
00145 return -1;
00146 blocks = len / 8;
00147 for (i = 0; i < blocks; i++) {
00148 for (j = 0; j < 8; j++)
00149 ctx->u.des3.cbc[j] ^= plain[j];
00150 des3_encrypt(ctx->u.des3.cbc, &ctx->u.des3.key,
00151 ctx->u.des3.cbc);
00152 os_memcpy(crypt, ctx->u.des3.cbc, 8);
00153 plain += 8;
00154 crypt += 8;
00155 }
00156 break;
00157 case CRYPTO_CIPHER_ALG_DES:
00158 if (len % 8)
00159 return -1;
00160 blocks = len / 8;
00161 for (i = 0; i < blocks; i++) {
00162 for (j = 0; j < 8; j++)
00163 ctx->u.des3.cbc[j] ^= plain[j];
00164 des_block_encrypt(ctx->u.des.cbc, ctx->u.des.ek,
00165 ctx->u.des.cbc);
00166 os_memcpy(crypt, ctx->u.des.cbc, 8);
00167 plain += 8;
00168 crypt += 8;
00169 }
00170 break;
00171 default:
00172 return -1;
00173 }
00174
00175 return 0;
00176 }
00177
00178
00179 int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt,
00180 u8 *plain, size_t len)
00181 {
00182 size_t i, j, blocks;
00183 u8 tmp[32];
00184
00185 switch (ctx->alg) {
00186 case CRYPTO_CIPHER_ALG_RC4:
00187 if (plain != crypt)
00188 os_memcpy(plain, crypt, len);
00189 rc4_skip(ctx->u.rc4.key, ctx->u.rc4.keylen,
00190 ctx->u.rc4.used_bytes, plain, len);
00191 ctx->u.rc4.used_bytes += len;
00192 break;
00193 case CRYPTO_CIPHER_ALG_AES:
00194 if (len % ctx->u.aes.block_size)
00195 return -1;
00196 blocks = len / ctx->u.aes.block_size;
00197 for (i = 0; i < blocks; i++) {
00198 os_memcpy(tmp, crypt, ctx->u.aes.block_size);
00199 aes_decrypt(ctx->u.aes.ctx_dec, crypt, plain);
00200 for (j = 0; j < ctx->u.aes.block_size; j++)
00201 plain[j] ^= ctx->u.aes.cbc[j];
00202 os_memcpy(ctx->u.aes.cbc, tmp, ctx->u.aes.block_size);
00203 plain += ctx->u.aes.block_size;
00204 crypt += ctx->u.aes.block_size;
00205 }
00206 break;
00207 case CRYPTO_CIPHER_ALG_3DES:
00208 if (len % 8)
00209 return -1;
00210 blocks = len / 8;
00211 for (i = 0; i < blocks; i++) {
00212 os_memcpy(tmp, crypt, 8);
00213 des3_decrypt(crypt, &ctx->u.des3.key, plain);
00214 for (j = 0; j < 8; j++)
00215 plain[j] ^= ctx->u.des3.cbc[j];
00216 os_memcpy(ctx->u.des3.cbc, tmp, 8);
00217 plain += 8;
00218 crypt += 8;
00219 }
00220 break;
00221 case CRYPTO_CIPHER_ALG_DES:
00222 if (len % 8)
00223 return -1;
00224 blocks = len / 8;
00225 for (i = 0; i < blocks; i++) {
00226 os_memcpy(tmp, crypt, 8);
00227 des_block_decrypt(crypt, ctx->u.des.dk, plain);
00228 for (j = 0; j < 8; j++)
00229 plain[j] ^= ctx->u.des.cbc[j];
00230 os_memcpy(ctx->u.des.cbc, tmp, 8);
00231 plain += 8;
00232 crypt += 8;
00233 }
00234 break;
00235 default:
00236 return -1;
00237 }
00238
00239 return 0;
00240 }
00241
00242
00243 void crypto_cipher_deinit(struct crypto_cipher *ctx)
00244 {
00245 switch (ctx->alg) {
00246 case CRYPTO_CIPHER_ALG_AES:
00247 aes_encrypt_deinit(ctx->u.aes.ctx_enc);
00248 aes_decrypt_deinit(ctx->u.aes.ctx_dec);
00249 break;
00250 case CRYPTO_CIPHER_ALG_3DES:
00251 break;
00252 default:
00253 break;
00254 }
00255 os_free(ctx);
00256 }