Live data from Hacker News

Don't pass on small block ciphers

00f.net

51–60 of 64 posts

Re: Don't pass on small block ciphers

#51

Earlier quoted context omitted.

I agree? That doesn't affect what I said. You shouldn't make a one-size-fits-all function that scales that small. It should have to be a deliberate choice to switch from normal mode to small mode, and anyone that hasn't looked into it deeper shouldn't even know about the small mode.

I suppose I don't understand your point. On one hand, you can have different algorithms for each of 32, 64, etc with potentially different pitfalls and usage requirements. On the other, you can have one algorithm that implements all of them. I wasn't trying to comment on how that should be exposed in the library (because crypto lib design is a whole 'nother topic), but I'm not opposed to it being explicit. Same as CR…

I'm responding to the idea of "use as many bits as you need" by saying it could be reasonable for small encryption but it should be kept separate from normal encryption and not made into a general statement.

Purely inside the realm of small lengths with deliberate tradeoffs I have no critique on your original statement, but I wanted to make clear that it should stay within that realm or it needs changes.

Re: Don't pass on small block ciphers

#52
post #42
post #39

Earlier quoted context omitted.

Well, yes. But at this point you're just making a new cipher with AES as the round function. And I think it should be at least as safe as the round function? I have not checked lately, but is it actually the recommendation for format-preserving encryption?

I don't know about "the" recommendation, but it's how NIST standardized it (FF1 and FF3, both Feistel networks) and in the NIST rubric these aren't "new ciphers"; they're "block cipher modes". I'll say I'm more comfortable using a straightforward FPE block cipher mode with AES than I am repurposing a weaker lightweight cipher to take advantage of its 32-bit block size.

Thanks! It indeed makes sense.

I used the RC-5 cipher around 2015 to do that ID generation trick (and it's still in place in AWS as I can see), and there was no NIST standard back then. It also was not a really sensitive application, we just wanted to make IDs opaque.

Re: Don't pass on small block ciphers

#53

Nowadays even many small microcontrollers get AES acceleration so I don't see much reason

The ch32v003 implements RISC-V without the M extension, meaning there's not even a MUL/DIV instruction.

Out of all micro controllers I've worked with, only a single one had AES cpu instructions.

Re: Don't pass on small block ciphers

#54
post #49
post #41

Earlier quoted context omitted.

Good points, but might be mitigated by knowing that the first key after boot is for HDD encryption and if storage is limited then keep counter for each key, and always overwrite least frequently observed key.

Could work. How do you know what the least-frequently used key is if you can't store them, though? Would need some heuristics. Maybe it could write the first five keys it sees after power on on every power on, or some other useful heuristic. Like, I do take your point but it does seem quite involved for the chance that it'll get them something useful, and they still need to gain physical access to the intact device,…

I think Linux/LUKS software encryption was a very big challenge and they solved it with multiple approaches

- 2004: Linux LUKS disk encryption [0]

- 2008: ring −3 / intel management engine [1]

- 2010: AES instruction set [2]

- 2009: TPM [3]

[0] https://en.wikipedia.org/wiki/Linux_Unified_Key_Setup

[1] https://en.wikipedia.org/wiki/Intel_Management_Engine

[2] https://en.wikipedia.org/wiki/AES_instruction_set

[3] https://en.wikipedia.org/wiki/Trusted_Platform_Module

Re: Don't pass on small block ciphers

#55
post #6

Slightly unrelated, but aren't these AES-specific custom CPU instructions just a way to easily collect the encryption keys? There is a speedup but is it worth the risks? If I were a nation state actor, I'd just store the encryption keys supplied to the AES CPU instruction somewhere and in case the data needs to be accessed you just read the stored keys. No need to waste time deploying a backdoored CPU firmware and wa…

I don't imagine it would be too difficult to snoop the instruction stream to identify a software implementation of AES and yoink the keys from it, at least if the implementation isn't obfuscated. If your threat model includes an adversarial CPU then you probably need to at least obfuscate your implementation, if not entirely offload the crypto to somewhere you trust.

Yes but it's much easier to tell devs "put your keys here" and then just take that.

Re: Don't pass on small block ciphers

#56
post #55

Earlier quoted context omitted.

I don't imagine it would be too difficult to snoop the instruction stream to identify a software implementation of AES and yoink the keys from it, at least if the implementation isn't obfuscated. If your threat model includes an adversarial CPU then you probably need to at least obfuscate your implementation, if not entirely offload the crypto to somewhere you trust.

Yes but it's much easier to tell devs "put your keys here" and then just take that.

We’re talking about a hidden CPU backdoor that would let you secretly come in and retrieve keys you’ve squirreled away somewhere. I don’t think finding the keys is the hard part.

Re: Don't pass on small block ciphers

#57
post #34

Earlier quoted context omitted.

If you really want to encrypt and decrypt 32-bit numbers without having any nonces available, the fastest way on non-microcontroller CPUs remains using the AES instructions. You can exploit the fact that the core of AES consists of 32-bit invertible mixing functions. In order to extend AES to 128-bit, a byte permutation is used, which mixes the bytes of the 32-bit words. The AES instructions are such, that you can ca…

Are you certain using AES is still faster? Let's say for a 32-bit block size and 64-bit key. From https://en.wikipedia.org/wiki/Speck_(cipher) , that Speck combination would use 22 rounds, and using the instruction timings for Zen 5 from https://instlatx64.github.io/InstLatx64/AuthenticAMD/Authent... , it looks like each round would take at most 3 cycles. (Dependency chain for each round is 3 instructions long, ror+a…

Standard AES-128 has a throughput of around 16 bytes per 8 clock cycles or even less in recent CPUs, because they can do 2 or 4 AES instructions per clock cycle (in the modes of operation that are not limited by latency).

AES-128 can be easily modified to independently encrypting four 32-bit words per execution, instead of one 128-bit block, by cancelling the byte permutation that extends the AES mixing function from 32-bit to 128-bit. this would increase the throughput at least twice, depending on whether PSHUFB is done concurrently or not.

You have given the latencies of the instructions, not their throughput. When you use AES in such a way that you are limited by latency, that is normally wrong. The cryptographic libraries have multi-buffer functions, which compute e.g. 8 AES values, so that they are not limited by latencies.

Regarding the parent article, if you want an unpredictable identifier for a record, you should not do this by encrypting some value with the intent of decrypting it in the future. Instead of this, you should use as identifier an unpredictable random number. Such identifiers can be generated with AES in batches, at maximum throughput, and stored until they are needed for assignment to a record.

If you need in your record some information like time of creation or a monotonically increasing number, which you consider private, such information should be put in distinct fields, that you do not give externally, instead of attempting to encrypt them in a record identifier, which would need to be decrypted to access such information.

Re: Don't pass on small block ciphers

#58
post #36

Earlier quoted context omitted.

Would it, though? Either way you're operating in ECB mode with 2^32 or 2^64 values. Why is one more secure than the other? EDIT: What I mean is you can do cypher = truncate(plain ^ AES(zero_extend(plain))).

>EDIT: What I mean is you can do cypher = truncate(plain ^ AES(zero_extend(plain))). How would you decrypt that though? You truncated 3/4ths of the AES output needed to decrypt it. I thought you were suggesting this: ciphertext = truncate(AES(key) ^ plaintext) And in this case, since AES(key) does not depend on the plaintext, it would just be XOR by a constant.

The first examples in the parent article do not require decryption. They only require unpredictable random numbers that are unique.

If uniqueness is needed for a 32-bit number or a 64-bit number, then in AES-128 the byte permutation can be modified, to reduce the block size accordingly.

For the other examples with record identifiers, I am not sure whether the author meant for them to ever be decrypted. If decryption was intended, I disagree that this is the right solution. If an opaque record identifier is desired, it should be an unpredictable random number, which can be generated at maximum speed with AES. There is no need to ever decrypt such an identifier.

If other private information is needed, like a record counter, it should be put in separate fields, that are not provided to external entities, instead of encrypting it inside the identifier. Encrypting such private information would prevent its use in indexing anyway.

Re: Don't pass on small block ciphers

#59
post #30

Earlier quoted context omitted.

The RC-5 cipher was very nice for its day, but I am certain that it is much slower than AES on any modern CPU, with the exception of microcontrollers, where nonetheless other solutions, e.g. ChaCha20, may be faster. AES also needs only a handful of lines of code for its implementation (using assembly). For such an application, you can even reduce the number of rounds of AES-128, e.g. from 10 to 4. When you want truly…

The problem is that AES needs a 128-bit block. Imagine that you want to obfuscate your order numbers in the database so that customers can't infer the volume of business by checking the order number. You can use UUIDs, but you also want to keep the numbers short so they can be dictated over the phone. You can use random IDs, but then you need to lock them in the database during the object creation otherwise you might…

Standard AES needs an 128-bit block.

However, the AES mixing function is made from a 32-bit mixing function that is extended to blocks whose lengths are multiples of 32-bit by composing it with a byte permutation.

The standard byte permutation extends the block size from 32-bit to 128-bit, but with the current AES instructions of CPUs you can either cancel the byte permutation to get a 32-bit block size or you can replace it with a non-standard byte permutation, to get any block size that is a multiple of 32-bit.

If you cancel the byte permutation, four 32-bit words are encrypted independently, instead of one 128-bit block. This doubles the number of instructions, but this does not necessarily reduce the throughput, as the instructions may be executed concurrently, so the throughput measured in encrypted numbers will increase by a number between 2 and 4, depending on the CPU.

Re: Don't pass on small block ciphers

#60
post #55

Earlier quoted context omitted.

Yes but it's much easier to tell devs "put your keys here" and then just take that.

We’re talking about a hidden CPU backdoor that would let you secretly come in and retrieve keys you’ve squirreled away somewhere. I don’t think finding the keys is the hard part.

Are you serious?

The CPU firmware blobs are encrypted and nobody except Intel can see what is running there. A handful of people on the planet have the tools and skills to analyze the chip for backdoors.

A small section of CPU cache could stay powered even though the OS is shut down, persisting the keys that were passed to the AES CPU instruction. As CPU is directly linked to wifi/bluetooth and USB chipsets, exfiltration could be possible both wirelessly and via special USB payload.

Post reply on HN