Live data from Hacker News

How I implemented my own crypto

loup-vaillant.fr

81–90 of 409 posts

Re: How I implemented my own crypto

#81

It was a fun read, except when all the C bugs were listed. It's getting tiresome to hear about folks writing nominally Important software in a language where it is extraordinarily difficult to get things absolutely correct, with paltry excuses such as "it needs to be fast" or "it needs to be portable [0] to a VAX-11/750." It doesn't give me confidence that these completely usual bugs popped up early on, and it will n…

> The author's lack of practical familiarity with the memory hierarchy, caching, and pipelining

Maybe I didn't express myself clearly. I knew loading stuff word by word would be much faster, thanks to my knowledge of the memory hierarchy, caching, and pipelining.

What I didn't expect was the magnitude of the overall impact. The core round functions are much, much faster that I had anticipated. I didn't think the loading code, even in its slow version, would account for a significant percentage of the total running time.

> It would be great if this was written in another language.

Easier said than done. I aim for easy integration in projects written in basically anything: C, C++, OCaml, Rust, Python… What would you suggest? Rust? That's a possibility, but (i) it's LLVM only at the moment, and (ii) I believe there's an impedance mismatch between Rust and a C compatible ABI.

I would totally recommend to rewrite the whole thing in Rust for Rust projects, though.

Re: How I implemented my own crypto

#82
post #75

I am terrified that I do not consider myself competent enough to write a crypto library, and yet there isn't a single mention - in this article, nor at the time of writing the comments here on Hacker News - of many of the pitfalls I know to avoid when undertaking such an endeavour. There is even a list of "you have to do A, B, C, and that's about it" that is missing some major - well known, even! - items. I know "don…

Could you list the main pitfalls you are thinking about? Also, I may have mentioned some of them in this earlier article: http://loup-vaillant.fr/articles/rolling-your-own-crypto

Re: How I implemented my own crypto

#83
post #41

I still believe it's a bad idea to roll your own crypto, interesting as an exercise, but I would never use it in a production environment.

There is a difference between rolling your own crypto and rolling your own crypto. There is Monocypher, then there is this company that is trying to do some weird protocol using CRC, DES in CBC mode and MD5. The sentence was targeting the latter case.

No, it is targeting both. I see no mention of how monocypher implementation does anything 5o prevent side channel timing attacks, I haven't looked to see if there is any sensitive memory scrubbing. Of the bugs listed most are performance bugs by someone who doesn't know C very well yet have they done the things actually!my required in a crypto library like attempting to make sure all branches are the same instruction length for all implemented algorithms?

Re: How I implemented my own crypto

#84
post #40

Earlier quoted context omitted.

Just because you don't see those ugly macros to make your pure high level language portable, doesn't mean they're not there, somewhere.

Yes but this is a separation of concerns. This is precisely the point of an abstraction, especially at the level of a language and its implementations. Writing code in Common Lisp means you're writing something with semantics promised by the Common Lisp specification. Vendors implement the spec (perhaps using nasty #ifdefs), and developers write code against the spec. The spec is a contract, and from the point of vie…

Unfortunately the architectural details of the machine will leak through to the program you are writing, and you will need to twist your code in order to get correct behaviour and fast execution.

Case in point is the recent article posted on HN about the platform specific details of getTimeMilliseconds() in Java.

Re: How I implemented my own crypto

#85

Earlier quoted context omitted.

Relying on a macro processor to patch and bandage your program at compile time depending on a collection of symbolic features isn't really representative of portability of a language and your code. To me, that is brute forcing portability, and is a web of conditional inclusions/exclusions that needs to be maintained and added to per-architecture and per-OS. Something that is, in some sense, truly portable is one that…

I would argue the other way. Something which requires a base implementation to be installed on a system which generates different machine code based on a single specification is less portable than a macro processor generating different versions of a program. Sure, people will have had something like python installed since a long time ago, but a new setup requires downloading 2 objects (the base implementation and the…

How is the deployment of a high-level runtime different from libc? Both can be statically-linked if required.

Re: How I implemented my own crypto

#87
post #60

Earlier quoted context omitted.

Yeah and imagine the kind of exciting bugs that exist in new and immature libraries! :)

Yes, but are hackers going after common used libraries to get more vulnerable systems to attack or are they going to spend time on some unknown homebuilt crypto? In some cases, security through obscurity works well in practice.

> In some cases, security through obscurity works well in practice.

This is not one of those cases. Absolutely not. I'm moderately competent at finding security bugs in things, but I doubt I could find any in OpenSSL. I am confident I could find some in your average hand-rolled code.

The thing is people make the same mistakes. There's a set of well-known mistakes that are very easy to make, especially if you're not versed with the entire history of implementing crypto - which is the case for the majority of people rolling their own. This makes it very, very easy to guess what mistakes they will make, and if you know what you're looking for it's easy to find it.

My "personal best" for finding a crypto bug in a project is 50 seconds.

I doubt anyone has found a bug in OpenSSL (or any established crypto project) anywhere near that fast.

Re: How I implemented my own crypto

#88
post #31

Earlier quoted context omitted.

Curious about the other language. What other language that doesn't add another layer between the code and system instructions were you thinking about?

Most programming languages with compilers to native code (JIT/AOT), the myth of high level Assembler for C only applies if your computer is a PDP-11 or a basic 8-bit CPU like a 6502 or Z80. The ANSI C and C++ standards define the concept of abstract machine for the language semantics, just like in most languages. Additionally you have the concepts of sequence points, the new memory model semantics for multi-threaded…

You could argue that each processor's errata is UB in assembly. I remember that programming for the XScale we had a whole manual of errata that we had to program around. Though because it's documented it's not "Undefined", it's just "Incorrect but we know how incorrect".

Re: How I implemented my own crypto

#89
post #26

Earlier quoted context omitted.

> Haskell I think writing timing-attack resistant code in Haskell would be very hard to impossible, at least without writing very unidiomatic code (basically "C in Haskell"). I'm happy to be proven wrong, though.

Honest question: What makes you think you can't mitigate? A̶ ̶t̶y̶p̶e̶s̶a̶f̶e̶ ̶c̶r̶y̶p̶t̶o̶ ̶t̶h̶a̶t̶ ̶m̶e̶a̶s̶u̶r̶e̶s̶ ̶i̶t̶s̶ ̶e̶x̶e̶c̶u̶t̶i̶o̶n̶ ̶t̶i̶m̶e̶ ̶a̶p̶p̶e̶n̶d̶e̶d̶ ̶w̶i̶t̶h̶ ̶a̶ ̶f̶i̶n̶a̶l̶ ̶d̶e̶l̶a̶y̶ ̶t̶i̶m̶e̶ ̶r̶e̶a̶d̶ ̶f̶r̶o̶m̶ ̶/̶d̶e̶v̶/̶u̶r̶a̶n̶d̶o̶m̶ ̶c̶a̶n̶ ̶s̶t̶i̶l̶l̶ ̶b̶e̶ ̶i̶d̶i̶o̶m̶a̶t̶i̶c̶.̶ It has to be monadic, that is for sure but abstracting a crypto algorithm as IO is actually treating…

I believe padding the timing always has been considered a bad idea. If you want to guarantee you won't exceed the timing, you probably have to take so much margin that your primitive becomes prohibitively slow. And I'm not even sure it would protect you against cache timing attacks.

Simply put, there are easier and cheaper ways to guarantee timings. Perhaps Haskell is even capable of harnessing them. (I'm thinking of the usual "no secret dependent branches", and "no secret dependent indices".)

Re: How I implemented my own crypto

#90
post #77
post #67

Earlier quoted context omitted.

If you say "foo + 3", and foo is a uint8_t, then 3 is technically an int, so the addition will do an integer promotion. If you say "foo + bar" and both are uint8_t, then both will be promoted to integer. That's how C works. Assigning the result to another uint8_t will truncate it. Please do not write your own crypto library until you really understand how C works, especially including this kind of detail.

I understand the issue, but not the explanation. Your example is different, this is because you're doing an addition. I can see how this could be a problem if you want to do a rotation (a > 60) and hence why you should use a ^ instead of a + here (example: https://github.com/gvanas/KeccakCodePackage/blob/master/SnP/... )

6.5.7.3 of the C99 standard specifies that each operand of a bit shift first undergoes integer promotion.
Post reply on HN