defmodule CA.AES do def e(x,y), do: :erlang.element(x,y) def privat(name), do: e(3,:public_key.pem_entry_decode(readPEM("priv/certs/",name))) def public(name), do: e(3,e(8, e(2, :public_key.pem_entry_decode(readPEM("priv/certs/",name))))) def readPEM(folder, name), do: hd(:public_key.pem_decode(e(2, :file.read_file(folder <> name)))) def shared(pub, key, scheme), do: :crypto.compute_key(:ecdh, pub, key, scheme) def decryptAES256ECB(data, key, iv \\ :crypto.strong_rand_bytes(16)) do :crypto.crypto_one_time(:aes_256_ecb,key,iv,data,[{:encrypt,false}]) end def decryptAES256CBC(data, key, iv \\ :crypto.strong_rand_bytes(16)) do :crypto.crypto_one_time(:aes_256_cbc,key,iv,data,[{:encrypt,false}]) end def decryptAES256GCM(data, key, iv \\ :crypto.strong_rand_bytes(16)) do <> = data :crypto.crypto_one_time_aead(:aes_256_gcm, key, iv, data, "AES256GCM", tag, false) end def decryptAES256CCM(data, key, iv \\ :crypto.strong_rand_bytes(16)) do <> = data :crypto.crypto_one_time_aead(:aes_256_ccm, key, iv, data, "AES256CCM", tag, false) end def encryptAES256ECB(data, key, iv \\ :crypto.strong_rand_bytes(16)) do :crypto.crypto_one_time(:aes_256_ecb,key,iv,data,[{:encrypt,true}]) end def encryptAES256CBC(data, key, iv \\ :crypto.strong_rand_bytes(16)) do :crypto.crypto_one_time(:aes_256_cbc,key,iv,data,[{:encrypt,true}]) end def encryptAES256GCM(data, key, iv \\ :crypto.strong_rand_bytes(16)) do {cipher, tag} = :crypto.crypto_one_time_aead(:aes_256_gcm, key, iv, data, "AES256GCM", true) iv <> tag <> cipher end def encryptAES256CCM(data, key, iv \\ :crypto.strong_rand_bytes(16)) do {cipher, tag} = :crypto.crypto_one_time_aead(:aes_256_ccm, key, iv, data, "AES256CCM", true) iv <> tag <> cipher end def encrypt(crypto_codec, data, key, iv \\ :crypto.strong_rand_bytes(16)) def encrypt(:aes_256_ecb, data, key, iv), do: encryptAES256ECB(data, key, iv) def encrypt(:aes_256_cbc, data, key, iv), do: encryptAES256CBC(data, key, iv) def encrypt(:aes_256_gcm, data, key, iv), do: encryptAES256GCM(data, key, iv) def encrypt(:aes_256_ccm, data, key, iv), do: encryptAES256CCM(data, key, iv) def decrypt(crypto_codec, data, key, iv \\ :crypto.strong_rand_bytes(16)) def decrypt(:aes_256_ecb, data, key, iv), do: decryptAES256ECB(data, key, iv) def decrypt(:aes_256_cbc, data, key, iv), do: decryptAES256CBC(data, key, iv) def decrypt(:aes_256_gcm, data, key, iv), do: decryptAES256GCM(data, key, iv) def decrypt(:aes_256_ccm, data, key, iv), do: decryptAES256CCM(data, key, iv) def testSMIME() do {:ok,base} = :file.read_file "priv/encrypted.txt" ; [_,s] = :string.split base, "\n\n" :'CryptographicMessageSyntax-2010'.decode(:ContentInfo, :base64.decode(s)) end def check_SECP384R1_GCM256() do # SECP384r1 scheme = :secp384r1 aliceP = public "client.pem" aliceK = privat "client.key" maximP = public "server.pem" maximK = privat "server.key" maximS = :binary.part(shared(aliceP,maximK,scheme),0,32) aliceS = :binary.part(shared(maximP,aliceK,scheme),0,32) iv = :crypto.strong_rand_bytes(16) x = encrypt(:aes_256_gcm, "Success!", maximS, iv) "Success!" == decrypt(:aes_256_gcm, x, aliceS, iv) :ok end def check_X25519_GCM256() do # X25519 scheme = :x25519 {aliceP,aliceK} = :crypto.generate_key(:ecdh, scheme) {maximP,maximK} = :crypto.generate_key(:ecdh, scheme) maximS = shared(aliceP,maximK,scheme) aliceS = shared(maximP,aliceK,scheme) iv = :crypto.strong_rand_bytes(16) x = encrypt(:aes_256_gcm, "Success!", maximS, iv) "Success!" == decrypt(:aes_256_gcm, x, aliceS, iv) :ok end def check_X448_GCM256() do # X488 scheme = :x448 {aliceP,aliceK} = :crypto.generate_key(:ecdh, scheme) {maximP,maximK} = :crypto.generate_key(:ecdh, scheme) maximS = :binary.part(shared(aliceP,maximK,scheme),0,32) aliceS = :binary.part(shared(maximP,aliceK,scheme),0,32) iv = :crypto.strong_rand_bytes(16) x = encrypt(:aes_256_gcm, "Success!", maximS, iv) "Success!" == decrypt(:aes_256_gcm, x, aliceS, iv) :ok end def check_X448_CBC256() do # X488 scheme = :x448 {aliceP,aliceK} = :crypto.generate_key(:ecdh, scheme) {maximP,maximK} = :crypto.generate_key(:ecdh, scheme) maximS = :binary.part(shared(aliceP,maximK,scheme),0,32) aliceS = :binary.part(shared(maximP,aliceK,scheme),0,32) x = encrypt(:aes_256_cbc, "Success!", maximS) "Success!" == decrypt(:aes_256_cbc, x, aliceS) :ok end def check_X448_ECB256() do # X488 scheme = :x448 {aliceP,aliceK} = :crypto.generate_key(:ecdh, scheme) {maximP,maximK} = :crypto.generate_key(:ecdh, scheme) maximS = :binary.part(shared(aliceP,maximK,scheme),0,32) aliceS = :binary.part(shared(maximP,aliceK,scheme),0,32) x = encrypt(:aes_256_ecb, "Success!", maximS) "Success!" == decrypt(:aes_256_ecb, x, aliceS) :ok end end