Edit notes and updates below.
Re-post from https://support.google.com/googleplay/android-developer/thread/277993015 as Google Support FAQ answer 9450925 states to post this here. (https://support.google.com/faqs/answer/9450925)
Since a while we're hit by the "Your app contains unsafe cryptographic encryption patterns." / Unsafe encryption error / "Security and Trust issue" in the Google Play console as well. We ignored that at first as we saw class and method referenced an AES-CMAC implementation.
See:
- "The AES-CMAC Algorithm" https://www.rfc-editor.org/rfc/rfc4493.html from 2006
- NIST publication NIST SP-800 38B https://csrc.nist.gov/pubs/sp/800/38/b/upd1/final
- high-level at https://en.wikipedia.org/wiki/One-key_MAC for the details. We hoped this would be reviewed and fixed - but didn't happen for years.
Obviously the app scanner has been designed without knowledge of the interiors of a Cipher-MAC. The operations in the initializer include the generation of a sub-key. Exactly this involves the encryption of a blocksized (16-byte for AES) ALL-ZEROES byte array.
See section 2.3 and figure 2.2 of RFC 4493:
Constants: const_Zero is 0x00000000000000000000000000000000
const_Rb is 0x00000000000000000000000000000087
Variables: L for output of AES-128 applied to 0^128
Step 1. L := AES-128(K, const_Zero)
Step 2. if MSB(L) is equal to 0
then K1 := L << 1;
else K1 := (L << 1) XOR const_Rb;
Step 3. if MSB(K1) is equal to 0
then K2 := K1 << 1;
else K2 := (K1 << 1) XOR const_Rb;
Step 4. return K1, K2;
No, it is not a remediation to use Jetpack Security or EncryptedSharedPreferences - especially as this functionality is not provided there and it is a complete false alarm. So, the FAQ answer is invalid here.
Yes, this functionality is vital for the app as the infrastructure around requires this in standards as well:
- BSI TR-03110-3 section A.1.1 https://www.bsi.bund.de/dok/TR-03110-en
- BSI TR-03111 section 5.3.1.2 https://www.bsi.bund.de/dok/TR-03111-en
- ANSSI eIDAS https://cyber.gouv.fr/en/publications/electronic-identity-technical-specifications-eidas and more.
My questions: 1) who is responsible for this? 2) when will this be fixed?
Thanks & best regards,
Christian
Edit: added direct URL to the invalid Google FAQ answer for the readers.
Update1: Google Play console support came back to me two times saying they need more time to investigate the reported issue. They also announced a technical engineer will reach out to me to clarify further details. Will keep you informed.
Update2: Someone from NIST over here? I think it would help to explain NIST SP 800-38B section 6.1 "Subkey Generation" to Google, esp. the CIPHK(0b) operation - which is detected by the scanner here.
Prerequisites:
block cipher CIPH with block size b;
key K.
Output:
subkeys K1, K2.
Suggested Notation: SUBK(K).
Steps:
1. Let L = CIPHK(0b).
2. If MSB1(L) = 0, then K1 = L << 1; Else K1 = (L << 1) ⊕ Rb; see Sec. 5.3 for the definition of Rb.
3. If MSB1(K1) = 0, then K2 = K1 << 1; Else K2 = (K1 << 1) ⊕ Rb.
4. Return K1, K2.