New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support ZUC and 128-EEA3 algorithm #6886
base: master
Are you sure you want to change the base?
Conversation
ZUC is a stream cipher standardized originally by Chinese SCA (State Cryptography Administration) in GM/T 0001.1-2012 - GM/T 0001.3-2012. ZUC is also standardized by 3GPP as an encryption and integrity method for using in LTE environment, naming 128-EEA3 and 128-EIA3 respectively. This commit contains the keystream generation logic of ZUC, which is the common part of EEA3 and EIA3. The implementation for those two 'real' algorithms exist in the upcoming commits.
This cipher is based on ZUC...
Test vectors come from 3GPP specification.
Well, I mean 'let EVP test framework compare memory as a given-length bit-stream' |
crypto/evp/e_eea3.c
Outdated
zk->iv[0] = (count >> 24) & 0xFF; | ||
zk->iv[1] = (count >> 16) & 0xFF; | ||
zk->iv[2] = (count >> 8) & 0xFF; | ||
zk->iv[3] = count; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be masked with & 0xFF
as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be masked with
& 0xFF
as well?
zk->iv
is a uint8_t
pointer, so the truncation suffices here, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
zk->iv is a uint8_t pointer, so the truncation suffices here, right?
Yes. But I think Richard's suggestion is also good because that could reduce misunderstandings...
* So we choose to output a final whole byte, even if there are some | ||
* bits at the end of the input. Those trailing bits in the last byte | ||
* should be discarded by caller. | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, you're getting whole bytes as input, so I fail to understand how you would output anything other than whole bytes as well, even if ZUC is a bitwise stream cipher.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to zero out the trailing bits instead of relying on the caller for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's like saying SHA1 is based on bits. Technically true. But in the context of software, it doesn't matter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to zero out the trailing bits instead of relying on the caller for this?
Right. That's an option I considered. But that requires more input parameter - the length of bits the algorithm needs to handle. And I guess that could be passed by something like EVP_ctrl?
So if leaving this to the caller, it will be more simple on our side. That is to say, encrypt/decrypt everything a caller feeds in and the caller knows how many bits in the output should be considered 'valuable', is this a right thought?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So if leaving this to the caller
is this a right thought?
Yes. Put another way, the implementation only supports messages that have length that is a multiple of 8 bits.
This assumption is totally fine in the real world. For example: how would you SHA1 hash a 7-bit message through the EVP interface?
This isn't just trailing bits, it's trailing bytes, and I don't quite understand why you'd have extra trailing zeros in the expected output unless that's exactly what you expect to get. Also, as already mentioned, I fail to see how we can talk about trailing bits when the EVP functions work with bytes. How does the underlying algo know exactly when the bit stream ends? |
crypto/zuc/zuc.c
Outdated
/* s16... */ | ||
s16 = modular_add(v, u); | ||
|
||
/* if s16 == 0, set it to 2 ^ 31 - 1 */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This branch will never be taken. It is a good learning exercise to understand why.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ohh, I didn't consider this, I just followed the steps in the spec...But why the specs described this step?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But why the specs described this step?
Because needing or not needing this branch statement depends on your implementation of "mod p" according to the ZUC specification. Think about what your modular_add
is actually doing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh, I get it. Because the implementation of modular_add
will directly set the addition result to modulus p (2^31 -1) if the 'addition result mod p' equals to zero.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's pretty much it. IMO worth documenting modular_add
with something like "Inputs a
and b
are in the interval MIN to MAX because FOO. The return value is in the range MINC to MAXC because BAR.
u = L1((W1 << 16) | (W2 >> 16)); | ||
v = L2((W2 << 16) | (W1 >> 16)); | ||
/* S-Box... */ | ||
zk->R1 = MAKEU32(S0[u >> 24], S1[(u >> 16) & 0xFF], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You have side-channel vulnerabilities here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you please give more suggestions on this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are several pointers I could give, but let's try this one.
Using (any part of) u
as an index into a memory-resident LUT potentially leaks algorithm state that should remain secret. To me, it looks like a pretty classic cache-timing attack vulnerability.
|
||
typedef struct ZUC_KEY_st { | ||
/* Linear Feedback Shift Register cells */ | ||
uint32_t s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest a circular buffer here. Previous work on optimizing EEA3 and EIA3.
Edit: When I point to the literature, I'm not suggesting to borrow all the EEA3/EIA3 techniques from there. In fact, I'm explicitly suggesting not to do that. But the circular buffer / sliding window is a standard technique for LFSRs / NLFSRs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh, interesting paper, will read.
|
||
if (zk->keystream == NULL) { | ||
zk->keystream_len = zk->L * sizeof(uint32_t); | ||
zk->keystream = OPENSSL_malloc(zk->keystream_len); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
malloc
should never be called in a stream cipher. Try to rethink your design.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For performance considerations?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe. Also just not necessary. Keep a fixed length keystream buffer in the context. When it's all used, fill it up again.
crypto/zuc/zuc.c
Outdated
tmp = mulp2(zk->s15, 15); | ||
s16 = modular_add(s16, tmp); | ||
|
||
/* if s16 == 0, set it to 2 ^ 31 - 1 */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto for this branch.
crypto/zuc/zuc.c
Outdated
}; | ||
|
||
/* | ||
* This is a method to calculate a + b mod (2 ^ 32 -1), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
p=2**31-1 for ZUC.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch...
+1. Also puzzled by this output. |
Actually the standards about EEA3 says the trailing bits should be ignored. But you cannot output any less-than-8 bits in C. So in the standard, it sets all trailing bits to zero and they give the test vectors in this format... For EEA3 and EIA3 (all ZUC based algo), in fact there is another input parameter indicating how many bits should be XOR'ed and the length of the keystream is also relied on this parameter. But I ignored that parameter, I took the 'byte' number, as what EVP gave me. The reason: 1) 'byte' number is always greater than or equal to 'bit' number if the byte number has been turned into bits, so it won't affect the keystream generation... 2) I decided to leave to the caller to decide how many bits to use in the output, EEA3 just simply handles whatever the caller sends in (in whole byte...) Do you guys consider this rational, or should this EEA3 take a bit-length input and just handle that many bits? (and finally set the trailing bits in the last byte of the output, to zero)? I guess I answered your question @levitte @bbbrumley , the output has extra zero because currently the EEA3 cipher doesn't have an bit-length input, so it XOR'ed every bits in all bytes it gets... So in current design, EVP test framework as a caller, should apply an input to indicate the length of bit it concerns, e.g.:
Then EVP test framework just compares the first 193 bits of the output against the Makes sense? |
Not IMO. Throw away tests where the bit length is not a multiple of 8. (Alternatively, peel off bit by bit from the end until it is, then use that as the KAT.) |
But in practice, how many people could feed an input with trailing bits instead of whole chunks of byte to a stream cipher? It seems very uncommon for a cipher to receive a length of bit parameter...(instead of number of byte) |
Even more, "never happens". That's why whoever wrote those KATs you're using didn't think it through very well. Preprocess them, then stick that output in the EVP test framework. |
This will drop 3 out of all 4 test cases in 3GPP's spec...
Err, but that will change the 'test' described in that standards, if there is not challenge about this, I think it's okay. |
I prefer this ;-) |
Hmmm, one thought just came across my mind: since EEA3 and EIA3 are used in LTE, does that mean there is possibility that mobile hardwares send 'bit' instead of 'byte' on the mobile low level network? (And that is why this cipher is designed to this style...I don't know anything about mobile network, just guess...) |
From my personal experience, that possibility does not exist. (At least in practice.) When I see these bit considerations in cryptographic primitives, it's normally because "they can". Specs would be so much simpler if authors would stick to "they should". |
Should be 4 of 5 tests... |
Ahh, interesting... |
No need to test the ciphers in bit...
Would you mind posting a link to the test vectors? For our purposes, I agree that you should either throw away the vectors that aren't multiple of 8 bits in length, or massage them to 8 bit boundary (I assume that's what @bbbrumley had in mind). |
This link: https://www.gsma.com/aboutus/wp-content/uploads/2014/12/eea3eia3testdatav11.pdf in "Section 4 - CONFIDENTIALITY ALGORITHM 128-EEA3" |
Actually I have already 'massaged' them into 8-bit boundary (for the Ciphertext listed in above link) in the new commit... |
* count is 32 bits, bearer is 5 bits and direction is 1 | ||
* bit so we read the first 38 bits of iv. And the whole | ||
* iv is set to 5 bytes (40 bits). | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems very adhoc. Can you point to a standard that defines this "packed" IV format?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is ad-hoc... the first part of the comment suggests that at least.
Another way would be to invent a few controls for ZUC with which one could give the individual parameters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you point to a standard that defines this "packed" IV format?
Hi @bbbrumley , actually there is no such standard yet. The standard of EEA3 defines that the 3 parameters are used to form the final IV. So I think this is a way of passing those parameters by using EVP in OpenSSL (at least those 3 parameters have relations with the final IV).
Another way is as what @levitte said, it's also possible to pass those 3 parameters by other method, as EVP_ctrl I think...
I don't know which one is better, but it seems current method could avoid changes to other part of OpenSSL, say the openssl enc
command...
Plaintext = 38f07f4be2d8ff5805f5132229bde93bbbdcaf382bf1ee972fbf9977bada8945847a2a6c9ad34a667554e04d1f7fa2c33241bd8f01ba220d3ca4ec41e074595f54ae2b454fd971432043601965cca85c2417ed6cbec3bada84fc8a579aea7837b0271177242a64dc0a9de71a8edee86ca3d47d033d6bf539804eca86c584a9052de46ad3fced65543bd90207372b27afb79234f5ff43ea870820e2c2b78a8aae61cce52a0515e348d196664a3456b182a07c406e4a20791271cfeda165d535ec5ea2d4df40000000 | ||
Ciphertext = 8383b0229fcc0b9d2295ec41c977e9c2bb72e220378141f9c8318f3a270dfbcdee6411c2b3044f176dc6e00f8960f97afacd131ad6a3b49b16b7babcf2a509ebb16a75dcab14ff275dbeeea1a2b155f9d52c26452d0187c310a4ee55beaa78ab4024615ba9f5d5adc7728f73560671f013e5e550085d3291df7d5fecedded559641b6c2f585233bc71e9602bd2305855bbd25ffa7f17ecbc042daae38c1f57ad8e8ebd37346f71befdbb7432e0e0bb2cfc09bcd96570cb0c0c39df5e29294e82703a637f80000000 | ||
Plaintext = 38f07f4be2d8ff5805f5132229bde93bbbdcaf382bf1ee972fbf9977bada8945847a2a6c9ad34a667554e04d1f7fa2c33241bd8f01ba220d3ca4ec41e074595f54ae2b454fd971432043601965cca85c2417ed6cbec3bada84fc8a579aea7837b0271177242a64dc0a9de71a8edee86ca3d47d033d6bf539804eca86c584a9052de46ad3fced65543bd90207372b27afb79234f5ff43ea870820e2c2b78a8aae61cce52a0515e348d196664a3456b182a07c406e4a20791271cfeda165d535ec5ea2d4df40 | ||
Ciphertext = 8383b0229fcc0b9d2295ec41c977e9c2bb72e220378141f9c8318f3a270dfbcdee6411c2b3044f176dc6e00f8960f97afacd131ad6a3b49b16b7babcf2a509ebb16a75dcab14ff275dbeeea1a2b155f9d52c26452d0187c310a4ee55beaa78ab4024615ba9f5d5adc7728f73560671f013e5e550085d3291df7d5fecedded559641b6c2f585233bc71e9602bd2305855bbd25ffa7f17ecbc042daae38c1f57ad8e8ebd37346f71befdbb7432e0e0bb2cfc09bcd96570cb0c0c39df5e29294e82703a637f84 | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test is now longer (1576 bits) than the original (1570 bits). Suggest peeling off the last byte.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmmm, I haven't quite followed... did you decide to shave off bits that are past the byte boundary? Meaning that the shaved test will be 1568 bits?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Meaning that the shaved test will be 1568 bits?
Yes, IMO that is the reasonable solution. (Otherwise, what goes into the test is some extra bits that we essentially have no paper trail for.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, that seems sensible. Just wanted to have it confirmed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, I agree with this. I will shorten this along with other cases...
Plaintext = e539f3b8973240da03f2b8aa05ee0a00dbafc0e182055dfe3d7383d92cef40e92928605d52d05f4f9018a1f189ae3997ce19155fb1221db8bb0951a853ad852ce16cff07382c93a157de00ddb125c7539fd85045e4ee07e0c43f9e9d6f414fc4d1c62917813f74c00fc83f3e2ed7c45ba5835264b43e0b20afda6b3053bfb6423b7fce25479ff5f139dd9b5b995558e2a56be18dd581cd017c735e6f0d0d97c4ddc1d1da70c6db4a12cc92778e2fbbd6f3ba52af91c9c6b64e8da4f7a2c266d02d001753df08960393c5d56888bf49eb5c16d9a80427a416bcb597df5bfe6f13890a07ee1340e6476b0d9aa8f822ab0fd1ab0d204f40b7ce6f2e136eb67485e507804d504588ad37ffd816568b2dc40311dfb654cdead47e2385c3436203dd836f9c64d97462ad5dfa63b5cfe08acb9532866f5ca787566fca93e6b1693ee15cf6f7a2d689d9741798dc1c238e1be650733b18fb34ff880e16bbd21b47ac0000 | ||
Ciphertext = 4bbfa91ba25d47db9a9f190d962a19ab323926b351fbd39e351e05da8b8925e30b1cce0d1221101095815cc7cb6319509ec0d67940491987e13f0affac332aa6aa64626d3e9a1917519e0b97b655c6a165e44ca9feac0790d2a321ad3d86b79c5138739fa38d887ec7def449ce8abdd3e7f8dc4ca9e7b73314ad310f9025e61946b3a56dc649ec0da0d63943dff592cf962a7efb2c8524e35a2a6e7879d62604ef268695fa4003027e22e6083077522064bd4a5b906b5f531274f235ed506cff0154c754928a0ce5476f2cb1020a1222d32c1455ecaef1e368fb344d1735bfbedeb71d0a33a2a54b1da5a294e679144ddf11eb1a3de8cf0cc061917974f35c1d9ca0ac81807f8fcce6199a6c7712da865021b04ce0439516f1a526ccda9fd9abbd53c3a684f9ae1e7ee6b11da138ea826c5516b5aadf1abbe36fa7fff92e3a1176064e8d95f2e4882b5500b93228b2194a475c1a27f63f9ffd264989a1bc0000 | ||
Plaintext = e539f3b8973240da03f2b8aa05ee0a00dbafc0e182055dfe3d7383d92cef40e92928605d52d05f4f9018a1f189ae3997ce19155fb1221db8bb0951a853ad852ce16cff07382c93a157de00ddb125c7539fd85045e4ee07e0c43f9e9d6f414fc4d1c62917813f74c00fc83f3e2ed7c45ba5835264b43e0b20afda6b3053bfb6423b7fce25479ff5f139dd9b5b995558e2a56be18dd581cd017c735e6f0d0d97c4ddc1d1da70c6db4a12cc92778e2fbbd6f3ba52af91c9c6b64e8da4f7a2c266d02d001753df08960393c5d56888bf49eb5c16d9a80427a416bcb597df5bfe6f13890a07ee1340e6476b0d9aa8f822ab0fd1ab0d204f40b7ce6f2e136eb67485e507804d504588ad37ffd816568b2dc40311dfb654cdead47e2385c3436203dd836f9c64d97462ad5dfa63b5cfe08acb9532866f5ca787566fca93e6b1693ee15cf6f7a2d689d9741798dc1c238e1be650733b18fb34ff880e16bbd21b47ac | ||
Ciphertext = 4bbfa91ba25d47db9a9f190d962a19ab323926b351fbd39e351e05da8b8925e30b1cce0d1221101095815cc7cb6319509ec0d67940491987e13f0affac332aa6aa64626d3e9a1917519e0b97b655c6a165e44ca9feac0790d2a321ad3d86b79c5138739fa38d887ec7def449ce8abdd3e7f8dc4ca9e7b73314ad310f9025e61946b3a56dc649ec0da0d63943dff592cf962a7efb2c8524e35a2a6e7879d62604ef268695fa4003027e22e6083077522064bd4a5b906b5f531274f235ed506cff0154c754928a0ce5476f2cb1020a1222d32c1455ecaef1e368fb344d1735bfbedeb71d0a33a2a54b1da5a294e679144ddf11eb1a3de8cf0cc061917974f35c1d9ca0ac81807f8fcce6199a6c7712da865021b04ce0439516f1a526ccda9fd9abbd53c3a684f9ae1e7ee6b11da138ea826c5516b5aadf1abbe36fa7fff92e3a1176064e8d95f2e4882b5500b93228b2194a475c1a27f63f9ffd264989a1bd | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test is also now longer (2800 bits) than the original (2798 bits).
Plaintext = 8d74e20d54894e06d3cb13cb3933065e8674be62adb1c72b3a646965ab63cb7b7854dfdc27e84929f49c64b872a490b13f957b64827e71f41fbd4269a42c97f824537027f86e9f4ad82d1df451690fdd98b6d03f3a0ebe3a312d6b840ba5a1820b2a2c9709c090d245ed267cf845ae41fa975d3333ac3009fd40eba9eb5b885714b768b697138baf21380eca49f644d48689e4215760b906739f0d2b3f091133ca15d981cbe401baf72d05ace05cccb2d297f4ef6a5f58d91246cfa77215b892ab441d5278452795ccb7f5d79057a1c4f77f80d46db2033cb79bedf8e60551ce10c667f62a97abafabbcd6772018df96a282ea737ce2cb331211f60d5354ce78f9918d9c206ca042c9b62387dd709604a50af16d8d35a8906be484cf2e74a9289940364353249b27b4c9ae29eddfc7da6418791a4e7baa0660fa64511f2d685cc3a5ff70e0d2b74292e3b8a0cd6b04b1c790b8ead2703708540dea2fc09c3da770f65449e84d817a4f551055e19ab85018a0028b71a144d96791e9a3577933504eee0060340c69d274e1bf9d805dcbcc1a6faa976800b6ff2b671dc463652fa8a33ee50974c1c21be01eabb2167430269d72ee511c9dde30797c9a25d86ce74f5b961be5fdfb6807814039e7137636bd1d7fa9e09efd2007505906a5ac45dfdeed7757bbee745749c29633350bee0ea6f409df4580160000 | ||
Ciphertext = 94eaa4aa30a57137ddf09b97b25618a20a13e2f10fa5bf8161a879cc2ae797a6b4cf2d9df31debb9905ccfec97de605d21c61ab8531b7f3c9da5f03931f8a0642de48211f5f52ffea10f392a047669985da454a28f080961a6c2b62daa17f33cd60a4971f48d2d909394a55f48117ace43d708e6b77d3dc46d8bc017d4d1abb77b7428c042b06f2f99d8d07c9879d99600127a31985f1099bbd7d6c1519ede8f5eeb4a610b349ac01ea2350691756bd105c974a53eddb35d1d4100b012e522ab41f4c5f2fde76b59cb8b96d885cfe4080d1328a0d636cc0edc05800b76acca8fef672084d1f52a8bbd8e0993320992c7ffbae17c408441e0ee883fc8a8b05e22f5ff7f8d1b48c74c468c467a028f09fd7ce91109a570a2d5c4d5f4fa18c5dd3e4562afe24ef771901f59af645898acef088abae07e92d52eb2de55045bb1b7c4164ef2d7a6cac15eeb926d7ea2f08b66e1f759f3aee44614725aa3c7482b30844c143ff85b53f1e583c501257dddd096b81268daa303f17234c2333541f0bb8e190648c5807c866d7193228609adb948686f7de294a802cc38f7fe5208f5ea3196d0167b9bdd02f0d2a5221ca508f893af5c4b4bb9f4f520fd84289b3dbe7e61497a7e2a584037ea637b6981127174af57b471df4b2768fd79c1540fb3edf2ea22cb69bec0cf8d933d9c6fdd645e850591cca3d62c0cc000 | ||
Plaintext = 8d74e20d54894e06d3cb13cb3933065e8674be62adb1c72b3a646965ab63cb7b7854dfdc27e84929f49c64b872a490b13f957b64827e71f41fbd4269a42c97f824537027f86e9f4ad82d1df451690fdd98b6d03f3a0ebe3a312d6b840ba5a1820b2a2c9709c090d245ed267cf845ae41fa975d3333ac3009fd40eba9eb5b885714b768b697138baf21380eca49f644d48689e4215760b906739f0d2b3f091133ca15d981cbe401baf72d05ace05cccb2d297f4ef6a5f58d91246cfa77215b892ab441d5278452795ccb7f5d79057a1c4f77f80d46db2033cb79bedf8e60551ce10c667f62a97abafabbcd6772018df96a282ea737ce2cb331211f60d5354ce78f9918d9c206ca042c9b62387dd709604a50af16d8d35a8906be484cf2e74a9289940364353249b27b4c9ae29eddfc7da6418791a4e7baa0660fa64511f2d685cc3a5ff70e0d2b74292e3b8a0cd6b04b1c790b8ead2703708540dea2fc09c3da770f65449e84d817a4f551055e19ab85018a0028b71a144d96791e9a3577933504eee0060340c69d274e1bf9d805dcbcc1a6faa976800b6ff2b671dc463652fa8a33ee50974c1c21be01eabb2167430269d72ee511c9dde30797c9a25d86ce74f5b961be5fdfb6807814039e7137636bd1d7fa9e09efd2007505906a5ac45dfdeed7757bbee745749c29633350bee0ea6f409df45801600 | ||
Ciphertext = 94eaa4aa30a57137ddf09b97b25618a20a13e2f10fa5bf8161a879cc2ae797a6b4cf2d9df31debb9905ccfec97de605d21c61ab8531b7f3c9da5f03931f8a0642de48211f5f52ffea10f392a047669985da454a28f080961a6c2b62daa17f33cd60a4971f48d2d909394a55f48117ace43d708e6b77d3dc46d8bc017d4d1abb77b7428c042b06f2f99d8d07c9879d99600127a31985f1099bbd7d6c1519ede8f5eeb4a610b349ac01ea2350691756bd105c974a53eddb35d1d4100b012e522ab41f4c5f2fde76b59cb8b96d885cfe4080d1328a0d636cc0edc05800b76acca8fef672084d1f52a8bbd8e0993320992c7ffbae17c408441e0ee883fc8a8b05e22f5ff7f8d1b48c74c468c467a028f09fd7ce91109a570a2d5c4d5f4fa18c5dd3e4562afe24ef771901f59af645898acef088abae07e92d52eb2de55045bb1b7c4164ef2d7a6cac15eeb926d7ea2f08b66e1f759f3aee44614725aa3c7482b30844c143ff85b53f1e583c501257dddd096b81268daa303f17234c2333541f0bb8e190648c5807c866d7193228609adb948686f7de294a802cc38f7fe5208f5ea3196d0167b9bdd02f0d2a5221ca508f893af5c4b4bb9f4f520fd84289b3dbe7e61497a7e2a584037ea637b6981127174af57b471df4b2768fd79c1540fb3edf2ea22cb69bec0cf8d933d9c6fdd645e850591cca3d62c0cdd |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto for this one. (4019 original vs 4024 here.)
@@ -385,6 +385,11 @@ sm-scheme 301 : SM2 : sm2 | |||
sm-scheme 401 : SM3 : sm3 | |||
sm-scheme 504 : RSA-SM3 : sm3WithRSAEncryption | |||
|
|||
# ZUC stream cipher | |||
sm-scheme 201 : ZUC : zuc |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@InfoHunter Is there such a thing as ZUC as an actual stream cipher, and not just a keystream generator? (Standards wise.)
I googled around, but not much in English.
I'm asking because in that case, you could make an argument for it's own EVP interface. Exposing only EEA3 to EVP seems curious to me, since the use case is so restricted and so different from a "normal" stream cipher. (Even more weird if you have planned efforts for EIA3, since the maximum message length is slightly below 64KB due to mobile network details.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi there, this is a good question and what you concerned is exactly the thing what which I also care about...
Unfortunately, there is no standard defined yet describing a stream cipher other than EEA3. Even in Chinese national standards, ZUC is also only used as a keystream generator. This is the current status.
Fortunately, we (some Chinese companies) are putting lots of effort to make an actual ZUC stream cipher, which could be used in a TLS context (for instance the IV is not formed by those very specific parameters). But we are not the agency in control of this kind of things, so we need to coordinate with the 'real' agency (the Chinese SCA) to push this forward.
I hope this could happen in a not very far future...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What I also think about is those ZUC_*
functions. Should they be exported either, for ZUC to be used as a keystream generator?
A new commit is pushed to shorten the test data...(kills the last byte which contains the incomplete bits...." |
I think it's proper to put an 'after 1.1.1' label on this... |
ZUC is a keystream generation algorithm standardized by Chinese SCA as GM/T 0001.1-2012. ZUC is also standardized by 3GPP: 3GPP-ZUC
128-EEA3 is standardized by 3GPP in its "TS 35.221" specification (128-EEA3) as a stream cipher for using in 3G and LTE.
128-EEA3 is also known as "The ZUC-based confidentiality algorithm", which is standardized by SCA as GM/T 0001.2-2012.
The name ZUC is the abbreviation of an ancient Chinese mathematician "Zu Chongzhi", so this algorithm is also called "Zu Chongzhi Algorithm" in China.
There is also an integrity algorithm based on ZUC, which is standardized by 3GPP as 128-EIA3. That one is not included in this PR, but will be implemented soon...
Known issue: the test vectors for ZUC stream cipher/128-EEA are based on 'bit' instead of 'byte', but the EVP cipher test framework can only handle the comparison of bytes, which lead to failures when comparing the trailing bits at the end of the testing data. For instance, you can find details as follows:
Does this mean the EVP cipher test framework should be improved to compare memory by 'bit'?
Checklist