That makes sense. So instead you could just require that your crypto stuff takes an absurd amount of time, say 0.5 seconds / MiB? Then every operation will take that long and no information can be gleaned.
I'm not saying this is a good solution, just trying to understand the problem space.
That works if you're willing to have your system be DoS'd. If every request takes half a second, that just means the attacker needs more systems sending requests in parallel to get the required number of samples quickly. In today's world, you'd probably just scale up a bit to ensure you could still serve requests. If you let your system go down under load, you can severely restrict how much data attackers can get at the cost of being useless to whoever your intended users are.
The attacker would also likely need more patience, but timing attacks are not for those looking for quick wins.
The preferred way to handle this is to make sure your operations are constant-time. This eliminates the timing side channel. This is harder, and often slower, but solves the problem entirely.
So instead you could just require that your crypto stuff takes an absurd amount of time, say 0.5 seconds / MiB?
To add to the other (correct) answer: it’s not a terrible idea, because constant time does not leak. However:
- You need to make sure the time is only a function of input data, otherwise you might leak info about internal code paths.
- If the operation cannot complete in time you may be leaking information, even if you only return a generic error.
These are not massive attack surfaces, but they do exist. As with regular programming, you want to reduce the risk of things that can go wrong by reducing the number of code paths. Only now, the cost of an error is much higher, and can go undetected. But no, other than the various and highly subtle side channels there’s no magic to rolling your own crypto, only a long track record of people who overestimated their abilities (or underestimated their adversaries). Oftentimes it’s due to optimizations in the CPU, memory, disks, language runtimes etc that are the culprits. These subsystems often cache, share, or soft-delete data that the programmer thought was exclusive or lifetime-bounded in a way that it wasn’t.
That’s why I like ECC or AES much more than say RSA or other bigint math heavy things. Bit operations are very predictable, and if they run in a loop of constant iterations even better. All else equal, I’d pick an ECC implementation (and not just because it’s faster and smaller). Almost all vulnerabilities have been implementation or parameter choices, not the foundational math. That said, say OpenSSL RSA has been battletested heavily and for a long time.
Comments
That makes sense. So instead you could just require that your crypto stuff takes an absurd amount of time, say 0.5 seconds / MiB? Then every operation will take that long and no information can be gleaned.
I'm not saying this is a good solution, just trying to understand the problem space.
That works if you're willing to have your system be DoS'd. If every request takes half a second, that just means the attacker needs more systems sending requests in parallel to get the required number of samples quickly. In today's world, you'd probably just scale up a bit to ensure you could still serve requests. If you let your system go down under load, you can severely restrict how much data attackers can get at the cost of being useless to whoever your intended users are.
The attacker would also likely need more patience, but timing attacks are not for those looking for quick wins.
The preferred way to handle this is to make sure your operations are constant-time. This eliminates the timing side channel. This is harder, and often slower, but solves the problem entirely.
To add to the other (correct) answer: it’s not a terrible idea, because constant time does not leak. However:
- You need to make sure the time is only a function of input data, otherwise you might leak info about internal code paths.
- If the operation cannot complete in time you may be leaking information, even if you only return a generic error.
These are not massive attack surfaces, but they do exist. As with regular programming, you want to reduce the risk of things that can go wrong by reducing the number of code paths. Only now, the cost of an error is much higher, and can go undetected. But no, other than the various and highly subtle side channels there’s no magic to rolling your own crypto, only a long track record of people who overestimated their abilities (or underestimated their adversaries). Oftentimes it’s due to optimizations in the CPU, memory, disks, language runtimes etc that are the culprits. These subsystems often cache, share, or soft-delete data that the programmer thought was exclusive or lifetime-bounded in a way that it wasn’t.
That’s why I like ECC or AES much more than say RSA or other bigint math heavy things. Bit operations are very predictable, and if they run in a loop of constant iterations even better. All else equal, I’d pick an ECC implementation (and not just because it’s faster and smaller). Almost all vulnerabilities have been implementation or parameter choices, not the foundational math. That said, say OpenSSL RSA has been battletested heavily and for a long time.