Redirect HMAC and CMAC operations to module.
authorDr. Stephen Henson <steve@openssl.org>
Sun, 12 Jun 2011 15:07:26 +0000 (15:07 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Sun, 12 Jun 2011 15:07:26 +0000 (15:07 +0000)
CHANGES
crypto/cmac/cmac.c
crypto/evp/evp.h
crypto/evp/evp_err.c
crypto/hmac/hmac.c

diff --git a/CHANGES b/CHANGES
index 2330402f9196ba16a6be9a388c969b7b0d401f49..933aae0fabd5c7c259863888d3a4c008a9fea418 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,11 @@
 
  Changes between 1.0.0d and 1.0.1  [xx XXX xxxx]
 
+  *) Redirect HMAC and CMAC operations to FIPS module in FIPS mode. If an
+     ENGINE is used then we cannot handle that in the FIPS module so we
+     keep original code iff non-FIPS operations are allowed.
+     [Steve Henson]
+
   *) Add -attime option to openssl verify.
      [Peter Eckersley <pde@eff.org> and Ben Laurie]
 
index 0069ae807fbf9aee9fafd24f1c74843cde62928f..b58602680bb00595845be76e2706df807fc1ff66 100644 (file)
  * ====================================================================
  */
 
-#define OPENSSL_FIPSAPI
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include "cryptlib.h"
 #include <openssl/cmac.h>
 
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
 struct CMAC_CTX_st
        {
        /* Cipher context to use */
@@ -105,6 +107,13 @@ CMAC_CTX *CMAC_CTX_new(void)
 
 void CMAC_CTX_cleanup(CMAC_CTX *ctx)
        {
+#ifdef OPENSSL_FIPS
+       if (FIPS_mode() && !ctx->cctx.engine)
+               {
+               FIPS_cmac_ctx_cleanup(ctx);
+               return;
+               }
+#endif
        EVP_CIPHER_CTX_cleanup(&ctx->cctx);
        OPENSSL_cleanse(ctx->tbl, EVP_MAX_BLOCK_LENGTH);
        OPENSSL_cleanse(ctx->k1, EVP_MAX_BLOCK_LENGTH);
@@ -144,6 +153,24 @@ int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen,
                        const EVP_CIPHER *cipher, ENGINE *impl)
        {
        static unsigned char zero_iv[EVP_MAX_BLOCK_LENGTH];
+#ifdef OPENSSL_FIPS
+       if (FIPS_mode())
+               {
+               /* If we have an ENGINE need to allow non FIPS */
+               if ((impl || ctx->cctx.engine)
+                       && !(ctx->cctx.flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW))
+
+                       {
+                       EVPerr(EVP_F_CMAC_INIT, EVP_R_DISABLED_FOR_FIPS);
+                       return 0;
+                       }
+               /* Other algorithm blocking will be done in FIPS_cmac_init,
+                * via FIPS_cipherinit().
+                */
+               if (!impl && !ctx->cctx.engine)
+                       return FIPS_cmac_init(ctx, key, keylen, cipher, NULL);
+               }
+#endif
        /* All zeros means restart */
        if (!key && !cipher && !impl && keylen == 0)
                {
@@ -187,6 +214,10 @@ int CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen)
        {
        const unsigned char *data = in;
        size_t bl;
+#ifdef OPENSSL_FIPS
+       if (FIPS_mode() && !ctx->cctx.engine)
+               return FIPS_cmac_update(ctx, in, dlen);
+#endif
        if (ctx->nlast_block == -1)
                return 0;
        if (dlen == 0)
@@ -228,6 +259,10 @@ int CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen)
 int CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen)
        {
        int i, bl, lb;
+#ifdef OPENSSL_FIPS
+       if (FIPS_mode() && !ctx->cctx.engine)
+               return FIPS_cmac_final(ctx, out, poutlen);
+#endif
        if (ctx->nlast_block == -1)
                return 0;
        bl = EVP_CIPHER_CTX_block_size(&ctx->cctx);
index 0a0fc329d0cdfd37120a442f8c1e522d107150e6..736faf8ee11330a2eb9382291751cb14fd980d62 100644 (file)
@@ -1236,6 +1236,7 @@ void ERR_load_EVP_strings(void);
 #define EVP_F_AES_INIT_KEY                              133
 #define EVP_F_AES_XTS                                   172
 #define EVP_F_CAMELLIA_INIT_KEY                                 159
+#define EVP_F_CMAC_INIT                                         173
 #define EVP_F_D2I_PKEY                                  100
 #define EVP_F_DO_SIGVER_INIT                            161
 #define EVP_F_DSAPKEY2PKCS8                             134
@@ -1296,6 +1297,7 @@ void ERR_load_EVP_strings(void);
 #define EVP_F_FIPS_CIPHER_CTX_SET_KEY_LENGTH            171
 #define EVP_F_FIPS_DIGESTINIT                           168
 #define EVP_F_FIPS_MD_CTX_COPY                          169
+#define EVP_F_HMAC_INIT_EX                              174
 #define EVP_F_INT_CTX_NEW                               157
 #define EVP_F_PKCS5_PBE_KEYIVGEN                        117
 #define EVP_F_PKCS5_V2_PBE_KEYIVGEN                     118
index 095f7c712bccbcd7b751df63429cd0af4d203fab..e27d56f93659e4583548822b65ea935144bccdbe 100644 (file)
@@ -1,6 +1,6 @@
 /* crypto/evp/evp_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2010 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-2011 The OpenSSL Project.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -74,6 +74,7 @@ static ERR_STRING_DATA EVP_str_functs[]=
 {ERR_FUNC(EVP_F_AES_INIT_KEY), "AES_INIT_KEY"},
 {ERR_FUNC(EVP_F_AES_XTS),      "AES_XTS"},
 {ERR_FUNC(EVP_F_CAMELLIA_INIT_KEY),    "CAMELLIA_INIT_KEY"},
+{ERR_FUNC(EVP_F_CMAC_INIT),    "CMAC_INIT"},
 {ERR_FUNC(EVP_F_D2I_PKEY),     "D2I_PKEY"},
 {ERR_FUNC(EVP_F_DO_SIGVER_INIT),       "DO_SIGVER_INIT"},
 {ERR_FUNC(EVP_F_DSAPKEY2PKCS8),        "DSAPKEY2PKCS8"},
@@ -134,6 +135,7 @@ static ERR_STRING_DATA EVP_str_functs[]=
 {ERR_FUNC(EVP_F_FIPS_CIPHER_CTX_SET_KEY_LENGTH),       "FIPS_CIPHER_CTX_SET_KEY_LENGTH"},
 {ERR_FUNC(EVP_F_FIPS_DIGESTINIT),      "FIPS_DIGESTINIT"},
 {ERR_FUNC(EVP_F_FIPS_MD_CTX_COPY),     "FIPS_MD_CTX_COPY"},
+{ERR_FUNC(EVP_F_HMAC_INIT_EX), "HMAC_Init_ex"},
 {ERR_FUNC(EVP_F_INT_CTX_NEW),  "INT_CTX_NEW"},
 {ERR_FUNC(EVP_F_PKCS5_PBE_KEYIVGEN),   "PKCS5_PBE_keyivgen"},
 {ERR_FUNC(EVP_F_PKCS5_V2_PBE_KEYIVGEN),        "PKCS5_v2_PBE_keyivgen"},
index 6c98fc43a31c310c69781c0430a5423b1dc77be8..ba27cbf56f2e9f843627795da68240240b67f5d9 100644 (file)
 #include "cryptlib.h"
 #include <openssl/hmac.h>
 
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
 int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
                  const EVP_MD *md, ENGINE *impl)
        {
        int i,j,reset=0;
        unsigned char pad[HMAC_MAX_MD_CBLOCK];
 
+#ifdef OPENSSL_FIPS
+       if (FIPS_mode())
+               {
+               /* If we have an ENGINE need to allow non FIPS */
+               if ((impl || ctx->i_ctx.engine)
+                       &&  !(ctx->i_ctx.flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW))
+                       {
+                       EVPerr(EVP_F_HMAC_INIT_EX, EVP_R_DISABLED_FOR_FIPS);
+                       return 0;
+                       }
+               /* Other algorithm blocking will be done in FIPS_cmac_init,
+                * via FIPS_hmac_init_ex().
+                */
+               if (!impl && !ctx->i_ctx.engine)
+                       return FIPS_hmac_init_ex(ctx, key, len, md, NULL);
+               }
+#endif
+
        if (md != NULL)
                {
                reset=1;
@@ -133,6 +155,10 @@ int HMAC_Init(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md)
 
 int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len)
        {
+#ifdef OPENSSL_FIPS
+       if (FIPS_mode() && !ctx->i_ctx.engine)
+               return FIPS_hmac_update(ctx, data, len);
+#endif
        return EVP_DigestUpdate(&ctx->md_ctx,data,len);
        }
 
@@ -140,6 +166,10 @@ int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len)
        {
        unsigned int i;
        unsigned char buf[EVP_MAX_MD_SIZE];
+#ifdef OPENSSL_FIPS
+       if (FIPS_mode() && !ctx->i_ctx.engine)
+               return FIPS_hmac_final(ctx, md, len);
+#endif
 
        if (!EVP_DigestFinal_ex(&ctx->md_ctx,buf,&i))
                goto err;
@@ -179,6 +209,13 @@ int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx)
 
 void HMAC_CTX_cleanup(HMAC_CTX *ctx)
        {
+#ifdef OPENSSL_FIPS
+       if (FIPS_mode() && !ctx->i_ctx.engine)
+               {
+               FIPS_hmac_ctx_cleanup(ctx);
+               return;
+               }
+#endif
        EVP_MD_CTX_cleanup(&ctx->i_ctx);
        EVP_MD_CTX_cleanup(&ctx->o_ctx);
        EVP_MD_CTX_cleanup(&ctx->md_ctx);