Support RC4 in EVP

This commit is contained in:
Love Hornquist Astrand
2009-08-10 11:48:12 +02:00
parent 8276a469ab
commit 21e8270aa2
5 changed files with 320 additions and 89 deletions

View File

@@ -183,8 +183,6 @@ EVP_cc_des_cbc(void)
return &des_ede3_cbc;
}
/*
*
*/
@@ -391,21 +389,6 @@ EVP_cc_rc2_64_cbc(void)
return &rc2_64_cbc;
}
/**
* The RC4 cipher type (Apple CommonCrypto provider)
*
* @return the RC4 EVP_CIPHER pointer.
*
* @ingroup hcrypto_evp
*/
const EVP_CIPHER *
EVP_cc_rc4(void)
{
abort();
}
/**
* The CommonCrypto md2 provider
*
@@ -553,5 +536,78 @@ EVP_cc_camellia_256_cbc(void)
return NULL;
}
/*
*
*/
static int
cc_rc4_init(EVP_CIPHER_CTX *ctx,
const unsigned char * key,
const unsigned char * iv,
int encp)
{
struct cc_key *cc = ctx->cipher_data;
return init_cc_key(encp, kCCAlgorithmRC4, key, ctx->key_len, iv, &cc->href);
}
/**
* The RC4 cipher type (Apple CommonCrypto provider)
*
* @return the RC4 EVP_CIPHER pointer.
*
* @ingroup hcrypto_evp
*/
const EVP_CIPHER *
EVP_cc_rc4(void)
{
static const EVP_CIPHER rc4 = {
0,
1,
16,
0,
EVP_CIPH_STREAM_CIPHER|EVP_CIPH_VARIABLE_LENGTH,
cc_rc4_init,
cc_do_cipher,
cc_cleanup,
sizeof(struct cc_key),
NULL,
NULL,
NULL,
NULL
};
return &rc4;
}
/**
* The RC4-40 cipher type (Apple CommonCrypto provider)
*
* @return the RC4 EVP_CIPHER pointer.
*
* @ingroup hcrypto_evp
*/
const EVP_CIPHER *
EVP_cc_rc4_40(void)
{
static const EVP_CIPHER rc4_40 = {
0,
1,
5,
0,
EVP_CIPH_STREAM_CIPHER|EVP_CIPH_VARIABLE_LENGTH,
cc_rc4_init,
cc_do_cipher,
cc_cleanup,
sizeof(struct cc_key),
NULL,
NULL,
NULL,
NULL
};
return &rc4_40;
}
#endif /* __APPLE__ */

View File

@@ -87,13 +87,6 @@ aes_do_cipher(EVP_CIPHER_CTX *ctx,
return 1;
}
static int
aes_cleanup(EVP_CIPHER_CTX *ctx)
{
memset(ctx->cipher_data, 0, sizeof(AES_KEY));
return 1;
}
/**
* The AES-128 cipher type (hcrypto)
*
@@ -113,7 +106,7 @@ EVP_hcrypto_aes_128_cbc(void)
EVP_CIPH_CBC_MODE,
aes_init,
aes_do_cipher,
aes_cleanup,
NULL,
sizeof(AES_KEY),
NULL,
NULL,
@@ -143,7 +136,7 @@ EVP_hcrypto_aes_192_cbc(void)
EVP_CIPH_CBC_MODE,
aes_init,
aes_do_cipher,
aes_cleanup,
NULL,
sizeof(AES_KEY),
NULL,
NULL,
@@ -172,7 +165,7 @@ EVP_hcrypto_aes_256_cbc(void)
EVP_CIPH_CBC_MODE,
aes_init,
aes_do_cipher,
aes_cleanup,
NULL,
sizeof(AES_KEY),
NULL,
NULL,
@@ -297,22 +290,6 @@ EVP_hcrypto_md2(void)
return &md2;
}
const EVP_CIPHER *
EVP_hcrypto_rc4(void)
{
printf("evp rc4\n");
abort();
return NULL;
}
const EVP_CIPHER *
EVP_hcrypto_rc4_40(void)
{
printf("evp rc4_40\n");
abort();
return NULL;
}
/*
*
*/
@@ -342,13 +319,6 @@ des_cbc_do_cipher(EVP_CIPHER_CTX *ctx,
return 1;
}
static int
des_cbc_cleanup(EVP_CIPHER_CTX *ctx)
{
memset(ctx->cipher_data, 0, sizeof(struct DES_key_schedule));
return 1;
}
/**
* The DES cipher type
*
@@ -368,7 +338,7 @@ EVP_hcrypto_des_cbc(void)
EVP_CIPH_CBC_MODE,
des_cbc_init,
des_cbc_do_cipher,
des_cbc_cleanup,
NULL,
sizeof(DES_key_schedule),
NULL,
NULL,
@@ -423,13 +393,6 @@ des_ede3_cbc_do_cipher(EVP_CIPHER_CTX *ctx,
return 1;
}
static int
des_ede3_cbc_cleanup(EVP_CIPHER_CTX *ctx)
{
memset(ctx->cipher_data, 0, sizeof(struct des_ede3_cbc));
return 1;
}
/**
* The tripple DES cipher type - hcrypto
*
@@ -449,7 +412,7 @@ EVP_hcrypto_des_ede3_cbc(void)
EVP_CIPH_CBC_MODE,
des_ede3_cbc_init,
des_ede3_cbc_do_cipher,
des_ede3_cbc_cleanup,
NULL,
sizeof(struct des_ede3_cbc),
NULL,
NULL,
@@ -494,13 +457,6 @@ rc2_do_cipher(EVP_CIPHER_CTX *ctx,
return 1;
}
static int
rc2_cleanup(EVP_CIPHER_CTX *ctx)
{
memset(ctx->cipher_data, 0, sizeof(struct rc2_cbc));
return 1;
}
/**
* The RC2 cipher type - hcrypto
*
@@ -517,10 +473,10 @@ EVP_hcrypto_rc2_cbc(void)
RC2_BLOCK_SIZE,
RC2_KEY_LENGTH,
RC2_BLOCK_SIZE,
EVP_CIPH_CBC_MODE,
EVP_CIPH_CBC_MODE|EVP_CIPH_VARIABLE_LENGTH,
rc2_init,
rc2_do_cipher,
rc2_cleanup,
NULL,
sizeof(struct rc2_cbc),
NULL,
NULL,
@@ -549,7 +505,7 @@ EVP_hcrypto_rc2_40_cbc(void)
EVP_CIPH_CBC_MODE,
rc2_init,
rc2_do_cipher,
rc2_cleanup,
NULL,
sizeof(struct rc2_cbc),
NULL,
NULL,
@@ -578,7 +534,7 @@ EVP_hcrypto_rc2_64_cbc(void)
EVP_CIPH_CBC_MODE,
rc2_init,
rc2_do_cipher,
rc2_cleanup,
NULL,
sizeof(struct rc2_cbc),
NULL,
NULL,
@@ -611,13 +567,6 @@ camellia_do_cipher(EVP_CIPHER_CTX *ctx,
return 1;
}
static int
camellia_cleanup(EVP_CIPHER_CTX *ctx)
{
memset(ctx->cipher_data, 0, sizeof(CAMELLIA_KEY));
return 1;
}
/**
* The Camellia-128 cipher type - hcrypto
*
@@ -637,7 +586,7 @@ EVP_hcrypto_camellia_128_cbc(void)
EVP_CIPH_CBC_MODE,
camellia_init,
camellia_do_cipher,
camellia_cleanup,
NULL,
sizeof(CAMELLIA_KEY),
NULL,
NULL,
@@ -666,7 +615,7 @@ EVP_hcrypto_camellia_192_cbc(void)
EVP_CIPH_CBC_MODE,
camellia_init,
camellia_do_cipher,
camellia_cleanup,
NULL,
sizeof(CAMELLIA_KEY),
NULL,
NULL,
@@ -695,7 +644,7 @@ EVP_hcrypto_camellia_256_cbc(void)
EVP_CIPH_CBC_MODE,
camellia_init,
camellia_do_cipher,
camellia_cleanup,
NULL,
sizeof(CAMELLIA_KEY),
NULL,
NULL,
@@ -704,3 +653,68 @@ EVP_hcrypto_camellia_256_cbc(void)
};
return &cipher;
}
static int
rc4_init(EVP_CIPHER_CTX *ctx,
const unsigned char *key,
const unsigned char *iv,
int enc)
{
RC4_KEY *k = ctx->cipher_data;
RC4_set_key(k, ctx->key_len, key);
return 1;
}
static int
rc4_do_cipher(EVP_CIPHER_CTX *ctx,
unsigned char *out,
const unsigned char *in,
unsigned int size)
{
RC4_KEY *k = ctx->cipher_data;
RC4(k, size, in, out);
return 1;
}
const EVP_CIPHER *
EVP_hcrypto_rc4(void)
{
static const EVP_CIPHER rc4 = {
0,
1,
16,
0,
EVP_CIPH_STREAM_CIPHER|EVP_CIPH_VARIABLE_LENGTH,
rc4_init,
rc4_do_cipher,
NULL,
sizeof(RC4_KEY),
NULL,
NULL,
NULL,
NULL
};
return &rc4;
}
const EVP_CIPHER *
EVP_hcrypto_rc4_40(void)
{
static const EVP_CIPHER rc4_40 = {
0,
1,
5,
0,
EVP_CIPH_STREAM_CIPHER|EVP_CIPH_VARIABLE_LENGTH,
rc4_init,
rc4_do_cipher,
NULL,
sizeof(RC4_KEY),
NULL,
NULL,
NULL,
NULL
};
return &rc4_40;
}

View File

@@ -546,19 +546,35 @@ EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c)
if (c->cipher && c->cipher->cleanup)
c->cipher->cleanup(c);
if (c->cipher_data) {
memset(c->cipher_data, 0, c->cipher->ctx_size);
free(c->cipher_data);
c->cipher_data = NULL;
}
return 1;
}
#if 0
/**
* If the cipher type supports it, change the key length
*
* @param c the cipher context to change the key length for
* @param length new key length
*
* @return 1 on success.
*
* @ingroup hcrypto_evp
*/
int
EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int length)
{
if ((c->cipher->flags & EVP_CIPH_VARIABLE_LENGTH) && length > 0) {
c->key_len = length;
return 1;
}
return 0;
}
#if 0
int
EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *c, int pad)
{
@@ -737,7 +753,7 @@ EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *c, ENGINE *engine,
return 0;
}
switch (EVP_CIPHER_CTX_flags(ctx)) {
switch (EVP_CIPHER_CTX_mode(ctx)) {
case EVP_CIPH_CBC_MODE:
assert(EVP_CIPHER_CTX_iv_length(ctx) <= sizeof(ctx->iv));
@@ -746,6 +762,10 @@ EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *c, ENGINE *engine,
memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
break;
case EVP_CIPH_STREAM_CIPHER:
break;
default:
return 0;
}

View File

@@ -131,6 +131,7 @@ struct hc_CIPHER {
#define EVP_CIPH_CBC_MODE 2
#define EVP_CIPH_MODE 0x7
#define EVP_CIPH_VARIABLE_LENGTH 0x008 /* variable key length */
#define EVP_CIPH_ALWAYS_CALL_INIT 0x020
#define EVP_CIPH_RAND_KEY 0x200

View File

@@ -349,7 +349,116 @@ struct tests camellia128_tests[] = {
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
16,
"\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
"\x07\x92\x3A\x39\xEB\x0A\x81\x7D\x1C\x4D\x87\xBD\xB8\x2D\x1F\x1C"
"\x07\x92\x3A\x39\xEB\x0A\x81\x7D\x1C\x4D\x87\xBD\xB8\x2D\x1F\x1C",
NULL
}
};
struct tests rc4_tests[] = {
{
"rc4 8",
"\x01\x23\x45\x67\x89\xAB\xCD\xEF",
8,
NULL,
8,
"\x00\x00\x00\x00\x00\x00\x00\x00",
"\x74\x94\xC2\xE7\x10\x4B\x08\x79",
NULL
},
{
"rc4 5",
"\x61\x8a\x63\xd2\xfb",
5,
NULL,
5,
"\xdc\xee\x4c\xf9\x2c",
"\xf1\x38\x29\xc9\xde",
NULL
},
{
"rc4 309",
"\x29\x04\x19\x72\xfb\x42\xba\x5f\xc7\x12\x77\x12\xf1\x38\x29\xc9",
16,
NULL,
309,
"\x52\x75\x69\x73\x6c\x69\x6e\x6e"
"\x75\x6e\x20\x6c\x61\x75\x6c\x75"
"\x20\x6b\x6f\x72\x76\x69\x73\x73"
"\x73\x61\x6e\x69\x2c\x20\x74\xe4"
"\x68\x6b\xe4\x70\xe4\x69\x64\x65"
"\x6e\x20\x70\xe4\xe4\x6c\x6c\xe4"
"\x20\x74\xe4\x79\x73\x69\x6b\x75"
"\x75\x2e\x20\x4b\x65\x73\xe4\x79"
"\xf6\x6e\x20\x6f\x6e\x20\x6f\x6e"
"\x6e\x69\x20\x6f\x6d\x61\x6e\x61"
"\x6e\x69\x2c\x20\x6b\x61\x73\x6b"
"\x69\x73\x61\x76\x75\x75\x6e\x20"
"\x6c\x61\x61\x6b\x73\x6f\x74\x20"
"\x76\x65\x72\x68\x6f\x75\x75\x2e"
"\x20\x45\x6e\x20\x6d\x61\x20\x69"
"\x6c\x6f\x69\x74\x73\x65\x2c\x20"
"\x73\x75\x72\x65\x20\x68\x75\x6f"
"\x6b\x61\x61\x2c\x20\x6d\x75\x74"
"\x74\x61\x20\x6d\x65\x74\x73\xe4"
"\x6e\x20\x74\x75\x6d\x6d\x75\x75"
"\x73\x20\x6d\x75\x6c\x6c\x65\x20"
"\x74\x75\x6f\x6b\x61\x61\x2e\x20"
"\x50\x75\x75\x6e\x74\x6f\x20\x70"
"\x69\x6c\x76\x65\x6e\x2c\x20\x6d"
"\x69\x20\x68\x75\x6b\x6b\x75\x75"
"\x2c\x20\x73\x69\x69\x6e\x74\x6f"
"\x20\x76\x61\x72\x61\x6e\x20\x74"
"\x75\x75\x6c\x69\x73\x65\x6e\x2c"
"\x20\x6d\x69\x20\x6e\x75\x6b\x6b"
"\x75\x75\x2e\x20\x54\x75\x6f\x6b"
"\x73\x75\x74\x20\x76\x61\x6e\x61"
"\x6d\x6f\x6e\x20\x6a\x61\x20\x76"
"\x61\x72\x6a\x6f\x74\x20\x76\x65"
"\x65\x6e\x2c\x20\x6e\x69\x69\x73"
"\x74\xe4\x20\x73\x79\x64\xe4\x6d"
"\x65\x6e\x69\x20\x6c\x61\x75\x6c"
"\x75\x6e\x20\x74\x65\x65\x6e\x2e"
"\x20\x2d\x20\x45\x69\x6e\x6f\x20"
"\x4c\x65\x69\x6e\x6f",
"\x35\x81\x86\x99\x90\x01\xe6\xb5"
"\xda\xf0\x5e\xce\xeb\x7e\xee\x21"
"\xe0\x68\x9c\x1f\x00\xee\xa8\x1f"
"\x7d\xd2\xca\xae\xe1\xd2\x76\x3e"
"\x68\xaf\x0e\xad\x33\xd6\x6c\x26"
"\x8b\xc9\x46\xc4\x84\xfb\xe9\x4c"
"\x5f\x5e\x0b\x86\xa5\x92\x79\xe4"
"\xf8\x24\xe7\xa6\x40\xbd\x22\x32"
"\x10\xb0\xa6\x11\x60\xb7\xbc\xe9"
"\x86\xea\x65\x68\x80\x03\x59\x6b"
"\x63\x0a\x6b\x90\xf8\xe0\xca\xf6"
"\x91\x2a\x98\xeb\x87\x21\x76\xe8"
"\x3c\x20\x2c\xaa\x64\x16\x6d\x2c"
"\xce\x57\xff\x1b\xca\x57\xb2\x13"
"\xf0\xed\x1a\xa7\x2f\xb8\xea\x52"
"\xb0\xbe\x01\xcd\x1e\x41\x28\x67"
"\x72\x0b\x32\x6e\xb3\x89\xd0\x11"
"\xbd\x70\xd8\xaf\x03\x5f\xb0\xd8"
"\x58\x9d\xbc\xe3\xc6\x66\xf5\xea"
"\x8d\x4c\x79\x54\xc5\x0c\x3f\x34"
"\x0b\x04\x67\xf8\x1b\x42\x59\x61"
"\xc1\x18\x43\x07\x4d\xf6\x20\xf2"
"\x08\x40\x4b\x39\x4c\xf9\xd3\x7f"
"\xf5\x4b\x5f\x1a\xd8\xf6\xea\x7d"
"\xa3\xc5\x61\xdf\xa7\x28\x1f\x96"
"\x44\x63\xd2\xcc\x35\xa4\xd1\xb0"
"\x34\x90\xde\xc5\x1b\x07\x11\xfb"
"\xd6\xf5\x5f\x79\x23\x4d\x5b\x7c"
"\x76\x66\x22\xa6\x6d\xe9\x2b\xe9"
"\x96\x46\x1d\x5e\x4d\xc8\x78\xef"
"\x9b\xca\x03\x05\x21\xe8\x35\x1e"
"\x4b\xae\xd2\xfd\x04\xf9\x46\x73"
"\x68\xc4\xad\x6a\xc1\x86\xd0\x82"
"\x45\xb2\x63\xa2\x66\x6d\x1f\x6c"
"\x54\x20\xf1\x59\x9d\xfd\x9f\x43"
"\x89\x21\xc2\xf5\xa4\x63\x93\x8c"
"\xe0\x98\x22\x65\xee\xf7\x01\x79"
"\xbc\x55\x3f\x33\x9e\xb1\xa4\xc1"
"\xaf\x5f\x6a\x54\x7f"
}
};
@@ -369,9 +478,17 @@ test_cipher(int i, const EVP_CIPHER *c, struct tests *t)
EVP_CIPHER_CTX_init(&ectx);
EVP_CIPHER_CTX_init(&dctx);
if (EVP_CipherInit_ex(&ectx, c, NULL, t->key, t->iv, 1) != 1)
if (EVP_CipherInit_ex(&ectx, c, NULL, NULL, NULL, 1) != 1)
errx(1, "%s: %d EVP_CipherInit_ex einit", t->name, i);
if (EVP_CipherInit_ex(&dctx, c, NULL, NULL, NULL, 0) != 1)
errx(1, "%s: %d EVP_CipherInit_ex dinit", t->name, i);
EVP_CIPHER_CTX_set_key_length(&ectx, t->keysize);
EVP_CIPHER_CTX_set_key_length(&dctx, t->keysize);
if (EVP_CipherInit_ex(&ectx, NULL, NULL, t->key, t->iv, 1) != 1)
errx(1, "%s: %d EVP_CipherInit_ex encrypt", t->name, i);
if (EVP_CipherInit_ex(&dctx, c, NULL, t->key, t->iv, 0) != 1)
if (EVP_CipherInit_ex(&dctx, NULL, NULL, t->key, t->iv, 0) != 1)
errx(1, "%s: %d EVP_CipherInit_ex decrypt", t->name, i);
d = emalloc(t->datasize);
@@ -450,18 +567,41 @@ main(int argc, char **argv)
ret += test_cipher(i, EVP_hcrypto_aes_128_cts(), &aes_128_cts_tests[i]);
for (i = 0; i < sizeof(aes_256_cts_tests)/sizeof(aes_256_cts_tests[0]); i++)
ret += test_cipher(i, EVP_hcrypto_aes_256_cts(), &aes_256_cts_tests[i]);
for (i = 0; i < sizeof(aes_tests)/sizeof(aes_tests[0]); i++)
ret += test_cipher(i, EVP_aes_256_cbc(), &aes_tests[i]);
ret += test_cipher(i, EVP_hcrypto_aes_256_cbc(), &aes_tests[i]);
#ifdef __APPLE__
for (i = 0; i < sizeof(aes_tests)/sizeof(aes_tests[0]); i++)
ret += test_cipher(i, EVP_cc_aes_256_cbc(), &aes_tests[i]);
#endif
for (i = 0; i < sizeof(rc2_40_tests)/sizeof(rc2_40_tests[0]); i++)
ret += test_cipher(i, EVP_rc2_40_cbc(), &rc2_40_tests[i]);
ret += test_cipher(i, EVP_hcrypto_rc2_40_cbc(), &rc2_40_tests[i]);
#ifdef __APPLE__
for (i = 0; i < sizeof(rc2_40_tests)/sizeof(rc2_40_tests[0]); i++)
ret += test_cipher(i, EVP_cc_rc2_40_cbc(), &rc2_40_tests[i]);
#endif
for (i = 0; i < sizeof(des_ede3_tests)/sizeof(des_ede3_tests[0]); i++)
ret += test_cipher(i, EVP_des_ede3_cbc(), &des_ede3_tests[i]);
ret += test_cipher(i, EVP_hcrypto_des_ede3_cbc(), &des_ede3_tests[i]);
#ifdef __APPLE__
for (i = 0; i < sizeof(des_ede3_tests)/sizeof(des_ede3_tests[0]); i++)
ret += test_cipher(i, EVP_cc_des_ede3_cbc(), &des_ede3_tests[i]);
#endif
for (i = 0; i < sizeof(camellia128_tests)/sizeof(camellia128_tests[0]); i++)
ret += test_cipher(i, EVP_camellia_128_cbc(), &camellia128_tests[i]);
ret += test_cipher(i, EVP_hcrypto_camellia_128_cbc(), &camellia128_tests[i]);
#ifdef __APPLE__
for (i = 0; i < sizeof(camellia128_tests)/sizeof(camellia128_tests[0]); i++)
ret += test_cipher(i, EVP_cc_camellia_128_cbc(), &camellia128_tests[i]);
#endif
for (i = 0; i < sizeof(rc4_tests)/sizeof(rc4_tests[0]); i++)
ret += test_cipher(i, EVP_hcrypto_rc4(), &rc4_tests[i]);
#ifdef __APPLE__
for (i = 0; i < sizeof(rc4_tests)/sizeof(rc4_tests[0]); i++)
ret += test_cipher(i, EVP_cc_rc4(), &rc4_tests[i]);
#endif
return ret;
}