Fix EVP CCM decrypt. Add decrypt support to algorithm test program.

This commit is contained in:
Dr. Stephen Henson
2011-04-18 22:48:40 +00:00
parent 98279c1629
commit b5dd178740
3 changed files with 65 additions and 16 deletions

View File

@@ -4,9 +4,10 @@
Changes between 1.0.1 and 1.1.0 [xx XXX xxxx] Changes between 1.0.1 and 1.1.0 [xx XXX xxxx]
*) Initial untested CCM support via EVP. Interface is very similar to GCM *) CCM support via EVP. Interface is very similar to GCM case except we
case except we must supply all data in one chunk (i.e. no update, final) must supply all data in one chunk (i.e. no update, final) and the
and the message length must be supplied if AAD is used. message length must be supplied if AAD is used. Add algorithm test
support.
[Steve Henson] [Steve Henson]
*) Initial version of POST overhaul. Add POST callback to allow the status *) Initial version of POST overhaul. Add POST callback to allow the status

View File

@@ -625,7 +625,7 @@ static int aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
case EVP_CTRL_CCM_GET_TAG: case EVP_CTRL_CCM_GET_TAG:
if (!c->encrypt || !cctx->tag_set) if (!c->encrypt || !cctx->tag_set)
return 0; return 0;
if(CRYPTO_ccm128_tag(&cctx->ccm, ptr, (size_t)arg)) if(!CRYPTO_ccm128_tag(&cctx->ccm, ptr, (size_t)arg))
return 0; return 0;
cctx->tag_set = 0; cctx->tag_set = 0;
cctx->iv_set = 0; cctx->iv_set = 0;
@@ -707,7 +707,7 @@ static int aes_ccm(EVP_CIPHER_CTX *ctx, unsigned char *out,
if (!CRYPTO_ccm128_decrypt(ccm, in, out, len)) if (!CRYPTO_ccm128_decrypt(ccm, in, out, len))
{ {
unsigned char tag[16]; unsigned char tag[16];
if (!CRYPTO_ccm128_tag(ccm, tag, cctx->M)) if (CRYPTO_ccm128_tag(ccm, tag, cctx->M))
{ {
if (!memcmp(tag, ctx->buf, cctx->M)) if (!memcmp(tag, ctx->buf, cctx->M))
rv = len; rv = len;

View File

@@ -337,7 +337,7 @@ static void xtstest(FILE *in, FILE *out)
} }
} }
static void ccmencrypt(FILE *in, FILE *out) static void ccmtest(FILE *in, FILE *out)
{ {
char buf[2048]; char buf[2048];
char lbuf[2048]; char lbuf[2048];
@@ -347,26 +347,37 @@ static void ccmencrypt(FILE *in, FILE *out)
unsigned char *Adata = NULL, *Payload = NULL; unsigned char *Adata = NULL, *Payload = NULL;
unsigned char *CT = NULL; unsigned char *CT = NULL;
int Plen = -1, Nlen = -1, Tlen = -1, Alen = -1; int Plen = -1, Nlen = -1, Tlen = -1, Alen = -1;
int decr = 0;
EVP_CIPHER_CTX ctx; EVP_CIPHER_CTX ctx;
const EVP_CIPHER *ccm = NULL; const EVP_CIPHER *ccm = NULL;
FIPS_cipher_ctx_init(&ctx); FIPS_cipher_ctx_init(&ctx);
while(fgets(buf,sizeof buf,in) != NULL) while(fgets(buf,sizeof buf,in) != NULL)
{ {
char *p;
fputs(buf,out); fputs(buf,out);
redo:
if (!parse_line(&keyword, &value, lbuf, buf)) if (!parse_line(&keyword, &value, lbuf, buf))
continue; continue;
/* If surrounded by square brackets zap them */ /* If surrounded by square brackets zap them */
if (keyword[0] == '[') if (keyword[0] == '[')
{ {
char *p;
keyword++; keyword++;
p = strchr(value, ']'); p = strchr(value, ']');
if (p) if (p)
*p = 0; *p = 0;
} }
/* See if we have a comma separated list of parameters
* if so copy rest of line back to buffer and redo later.
*/
p = strchr(value, ',');
if (p)
{
*p = 0;
strcpy(buf, p + 1);
decr = 1;
}
if (!strcmp(keyword,"Plen")) if (!strcmp(keyword,"Plen"))
Plen = atoi(value); Plen = atoi(value);
else if (!strcmp(keyword,"Nlen")) else if (!strcmp(keyword,"Nlen"))
@@ -375,7 +386,9 @@ static void ccmencrypt(FILE *in, FILE *out)
Tlen = atoi(value); Tlen = atoi(value);
else if (!strcmp(keyword,"Alen")) else if (!strcmp(keyword,"Alen"))
Alen = atoi(value); Alen = atoi(value);
else if (!strcmp(keyword,"Key")) if (p)
goto redo;
if (!strcmp(keyword,"Key"))
{ {
if (Key) if (Key)
OPENSSL_free(Key); OPENSSL_free(Key);
@@ -403,7 +416,7 @@ static void ccmencrypt(FILE *in, FILE *out)
exit(1); exit(1);
} }
} }
else if (!strcmp(keyword,"Payload")) else if (!strcmp(keyword,"Payload") && !decr)
{ {
Payload = hex2bin_m(value, &l); Payload = hex2bin_m(value, &l);
if (Plen && l != Plen) if (Plen && l != Plen)
@@ -421,6 +434,15 @@ static void ccmencrypt(FILE *in, FILE *out)
exit(1); exit(1);
} }
} }
else if (!strcmp(keyword,"CT") && decr)
{
CT = hex2bin_m(value, &l);
if (l != (Plen + Tlen))
{
fprintf(stderr, "Inconsistent CT length\n");
exit(1);
}
}
if (Payload) if (Payload)
{ {
FIPS_cipherinit(&ctx, ccm, NULL, NULL, 1); FIPS_cipherinit(&ctx, ccm, NULL, NULL, 1);
@@ -439,6 +461,32 @@ static void ccmencrypt(FILE *in, FILE *out)
OPENSSL_free(Payload); OPENSSL_free(Payload);
CT = Payload = NULL; CT = Payload = NULL;
} }
if (CT)
{
int rv;
int len = Plen == 0 ? 1: Plen;
FIPS_cipherinit(&ctx, ccm, NULL, NULL, 0);
FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_CCM_SET_IVLEN, Nlen, 0);
FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_CCM_SET_TAG,
Tlen, CT + Plen);
FIPS_cipherinit(&ctx, NULL, Key, Nonce, 0);
FIPS_cipher(&ctx, NULL, NULL, Plen);
FIPS_cipher(&ctx, NULL, Adata, Alen);
Payload = OPENSSL_malloc(len);
rv = FIPS_cipher(&ctx, Payload, CT, Plen);
if (rv >= 0)
{
if (rv == 0)
Payload[0] = 0;
fputs("Result = Pass\n", out);
OutputValue("Payload", Payload, len, out, 0);
}
else
fputs("Result = Fail\n", out);
OPENSSL_free(CT);
OPENSSL_free(Payload);
CT = Payload = NULL;
}
} }
if (Key) if (Key)
OPENSSL_free(Key); OPENSSL_free(Key);
@@ -450,7 +498,7 @@ static void ccmencrypt(FILE *in, FILE *out)
int main(int argc,char **argv) int main(int argc,char **argv)
{ {
int encrypt; int encrypt;
int xts = 0, ccmenc = 0; int xts = 0, ccm = 0;
FILE *in, *out; FILE *in, *out;
if (argc == 4) if (argc == 4)
{ {
@@ -484,8 +532,8 @@ 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],"-ccmencrypt")) else if(!strcmp(argv[1],"-ccm"))
ccmenc = 1; ccm = 1;
else if(!strcmp(argv[1],"-xts")) else if(!strcmp(argv[1],"-xts"))
xts = 1; xts = 1;
else else
@@ -494,8 +542,8 @@ int main(int argc,char **argv)
exit(1); exit(1);
} }
if (ccmenc) if (ccm)
ccmencrypt(in, out); ccmtest(in, out);
else if (xts) else if (xts)
xtstest(in, out); xtstest(in, out);
else else