Skip to content

Commit

Permalink
ex_doc, restrict to OTP27 and later
Browse files Browse the repository at this point in the history
  • Loading branch information
sg2342 committed Jun 19, 2024
1 parent b001c13 commit aa6bbc9
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 20 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:

strategy:
matrix:
otp_version: [26, 27]
otp_version: [27]
os: [ubuntu-latest]

container:
Expand All @@ -24,4 +24,4 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: Check
run: rebar3 as test check
run: rebar3 as test check
9 changes: 8 additions & 1 deletion rebar.config
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
%% -*- erlang -*-
{minimum_otp_vsn, "27.0"}.
{erl_opts, [debug_info]}.
{deps, []}.
{

{project_plugins, [rebar3_lint]}.
{project_plugins, [rebar3_lint, rebar3_hex, rebar3_ex_doc]}.

{alias, [{check, [lint, dialyzer, xref, ct, cover]}]}.

Expand All @@ -14,3 +16,8 @@
{xref_checks, [undefined_function_calls, undefined_functions,
locals_not_used, deprecated_function_calls,
deprecated_functions]}.

{ex_doc, [{extras, ["LICENSE.md"]},
{source_url, "https://github.com/sg2342/erl_rfc3394"},
{homepage_url, "https://github.com/sg2342/erl_rfc3394"},
{prefix_ref_vsn_with_v, false}]}.
4 changes: 2 additions & 2 deletions src/rfc3394.app.src
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{application, rfc3394,
[{description, "Advanced Encryption Standard (AES) Key Wrap Algorithm"},
{vsn, git},
{vsn, "1.0.0"},
{registered, []},
{applications,
[kernel,
Expand All @@ -10,5 +10,5 @@
{modules, []},

{licenses, ["Apache-2.0"]},
{links, []}
{links, [{"GitHub", "https://github.com/sg2342/erl_rfc3394"}]}
]}.
89 changes: 74 additions & 15 deletions src/rfc3394.erl
Original file line number Diff line number Diff line change
@@ -1,25 +1,70 @@
-module(rfc3394).

-moduledoc """
Implementation of Advanced Encryption Standard (AES) Key Wrap Algorithm
as defined in https://datatracker.ietf.org/doc/html/rfc3394.html.
""".
-export([wrap/2, unwrap/2]).
-export([wrap/3, unwrap/3]).

%%% https://datatracker.ietf.org/doc/html/rfc3394.txt#section-2.2.3.1
-define(DEFAULT_IV, <<16#A6, 16#A6, 16#A6, 16#A6, 16#A6, 16#A6, 16#A6, 16#A6>>).

-doc """
wrap `KeyData` with `KEK` and default initial value (`IV`)
`KeyData` is a binary of at least 16 bytes,`byte_size(KeyData)`
must be divisible by 8.
`KEK` is a 128 bit or 192 bit or 256 bit AES key (binary).
the resulting `Ciphertext` 8 bytes larger than `KeyData`
""".
-spec wrap(KeyData :: binary(), KEK :: binary()) ->
Ciphertext :: binary().
wrap(KeyData, KEK) -> wrap(KeyData, KEK, ?DEFAULT_IV).

-doc """
unwrap `Ciphertext` with `KEK` and check `KeyData` integrity with default
initial value (`IV`)
-spec wrap(Plaintext :: binary(), KEK :: binary()) -> binary().
wrap(Plaintext, KEK) -> wrap(Plaintext, KEK, ?DEFAULT_IV).
`Ciphertext` is a binard of at least 24 bytes, `byte_size(Ciphertext)`
must be divisible by 8.
-spec unwrap(Ciphertext :: binary(), KEK :: binary()) -> binary().
`KEK` is a 128 bit or 192 bit or 256 bit AES key (binary).
the resulting `KeyData` 8 smaller than `Ciphertext`
Will raise an exception of class `error` wht reason `iv_mismatch` if the
integrity check fails.
""".
-spec unwrap(Ciphertext :: binary(), KEK :: binary()) ->
KeyData :: binary().
unwrap(Ciphertext, KEK) -> unwrap(Ciphertext, KEK, ?DEFAULT_IV).

%%% https://datatracker.ietf.org/doc/html/rfc3394.txt#section-2.2.1
-spec wrap(Plaintext :: binary(), KEK :: binary(), IV :: binary()) -> binary().
wrap(Plaintext, KEK, <<A:64>>) when
is_binary(Plaintext), (byte_size(Plaintext) rem 8) == 0, is_binary(KEK),

-doc """
wrap `KeyData` with `KEK` and `IV`
`KeyData` is a binary of at least 16 bytes,`byte_size(KeyData)`
must be divisible by 8.
`KEK` is a 128 bit or 192 bit or 256 bit binary.
`IV` is a 8 byte binary.
the resulting `Ciphertext` 8 bytes larger than `KeyData`
see: https://datatracker.ietf.org/doc/html/rfc3394.txt#section-2.2.1
""".
-spec wrap(KeyData :: binary(), KEK :: binary(), IV :: binary()) ->
Ciphertext :: binary().
wrap(KeyData, KEK, <<A:64>>) when
is_binary(KeyData), (byte_size(KeyData) rem 8) == 0,
byte_size(KeyData) >= 16,
is_binary(KEK),
((byte_size(KEK) == 16) orelse (byte_size(KEK) == 24)
orelse (byte_size(KEK) == 32)) ->
wrap1(lists:seq(0, 5), byte_size(Plaintext) div 8, KEK, {A, Plaintext}).
wrap1(lists:seq(0, 5), byte_size(KeyData) div 8, KEK, {A, KeyData}).

wrap1([], _N, _KEK, {A, R}) -> <<A:64, R/binary>>;
wrap1([J | T], N, KEK, {A, R}) ->
Expand All @@ -33,20 +78,34 @@ wrap2([I | T], JxN, KEK, {A, R}) ->
<<A:64, Ri/binary>>, [{encrypt, true}]),
wrap2(T, JxN, KEK, {B bxor (JxN + I), <<S/binary, Ro/binary, E/binary>>}).

-doc """
unwrap `Ciphertext` with `KEK` and check `KeyData` integrity with `IV`
`Ciphertext` is a binardf of at least 24 bytes, `byte_size(Ciphertext)`
must be divisible by 8.
`KEK` is a 128 bit or 192 bit or 256 bit AES key (binary).
`IV` is a 8 byte binary.
the resulting `KeyData` 8 smaller than `Ciphertext`
Will raise an exception of class `error` wht reason `iv_mismatch` if the
integrity check fails.
%%% https://datatracker.ietf.org/doc/html/rfc3394.txt#section-2.2.2
%%% and
%%% https://datatracker.ietf.org/doc/html/rfc3394.txt#section-2.2.3
see: https://datatracker.ietf.org/doc/html/rfc3394.txt#section-2.2.2 and
https://datatracker.ietf.org/doc/html/rfc3394.txt#section-2.2.3
""".
-spec unwrap(Ciphertext :: binary(), KEK :: binary(), IV :: binary()) ->
binary().
KeyData :: binary().
unwrap(<<A:64, _/binary>> = Ciphertext, KEK, IV) when
(byte_size(Ciphertext) rem 8) == 0,
(byte_size(Ciphertext) rem 8) == 0, byte_size(Ciphertext) >= 24,
is_binary(IV), byte_size(IV) == 8, is_binary(KEK),
((byte_size(KEK) == 16) orelse (byte_size(KEK) == 24)
orelse (byte_size(KEK) == 32)) ->
N = (byte_size(Ciphertext) div 8) - 1,
case unwrap1([5, 4, 3, 2, 1, 0], N, KEK, {A, Ciphertext}) of
<<IV:(byte_size(IV))/binary, Plaintext/binary>> -> Plaintext;
<<IV:(byte_size(IV))/binary, KeyData/binary>> -> KeyData;
_ -> error(iv_mismatch) end.

unwrap1([], _N, _KEK, {A, <<_:8/binary, R/binary>>}) -> <<A:64, R/binary>>;
Expand Down

0 comments on commit aa6bbc9

Please sign in to comment.