The Advisory Boar

By Abhijit Menon-Sen <>

Reading about wireguard

I have more than a passing interest in VPN software, and have looked at and used many different implementations over the years. I haven't found much to cheer about, which led me to write tappet for my personal use.

I've been reading about Wireguard for the past few weeks, and I really like it so far. It follows through on many of the same goals that I had with tappet, and goes much further in areas important to more widespread adoption. The author, Jason Donenfeld, articulates the project's design goals in this presentation.

Keeping the code small and easy to review was a primary consideration for me (tappet is under a thousand lines of code, not including NaCl). By this measure, Wireguard does an admirable job of staying small at around 15,000 lines including crypto code and tests.

When I wrote tappet, the Noise Protocol did not exist in a usable (or recommended) form. Wireguard's adoption of this framework brings a host of desirable properties that tappet lacks, notably including perfect forward secrecy.

One of my major frustrations with OpenVPN is the extraordinary time it takes to establish a TLS connection on a high-latency link. Very often, when tethered via GPRS, it will retry forever and never succeed. Tappet goes to the other extreme—it requires zero setup for encrypted links (at the expense of perfect forward secrecy). Wireguard restricts its handshake to a single round-trip, which is an entirely acceptable compromise in practice.

Wireguard runs in the kernel, thereby avoiding the need to copy packets in and out of userspace. I didn't care nearly as much about performance. Tappet is fast enough in userspace that it keps up with the fastest link I've tried it on (42.2Mbps DCHSPA+), and I didn't need anything more.

Wireguard accepts multiple peers per interface, while tappet is limited to setting up point-to-point encrypted links. The former is obviously more practical in realistic deployments. (On the other hand, Wireguard is a Layer-3 VPN, while tappet operates at L2 and forwards Ethernet frames instead of IP packets. How much that matters depends on the circumstances.)

I look forward to a time when I can use Wireguard in production.

Strange cryptographic decisions in Ansible vault

I wrote about some useful changes to ansible-vault in Ansible 2 in an earlier post. Unfortunately, another significant change to the vault internals was rejected for Ansible 2.

Vault cryptography

The VaultAES256 class implements encryption and decryption. It uses sensible building blocks: PBKDF2 for key generation with a random salt, AES-CTR for encryption, and HMAC-SHA-256 for authentication (used in encrypt-then-mac fashion). This is a major improvement over the earlier VaultAES class, which used homebrew key generation and an SHA-256 digest alone for “verification”.

Nevertheless, the code has some embarrassing oversights. They are not vulnerabilities, but they show that the code was written with… rather less familiarity with cryptography than one might wish:

  • Plaintext is padded to the AES block size, but this is unnecessary because AES-CTR is used as a stream cipher.
  • An extra 32-byte block of PBKDF2 (10,000 iterations) output is derived to initialise the 16-byte IV, and the other half discarded; but this is unnecessary because the IV can be 0 (the salt ensures that we do not use the same key to encrypt the same plaintext).

Finally, the ciphertext is passed through hexlify() twice, thereby inflating it to 4x the size (instead of using, say, Base64). This is the least significant and yet the most annoying problem.

The most visible effects of the over-enthusiastic PBKDF2 use were mitigated by a pull request to use an optimised PBKDF2 implementation. This reduced the startup time by an order of magnitude for setups that loaded many vault-encrypted files from group_vars and host_vars.

All of these problems were solved by PR #12130, which saw several rounds of changes and was slated for inclusion in Ansible 2, but was eventually rejected by the maintainers because there wasn't “anyone in-house to review it for security problems and it's late to be adding it for v2”.

Other changes that didn't make it

A couple of other often-requested Vault changes fell by the wayside en route to Ansible 2:

  • GPG support for the vault was submitted as a PR over a year ago, but the code is now outdated after an initial rebase to the v2 codebase.
  • Lookup support (with the file lookup plugin, and also with the copy module) was partly implemented but never completed and merged.

Many people left +1 comments on Github to indicate their support for these features. I hope someone wants them enough to work on them for v2.1, and that they have better luck getting this work merged than I did.

Mojolicious session cookies

Mojolicious comes with safe, easy-to-use session cookies out of the box. You just write…

$self->session(key => "some value");

…and $self->session('key') will retrieve the value in subsequent requests by the same client.

Session data are stored in a hash, which may contain anything subject to a maximum size of 4KB. The hash is serialised and signed with a message authentication code to form a tamper-proof session cookie which expires after an hour by default. When the cookie is presented by a client, the server can verify the signature without any stored state. Cookies that fail signature verification are discarded before they ever reach the application code.

Read more…

Cryptographically secure randomness in Perl

I can usually sidestep the need for cryptographically secure randomness, but I decided to investigate the available options to generate CSRF protection tokens.

On Linux, /dev/random is a good, cryptographically secure random number generator, but the entropy available without special hardware support is severely limited. Reads from /dev/random block for however long it takes (even minutes) to gather enough entropy to satisfy the request. Entropy is in high demand throughout the system, so this is not a resource that can be indiscriminately drawn upon.

One standard solution to this problem is to use the output of a randomly keyed block cipher running in counter (CTR) mode. This provides only as much entropy as the random key, but if /dev/random is used to generate the key, the result is suitable for many purposes. Andrew Main's Data::Entropy module implements this strategy in Perl.

Read more…

Nonsensical DoT crypto restrictions

What are the regulations governing the use of cryptography and the development of cryptographic software in India? The answer is either "there aren't any" or "nobody really knows".

One of the few official documents to discuss the subject is this one ("Guidelines and general information for setting up of international gateways for internet") published by the Department of Telecommunications (DoT) in 2001. It is not clear why an informative document inviting proposals from ISPs to set up international gateways should have anything to say about the use of cryptography in general, or whether this amounts to a rule, but here's the relevant section:


Individuals/Groups/Organisations are permitted to use encryption upto 40 bit key length in the RSA algorithms or its equivalent in other algorithms without having to obtain permission. However, if encryption equipments higher than this limit are to be deployed, individuals/groups/organisations shall do so with the permission of the Telecom Authority and deposit the decryption key, split into two parts, with the Telecom Authority.

There has been plenty of criticism of this section as being "too weak", but the real problem is that it's stupid and wrong (as I have explained in email one too many times; hence this post).

Read more…