Hello Catageek,

thank you for showing this bug.
I'll fix it today and tomorrow you will be able to see the fix live in the 
CryptoJPM <https://github.com/DevJPM/CryptoJPM> library.
This library will be proposed to be integrated back into Crypto++ soon.
All users VMAC (which isn't widely used I believe)can refer to this thread 
until then.

BR

JPM

Am Dienstag, 6. Januar 2015 20:50:23 UTC+1 schrieb Catageek:
>
> Hello,
>
> I discovered recently a bug in vmac.cpp affecting VMAC-64 and resulting in 
> the repeated use of the same nonce even if the user is providing a proper 
> unique nonce, which opens the possibility of an attack.
>
> The vulnerability is affecting VMAC-64 when using arbitratry nonce, such 
> as a timestamp. Appplications using a counter as nonce are not affected by 
> the vulnerability, but do not conform to the specification (see below).
>
> The bug in in the Resynchronize(const byte* nonce) function. This function 
> executes the PDF algorithm and produces a pad of 128 bit. 2 equal nonces 
> except the LSB bit produce the same pad value, this allows to save an AES 
> operation, The code of the function implements the optimization that 
> consists in comparing the last nonce with the nonce provided by the user 
> (except the LSB bit) and running the PDF algorithm only if they differ, 
> otherwise use the same pad.
>
> The bug is at line 114 of vmac.cpp, here is the code with the diff showing 
> how to fix the bug:
>  
> --              if (m_padCached && (storedNonce[s-1] | 1) == 
> (nonce[length-1] | 1))
> ++            if (m_padCached && (m_padCached = (storedNonce[s-1] | 1) == 
> (nonce[length-1] | 1)))
>                 {
>                         m_padCached = 
> VerifyBufsEqual(storedNonce+s-length, nonce, length-1);
>                         for (size_t i=0; m_padCached && i<s-length; i++) 
>                                 m_padCached = (storedNonce[i] == 0);
>                 }       
>                 if (!m_padCached)
>                 {               
>                         memset(storedNonce, 0, s-length);
>                         memcpy(storedNonce+s-length, nonce, length-1);
>                         storedNonce[s-1] = nonce[length-1] & 0xfe;
>                         AccessCipher().ProcessBlock(storedNonce, m_pad());
>                         m_padCached = true;
>                 }       
>                 storedNonce[s-1] = nonce[length-1];
>
> The issue is that the result of the comparison (storedNonce[s-1] | 1) == 
> (nonce[length-1] | 1) is not stored in m_padCached. When the result is 
> false, the first block is not executed, but the second block is skipped 
> also, and the pad is not generated. The implementation uses the same pad 
> again and again until the result of the test is true.
>
> Using a counter as nonce, the implementation does not strictly conform to 
> the specifications but the security level is not decreased since a pad is 
> still computed every 2 nonces.
>
> The code below computes the digest of the same message using a different 
> nonce, but the tag produced will be the same:
>
> VMAC<AES,64> hasher;
> hasher.SetKeywithIV(key, keylength, nonce0);
> std::string msg("test");
> hasher.ComputeDigest(digest0, msg, 4);
> hasher.Resynchronize(nonce1); // nonce1 ! = nonce0, has no effect
> hasher.ComputeDigest(digest1, msg, 4);
> // digest0 == digest1
>

-- 
-- 
You received this message because you are subscribed to the "Crypto++ Users" 
Google Group.
To unsubscribe, send an email to [email protected].
More information about Crypto++ and this group is available at 
http://www.cryptopp.com.
--- 
You received this message because you are subscribed to the Google Groups 
"Crypto++ Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to