3

I'm using the following encryption code which works like a charm, but I have to validate that it's FIPS 197 compliant otherwise Legal will kill me.

mcrypt_encrypt(MCRYPT_RIJNDAEL_256, SALT, $plaintext, MCRYPT_MODE_ECB,
               mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB),
                                MCRYPT_RAND))

and

mcrypt_decrypt(MCRYPT_RIJNDAEL_256, SALT, $plaintext, MCRYPT_MODE_ECB,
               mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB),
                                MCRYPT_RAND))
hakre
  • 193,403
  • 52
  • 435
  • 836
justacoder
  • 2,684
  • 6
  • 47
  • 78

3 Answers3

6

Mcrypt's RIJNDAEL_256 algorithm is the version of the Rijndael algorithm with 256 bit block size. AES (which is what FIPS 197 defines) has only versions with 128-bit block size (and three different key sizes).

So no, you are not using AES here. Use RIJNDAEL_128 instead, which is the same as AES.

There are other things wrong with your code:

  • You should never use ECB if you are encrypting more than one block with the same key. So, never. Use a secure mode of operation instead, like CBC or CTR.

  • As CodeInChaos commented, you normally want to make sure you also have authenticity, not only confidentiality (and depending on your protocol, you might even need authentication for confidentiality). So, add a MAC to your message, or use a mode of operation which also gives authentication together with confidentiality (like CCM or GCM) - not sure which ones are included in mcrypt.

  • You generate a random initialization vector on encryption (good) and decryption (bad). This doesn't matter for ECB, since it doesn't use an initialization vector, but with any other mode you'll get a different initialization vector for both actions, meaning that decryption will get different results. With CBC only the first block will be garbage, while with CTR everything will be garbage (and CCM/GCM will simply report "fail").

    As the initialization vector doesn't need to be secret (just non-predictable or non-repeating, depending on the mode), it is custom to either send it together with the message (as a prefix), or to derive it (on both sides) from a common secret (like the first initialization vectors in SSL/TLS, which are derived from the master secret, just as the encryption keys and MAC keys).

Paŭlo Ebermann
  • 73,284
  • 20
  • 146
  • 210
  • If I don't use ECB, then how do I decrypt if the iv isn't the same? – justacoder Nov 08 '11 at 18:19
  • You normally transmit the IV together with the message. I should have added this to this paragraph (I'll do so now). – Paŭlo Ebermann Nov 08 '11 at 18:22
  • Ah, message can mean either the plaintext (i.e. what you want to encrypt and later get after decryption), or the ciphertext (i.e. what is sent or stored, what you get after encryption and pass to decryption). Here I mean that you simply send `$IV . $ciphertext`, in PHP-speak. – Paŭlo Ebermann Nov 08 '11 at 19:00
  • I found another example on here that does what you're saying: (http://stackoverflow.com/questions/2746939/using-mcrypt-to-pass-data-across-a-webservice-is-failing). I'll use this example and convert the cipher accordingly. Thanks. – justacoder Nov 08 '11 at 19:00
  • Yes, that does the right thing about the initialization vector. You still would want to add authentication. – Paŭlo Ebermann Nov 08 '11 at 19:04
1

Depends on what your definition of "compliant". Does it comply with all of the rules set out with FIPS 197 - yes I believe so.

It is not FIPS 197 validated. A validated implementation means it's been specifically tested by NIST / CST Labs and certified to comply with FIPS pub 197. You can use this list for a list of all vendors and products that are FIPS 197 validated.

vcsjones
  • 138,677
  • 31
  • 291
  • 286
1

FIPS 197 only specifies the Rijndael algorithm, not the implementation. So yes, it is compliant.

The implementation however is specified in NIST SP 800-38A.

I do not know about the rest (plaintext padding, strength of the PRNG, etc.), but ECB is a very, very bad thing to do in 99% of Rijndael's implementations and thus not recommended.

Dennis
  • 14,264
  • 2
  • 48
  • 57
  • What mode do you recommend if not ECB? cbc, cfb, or ofb? – justacoder Nov 08 '11 at 18:17
  • CFB and OFB convert a block cipher into a stream cipher. Personally, I like *real* block ciphers (like CBC) better, but that is only my personal opinion. All three are good modes of operation. – Dennis Nov 08 '11 at 20:23