Unknown cipher when encrypting data

Hello,
I am trying to encrypt data in migrations. Just using cloak gave me some pretty weird errors (like :crypto.strong_rand_bytes seemed to return nil for it :103:) so I am trying to replicate its functionality inline just for one migration.

Long story short, this is the problem (I am on Erlang 23.3.4.4 and Elixir 1.12.2-otp-23):

iex(1)> :crypto.crypto_one_time_aead(:aes_256_gcm, "9hs4ndXeD4p/OkcogRyVBa4pUznauN6ZRnh4eLZgsIg=", <<95, 198, 233, 21, 58, 174, 237, 201, 33, 252, 35, 26, 168, 138, 241, 61>>, "123123123123\ndfvdfv\ndfvdfvdfv", "AES256GCM", 16, true)
** (ErlangError) Erlang error: {:badarg, {'aead.c', 90}, 'Unknown cipher'}
    (crypto 4.9.0.2) :crypto.aead_cipher(:aes_256_gcm, "9hs4ndXeD4p/OkcogRyVBa4pUznauN6ZRnh4eLZgsIg=", <<95, 198, 233, 21, 58, 174, 237, 201, 33, 252, 35, 26, 168, 138, 241, 61>>, "123123123123\ndfvdfv\ndfvdfvdfv", "AES256GCM", 16, true)

One random idea that popped in my mind was to limit the IV to 12 bytes and I did but the error stays the same.

I also do this just to check:

iex(2)> :crypto.cipher_info :aes_256_gcm
%{block_size: 1, iv_length: 12, key_length: 32, mode: :gcm_mode, type: 901}

And this:

iex(3)> :crypto.supports(:ciphers)
[:chacha20, :blowfish_ecb, :blowfish_ofb64, :blowfish_cfb64, :blowfish_cbc,
 :des_ecb, :rc2_cbc, :aes_192_cbc, :aes_256_cfb128, :aes_192_cfb128,
 :aes_256_cfb8, :aes_192_cfb8, :aes_256_ecb, :aes_192_ecb, :aes_256_cbc,
 :des_ede3_cfb, :aes_128_ecb, :aes_128_cfb128, :aes_128_cfb8, :aes_128_cbc,
 :aes_256_ccm, :aes_192_gcm, :aes_192_ccm, :aes_128_ccm, :des_cfb, :des_cbc,
 :rc4, :aes_ige256, :aes_256_ctr, :aes_192_ctr, :aes_128_ctr,
 :chacha20_poly1305, :aes_256_gcm, :aes_128_gcm, :des_ede3_cbc]

I am completely lost. Can anyone help? (@voltone hope you don’t mind me tagging you)

1 Like

Maybe you hit this:

The actual supported algorithms and features depends on their availability in the actual libcrypto used. See the crypto (App) about dependencies.

[Erlang -- crypto]

Hit what exactly? The cipher seems to be supported (judging by the calls to :crypto.cipher_info and :crypto.ciphers). Are there any additional considerations?

Just a wild guess.

I get the same error {:badarg, {'aead.c', 90}, 'Unknown cipher'}, but

iex(3)> :aes_256_gcm in :crypto.supports(:ciphers)
true

It seems like get_cipher_type in aead.c#89 runs in the struct initialized here.

Not sure what you mean – maybe that my key isn’t 32 bytes long?

EDIT: Just checked, it’s 32 bytes after Base64 decoding.

Yes either that or somehow code was compiled with HAVE_GCM not set and :crypto.supports is lying.

Somehow

get_cipher_type(type, key.size)

returnsNULL

I think its your key.
When following the example in the user manual:

iex(1)> key = <<1::128>>
iex(2)> iv = <<0::128>>
iex(3)> txt = ["First bytes", "Second bytes"] 
iex(4)> aad = "some bytes"
iex(5)> :crypto.crypto_one_time_aead(:aes_128_gcm, key, iv, txt, aad, true)
{<<240, 130, 38, 96, 130, 241, 189, 52, 3, 190, 179, 213, 132, 1, 72, 192, 103,
   176, 90, 104, 15, 71, 158>>,
 <<35, 33, 39, 156, 15, 240, 252, 67, 39, 162, 221, 233, 146, 86, 21, 40>>}
iex(6)> :crypto.crypto_one_time_aead(:aes_256_gcm, key, iv, txt, aad, true)
** (ErlangError) Erlang error: {:badarg, {'aead.c', 90}, 'Unknown cipher'}

I get the “unknown cypher error” but its just the wrong key size (128 bit from example).

But:

iex(6)> key = <<1::256>>
<<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 1>>
iex(7)> iv = <<0::256>>
<<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0>>
iex(8)> :crypto.crypto_one_time_aead(:aes_256_gcm, key, iv, txt, aad, true)
{<<158, 135, 28, 93, 111, 17, 234, 107, 10, 237, 242, 151, 2, 166, 180, 14, 105,
   125, 228, 174, 101, 81, 28>>,
 <<171, 236, 22, 207, 207, 21, 255, 85, 217, 17, 153, 40, 231, 68, 190, 189>>}

your key:

iex(10)> bit_size("9hs4ndXeD4p/OkcogRyVBa4pUznauN6ZRnh4eLZgsIg=") 
352

But you should first Base.decode64 this string. The key size is fine. I have no clue what’s the problem still. :expressionless:

Why do you think that :cypto will decode the key?

This: Cloak.Vault — cloak v1.1.1

Check how the key is initialized.

Actually you know what, you could be correct. Checking…

Yep. The key is stored base64-encoded in our config and my inlining code didn’t decode it. :man_facepalming:

Just base64-decoding the key before use solved it! Thanks for being my rubber duck! :heart:

1 Like

you lost me there, you are calling crypto_one_time_aead with a String as key. No idea what that lib has to do with it. crypto_one_time_aead will just call iolist_to_binary on it and then try to find the cypher looking at the name you provide and the key-length.

1 Like

:duck:

that was definitely more fun than what I’m actually doing right now.

1 Like

I could tell! :003:

Then when I finally get the time to get back on my Elixir + Rust sqlite3 library I’ll definitely ping you. You’ll be in a world of… fun. Yes, fun, nothing else.

1 Like

Do that, looking into SQLite (and CubDB) right now to securely save configs in an embedded (nerves) device.

Dude, it’s a tragedy but it’s also for another thread / chat. I have so many good ideas and I’ll make the thing ironclad. I just don’t have the extra energy, these pre-diabetes symptoms are keeping me barely above the surface sadly. I barely manage to work and function and have some semblance of an okay diet. But things are gradually improving which is motivating.

I definitely want to get back to that and show everyone how it’s done. I am inching my way to that.

that sucks, wish you all the best, keep on improving.

Ironclad is what I’m looking for! :robot: