Add algorithm driver for XTS mode. Fix several bugs in EVP XTS implementation.

This commit is contained in:
Dr. Stephen Henson 2011-04-15 02:49:30 +00:00
parent 706735aea3
commit 06b7e5a0e4
3 changed files with 100 additions and 11 deletions

View file

@ -9,9 +9,10 @@
to use callback. Always run all selftests even if one fails. to use callback. Always run all selftests even if one fails.
[Steve Henson] [Steve Henson]
*) Provisional XTS support. Note: this does increase the maximum key *) XTS support including algorithm test driver in the fips_gcmtest program.
length from 32 to 64 bytes but there should be no binary compatibility Note: this does increase the maximum key length from 32 to 64 bytes but
issues as existing applications will never use XTS mode. there should be no binary compatibility issues as existing applications
will never use XTS mode.
[Steve Henson] [Steve Henson]
*) Extensive reorganisation of FIPS PRNG behaviour. Remove all dependencies *) Extensive reorganisation of FIPS PRNG behaviour. Remove all dependencies

View file

@ -471,8 +471,6 @@ static int aes_xts_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
/* key1 and key2 are used as an indicator both key and IV are set */ /* key1 and key2 are used as an indicator both key and IV are set */
xctx->xts.key1 = NULL; xctx->xts.key1 = NULL;
xctx->xts.key2 = NULL; xctx->xts.key2 = NULL;
xctx->xts.block1 = (block128_f)AES_encrypt;
xctx->xts.block2 = (block128_f)AES_encrypt;
return 1; return 1;
} }
@ -485,13 +483,23 @@ static int aes_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
if (key) if (key)
{ {
AES_set_encrypt_key(key, ctx->key_len * 8, &xctx->ks1); /* key_len is two AES keys */
AES_set_encrypt_key(key + ctx->key_len, ctx->key_len * 8, if (ctx->encrypt)
&xctx->ks2); {
AES_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1);
xctx->xts.block1 = (block128_f)AES_encrypt;
}
else
{
AES_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1);
xctx->xts.block1 = (block128_f)AES_decrypt;
}
AES_set_encrypt_key(key + ctx->key_len/2,
ctx->key_len * 4, &xctx->ks2);
xctx->xts.block2 = (block128_f)AES_encrypt;
xctx->xts.key1 = &xctx->ks1; xctx->xts.key1 = &xctx->ks1;
xctx->xts.block1 = (block128_f)AES_encrypt;
xctx->xts.block2 = (block128_f)AES_encrypt;
} }
if (iv) if (iv)

View file

@ -263,9 +263,84 @@ static void gcmtest(FILE *in, FILE *out, int encrypt)
} }
} }
static void xtstest(FILE *in, FILE *out)
{
char buf[2048];
char lbuf[2048];
char *keyword, *value;
int inlen;
int encrypt = 0;
int rv;
long l;
unsigned char *key = NULL, *iv = NULL;
unsigned char *inbuf = NULL, *outbuf = NULL;
EVP_CIPHER_CTX ctx;
const EVP_CIPHER *xts = NULL;
FIPS_cipher_ctx_init(&ctx);
while(fgets(buf,sizeof buf,in) != NULL)
{
fputs(buf,out);
if (buf[0] == '[' && strlen(buf) >= 9)
{
if(!strncmp(buf,"[ENCRYPT]", 9))
encrypt = 1;
else if(!strncmp(buf,"[DECRYPT]", 9))
encrypt = 0;
}
if (!parse_line(&keyword, &value, lbuf, buf))
continue;
else if(!strcmp(keyword,"Key"))
{
key = hex2bin_m(value, &l);
if (l == 32)
xts = EVP_aes_128_xts();
else if (l == 64)
xts = EVP_aes_256_xts();
else
{
fprintf(stderr, "Inconsistent Key length\n");
exit(1);
}
}
else if(!strcmp(keyword,"i"))
{
iv = hex2bin_m(value, &l);
if (l != 16)
{
fprintf(stderr, "Inconsistent i length\n");
exit(1);
}
}
else if(encrypt && !strcmp(keyword,"PT"))
{
inbuf = hex2bin_m(value, &l);
inlen = l;
}
else if(!encrypt && !strcmp(keyword,"CT"))
{
inbuf = hex2bin_m(value, &l);
inlen = l;
}
if (inbuf)
{
FIPS_cipherinit(&ctx, xts, key, iv, encrypt);
outbuf = OPENSSL_malloc(inlen);
rv = FIPS_cipher(&ctx, outbuf, inbuf, inlen);
OutputValue(encrypt ? "CT":"PT", outbuf, inlen, out, 0);
OPENSSL_free(inbuf);
OPENSSL_free(outbuf);
OPENSSL_free(key);
OPENSSL_free(iv);
iv = key = inbuf = outbuf = NULL;
}
}
}
int main(int argc,char **argv) int main(int argc,char **argv)
{ {
int encrypt; int encrypt;
int xts = 0;
FILE *in, *out; FILE *in, *out;
if (argc == 4) if (argc == 4)
{ {
@ -299,13 +374,18 @@ int main(int argc,char **argv)
encrypt = 2; encrypt = 2;
else if(!strcmp(argv[1],"-decrypt")) else if(!strcmp(argv[1],"-decrypt"))
encrypt = 0; encrypt = 0;
else if(!strcmp(argv[1],"-xts"))
xts = 1;
else else
{ {
fprintf(stderr,"Don't know how to %s.\n",argv[1]); fprintf(stderr,"Don't know how to %s.\n",argv[1]);
exit(1); exit(1);
} }
gcmtest(in, out, encrypt); if (xts)
xtstest(in, out);
else
gcmtest(in, out, encrypt);
if (argc == 4) if (argc == 4)
{ {