Maintaining cryptographic library for 12 languages

042b7c0e45c53de46667f07de2fb2614?s=47 vixentael
November 07, 2019

Maintaining cryptographic library for 12 languages

Maintaining cross-platform cryptographic library is a journey full of unexpected bugs, language-specific hacks, difficult decisions and endless struggle to make developer-facing APIs easy-to-use and hard-to-misuse.

This talk is useful for ppl that believe that perfect crypto lib is a C lib with 1-page readme :)


As developers, what do we want from using cryptographic tools? They should be easy to use and hard to misuse, cover complete use-cases instead of providing crypto-primitives, support language-specific style, work in the same way on numerous platforms and languages. Basically, we want less stress and more work done.

But is it so easy to maintain cross-platform crypto library? How to simplify complex crypto concepts into simple "encrypt(msg, key)" and "decrypt(data, key)" functions? How to provide unified API for 11 languages, when some of them are strongly-typed and another one is javascript? Secure by default: what design choices should be made to protect from misuse. Multi-platformness: how to make sure that message encrypted using Ruby on x64 Ubuntu 18.04 will be [successfully] decrypted on iOS12 on iPhone armv7s? Testing wildness: static analyzers, fuzzing, unit tests, integration tests. Docs: developers copy-paste from readme anyway, how to make sure that they copy-paste correct things.

I'll describe the 4yrs experience on maintaining multi-platform open source library Themis: from API design to language-specific hacks.

Bonus questions:
- what maintainers completely forget about: the biggest fail reason for users.
- what is faster in Go: calling OpenSSL via c-Go interop or using native Go crypto primitives?
- how to deal with multi-platformness, if BoringSSL for iOS doesn't support AES XTS?
- epic bug with iOS-Android compatibility, which appears to be a sad story about `size_t`.
- switching cryptographic backends for fun and profit: switching between BoringSSL, OpenSSL, LibreSSL, ~libsodium and CommonCrypto~, and governmental crypto standards of some countries, leaving same high-level API.

Key takeaways:
- cryptography is easy, but "secure by default" APIs are hard;
- never agree to support multi-platform libs;
- each language has unique hacks and typical mistakes, deal with it.



November 07, 2019