Re: Inconsistent behavior between FIPS and non-FIPS AES
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
Re: Inconsistent behavior between FIPS and non-FIPS AES
On Tue, Oct 16, 2012, AJ wrote: Any other comments on the actual issue here? I don't believe the inconsistency is the expected way the API should work. It's a bug. The fix was applied to non-validated versions of OpenSSL but was too late to be included in the last validation. Steve. -- Dr Stephen N. Henson. OpenSSL project core developer. Commercial tech support now available see: http://www.openssl.org __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Re: Inconsistent behavior between FIPS and non-FIPS AES
Steve, Thank you for the confirmation. It would be useful to put known issues exceptions in the Users Guide, particularly for the FIPS validated versions, as they have such long cycles between when they will be revalidated. Thanks, -AJ - Original Message - From: Dr. Stephen Henson st...@openssl.org To: openssl-users@openssl.org Cc: Sent: Tuesday, October 16, 2012 11:35 AM Subject: Re: Inconsistent behavior between FIPS and non-FIPS AES On Tue, Oct 16, 2012, AJ wrote: Any other comments on the actual issue here? I don't believe the inconsistency is the expected way the API should work. It's a bug. The fix was applied to non-validated versions of OpenSSL but was too late to be included in the last validation. Steve. -- Dr Stephen N. Henson. OpenSSL project core developer. Commercial tech support now available see: http://www.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 Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
Inconsistent behavior between FIPS and non-FIPS AES
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. Thanks, AJ __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
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 Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
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 Listopenssl-users@openssl.org Automated List