Add algorithm driver for XTS mode. Fix several bugs in EVP XTS implementation.
This commit is contained in:
parent
706735aea3
commit
06b7e5a0e4
3 changed files with 100 additions and 11 deletions
7
CHANGES
7
CHANGES
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue