Fix EVP CCM decrypt. Add decrypt support to algorithm test program.
authorDr. Stephen Henson <steve@openssl.org>
Mon, 18 Apr 2011 22:48:40 +0000 (22:48 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Mon, 18 Apr 2011 22:48:40 +0000 (22:48 +0000)
CHANGES
crypto/evp/e_aes.c
fips/aes/fips_gcmtest.c

diff --git a/CHANGES b/CHANGES
index e7a232e..29ac9dc 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,9 +4,10 @@
 
  Changes between 1.0.1 and 1.1.0  [xx XXX xxxx]
 
-  *) Initial untested CCM support via EVP. Interface is very similar to GCM
-     case except we must supply all data in one chunk (i.e. no update, final)
-     and the message length must be supplied if AAD is used.
+  *) CCM support via EVP. Interface is very similar to GCM case except we
+     must supply all data in one chunk (i.e. no update, final) and the
+     message length must be supplied if AAD is used. Add algorithm test
+     support.
      [Steve Henson]
 
   *) Initial version of POST overhaul. Add POST callback to allow the status
index 2d33837..e862096 100644 (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:
                if (!c->encrypt || !cctx->tag_set)
                        return 0;
-               if(CRYPTO_ccm128_tag(&cctx->ccm, ptr, (size_t)arg))
+               if(!CRYPTO_ccm128_tag(&cctx->ccm, ptr, (size_t)arg))
                        return 0;
                cctx->tag_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))
                        {
                        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))
                                        rv = len;
index cb81f3e..6d0563b 100644 (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 lbuf[2048];
@@ -347,26 +347,37 @@ static void ccmencrypt(FILE *in, FILE *out)
        unsigned char *Adata = NULL, *Payload = NULL;
        unsigned char *CT = NULL;
        int Plen = -1, Nlen = -1, Tlen = -1, Alen = -1;
+       int decr = 0;
        EVP_CIPHER_CTX ctx;
        const EVP_CIPHER *ccm = NULL;
        FIPS_cipher_ctx_init(&ctx);
 
        while(fgets(buf,sizeof buf,in) != NULL)
                {
+               char *p;
                fputs(buf,out);
+               redo:
                if (!parse_line(&keyword, &value, lbuf, buf))
                        continue;
 
                /* If surrounded by square brackets zap them */
                if (keyword[0] == '[')
                        {
-                       char *p;
                        keyword++;
                        p = strchr(value, ']');
                        if (p)
                                *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"))
                        Plen = atoi(value);
                else if (!strcmp(keyword,"Nlen"))
@@ -375,7 +386,9 @@ static void ccmencrypt(FILE *in, FILE *out)
                        Tlen = atoi(value);
                else if (!strcmp(keyword,"Alen"))
                        Alen = atoi(value);
-               else if (!strcmp(keyword,"Key"))
+               if (p)
+                       goto redo;
+               if (!strcmp(keyword,"Key"))
                        {
                        if (Key)
                                OPENSSL_free(Key);
@@ -403,7 +416,7 @@ static void ccmencrypt(FILE *in, FILE *out)
                                exit(1);
                                }
                        }
-               else if (!strcmp(keyword,"Payload"))
+               else if (!strcmp(keyword,"Payload") && !decr)
                        {
                        Payload = hex2bin_m(value, &l);
                        if (Plen && l != Plen)
@@ -421,6 +434,15 @@ static void ccmencrypt(FILE *in, FILE *out)
                                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)
                        {
                        FIPS_cipherinit(&ctx, ccm, NULL, NULL, 1);
@@ -438,7 +460,33 @@ static void ccmencrypt(FILE *in, FILE *out)
                        OPENSSL_free(CT);
                        OPENSSL_free(Payload);
                        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)
                OPENSSL_free(Key);
@@ -450,7 +498,7 @@ static void ccmencrypt(FILE *in, FILE *out)
 int main(int argc,char **argv)
        {
        int encrypt;
-       int xts = 0, ccmenc = 0;
+       int xts = 0, ccm = 0;
        FILE *in, *out;
        if (argc == 4)
                {
@@ -484,8 +532,8 @@ int main(int argc,char **argv)
                encrypt = 2;
        else if(!strcmp(argv[1],"-decrypt"))
                encrypt = 0;
-       else if(!strcmp(argv[1],"-ccmencrypt"))
-               ccmenc = 1;
+       else if(!strcmp(argv[1],"-ccm"))
+               ccm = 1;
        else if(!strcmp(argv[1],"-xts"))
                xts = 1;
        else
@@ -494,8 +542,8 @@ int main(int argc,char **argv)
                exit(1);
                }
 
-       if (ccmenc)
-               ccmencrypt(in, out);
+       if (ccm)
+               ccmtest(in, out);
        else if (xts)
                xtstest(in, out);
        else