1defmodule JOSE.JWA do 2 @moduledoc ~S""" 3 JWA stands for JSON Web Algorithms which is defined in [RFC 7518](https://tools.ietf.org/html/rfc7518). 4 5 ## Cryptographic Algorithm Fallback 6 7 Native implementations of all cryptographic and public key algorithms 8 required by the JWA specifications are not present in current versions 9 of Elixir and OTP. 10 11 JOSE will detect whether a specific algorithm is natively supported or not 12 and, by default, it will mark the algorithm as unsupported if a native 13 implementation is not found. 14 15 However, JOSE also has pure Erlang versions of many of the missing algorithms 16 which can be used as a fallback by calling `JOSE.crypto_fallback/1` and 17 passing `true`. 18 """ 19 20 ## Crypto API 21 22 @doc """ 23 Decrypts `cipher_text` according to `cipher` block cipher. 24 25 Currently supported block ciphers: 26 27 * `{:aes_ecb, 128}` - AES ECB with 128-bit `key` size 28 * `{:aes_ecb, 192}` - AES ECB with 192-bit `key` size 29 * `{:aes_ecb, 256}` - AES ECB with 256-bit `key` size 30 """ 31 defdelegate block_decrypt(cipher, key, cipher_text), to: :jose_jwa 32 33 @doc """ 34 Decrypts `cipher_text` according to `cipher` block cipher. 35 36 Currently supported block ciphers: 37 38 * `{:aes_cbc, 128}` - AES CBC with 128-bit `key` size and 128-bit `iv` size 39 * `{:aes_cbc, 192}` - AES CBC with 192-bit `key` size and 128-bit `iv` size 40 * `{:aes_cbc, 256}` - AES CBC with 256-bit `key` size and 128-bit `iv` size 41 * `{:aes_gcm, 128}` - AES GCM with 128-bit `key` size and variable `iv` size 42 * `{:aes_gcm, 192}` - AES GCM with 192-bit `key` size and variable `iv` size 43 * `{:aes_gcm, 256}` - AES GCM with 256-bit `key` size and variable `iv` size 44 * `{:chacha20_poly1305, 256}` - ChaCha20/Poly1305 with 256-bit `key` size and 96-bit `iv` size 45 """ 46 defdelegate block_decrypt(cipher, key, iv, cipher_text), to: :jose_jwa 47 48 @doc """ 49 Encrypts `plain_text` according to `cipher` block cipher. 50 51 Currently supported block ciphers: 52 53 * `{:aes_ecb, 128}` - AES ECB with 128-bit `key` size 54 * `{:aes_ecb, 192}` - AES ECB with 192-bit `key` size 55 * `{:aes_ecb, 256}` - AES ECB with 256-bit `key` size 56 """ 57 defdelegate block_encrypt(cipher, key, plain_text), to: :jose_jwa 58 59 @doc """ 60 Encrypts `plain_text` according to `cipher` block cipher. 61 62 Currently supported block ciphers: 63 64 * `{:aes_cbc, 128}` - AES CBC with 128-bit `key` size and 128-bit `iv` size 65 * `{:aes_cbc, 192}` - AES CBC with 192-bit `key` size and 128-bit `iv` size 66 * `{:aes_cbc, 256}` - AES CBC with 256-bit `key` size and 128-bit `iv` size 67 * `{:aes_gcm, 128}` - AES GCM with 128-bit `key` size and variable `iv` size 68 * `{:aes_gcm, 192}` - AES GCM with 192-bit `key` size and variable `iv` size 69 * `{:aes_gcm, 256}` - AES GCM with 256-bit `key` size and variable `iv` size 70 * `{:chacha20_poly1305, 256}` - ChaCha20/Poly1305 with 256-bit `key` size and 96-bit `iv` size 71 """ 72 defdelegate block_encrypt(cipher, key, iv, plain_text), to: :jose_jwa 73 74 ## Public Key API 75 76 @doc """ 77 Decrypts `cipher_text` using the `private_key`. 78 79 ## Options 80 81 * `:rsa_padding` - one of `:rsa_pkcs1_oaep_padding` or `:rsa_pkcs1_padding` 82 * `:rsa_oaep_md` - sets the hashing algorithm for `:rsa_pkcs1_oaep_padding`, defaults to `:sha` 83 * `:rsa_oaep_label` - sets the label for `:rsa_pkcs1_oaep_padding`, defaults to `<<>>` 84 """ 85 defdelegate decrypt_private(cipher_text, private_key, options), to: :jose_jwa 86 87 @doc """ 88 Encrypts `plain_text` using the `public_key`. 89 90 ## Options 91 92 * `:rsa_padding` - one of `:rsa_pkcs1_oaep_padding` or `:rsa_pkcs1_padding` 93 * `:rsa_oaep_md` - sets the hashing algorithm for `:rsa_pkcs1_oaep_padding`, defaults to `:sha` 94 * `:rsa_oaep_label` - sets the label for `:rsa_pkcs1_oaep_padding`, defaults to `<<>>` 95 """ 96 defdelegate encrypt_public(plain_text, public_key, options), to: :jose_jwa 97 98 @doc """ 99 Signs the digested `message` using the `digest_type` and `private_key`. 100 101 ## Options 102 103 * `:rsa_padding` - one of `:rsa_pkcs1_pss_padding` or `:rsa_pkcs1_padding` 104 * `:rsa_pss_saltlen` - sets the salt length for `:rsa_pkcs1_pss_padding`, defaults to `-1` 105 * `-2` - use maximum for salt length 106 * `-1` - use hash length for salt length 107 * any number higher than `-1` is used as the actual salt length 108 """ 109 defdelegate sign(message, digest_type, private_key, options), to: :jose_jwa 110 111 @doc """ 112 Verifies the `signature` with the digested `message` using the `digest_type` and `public_key`. 113 114 ## Options 115 116 * `:rsa_padding` - one of `:rsa_pkcs1_pss_padding` or `:rsa_pkcs1_padding` 117 * `:rsa_pss_saltlen` - sets the salt length for `:rsa_pkcs1_pss_padding`, defaults to `-1` 118 * `-2` - automatically determine based on the PSS block structure 119 * `-1` - use hash length for salt length 120 * any number higher than `-1` is used as the actual salt length 121 """ 122 defdelegate verify(message, digest_type, signature, public_key, options), to: :jose_jwa 123 124 ## API 125 126 @doc """ 127 Returns the current module and first argument for the specified `cipher`. 128 129 iex> JOSE.JWA.block_cipher({:aes_cbc, 128}) 130 {:crypto, :aes_cbc128} 131 iex> JOSE.JWA.block_cipher({:aes_cbc, 192}) 132 {:jose_jwa_unsupported, {:aes_cbc, 192}} 133 iex> JOSE.crypto_fallback(true) 134 :ok 135 iex> JOSE.JWA.block_cipher({:aes_cbc, 192}) 136 {:jose_jwa_aes, {:aes_cbc, 192}} 137 138 """ 139 defdelegate block_cipher(cipher), to: :jose_jwa 140 141 @doc """ 142 Returns the current block ciphers and their associated modules. 143 144 iex> JOSE.JWA.crypto_ciphers() 145 [{{:aes_cbc, 128}, :crypto}, {{:aes_cbc, 192}, :crypto}, 146 {{:aes_cbc, 256}, :crypto}, {{:aes_ecb, 128}, :crypto}, 147 {{:aes_ecb, 192}, :crypto}, {{:aes_ecb, 256}, :crypto}, 148 {{:aes_gcm, 128}, :crypto}, {{:aes_gcm, 192}, :crypto}, 149 {{:aes_gcm, 256}, :crypto}, 150 {{:chacha20_poly1305, 256}, :jose_chacha20_poly1305}] 151 152 """ 153 defdelegate crypto_ciphers(), to: :jose_jwa 154 155 @doc """ 156 See `JOSE.crypto_fallback/0` 157 """ 158 defdelegate crypto_fallback(), to: :jose_jwa 159 160 @doc """ 161 See `JOSE.crypto_fallback/1` 162 """ 163 defdelegate crypto_fallback(boolean), to: :jose_jwa 164 165 @doc """ 166 Returns the current listing of supported `:crypto` and `:public_key` algorithms. 167 168 iex> JOSE.JWA.crypto_supports() 169 [ciphers: [aes_cbc: 128, aes_cbc: 192, aes_cbc: 256, aes_ecb: 128, aes_ecb: 192, 170 aes_ecb: 256, aes_gcm: 128, aes_gcm: 192, aes_gcm: 256, 171 chacha20_poly1305: 256], 172 hashs: [:md5, :poly1305, :sha, :sha256, :sha384, :sha512, :shake256], 173 public_keys: [:ec_gf2m, :ecdh, :ecdsa, :ed25519, :ed25519ph, :ed448, :ed448ph, 174 :rsa, :x25519, :x448], rsa_crypt: [:rsa1_5, :rsa_oaep, :rsa_oaep_256], 175 rsa_sign: [:rsa_pkcs1_padding, :rsa_pkcs1_pss_padding]] 176 177 """ 178 defdelegate crypto_supports(), to: :jose_jwa 179 180 @doc """ 181 Performs a constant time comparison between two binaries to help avoid [timing attacks](https://en.wikipedia.org/wiki/Timing_attack). 182 """ 183 defdelegate constant_time_compare(a, b), to: :jose_jwa 184 185 @doc """ 186 Returns either `:binary` or `:list` depending on the detected runtime behavior for EC keys. 187 """ 188 defdelegate ec_key_mode(), to: :jose_jwa 189 190 @doc """ 191 Checks whether the `cipher` is natively supported by `:crypto` or not. 192 """ 193 defdelegate is_block_cipher_supported(cipher), to: :jose_jwa 194 195 @doc """ 196 Checks whether ChaCha20/Poly1305 support is available or not. 197 """ 198 defdelegate is_chacha20_poly1305_supported(), to: :jose_jwa 199 200 @doc """ 201 Checks whether the `padding` is natively supported by `:public_key` or not. 202 """ 203 defdelegate is_rsa_crypt_supported(padding), to: :jose_jwa 204 205 @doc """ 206 Checks whether the `padding` is natively supported by `:public_key` or not. 207 """ 208 defdelegate is_rsa_sign_supported(padding), to: :jose_jwa 209 210 @doc """ 211 Returns the current listing of supported JOSE algorithms. 212 213 iex> JOSE.JWA.supports() 214 [{:jwe, 215 {:alg, 216 ["A128GCMKW", "A128KW", "A192GCMKW", "A192KW", "A256GCMKW", "A256KW", 217 "ECDH-ES", "ECDH-ES+A128KW", "ECDH-ES+A192KW", "ECDH-ES+A256KW", 218 "PBES2-HS256+A128KW", "PBES2-HS384+A192KW", "PBES2-HS512+A256KW", 219 "RSA-OAEP", "RSA-OAEP-256", "RSA1_5", "dir"]}, 220 {:enc, 221 ["A128CBC-HS256", "A128GCM", "A192CBC-HS384", "A192GCM", "A256CBC-HS512", 222 "A256GCM", "ChaCha20/Poly1305"]}, {:zip, ["DEF"]}}, 223 {:jwk, {:kty, ["EC", "OKP", "RSA", "oct"]}, 224 {:kty_OKP_crv, 225 ["Ed25519", "Ed25519ph", "Ed448", "Ed448ph", "X25519", "X448"]}}, 226 {:jws, 227 {:alg, 228 ["ES256", "ES384", "ES512", "Ed25519", "Ed25519ph", "Ed448", "Ed448ph", 229 "HS256", "HS384", "HS512", "PS256", "PS384", "PS512", "Poly1305", "RS256", 230 "RS384", "RS512", "none"]}}] 231 232 """ 233 defdelegate supports(), to: :jose_jwa 234 235 @doc """ 236 See `JOSE.unsecured_signing/0` 237 """ 238 defdelegate unsecured_signing(), to: :jose_jwa 239 240 @doc """ 241 See `JOSE.unsecured_signing/1` 242 """ 243 defdelegate unsecured_signing(boolean), to: :jose_jwa 244end 245