In my school every lecture in our cryptography course started with the sentence "Never roll your own crypto, use verified libraries and then also be careful"
That's dumb. It gives the impression the cryptographic library developers are grown in the lab or something.
Guess what, cryptographic library developers go the same schools as the rest of us. That's there's some sort of development that's somehow out of reach for "regular" devs is elitist and counterproductive.
It means there's a generation of graduates that don't do systems programming or anything where security is important.
Schools are dodging the important societal responsibility of teaching students how one designs and implements software that really, really needs to be correct.
The main ones certainly are nowadays. With some regularity, our customers ask us to verify some of the software or dependencies they're using, and this sometimes includes cryptographic libraries. We would then check the parts which the customer actually uses, so not all of openssl for example, but in general yes this is being looked at. These fixes are always upstreamed, by the way, although it's up to the customer whether they want to handle it themselves or whether we do the responsible disclosure process.
What tools do you use for verification? We don’t have many verified compilers yet so even if you verify the code how do you verify it’s compiled correctly?
For all I know I've got 5G implanted, how am I to verify that? Obviously the implant will make whatever measurements I do return the wrong results.
Gotta trust something, we decided we mainly trust the OS download and the repository keys that came with it.
Anyway we seem to have been talking about different kinds of verification, like checking that what Joan Daemen and Vincent Rijmen wrote is really what your CPU is executing versus verifying that implementations of a trusted algorithm aren't broken. We're not in the conspiracy theory or incident response business, so unless someone comes with something that sounds like we should forward them to incident response, the former is not what we do.
Formal verification is a thing people do - and I think that’s what most people think from ‘verified’. They aren’t conspiracy theorists they’re proving things like that your C implementation code is defined and matches what you think you’ve written, since that’s where these errors creep in.
Of course at some point some people will have to implement crypto.
But I think a good way to think about it is this: This shouldn't be on top of your list when you learn crypto. Before you even think about rolling your own crypto you should break other people's crypto. That'll help you to gain deeper insights in how the whole thing works.
(Disclaimer: I broke other people's crypto, I wrote papers about it. I still never tried to roll my own crypto.)
At peak, and in multiple independent courses, the teacher would step through a well-made AES key schedule visualization while none of us are (even planning on) doing the heavy math studies necessary to design a successor to or find vulnerabilities in something like AES. Most of us would be software engineers, sysadmins, or perhaps a handful of us might go into security fields like forensics or pentesting. The internals of AES are completely irrelevant. A curiosity maybe, but not something to be quizzed on. Then I went to do my master's and the teacher started about caesar ciphers...
All formal cryptography-for-non-cryptographers education I've ever had was completely useless (I was in tertiary education in the Netherlands between 2010 and 2018, in case anyone is wondering how dated this is).
The concept of authenticated encryption was mentioned in passing I think, though in one course I had to prompt the teacher to mention that as what you would want to be doing, but got far less attention or practice than doing things like a Caesar cipher or AES key schedule by hand.
Merely knowing that you have to look for the keyword authenticated encryption (when you want to do encryption for some reason) would already be enough in my opinion, from there you can find good answers. Or for secure connections, keyword searches should include something about key distribution/verification and, if you want to use something configurable like TLS, also configuration choices like enforcing allowed protocol versions. Which versions those are, that changes over time and there is little point memorizing it. You should just know that you should look into this when you need it.
Monocypher[0], unironically. Though it's not header-only (it's a single C file and a separate header), but it's easy enough to merge the two. It even beats your licensing requirements (CC-0 or BSD 2-clause dual-license).
IMO it's really unfortunate that Monocypher doesn't implement a high-level CSPRNG API. I appreciate that it goes against the design goal of being entirely dependency-free, but getting random number generation wrong is such an easy foot-gun in my view, and it's already my least favourite part of libsodium (its most obvious "competitor") that the AEAD constructs don't generate a random nonce for you.
Edit: Also, not sure why the author chose to use Argon2i over Argon2id as the PBKDF for Monocypher, my perception was that the id variant should be used unless you have a reason not to. Would be interested to hear other opinions on this.
The distinction between cryptographic issues and coding-level issues seems valuable.
I think "You Shouldn't Roll Your Own Crypto" is really three separate pieces of advice, each of which deserves justifying independently.
Roughly:
- You shouldn't try to invent your own cryptographic primitives.
- You shouldn't try to design your own equivalent to (say) SSL.
- You shouldn't try to implement something like SSL, or parse ASN.1, yourself.
I don't think many people are likely to fall foul of the first.
It seems to me the second is where the real devils lurk: dealing with padding and cipher modes and all that kind of stuff.
But it's not at all clear to me that the third has been historically justified.
I think if someone in the early 2000s had thought "I don't like the look of OpenSSL and I don't think C is a good choice of language. I'm going to write my own implementation of the parts I need in (say) Ada" they might well not have regretted that choice.
Given the many historic openssl bugs related to certificate parsing (ie x509 and asn1) I’m not sure you should even trust expert crypto programmers to deal with that
Some folks are trying to kill ASN.1. It is probably an awkward moment for that, when people are looking at binary encodings more because JSON is boring and doesn't stand out on a CV. It's got all the hallmarks of old tech that looks like it's survived on its merits, but it really isn't like that.
The difference between ASN.1 (BER/DER) and modern binary encodings is that people have tried to parse the former by hand but not the latter (at least to my experience). BER/DER itself is a fine encoding---sure, it has a legacy including six string types but we can deal with them---and in principle a simple library with bound checks should have been more than enough.
ASN.1 is however structured in a way that such a simple library looks like incomplete; it looks like that a correct way to parse BER/DER is an ASN.1 compiler, which tends to be bulky and annoying to integrate. As a result for a long time most ASN.1 implementations were either a "complete" ASN.1 compiler or a hand-crafted parser, with no middle ground of a library that is simple enough and prevents you from memory unsafety.
> Some folks are trying to kill ASN.1. It is probably an awkward moment for that, when people are looking at binary encodings more because JSON is boring and doesn't stand out on a CV. It's got all the hallmarks of old tech that looks like it's survived on its merits, but it really isn't like that.
I think it's rather more than this. ASN.1 is deeply embedded in daily life: 3G/4G/LTE/5G, V2X, and many other protocols are specified in ASN.1. The inertia has as much to do with backwards compatibility as anything else. If you need to read call data records, you have to parse BER; if you want to deal with vehicle to vehicle communications you have to parse OER. 3G protocols are generally PER. Crypto is DER.
Are there alternatives that are better in some respects? Sure. Are they likely to supplant existing telecommunications standards? No. Should move away from ASN.1 for crypto purposes? Probably, though I'm not experienced enough to have a strong opinion. I'd be interested to see whether we could install a new standard in a suitable time frame, and indeed what form that would take. (In the two links you cited, I didn't see anything, but I'm actually really interested!)
I think ASN.1 is probably here to stay for a long time, and not merely as a resume polishing agent.
> because JSON is boring and doesn't stand out on a CV.
It's a little bit more than that: cryptographic container formats usually need to be stable on traversal/canonicalized so that things like hashes remain consistent.
JSON alone doesn't have a canonicalized format (there are various suggested canonical forms), and leaves details about key iteration, duplication, etc. ambiguous in ways that are potential sources of vulnerability (what happens if a particular protocol allows users to introduce untrusted attributes to a JSON object and doesn't check for name clashes?).
Edit: not to mention integer width/representation of large integers! That's a big one for cryptographic protocols.
> It's a little bit more than that: cryptographic container formats usually need to be stable on traversal/canonicalized so that things like hashes remain consistent.
Yeah, this, too: there's got to be a single way of representing the same message. (BER, in contrast to DER, has multiple means of writing the same message. BOOLEAN types, for example, indicate FALSE by 0x00, but TRUE is any non-zero value. I forget how DER resolves this. DER disallows the use of indefinite lengths, while BER admits both definite and indefinite lengths. Etc., etc.)
I'm sympathetic to the challenges people face with ASN.1, having worked with it rather extensively in my career. I don't recommend it to people who have serialization challenges usually because something like protobuf or flatbuffers seems like a more reasonable choice in this day and age...but at the same time ASN.1 has a history of mistakes and innovations for solving some challenging problems in representation and encoding that should inform decision-making moving forward.
Often you don't have a choice but to write your own parsers for serialization formats, as inter-language & inter-tool interoperability is still not very good, except maybe for TLS-related stuff. There's e.g. no predefined way to verify an ECDSA signature created in JS using Golang (or vice versa), so you have to parse the R & S values by hand. Luckily they are just concatenated big-endian numbers.
That's exactly what I referred to: The function takes two BigInt's, which you have to unpack yourself from the byte-serialization created by JS. There's no JS-compatible ECDH key derivation function in Golang either, so you have to implement the multiplication yourself (which again isn't difficult).
My impression is that crypto people, being mildly allergic to asn.1, decided not to use it to specify standard serialization formats in our new world of EC crypto. So here we are without asn.1 and without a replacement. I generally think if you’re going to remove something because you think it sucks it’s on you to replace it with an equivalent or clearly justify why it was vestigial if you don't have one.
In this case you really don't need a DER calibre encoding either, you just need a standard in the first place. It’s just that the standard would historically likely use asn.1. But that doesn't have to be the case. Maybe the closest thing is the ECDSA point form specified in https://www.secg.org/sec1-v2.pdf#page16. The the curve domain parameters in sec2 are, you guessed it, specified in asn.1.
> - You shouldn't try to invent your own cryptographic primitives.
> - You shouldn't try to design your own equivalent to (say) SSL.
> - You shouldn't try to implement something like SSL, or parse ASN.1, yourself.
Why not? You should do all those things, how else can one get a deeper insight into how things work. It's just that you probably don't want to use that in production environment unless you really know what you're doing.
You make a good point, but I feel it's getting downvoted thanks to the implied tone.
> [...] get a deeper insight into how things work. It's just that you probably don't want to use that in production [...]
That is the gist of it. If you are really into applied cryptography, then rolling your own crypto - and I can't stress this enough - for PURELY ACADEMIC purposes is fine. As long as you are honest with yourself, writing some applied crypto code is a good way to learn some of the horrible ways things can go wrong. Know deep in your heart that no matter how well you thought you did, the code you wrote is broken. Badly.
The "oh... oh shit..." realisation when looking back at the code will be enlightening.
Just please, for the love of all that is good, do not publish the code you wrote. Otherwise, thanks to the law of large numbers, someone, somewhere will grab your code, embed it in their production systems and the next thing you know, a toy library you wrote is now responsible for yet another IoT disaster.
Or, here me out, roll your own crypto, and put it on a webservers that GPT-2 generated messages back and forth. That should give an intern at the NSA/KGB a really annoying summer.
> - You shouldn't try to implement something like SSL, or parse ASN.1, yourself.
What would you recommend for compiling and decoding/encoding ASN.1 using Java? I tried OSS NOKALVA's ASN.1 for Java but constraint checking is non-existent or very limited. I am forced to implement it myself as it does not exist from what I gathered. If you know one that does constraint checking, that would be amazing.
> I think if someone in the early 2000s had thought "I don't like the look of OpenSSL and I don't think C is a good choice of language. I'm going to write my own implementation of the parts I need in (say) Ada"
> I tried OSS NOKALVA's ASN.1 for Java but constraint checking is non-existent or very limited.
A quick look at their documentation suggests the use of the -constraints option.[1] Constraints are such a basic part of the ASN.1 specifications I can't imagine any vendor not implementing it. I know for a fact that Objective Systems' compiler does.[2]
Thank you, I think I missed `-constraints`, then! I will give it a go and check out the generated file. I expected it to be turned on automatically. My bad! That said, I will check if it does the constraint checking properly. I hope it does!
I know, Erlang's ASN.1 compiler does it too, automatically. It is pretty awesome.
---
Update: `-constraints` does work (`validConstraint = temp1 >= 10 && temp1 <= 20`)
If someone in the 2000s had thought "I don't like C and I don't like OpenSSL so I'm going to write my own Ada SSL/TLS", we would have yet another implementation of Bleichenbacher's RSA error oracle. It is not actually that easy to put a safe TLS implementation together; you need to study the TLS protocol and implementation vulnerabilities, and they're not all assembled in one nice place.
Non-rhetorical question: do you think that would have been likely to cause the hypothetical implementor more or less pain, over the next decade or so, than OpenSSL's buffer overflows?
It depends on the window of time you choose, but if the window is "in the last 10 years", then I'd say cryptographic mistakes are likely to cause more pain than OpenSSL memory corruption vulnerabilities. Any other C library, with less scrutiny, and it'd be the other way around.
I think we need to reconsider the definition of a "vetted library". It's only because I spend a lot of time in this space I'm aware of at least three different libraries that default to unauthenticated CBC mode, and choose key sizes magically based on input (hint: it never ends up what people expect).
But those libraries show up recommended on forums and subreddits everywhere. And if you inherit such a system and try to do something like "add an HMAC", you'll be cursed at for "rolling your own crypto" when you should apparently be trusting the library.
> We further compare our findings with non-cryptographic systems, observing that these systems are, indeed, more complex than similar counterparts, and that this excess complexity appears to produce significantly more vulnerabilities in cryptographic libraries than in non-cryptographic software.
This, to me at least, seems like a strange conclusion for this paper to reach. While there are evidently more vulnerabilities reported in NVD/CVE for cryptographic libraries, does this necessarily correlate with a larger number of vulnerabilities being present? Or could it be that cryptographic code is much more heavily scrutinised, and so it’s more likely that vulns will be found? I think the former is probably more reasonable, but I’m not sure you can come to either conclusion based on CVE data alone. Or am I missing something?
Many seems to agree with the "You Shouldn't Roll Your Own Crypto", but I interpret it differently.
If you are interested you definitely should. Implement existing ciphers, learn, compare, create your own ciphers, test, crack, research and discuss. It's the perfect way to learn more and become better at it.
However, don't put it in production or with real data.
You are correct, but to someone new, the phrase sounds like an absolute and probably discourages them from ever trying. A great blog post about this phenomenon is https://soatok.blog/2021/03/04/no-gates-no-keepers/ .
For my part, I've met people who have told me to not even try because I need to get a PhD before I even implement crypto. Not design crypto; implement crypto.
So while you are correct that it is the mainstream interpretation, that's not how it looks from the outside.
The paper says "all three of OpenSSL, LibreSSL, and BoringSSL have been gradually increasing in size since the 2014 fork, to the point where LibreSSL is now roughly the same size as OpenSSL was at Heartbleed's discovery." The authors then count CVEs. This won't yield a valid conclusion about vulnerabilities in the new code that's been added to Libre/Boring in 2014-2021. The OpenSSL project requires use of CVE numbers, but Libre/Boring don't. Nothing at https://www.libressl.org or https://boringssl.googlesource.com/boringssl talks about obtaining or listing CVEs (contrast to https://www.openssl.org/news/vulnerabilities.htmlhttps://www.openssl.org/policies/secpolicy.html etc,). OpenSSL Management Committee has a person on CVE's board https://www.openssl.org/community/omc.htmlhttps://cve.mitre.org/community/board (same Mark Cox). The authors say "the most widely used cryptographic library, OpenSSL" but don't say this means more users to report bugs/vulnerabilities to that project.
They say "Our case study of the LibreSSL and BoringSSL forks further demonstrates a linear correspondence between source code removal and vulnerability removal." Possibly a useful finding! But we still don't know what happens when you remove a ton of someone else's code, but then add a ton of your own unique code. To research that, they'd need competing projects that similarly care about vulnerability IDs (CVEs or other IDs), and have similar populations of potential bug reporters and/or similar opportunities for bug bounties.
I wonder why no "mbedTLS" or LibTomCrypt? The formeris very popular in IoT devices, which is where a lot of hacking is happening. I'm guessing no stats were available for those two.
It is interesting to see the trend split between crypto and non-crypto vulnerability. There is only one trendline, LOC, but I would like to see CVE trends over time as well because that would indicate if we are making progress. This is useful framework for a longer-term study.
I understand that they base their research on CVE data because it offers normalized quantifiers of severity and scope, but in my experience vendors by and large don't bother with CVE's for API bugs even when the affected primitive is clearly malfunctioning (memory or correctness issues).
I've been deeply fuzzing cryptographic libraries for a few years and found about 130 bugs [1]. The vast majority of these did not receive a CVE. Now some of these are merely theoretical, others will only manifest under particular circumstances like specific calling sequences, others were caught in the development phase before landing in stable releases, but a number of them are outright vulnerabilities. The usefulness of CVE incidence is questionable when it is so strongly influenced by the vendor's propensity for reporting these.
The conclusions about Wireshark vulnerability lifetimes look wrong to me. Average lifetimes are artificially capped around 2 years because of how Wireshark Security Advisory version reporting interacts with their support policy. Real lifetimes might be much higher.
Many Wireshark CVEs with numbers CVE-2018-16058 and lower (up until August 29, 2018) say that 2.2.0 was the lowest affected version. A bunch after that say that 2.4.0 was the lowest affected version. Is it plausible that everything discovered after August 2018 just randomly happened to be in code that was introduced on the 2.4 branch? I feel it's much more plausible that this is just an artifact of the Wireshark support policy. https://wiki.wireshark.org/Development/LifeCycle says the 2.2 version series hit End of Life on September 7, 2018. When Wireshark reported CVEs after then (such as CVE-2018-19622 up to CVE-2018-19627), I suspect they intentionally didn't list 2.2 affected versions because they weren't supported. So, I disagree that Wireshark advisories "have sufficiently accurate version reporting to calculate lifetime" and I feel that "Of the 509 CVEs in Wireshark, the average and median lifetimes are 1.29 and 1.4 years" may be hugely inaccurate.
58 comments
[ 222 ms ] story [ 692 ms ] threadGuess what, cryptographic library developers go the same schools as the rest of us. That's there's some sort of development that's somehow out of reach for "regular" devs is elitist and counterproductive.
It means there's a generation of graduates that don't do systems programming or anything where security is important.
Schools are dodging the important societal responsibility of teaching students how one designs and implements software that really, really needs to be correct.
Gotta trust something, we decided we mainly trust the OS download and the repository keys that came with it.
Anyway we seem to have been talking about different kinds of verification, like checking that what Joan Daemen and Vincent Rijmen wrote is really what your CPU is executing versus verifying that implementations of a trusted algorithm aren't broken. We're not in the conspiracy theory or incident response business, so unless someone comes with something that sounds like we should forward them to incident response, the former is not what we do.
But I think a good way to think about it is this: This shouldn't be on top of your list when you learn crypto. Before you even think about rolling your own crypto you should break other people's crypto. That'll help you to gain deeper insights in how the whole thing works.
(Disclaimer: I broke other people's crypto, I wrote papers about it. I still never tried to roll my own crypto.)
At peak, and in multiple independent courses, the teacher would step through a well-made AES key schedule visualization while none of us are (even planning on) doing the heavy math studies necessary to design a successor to or find vulnerabilities in something like AES. Most of us would be software engineers, sysadmins, or perhaps a handful of us might go into security fields like forensics or pentesting. The internals of AES are completely irrelevant. A curiosity maybe, but not something to be quizzed on. Then I went to do my master's and the teacher started about caesar ciphers...
All formal cryptography-for-non-cryptographers education I've ever had was completely useless (I was in tertiary education in the Netherlands between 2010 and 2018, in case anyone is wondering how dated this is).
The concept of authenticated encryption was mentioned in passing I think, though in one course I had to prompt the teacher to mention that as what you would want to be doing, but got far less attention or practice than doing things like a Caesar cipher or AES key schedule by hand.
Merely knowing that you have to look for the keyword authenticated encryption (when you want to do encryption for some reason) would already be enough in my opinion, from there you can find good answers. Or for secure connections, keyword searches should include something about key distribution/verification and, if you want to use something configurable like TLS, also configuration choices like enforcing allowed protocol versions. Which versions those are, that changes over time and there is little point memorizing it. You should just know that you should look into this when you need it.
Maybe it should be "never roll out your own crypto without independent review and verification as well as thorough testing" .
[0] https://monocypher.org/
[1] https://loup-vaillant.fr/articles/rolling-your-own-crypto , discussed here:
https://news.ycombinator.com/item?id=13221923 and related
https://news.ycombinator.com/item?id=14917378
[0] https://monocypher.org/quality-assurance/audit
No high or critical issues were found. The issues that were found were addressed in a timely manner.
Edit: Also, not sure why the author chose to use Argon2i over Argon2id as the PBKDF for Monocypher, my perception was that the id variant should be used unless you have a reason not to. Would be interested to hear other opinions on this.
I think "You Shouldn't Roll Your Own Crypto" is really three separate pieces of advice, each of which deserves justifying independently.
Roughly:
- You shouldn't try to invent your own cryptographic primitives.
- You shouldn't try to design your own equivalent to (say) SSL.
- You shouldn't try to implement something like SSL, or parse ASN.1, yourself.
I don't think many people are likely to fall foul of the first.
It seems to me the second is where the real devils lurk: dealing with padding and cipher modes and all that kind of stuff.
But it's not at all clear to me that the third has been historically justified.
I think if someone in the early 2000s had thought "I don't like the look of OpenSSL and I don't think C is a good choice of language. I'm going to write my own implementation of the parts I need in (say) Ada" they might well not have regretted that choice.
> "ASN.1 is a serialization format which enables C programmers to turn binary data into remote code execution vulnerabilities" -- https://twitter.com/bascule/status/1086778481864658945
Also https://twitter.com/TwitchiH/status/1382649508371308547, discussing it in context of the San Bernadino iPhone being broken with an ASN.1 vuln.
ASN.1 is however structured in a way that such a simple library looks like incomplete; it looks like that a correct way to parse BER/DER is an ASN.1 compiler, which tends to be bulky and annoying to integrate. As a result for a long time most ASN.1 implementations were either a "complete" ASN.1 compiler or a hand-crafted parser, with no middle ground of a library that is simple enough and prevents you from memory unsafety.
I think it's rather more than this. ASN.1 is deeply embedded in daily life: 3G/4G/LTE/5G, V2X, and many other protocols are specified in ASN.1. The inertia has as much to do with backwards compatibility as anything else. If you need to read call data records, you have to parse BER; if you want to deal with vehicle to vehicle communications you have to parse OER. 3G protocols are generally PER. Crypto is DER.
Are there alternatives that are better in some respects? Sure. Are they likely to supplant existing telecommunications standards? No. Should move away from ASN.1 for crypto purposes? Probably, though I'm not experienced enough to have a strong opinion. I'd be interested to see whether we could install a new standard in a suitable time frame, and indeed what form that would take. (In the two links you cited, I didn't see anything, but I'm actually really interested!)
I think ASN.1 is probably here to stay for a long time, and not merely as a resume polishing agent.
It's a little bit more than that: cryptographic container formats usually need to be stable on traversal/canonicalized so that things like hashes remain consistent.
JSON alone doesn't have a canonicalized format (there are various suggested canonical forms), and leaves details about key iteration, duplication, etc. ambiguous in ways that are potential sources of vulnerability (what happens if a particular protocol allows users to introduce untrusted attributes to a JSON object and doesn't check for name clashes?).
Edit: not to mention integer width/representation of large integers! That's a big one for cryptographic protocols.
Yeah, this, too: there's got to be a single way of representing the same message. (BER, in contrast to DER, has multiple means of writing the same message. BOOLEAN types, for example, indicate FALSE by 0x00, but TRUE is any non-zero value. I forget how DER resolves this. DER disallows the use of indefinite lengths, while BER admits both definite and indefinite lengths. Etc., etc.)
I'm sympathetic to the challenges people face with ASN.1, having worked with it rather extensively in my career. I don't recommend it to people who have serialization challenges usually because something like protobuf or flatbuffers seems like a more reasonable choice in this day and age...but at the same time ASN.1 has a history of mistakes and innovations for solving some challenging problems in representation and encoding that should inform decision-making moving forward.
Long before folks understood the security implications of a buffer overflow, we've been parsing ASN.1.
Most of the vulnerabilities stem from the basic problem of trusting length fields. Any binary encoding is going to have similar issues.
In this case you really don't need a DER calibre encoding either, you just need a standard in the first place. It’s just that the standard would historically likely use asn.1. But that doesn't have to be the case. Maybe the closest thing is the ECDSA point form specified in https://www.secg.org/sec1-v2.pdf#page16. The the curve domain parameters in sec2 are, you guessed it, specified in asn.1.
> - You shouldn't try to design your own equivalent to (say) SSL.
> - You shouldn't try to implement something like SSL, or parse ASN.1, yourself.
Why not? You should do all those things, how else can one get a deeper insight into how things work. It's just that you probably don't want to use that in production environment unless you really know what you're doing.
> [...] get a deeper insight into how things work. It's just that you probably don't want to use that in production [...]
That is the gist of it. If you are really into applied cryptography, then rolling your own crypto - and I can't stress this enough - for PURELY ACADEMIC purposes is fine. As long as you are honest with yourself, writing some applied crypto code is a good way to learn some of the horrible ways things can go wrong. Know deep in your heart that no matter how well you thought you did, the code you wrote is broken. Badly.
The "oh... oh shit..." realisation when looking back at the code will be enlightening.
Just please, for the love of all that is good, do not publish the code you wrote. Otherwise, thanks to the law of large numbers, someone, somewhere will grab your code, embed it in their production systems and the next thing you know, a toy library you wrote is now responsible for yet another IoT disaster.
Learn from other people's mistakes. You cannot possibly afford to make all those mistakes yourself.
What would you recommend for compiling and decoding/encoding ASN.1 using Java? I tried OSS NOKALVA's ASN.1 for Java but constraint checking is non-existent or very limited. I am forced to implement it myself as it does not exist from what I gathered. If you know one that does constraint checking, that would be amazing.
A quick search gave me this: https://github.com/yafred/asn1-tool/issues/13, so perhaps it does not seem so infeasible.
> I think if someone in the early 2000s had thought "I don't like the look of OpenSSL and I don't think C is a good choice of language. I'm going to write my own implementation of the parts I need in (say) Ada"
https://github.com/Componolit/libsparkcrypto might be of interest to some. It is written in Ada/SPARK.
A quick look at their documentation suggests the use of the -constraints option.[1] Constraints are such a basic part of the ASN.1 specifications I can't imagine any vendor not implementing it. I know for a fact that Objective Systems' compiler does.[2]
[1]: https://www.oss.com/asn1/products/documentation/asn1_java_8....
[2]: https://www.obj-sys.com/products/asn1c/index.php
I know, Erlang's ASN.1 compiler does it too, automatically. It is pretty awesome.
---
Update: `-constraints` does work (`validConstraint = temp1 >= 10 && temp1 <= 20`)
I will try out more complex ones. :)
But those libraries show up recommended on forums and subreddits everywhere. And if you inherit such a system and try to do something like "add an HMAC", you'll be cursed at for "rolling your own crypto" when you should apparently be trusting the library.
This, to me at least, seems like a strange conclusion for this paper to reach. While there are evidently more vulnerabilities reported in NVD/CVE for cryptographic libraries, does this necessarily correlate with a larger number of vulnerabilities being present? Or could it be that cryptographic code is much more heavily scrutinised, and so it’s more likely that vulns will be found? I think the former is probably more reasonable, but I’m not sure you can come to either conclusion based on CVE data alone. Or am I missing something?
If you are interested you definitely should. Implement existing ciphers, learn, compare, create your own ciphers, test, crack, research and discuss. It's the perfect way to learn more and become better at it.
However, don't put it in production or with real data.
For my part, I've met people who have told me to not even try because I need to get a PhD before I even implement crypto. Not design crypto; implement crypto.
So while you are correct that it is the mainstream interpretation, that's not how it looks from the outside.
They say "Our case study of the LibreSSL and BoringSSL forks further demonstrates a linear correspondence between source code removal and vulnerability removal." Possibly a useful finding! But we still don't know what happens when you remove a ton of someone else's code, but then add a ton of your own unique code. To research that, they'd need competing projects that similarly care about vulnerability IDs (CVEs or other IDs), and have similar populations of potential bug reporters and/or similar opportunities for bug bounties.
It is interesting to see the trend split between crypto and non-crypto vulnerability. There is only one trendline, LOC, but I would like to see CVE trends over time as well because that would indicate if we are making progress. This is useful framework for a longer-term study.
I've been deeply fuzzing cryptographic libraries for a few years and found about 130 bugs [1]. The vast majority of these did not receive a CVE. Now some of these are merely theoretical, others will only manifest under particular circumstances like specific calling sequences, others were caught in the development phase before landing in stable releases, but a number of them are outright vulnerabilities. The usefulness of CVE incidence is questionable when it is so strongly influenced by the vendor's propensity for reporting these.
[1] https://github.com/guidovranken/cryptofuzz#bugs-found-by-cry...
Many Wireshark CVEs with numbers CVE-2018-16058 and lower (up until August 29, 2018) say that 2.2.0 was the lowest affected version. A bunch after that say that 2.4.0 was the lowest affected version. Is it plausible that everything discovered after August 2018 just randomly happened to be in code that was introduced on the 2.4 branch? I feel it's much more plausible that this is just an artifact of the Wireshark support policy. https://wiki.wireshark.org/Development/LifeCycle says the 2.2 version series hit End of Life on September 7, 2018. When Wireshark reported CVEs after then (such as CVE-2018-19622 up to CVE-2018-19627), I suspect they intentionally didn't list 2.2 affected versions because they weren't supported. So, I disagree that Wireshark advisories "have sufficiently accurate version reporting to calculate lifetime" and I feel that "Of the 509 CVEs in Wireshark, the average and median lifetimes are 1.29 and 1.4 years" may be hugely inaccurate.