Any other comments on the actual issue here?

I don't believe the inconsistency is the expected way the API should work.

Thanks,
-AJ



----- Original Message -----
From: AJ <aunt.joma...@yahoo.com>
To: "openssl-users@openssl.org" <openssl-users@openssl.org>
Cc: 
Sent: Friday, October 12, 2012 7:14 PM
Subject: Re: Inconsistent behavior between FIPS and non-FIPS AES

Hi Jeff,

Thanks for the response ... all the return values are 1, including setting the 
FIPS mode.
I had removed the checks in this stripped down example code to get to my point 
and try to show the relevant portions, and minimize the code for someone to 
look at.

-AJ


----- Original Message -----
From: Jeffrey Walton <noloa...@gmail.com>
To: openssl-users@openssl.org
Cc: 
Sent: Friday, October 12, 2012 6:44 PM
Subject: Re: Inconsistent behavior between FIPS and non-FIPS AES

Hi aunt.jomamma,

You have ignored every return value. You should probably start by
checking all return values.

If you check all return values *and* assert all the checks, you will
have self debugging code. I find self debugging code the best code of
all, but I'm kind of lazy.

> 2) Is there purposely a difference in behavior between the FIPS and non-FIPS 
> versions,...
Did FIPS_mode_set succeed? It returns 1 on success.

Jeff

On Fri, Oct 12, 2012 at 4:40 PM, AJ <aunt.joma...@yahoo.com> wrote:
> Hi,
>
> I've noticed an inconsistency between the behavior of AES_CTR in FIPS and 
> non-FIPS modes.
> I am using openssl-1.0.1c and openssl-fips-2.0.
>
> The following code demonstrates the issue:
>
>   1 #include <stdio.h>
>   2 #include <string.h>
>   3 #include "openssl/evp.h"
>   4
>   5 #define MSG_SIZE 14
>   6 const unsigned char *key = (unsigned char *)"1234567890123456";
>   7 const unsigned char *iv =  (unsigned char *)"0101010101010101";
>   8
>   9 int main(void) {
>  10
>  11         unsigned char in_1[MSG_SIZE];
>  12         unsigned char in_2[MSG_SIZE];
>  13         unsigned char out_1[MSG_SIZE];
>  14         unsigned char out_2[MSG_SIZE];
>  15         int out_len_1, out_len_2;
>  16
>  17         EVP_CIPHER_CTX ctx_1, ctx_2;
>  18
>  19         memset ( in_1, 0, MSG_SIZE );
>  20         memset ( in_2, 0, MSG_SIZE );
>  21
>  22         EVP_CIPHER_CTX_init( &ctx_1 );
>  23         EVP_EncryptInit( &ctx_1, EVP_aes_128_ctr(), key, iv );
>  24         EVP_EncryptUpdate( &ctx_1, out_1, &out_len_1, in_1, MSG_SIZE );
>  25         EVP_EncryptInit( &ctx_1, NULL, NULL, iv );
>  26         EVP_EncryptUpdate( &ctx_1, out_1, &out_len_1, in_1, MSG_SIZE );
>  27
>  28         FIPS_mode_set(1);   /* Enable FIPS mode */
>  29
>  30         EVP_CIPHER_CTX_init( &ctx_2 );
>  31         EVP_EncryptInit( &ctx_2, EVP_aes_128_ctr(), key, iv );
>  32         EVP_EncryptUpdate( &ctx_2, out_2, &out_len_2, in_2, MSG_SIZE );
>  33         EVP_EncryptInit( &ctx_2, NULL, NULL, iv );
>  34         EVP_EncryptUpdate( &ctx_2, out_2, &out_len_2, in_2, MSG_SIZE );
>  35
>  36         if ( memcmp( out_1, out_2, MSG_SIZE ) == 0 ) {
>  37                 printf("Buffers are equal.\n\n");
>  38         } else {
>  39                 printf("Buffers are not equal.\n\n");
>  40         }
>  41
>  42         return 0;
>  43 }
>
> The reason for the difference outputs is that there is a difference in the 
> EVP_EncryptInit code (lines 25 and 33) for the 2 modes.
>
> In the non-FIPS mode, line 25 will reset the ctx_1->num to zero.  This is 
> done in EVP_CipherInit_ex(), line 240:
> 239                         case EVP_CIPH_CTR_MODE:
> 240                         ctx->num = 0;
> 241                         /* Don't reuse IV for CTR mode */
> 242                         if(iv)
> 243                                 memcpy(ctx->iv, iv, 
> EVP_CIPHER_CTX_iv_length(ctx));
> 244                         break;
> 245
>
> However, in FIPS mode, the equivalent line does not reset ctx_2->num.  This 
> is from FIPS_cipherinit(), lines 210-215:
> 210                         case EVP_CIPH_CTR_MODE:
> 211                         /* Don't reuse IV for CTR mode */
> 212                         if(iv)
> 213                                 memcpy(ctx->iv, iv, 
> M_EVP_CIPHER_CTX_iv_length(ctx));
> 214                         break;
> 215
>
>
> I can make my program work if I change line 33 from:
> EVP_EncryptInit( &ctx_2, NULL, NULL, iv );
> to:
> EVP_EncryptInit( &ctx_2, EVP_aes_128_ctr(), key, iv );
>
> This explicitly specifies the cipher and key again.  From the docs, it 
> appears that I should be able to set them to NULL and have it work, if they 
> don't need to be updated, and that is how it works in the non-FIPS mode.
>
> Questions:
> ========
> 1) Should I need to explicitly specifies the cipher and key again in 
> EVP_EncryptInit(), if I am only updating the IV?  (i.e. should I be able to 
> put NULL for key and cipher).
> 2) Is there purposely a difference in behavior between the FIPS and non-FIPS 
> versions, or is this a bug?  My understanding was that they *should* work 
> interchangeably.
>
______________________________________________________________________
OpenSSL Project                                http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                          majord...@openssl.org

______________________________________________________________________
OpenSSL Project                                http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                          majord...@openssl.org

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           majord...@openssl.org

Reply via email to