From fcc89ded7f5cb5f81533883c30e7daa89195970d Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Thu, 28 Feb 2019 19:59:30 +0100 Subject: crypto: Remove condition of block size Unnecessary, because the underlying crypto libraries handles this case. Also: - Relax the condition of binary Key and IV -Fix bug for empty data on historic cryptolibs because tests fails for empty data on at least aes_cfb8 on OpenSSL 0.9.8h. It does not fail on OpenSSL 0.9.8zh. --- lib/crypto/src/crypto.erl | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'lib/crypto/src') diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl index 97a4a7a3f0..8d6d24210a 100644 --- a/lib/crypto/src/crypto.erl +++ b/lib/crypto/src/crypto.erl @@ -2252,15 +2252,15 @@ check_otp_test_engine(LibDir) -> | block_cipher_with_iv() | block_cipher_without_iv() , Key :: iodata(), - IV :: binary(), + IV :: iodata(), EncryptFlag :: boolean() | undefined, State :: crypto_state() . -crypto_init(Cipher, Key, IV, EncryptFlag) when is_atom(Cipher), - is_binary(Key), - is_binary(IV), - is_atom(EncryptFlag) -> - case ng_crypto_init_nif(alias(Cipher), Key, IV, EncryptFlag) of +crypto_init(Cipher, Key, IV, EncryptFlag) -> + case ng_crypto_init_nif(alias(Cipher), + iolist_to_binary(Key), + iolist_to_binary(IV), + EncryptFlag) of {error,Error} -> {error,Error}; undefined -> % For compatibility function crypto_stream_init/3 @@ -2284,8 +2284,13 @@ crypto_init(Cipher, Key, IV, EncryptFlag) when is_atom(Cipher), when State :: crypto_state(), Data :: iodata(), Result :: binary() | {crypto_state(),binary()}. -crypto_update(State, Data) -> - mk_ret(ng_crypto_update_nif(State, Data)). +crypto_update(State, Data0) -> + case iolist_to_binary(Data0) of + <<>> -> + <<>>; % Known to fail on OpenSSL 0.9.8h + Data -> + mk_ret(ng_crypto_update_nif(State, Data)) + end. %%%---------------------------------------------------------------- %%% -- cgit v1.2.3 From 26754483d39dab9ab09f69fcecb89ab1fb5135bd Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Fri, 22 Feb 2019 19:06:34 +0100 Subject: crypto: Implement crypto one-shot Also: Compatibility functions for aes_ctr in historic crypto libs --- lib/crypto/src/crypto.erl | 106 +++++++++------------------------------------- 1 file changed, 21 insertions(+), 85 deletions(-) (limited to 'lib/crypto/src') diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl index 8d6d24210a..96213fa6e6 100644 --- a/lib/crypto/src/crypto.erl +++ b/lib/crypto/src/crypto.erl @@ -51,13 +51,13 @@ %% Experiment -export([crypto_init/4, - crypto_update/2, crypto_update/3, + crypto_update/2, + crypto_one_shot/5, + %% Emulates old api: crypto_stream_init/2, crypto_stream_init/3, crypto_stream_encrypt/2, - crypto_stream_decrypt/2, - crypto_block_encrypt/3, crypto_block_encrypt/4, - crypto_block_decrypt/3, crypto_block_decrypt/4 + crypto_stream_decrypt/2 ]). @@ -556,11 +556,6 @@ cipher_info(Type) -> block_encrypt(Type, Key, Ivec, Data) -> do_block_encrypt(alias(Type), Key, Ivec, Data). -do_block_encrypt(Type, Key0, Ivec, Data) when Type =:= des_ede3_cbc; - Type =:= des_ede3_cfb -> - Key = check_des3_key(Key0), - block_crypt_nif(Type, Key, Ivec, Data, true); - do_block_encrypt(Type, Key, Ivec, PlainText) when Type =:= aes_ige256 -> notsup_to_error(aes_ige_crypt_nif(Key, Ivec, PlainText, true)); @@ -577,14 +572,13 @@ do_block_encrypt(Type, Key, Ivec, Data) when Type =:= aes_gcm; end; do_block_encrypt(Type, Key, Ivec, PlainText) -> - block_crypt_nif(Type, Key, Ivec, PlainText, true). - + crypto_one_shot(Type, Key, Ivec, PlainText, true). -spec block_encrypt(Type::block_cipher_without_iv(), Key::key(), PlainText::iodata()) -> binary(). block_encrypt(Type, Key, PlainText) -> - block_crypt_nif(alias(Type), Key, PlainText, true). + crypto_one_shot(Type, Key, <<>>, PlainText, true). %%%---------------------------------------------------------------- %%%---------------------------------------------------------------- @@ -595,11 +589,6 @@ block_encrypt(Type, Key, PlainText) -> block_decrypt(Type, Key, Ivec, Data) -> do_block_decrypt(alias(Type), Key, Ivec, Data). -do_block_decrypt(Type, Key0, Ivec, Data) when Type =:= des_ede3_cbc; - Type =:= des_ede3_cfb -> - Key = check_des3_key(Key0), - block_crypt_nif(Type, Key, Ivec, Data, false); - do_block_decrypt(aes_ige256, Key, Ivec, Data) -> notsup_to_error(aes_ige_crypt_nif(Key, Ivec, Data, false)); @@ -609,14 +598,13 @@ do_block_decrypt(Type, Key, Ivec, {AAD, Data, Tag}) when Type =:= aes_gcm; aead_decrypt(Type, Key, Ivec, AAD, Data, Tag); do_block_decrypt(Type, Key, Ivec, Data) -> - block_crypt_nif(Type, Key, Ivec, Data, false). - + crypto_one_shot(Type, Key, Ivec, Data, false). -spec block_decrypt(Type::block_cipher_without_iv(), Key::key(), Data::iodata()) -> binary(). block_decrypt(Type, Key, Data) -> - block_crypt_nif(alias(Type), Key, Data, false). + crypto_one_shot(Type, Key, <<>>, Data, false). %%%---------------------------------------------------------------- -spec next_iv(Type:: cbc_cipher(), Data) -> NextIVec when % Type :: cbc_cipher(), %des_cbc | des3_cbc | aes_cbc | aes_ige, @@ -1785,19 +1773,6 @@ poly1305_nif(_Key, _Data) -> ?nif_stub. cipher_info_nif(_Type) -> ?nif_stub. -block_crypt_nif(_Type, _Key, _Ivec, _Text, _IsEncrypt) -> ?nif_stub. -block_crypt_nif(_Type, _Key, _Text, _IsEncrypt) -> ?nif_stub. - -check_des3_key(Key) -> - case lists:map(fun erlang:iolist_to_binary/1, Key) of - ValidKey = [B1, B2, B3] when byte_size(B1) =:= 8, - byte_size(B2) =:= 8, - byte_size(B3) =:= 8 -> - ValidKey; - _ -> - error(badarg) - end. - %% %% AES - in Galois/Counter Mode (GCM) %% @@ -2289,67 +2264,29 @@ crypto_update(State, Data0) -> <<>> -> <<>>; % Known to fail on OpenSSL 0.9.8h Data -> - mk_ret(ng_crypto_update_nif(State, Data)) + ng_crypto_update_nif(State, Data) end. -%%%---------------------------------------------------------------- -%%% -%%% Encrypt/decrypt a sequence of bytes but change the IV first. -%%% Not applicable for all modes. -%%% - --spec crypto_update(State, Data, IV) -> {ok,Result} | {error,term()} - when State :: crypto_state(), - Data :: iodata(), - IV :: binary(), - Result :: binary() | {crypto_state(),binary()}. -crypto_update(State, Data, IV) -> - mk_ret(ng_crypto_update_nif(State, Data, IV)). - -%%%---------------------------------------------------------------- -%%% Helpers -mk_ret(R) -> mk_ret(R, []). - -mk_ret({error,Error}, _) -> - {error,Error}; -mk_ret(Bin, Acc) when is_binary(Bin) -> - {ok, iolist_to_binary(lists:reverse([Bin|Acc]))}; -mk_ret({State1,Bin}, Acc) when is_tuple(State1), - size(State1) == 4, - is_binary(Bin) -> - %% compatibility with old cryptolibs < 1.0.1 - {ok, {State1, iolist_to_binary(lists:reverse([Bin|Acc]))}}. - %%%---------------------------------------------------------------- %%% NIFs + ng_crypto_init_nif(_Cipher, _Key, _IVec, _EncryptFlg) -> ?nif_stub. + +%% _Data MUST be binary() ng_crypto_update_nif(_State, _Data) -> ?nif_stub. -ng_crypto_update_nif(_State, _Data, _IV) -> ?nif_stub. + +%% _Data MUST be binary() +ng_crypto_one_shot_nif(_Cipher, _Key, _IVec, _Data, _EncryptFlg) -> ?nif_stub. %%%================================================================ %%% Compatibility functions to be called by "old" api functions. -%%%-------------------------------- -%%%---- block encrypt/decrypt -crypto_block_encrypt(Cipher, Key, Data) -> crypto_block_encrypt(Cipher, Key, <<>>, Data). -crypto_block_decrypt(Cipher, Key, Data) -> crypto_block_decrypt(Cipher, Key, <<>>, Data). - -crypto_block_encrypt(Cipher, Key, Ivec, Data) -> crypto_block(Cipher, Key, Ivec, Data, true). -crypto_block_decrypt(Cipher, Key, Ivec, Data) -> crypto_block(Cipher, Key, Ivec, Data, false). - -%% AEAD: use old funcs - -%%%---- helper -crypto_block(Cipher, Key, IV, Data, EncryptFlag) -> - case crypto_init(Cipher, iolist_to_binary(Key), iolist_to_binary(IV), EncryptFlag) of - {ok, Ref} -> - case crypto_update(Ref, Data) of - {ok, {_,Bin}} when is_binary(Bin) -> Bin; - {ok, Bin} when is_binary(Bin) -> Bin; - {error,_} -> error(badarg) - end; - - {error,_} -> error(badarg) +crypto_one_shot(Cipher, Key, IV, Data0, EncryptFlag) -> + case iolist_to_binary(Data0) of + <<>> -> + <<>>; % Known to fail on OpenSSL 0.9.8h + Data -> + ng_crypto_one_shot_nif(Cipher, iolist_to_binary(Key), iolist_to_binary(IV), Data, EncryptFlag) end. %%%-------------------------------- @@ -2391,7 +2328,6 @@ crypto_stream_emulate({Cipher,State}, Data, _) -> {error,_} -> error(badarg) end. - %%%================================================================ prepend_cipher_aliases(L) -> -- cgit v1.2.3 From cd08c844693fbb26d545f9cd981bfa9ae2d08042 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Thu, 7 Mar 2019 12:19:18 +0100 Subject: crypto: Use/implement new funcs for stream-api --- lib/crypto/src/crypto.erl | 278 ++++++++++++++++++++-------------------------- 1 file changed, 120 insertions(+), 158 deletions(-) (limited to 'lib/crypto/src') diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl index 96213fa6e6..608610f85e 100644 --- a/lib/crypto/src/crypto.erl +++ b/lib/crypto/src/crypto.erl @@ -50,14 +50,9 @@ -export([rand_seed/1]). %% Experiment --export([crypto_init/4, +-export([crypto_init/4, crypto_init/3, crypto_init/2, crypto_update/2, - crypto_one_shot/5, - - %% Emulates old api: - crypto_stream_init/2, crypto_stream_init/3, - crypto_stream_encrypt/2, - crypto_stream_decrypt/2 + crypto_one_shot/5 ]). @@ -633,9 +628,11 @@ next_iv(des_cfb, Data, IVec) -> next_iv(Type, Data, _Ivec) -> next_iv(Type, Data). -%%%---- Stream ciphers +%%%-------- Stream ciphers API --opaque stream_state() :: {stream_cipher(), reference()}. +-opaque stream_state() :: {stream_cipher(), + crypto_state() | {crypto_state(),flg_undefined} + }. -type stream_cipher() :: stream_cipher_iv() | stream_cipher_no_iv() . -type stream_cipher_no_iv() :: rc4 . @@ -645,47 +642,67 @@ next_iv(Type, Data, _Ivec) -> | aes_256_ctr | chacha20 . --spec stream_init(Type, Key, IVec) -> State when Type :: stream_cipher_iv(), - Key :: iodata(), - IVec :: binary(), - State :: stream_state() . -stream_init(aes_ctr, Key, Ivec) -> - {aes_ctr, aes_ctr_stream_init(Key, Ivec)}; -stream_init(aes_128_ctr, Key, Ivec) -> - {aes_ctr, aes_ctr_stream_init(Key, Ivec)}; -stream_init(aes_192_ctr, Key, Ivec) -> - {aes_ctr, aes_ctr_stream_init(Key, Ivec)}; -stream_init(aes_256_ctr, Key, Ivec) -> - {aes_ctr, aes_ctr_stream_init(Key, Ivec)}; -stream_init(chacha20, Key, Ivec) -> - {chacha20, chacha20_stream_init(Key,Ivec)}. - --spec stream_init(Type, Key) -> State when Type :: stream_cipher_no_iv(), - Key :: iodata(), - State :: stream_state() . -stream_init(rc4, Key) -> - {rc4, notsup_to_error(rc4_set_key(Key))}. - --spec stream_encrypt(State, PlainText) -> {NewState, CipherText} +%%%---- stream_init +-spec stream_init(Type, Key, IVec) -> State | no_return() + when Type :: stream_cipher_iv(), + Key :: iodata(), + IVec :: binary(), + State :: stream_state() . +stream_init(Type, Key, IVec) when is_binary(IVec) -> + case crypto_init(Type, Key, IVec) of + {ok,Ref} -> + {Type, {Ref,flg_undefined}}; + {error,_} -> + error(badarg) + end. + + +-spec stream_init(Type, Key) -> State | no_return() + when Type :: stream_cipher_no_iv(), + Key :: iodata(), + State :: stream_state() . +stream_init(rc4 = Type, Key) -> + case crypto_init(Type, Key, undefined) of + {ok,Ref} -> + {Type, {Ref,flg_undefined}}; + {error,_} -> + error(badarg) + end. + +%%%---- stream_encrypt +-spec stream_encrypt(State, PlainText) -> {NewState, CipherText} | no_return() when State :: stream_state(), PlainText :: iodata(), NewState :: stream_state(), CipherText :: iodata() . -stream_encrypt(State, Data0) -> - Data = iolist_to_binary(Data0), - MaxByts = max_bytes(), - stream_crypt(fun do_stream_encrypt/2, State, Data, erlang:byte_size(Data), MaxByts, []). +stream_encrypt(State, Data) -> + crypto_stream_emulate(State, Data, true). --spec stream_decrypt(State, CipherText) -> {NewState, PlainText} +%%%---- stream_decrypt +-spec stream_decrypt(State, CipherText) -> {NewState, PlainText} | no_return() when State :: stream_state(), CipherText :: iodata(), NewState :: stream_state(), PlainText :: iodata() . -stream_decrypt(State, Data0) -> - Data = iolist_to_binary(Data0), - MaxByts = max_bytes(), - stream_crypt(fun do_stream_decrypt/2, State, Data, erlang:byte_size(Data), MaxByts, []). +stream_decrypt(State, Data) -> + crypto_stream_emulate(State, Data, false). + +%%%-------- helpers +crypto_stream_emulate({Cipher,{Ref,flg_undefined}}, Data, EncryptFlag) when is_reference(Ref) -> + case crypto_init(Ref, EncryptFlag) of + {error,_} -> + error(badarg); + MaybeNewRef when is_reference(MaybeNewRef) -> + crypto_stream_emulate({Cipher,MaybeNewRef}, Data, EncryptFlag) + end; +crypto_stream_emulate({Cipher,Ref}, Data, _) when is_reference(Ref) -> + case crypto_update(Ref, Data) of + {error,_} -> + error(badarg); + Bin when is_binary(Bin) -> + {{Cipher,Ref},Bin} + end. %%%================================================================ %%% @@ -1789,59 +1806,7 @@ aead_decrypt(_Type, _Key, _Ivec, _AAD, _In, _Tag) -> ?nif_stub. aes_ige_crypt_nif(_Key, _IVec, _Data, _IsEncrypt) -> ?nif_stub. - -%% Stream ciphers -------------------------------------------------------------------- - -stream_crypt(Fun, State, Data, Size, MaxByts, []) when Size =< MaxByts -> - Fun(State, Data); -stream_crypt(Fun, State0, Data, Size, MaxByts, Acc) when Size =< MaxByts -> - {State, Cipher} = Fun(State0, Data), - {State, list_to_binary(lists:reverse([Cipher | Acc]))}; -stream_crypt(Fun, State0, Data, _, MaxByts, Acc) -> - <> = Data, - {State, CipherText} = Fun(State0, Increment), - stream_crypt(Fun, State, Rest, erlang:byte_size(Rest), MaxByts, [CipherText | Acc]). - -do_stream_encrypt({aes_ctr, State0}, Data) -> - {State, Cipher} = aes_ctr_stream_encrypt(State0, Data), - {{aes_ctr, State}, Cipher}; -do_stream_encrypt({rc4, State0}, Data) -> - {State, Cipher} = rc4_encrypt_with_state(State0, Data), - {{rc4, State}, Cipher}; -do_stream_encrypt({chacha20, State0}, Data) -> - {State, Cipher} = chacha20_stream_encrypt(State0, Data), - {{chacha20, State}, Cipher}. - -do_stream_decrypt({aes_ctr, State0}, Data) -> - {State, Text} = aes_ctr_stream_decrypt(State0, Data), - {{aes_ctr, State}, Text}; -do_stream_decrypt({rc4, State0}, Data) -> - {State, Text} = rc4_encrypt_with_state(State0, Data), - {{rc4, State}, Text}; -do_stream_decrypt({chacha20, State0}, Data) -> - {State, Cipher} = chacha20_stream_decrypt(State0, Data), - {{chacha20, State}, Cipher}. - - -%% -%% AES - in counter mode (CTR) with state maintained for multi-call streaming -%% -aes_ctr_stream_init(_Key, _IVec) -> ?nif_stub. -aes_ctr_stream_encrypt(_State, _Data) -> ?nif_stub. -aes_ctr_stream_decrypt(_State, _Cipher) -> ?nif_stub. - -%% -%% RC4 - symmetric stream cipher -%% -rc4_set_key(_Key) -> ?nif_stub. -rc4_encrypt_with_state(_State, _Data) -> ?nif_stub. - -%% -%% CHACHA20 - stream cipher -%% -chacha20_stream_init(_Key, _IVec) -> ?nif_stub. -chacha20_stream_encrypt(_State, _Data) -> ?nif_stub. -chacha20_stream_decrypt(_State, _Data) -> ?nif_stub. +%%%================================================================ %% Secure remote password ------------------------------------------------------------------- @@ -2214,7 +2179,7 @@ check_otp_test_engine(LibDir) -> %%% -> {ok,State::ref()} | {error,Reason} --opaque crypto_state() :: reference() | {any(),any(),any(),any()}. +-opaque crypto_state() :: reference() . %%%---------------------------------------------------------------- @@ -2222,32 +2187,64 @@ check_otp_test_engine(LibDir) -> %%% Create and initialize a new state for encryption or decryption %%% --spec crypto_init(Cipher, Key, IV, EncryptFlag) -> {ok,State} | {error,term()} | undefined +-spec crypto_init(Cipher, Key, IV, EncryptFlag) -> {ok,State} | {error,term()} when Cipher :: stream_cipher() | block_cipher_with_iv() - | block_cipher_without_iv() , + | block_cipher_without_iv(), Key :: iodata(), - IV :: iodata(), - EncryptFlag :: boolean() | undefined, + IV :: iodata() | undefined, + EncryptFlag :: boolean(), State :: crypto_state() . +crypto_init(Cipher, Key, undefined, EncryptFlag) -> + crypto_init(Cipher, Key, <<>>, EncryptFlag); crypto_init(Cipher, Key, IV, EncryptFlag) -> - case ng_crypto_init_nif(alias(Cipher), + case ng_crypto_init_nif(alias(Cipher), iolist_to_binary(Key), iolist_to_binary(IV), EncryptFlag) of - {error,Error} -> - {error,Error}; - undefined -> % For compatibility function crypto_stream_init/3 - undefined; Ref when is_reference(Ref) -> {ok,Ref}; - State when is_tuple(State), - size(State)==4 -> - {ok,State} % compatibility with old cryptolibs < 1.0.1 + {error,Error} -> + {error,Error} + end. + + +-spec crypto_init(Cipher, Key, IV) -> {ok,State} | {error,term()} + when Cipher :: stream_cipher() + | block_cipher_with_iv() + | block_cipher_without_iv(), + Key :: iodata(), + IV :: iodata() | undefined, + State :: crypto_state() . +crypto_init(Cipher, Key, undefined) -> + crypto_init(Cipher, Key, <<>>); + +crypto_init(Cipher, Key, IV) when is_atom(Cipher) -> + case ng_crypto_init_nif(alias(Cipher), + iolist_to_binary(Key), + iolist_to_binary(IV), + undefined) of + Ref when is_reference(Ref) -> + {ok,Ref}; + {error,Error} -> + {error,Error} end. +-spec crypto_init(Ref, EncryptFlag) -> crypto_state() | {error,term()} + when Ref :: crypto_state(), + EncryptFlag :: boolean() . + +crypto_init(Ref, EncryptFlag) when is_reference(Ref), + is_atom(EncryptFlag) -> + case ng_crypto_init_nif(Ref, <<>>, <<>>, EncryptFlag) of + {error,Error} -> + {error,Error}; + R when is_reference(R) -> + R + end. + %%%---------------------------------------------------------------- %%% %%% Encrypt/decrypt a sequence of bytes. The sum of the sizes @@ -2255,10 +2252,10 @@ crypto_init(Cipher, Key, IV, EncryptFlag) -> %%% blocksize. %%% --spec crypto_update(State, Data) -> {ok,Result} | {error,term()} +-spec crypto_update(State, Data) -> Result | {error,term()} when State :: crypto_state(), Data :: iodata(), - Result :: binary() | {crypto_state(),binary()}. + Result :: binary() . crypto_update(State, Data0) -> case iolist_to_binary(Data0) of <<>> -> @@ -2267,19 +2264,12 @@ crypto_update(State, Data0) -> ng_crypto_update_nif(State, Data) end. -%%%---------------------------------------------------------------- -%%% NIFs - -ng_crypto_init_nif(_Cipher, _Key, _IVec, _EncryptFlg) -> ?nif_stub. - -%% _Data MUST be binary() -ng_crypto_update_nif(_State, _Data) -> ?nif_stub. - -%% _Data MUST be binary() -ng_crypto_one_shot_nif(_Cipher, _Key, _IVec, _Data, _EncryptFlg) -> ?nif_stub. -%%%================================================================ -%%% Compatibility functions to be called by "old" api functions. +%%%---------------------------------------------------------------- +%%% +%%% Encrypt/decrypt one set bytes. +%%% The size must be an integer multiple of the crypto's blocksize. +%%% crypto_one_shot(Cipher, Key, IV, Data0, EncryptFlag) -> case iolist_to_binary(Data0) of @@ -2289,51 +2279,23 @@ crypto_one_shot(Cipher, Key, IV, Data0, EncryptFlag) -> ng_crypto_one_shot_nif(Cipher, iolist_to_binary(Key), iolist_to_binary(IV), Data, EncryptFlag) end. -%%%-------------------------------- -%%%---- stream init, encrypt/decrypt - -crypto_stream_init(Cipher, Key) -> - crypto_stream_init(Cipher, Key, <<>>). - -crypto_stream_init(Cipher, Key0, IV0) -> - Key = iolist_to_binary(Key0), - IV = iolist_to_binary(IV0), - %% First check the argumensts: - case crypto_init(Cipher, Key, IV, undefined) of - undefined -> - {Cipher, {Key, IV}}; - {error,_} -> - {error,badarg} - end. - -crypto_stream_encrypt(State, PlainText) -> - crypto_stream_emulate(State, PlainText, true). - -crypto_stream_decrypt(State, CryptoText) -> - crypto_stream_emulate(State, CryptoText, false). +%%%---------------------------------------------------------------- +%%% NIFs +ng_crypto_init_nif(_Cipher, _Key, _IVec, _EncryptFlg) -> ?nif_stub. -%%%---- helper -crypto_stream_emulate({Cipher,{Key,IV}}, Data, EncryptFlag) -> - case crypto_init(Cipher, Key, IV, EncryptFlag) of - {ok,State} -> - crypto_stream_emulate({Cipher,State}, Data, EncryptFlag); - {error,_} -> - error(badarg) - end; -crypto_stream_emulate({Cipher,State}, Data, _) -> - case crypto_update(State, Data) of - {ok, {State1,Bin}} when is_binary(Bin) -> {{Cipher,State1},Bin}; - {ok,Bin} when is_binary(Bin) -> {{Cipher,State},Bin}; - {error,_} -> error(badarg) - end. +%% _Data MUST be binary() +ng_crypto_update_nif(_State, _Data) -> ?nif_stub. -%%%================================================================ +%% _Data MUST be binary() +ng_crypto_one_shot_nif(_Cipher, _Key, _IVec, _Data, _EncryptFlg) -> ?nif_stub. +%%%---------------------------------------------------------------- +%%% Cipher aliases +%%% prepend_cipher_aliases(L) -> [des3_cbc, des_ede3, des_ede3_cbf, des3_cbf, des3_cfb, aes_cbc128, aes_cbc256 | L]. - %%%---- des_ede3_cbc alias(des3_cbc) -> des_ede3_cbc; alias(des_ede3) -> des_ede3_cbc; -- cgit v1.2.3 From 4d436bfc6dacd45b501b92845f8cf3ef5c1308d9 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Thu, 7 Mar 2019 14:39:21 +0100 Subject: crypto: Cleaning of comments + spec fixing --- lib/crypto/src/crypto.erl | 101 ++++++++++++++++++++++++++++------------------ 1 file changed, 61 insertions(+), 40 deletions(-) (limited to 'lib/crypto/src') diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl index 608610f85e..68cc1c1f65 100644 --- a/lib/crypto/src/crypto.erl +++ b/lib/crypto/src/crypto.erl @@ -40,16 +40,22 @@ -export([rand_plugin_uniform/2]). -export([rand_cache_plugin_next/1]). -export([rand_uniform/2]). --export([block_encrypt/3, block_decrypt/3, block_encrypt/4, block_decrypt/4]). -export([next_iv/2, next_iv/3]). --export([stream_init/2, stream_init/3, stream_encrypt/2, stream_decrypt/2]). -export([public_encrypt/4, private_decrypt/4]). -export([private_encrypt/4, public_decrypt/4]). -export([privkey_to_pubkey/2]). -export([ec_curve/1, ec_curves/0]). -export([rand_seed/1]). -%% Experiment +%% Old interface. Now implemented with the New interface +-export([stream_init/2, stream_init/3, + stream_encrypt/2, + stream_decrypt/2, + block_encrypt/3, block_encrypt/4, + block_decrypt/3, block_decrypt/4 + ]). + +%% New interface -export([crypto_init/4, crypto_init/3, crypto_init/2, crypto_update/2, crypto_one_shot/5 @@ -528,7 +534,7 @@ poly1305(Key, Data) -> %%%================================================================ %%% -%%% Encrypt/decrypt +%%% Encrypt/decrypt, The "Old API" %%% %%%================================================================ @@ -601,33 +607,6 @@ do_block_decrypt(Type, Key, Ivec, Data) -> block_decrypt(Type, Key, Data) -> crypto_one_shot(Type, Key, <<>>, Data, false). -%%%---------------------------------------------------------------- --spec next_iv(Type:: cbc_cipher(), Data) -> NextIVec when % Type :: cbc_cipher(), %des_cbc | des3_cbc | aes_cbc | aes_ige, - Data :: iodata(), - NextIVec :: binary(). -next_iv(Type, Data) when is_binary(Data) -> - IVecSize = case Type of - des_cbc -> 8; - des3_cbc -> 8; - aes_cbc -> 16; - aes_ige -> 32 - end, - {_, IVec} = split_binary(Data, size(Data) - IVecSize), - IVec; -next_iv(Type, Data) when is_list(Data) -> - next_iv(Type, list_to_binary(Data)). - --spec next_iv(des_cfb, Data, IVec) -> NextIVec when Data :: iodata(), - IVec :: binary(), - NextIVec :: binary(). - -next_iv(des_cfb, Data, IVec) -> - IVecAndData = list_to_binary([IVec, Data]), - {_, NewIVec} = split_binary(IVecAndData, byte_size(IVecAndData) - 8), - NewIVec; -next_iv(Type, Data, _Ivec) -> - next_iv(Type, Data). - %%%-------- Stream ciphers API -opaque stream_state() :: {stream_cipher(), @@ -704,6 +683,33 @@ crypto_stream_emulate({Cipher,Ref}, Data, _) when is_reference(Ref) -> {{Cipher,Ref},Bin} end. +%%%---------------------------------------------------------------- +-spec next_iv(Type:: cbc_cipher(), Data) -> NextIVec when % Type :: cbc_cipher(), %des_cbc | des3_cbc | aes_cbc | aes_ige, + Data :: iodata(), + NextIVec :: binary(). +next_iv(Type, Data) when is_binary(Data) -> + IVecSize = case Type of + des_cbc -> 8; + des3_cbc -> 8; + aes_cbc -> 16; + aes_ige -> 32 + end, + {_, IVec} = split_binary(Data, size(Data) - IVecSize), + IVec; +next_iv(Type, Data) when is_list(Data) -> + next_iv(Type, list_to_binary(Data)). + +-spec next_iv(des_cfb, Data, IVec) -> NextIVec when Data :: iodata(), + IVec :: binary(), + NextIVec :: binary(). + +next_iv(des_cfb, Data, IVec) -> + IVecAndData = list_to_binary([IVec, Data]), + {_, NewIVec} = split_binary(IVecAndData, byte_size(IVecAndData) - 8), + NewIVec; +next_iv(Type, Data, _Ivec) -> + next_iv(Type, Data). + %%%================================================================ %%% %%% RAND - pseudo random numbers using RN_ and BN_ functions in crypto lib @@ -2172,12 +2178,11 @@ check_otp_test_engine(LibDir) -> end. -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%================================================================ %%% -%%% Experimental NG +%%% Encrypt/decrypt, The "New API" %%% - -%%% -> {ok,State::ref()} | {error,Reason} +%%%================================================================ -opaque crypto_state() :: reference() . @@ -2233,11 +2238,11 @@ crypto_init(Cipher, Key, IV) when is_atom(Cipher) -> -spec crypto_init(Ref, EncryptFlag) -> crypto_state() | {error,term()} - when Ref :: crypto_state(), - EncryptFlag :: boolean() . + when Ref :: crypto_state(), + EncryptFlag :: boolean() . crypto_init(Ref, EncryptFlag) when is_reference(Ref), - is_atom(EncryptFlag) -> + is_atom(EncryptFlag) -> case ng_crypto_init_nif(Ref, <<>>, <<>>, EncryptFlag) of {error,Error} -> {error,Error}; @@ -2271,6 +2276,18 @@ crypto_update(State, Data0) -> %%% The size must be an integer multiple of the crypto's blocksize. %%% +-spec crypto_one_shot(Cipher, Key, IV, Data, EncryptFlag) -> Result | {error,term()} + when Cipher :: stream_cipher() + | block_cipher_with_iv() + | block_cipher_without_iv(), + Key :: iodata(), + IV :: iodata() | undefined, + Data :: iodata(), + EncryptFlag :: boolean(), + Result :: binary() . +crypto_one_shot(Cipher, Key, undefined, Data, EncryptFlag) -> + crypto_one_shot(Cipher, Key, <<>>, Data, EncryptFlag); + crypto_one_shot(Cipher, Key, IV, Data0, EncryptFlag) -> case iolist_to_binary(Data0) of <<>> -> @@ -2282,12 +2299,16 @@ crypto_one_shot(Cipher, Key, IV, Data0, EncryptFlag) -> %%%---------------------------------------------------------------- %%% NIFs +-spec ng_crypto_init_nif(atom(), binary(), binary(), boolean()|undefined ) -> crypto_state() | {error,term()} + ; (crypto_state(), <<>>, <<>>, boolean()) -> crypto_state() | {error,term()} . ng_crypto_init_nif(_Cipher, _Key, _IVec, _EncryptFlg) -> ?nif_stub. -%% _Data MUST be binary() + +-spec ng_crypto_update_nif(crypto_state(), binary()) -> binary() | {error,term()} . ng_crypto_update_nif(_State, _Data) -> ?nif_stub. -%% _Data MUST be binary() + +-spec ng_crypto_one_shot_nif(atom(), binary(), binary(), binary(), boolean() ) -> binary() | {error,term()}. ng_crypto_one_shot_nif(_Cipher, _Key, _IVec, _Data, _EncryptFlg) -> ?nif_stub. %%%---------------------------------------------------------------- -- cgit v1.2.3 From 3a74629664f3d7f6ae7483954130dca7f9794c10 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Thu, 7 Mar 2019 14:41:21 +0100 Subject: crypto: Relocate the new api code inside the crypto.erl file --- lib/crypto/src/crypto.erl | 303 +++++++++++++++++++++++----------------------- 1 file changed, 152 insertions(+), 151 deletions(-) (limited to 'lib/crypto/src') diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl index 68cc1c1f65..b4e2582fc6 100644 --- a/lib/crypto/src/crypto.erl +++ b/lib/crypto/src/crypto.erl @@ -710,6 +710,158 @@ next_iv(des_cfb, Data, IVec) -> next_iv(Type, Data, _Ivec) -> next_iv(Type, Data). +%%%================================================================ +%%% +%%% Encrypt/decrypt, The "New API" +%%% +%%%================================================================ + +-opaque crypto_state() :: reference() . + + +%%%---------------------------------------------------------------- +%%% +%%% Create and initialize a new state for encryption or decryption +%%% + +-spec crypto_init(Cipher, Key, IV, EncryptFlag) -> {ok,State} | {error,term()} + when Cipher :: stream_cipher() + | block_cipher_with_iv() + | block_cipher_without_iv(), + Key :: iodata(), + IV :: iodata() | undefined, + EncryptFlag :: boolean(), + State :: crypto_state() . +crypto_init(Cipher, Key, undefined, EncryptFlag) -> + crypto_init(Cipher, Key, <<>>, EncryptFlag); + +crypto_init(Cipher, Key, IV, EncryptFlag) -> + case ng_crypto_init_nif(alias(Cipher), + iolist_to_binary(Key), + iolist_to_binary(IV), + EncryptFlag) of + Ref when is_reference(Ref) -> + {ok,Ref}; + {error,Error} -> + {error,Error} + end. + + +-spec crypto_init(Cipher, Key, IV) -> {ok,State} | {error,term()} + when Cipher :: stream_cipher() + | block_cipher_with_iv() + | block_cipher_without_iv(), + Key :: iodata(), + IV :: iodata() | undefined, + State :: crypto_state() . +crypto_init(Cipher, Key, undefined) -> + crypto_init(Cipher, Key, <<>>); + +crypto_init(Cipher, Key, IV) when is_atom(Cipher) -> + case ng_crypto_init_nif(alias(Cipher), + iolist_to_binary(Key), + iolist_to_binary(IV), + undefined) of + Ref when is_reference(Ref) -> + {ok,Ref}; + {error,Error} -> + {error,Error} + end. + + +-spec crypto_init(Ref, EncryptFlag) -> crypto_state() | {error,term()} + when Ref :: crypto_state(), + EncryptFlag :: boolean() . + +crypto_init(Ref, EncryptFlag) when is_reference(Ref), + is_atom(EncryptFlag) -> + case ng_crypto_init_nif(Ref, <<>>, <<>>, EncryptFlag) of + {error,Error} -> + {error,Error}; + R when is_reference(R) -> + R + end. + +%%%---------------------------------------------------------------- +%%% +%%% Encrypt/decrypt a sequence of bytes. The sum of the sizes +%%% of all blocks must be an integer multiple of the crypto's +%%% blocksize. +%%% + +-spec crypto_update(State, Data) -> Result | {error,term()} + when State :: crypto_state(), + Data :: iodata(), + Result :: binary() . +crypto_update(State, Data0) -> + case iolist_to_binary(Data0) of + <<>> -> + <<>>; % Known to fail on OpenSSL 0.9.8h + Data -> + ng_crypto_update_nif(State, Data) + end. + + +%%%---------------------------------------------------------------- +%%% +%%% Encrypt/decrypt one set bytes. +%%% The size must be an integer multiple of the crypto's blocksize. +%%% + +-spec crypto_one_shot(Cipher, Key, IV, Data, EncryptFlag) -> Result | {error,term()} + when Cipher :: stream_cipher() + | block_cipher_with_iv() + | block_cipher_without_iv(), + Key :: iodata(), + IV :: iodata() | undefined, + Data :: iodata(), + EncryptFlag :: boolean(), + Result :: binary() . +crypto_one_shot(Cipher, Key, undefined, Data, EncryptFlag) -> + crypto_one_shot(Cipher, Key, <<>>, Data, EncryptFlag); + +crypto_one_shot(Cipher, Key, IV, Data0, EncryptFlag) -> + case iolist_to_binary(Data0) of + <<>> -> + <<>>; % Known to fail on OpenSSL 0.9.8h + Data -> + ng_crypto_one_shot_nif(Cipher, iolist_to_binary(Key), iolist_to_binary(IV), Data, EncryptFlag) + end. + +%%%---------------------------------------------------------------- +%%% NIFs + +-spec ng_crypto_init_nif(atom(), binary(), binary(), boolean()|undefined ) -> crypto_state() | {error,term()} + ; (crypto_state(), <<>>, <<>>, boolean()) -> crypto_state() | {error,term()} . +ng_crypto_init_nif(_Cipher, _Key, _IVec, _EncryptFlg) -> ?nif_stub. + + +-spec ng_crypto_update_nif(crypto_state(), binary()) -> binary() | {error,term()} . +ng_crypto_update_nif(_State, _Data) -> ?nif_stub. + + +-spec ng_crypto_one_shot_nif(atom(), binary(), binary(), binary(), boolean() ) -> binary() | {error,term()}. +ng_crypto_one_shot_nif(_Cipher, _Key, _IVec, _Data, _EncryptFlg) -> ?nif_stub. + +%%%---------------------------------------------------------------- +%%% Cipher aliases +%%% +prepend_cipher_aliases(L) -> + [des3_cbc, des_ede3, des_ede3_cbf, des3_cbf, des3_cfb, aes_cbc128, aes_cbc256 | L]. + +%%%---- des_ede3_cbc +alias(des3_cbc) -> des_ede3_cbc; +alias(des_ede3) -> des_ede3_cbc; +%%%---- des_ede3_cfb +alias(des_ede3_cbf) -> des_ede3_cfb; +alias(des3_cbf) -> des_ede3_cfb; +alias(des3_cfb) -> des_ede3_cfb; +%%%---- aes_*_cbc +alias(aes_cbc128) -> aes_128_cbc; +alias(aes_cbc256) -> aes_256_cbc; + +alias(Alg) -> Alg. + %%%================================================================ %%% %%% RAND - pseudo random numbers using RN_ and BN_ functions in crypto lib @@ -2178,154 +2330,3 @@ check_otp_test_engine(LibDir) -> end. -%%%================================================================ -%%% -%%% Encrypt/decrypt, The "New API" -%%% -%%%================================================================ - --opaque crypto_state() :: reference() . - - -%%%---------------------------------------------------------------- -%%% -%%% Create and initialize a new state for encryption or decryption -%%% - --spec crypto_init(Cipher, Key, IV, EncryptFlag) -> {ok,State} | {error,term()} - when Cipher :: stream_cipher() - | block_cipher_with_iv() - | block_cipher_without_iv(), - Key :: iodata(), - IV :: iodata() | undefined, - EncryptFlag :: boolean(), - State :: crypto_state() . -crypto_init(Cipher, Key, undefined, EncryptFlag) -> - crypto_init(Cipher, Key, <<>>, EncryptFlag); - -crypto_init(Cipher, Key, IV, EncryptFlag) -> - case ng_crypto_init_nif(alias(Cipher), - iolist_to_binary(Key), - iolist_to_binary(IV), - EncryptFlag) of - Ref when is_reference(Ref) -> - {ok,Ref}; - {error,Error} -> - {error,Error} - end. - - --spec crypto_init(Cipher, Key, IV) -> {ok,State} | {error,term()} - when Cipher :: stream_cipher() - | block_cipher_with_iv() - | block_cipher_without_iv(), - Key :: iodata(), - IV :: iodata() | undefined, - State :: crypto_state() . -crypto_init(Cipher, Key, undefined) -> - crypto_init(Cipher, Key, <<>>); - -crypto_init(Cipher, Key, IV) when is_atom(Cipher) -> - case ng_crypto_init_nif(alias(Cipher), - iolist_to_binary(Key), - iolist_to_binary(IV), - undefined) of - Ref when is_reference(Ref) -> - {ok,Ref}; - {error,Error} -> - {error,Error} - end. - - --spec crypto_init(Ref, EncryptFlag) -> crypto_state() | {error,term()} - when Ref :: crypto_state(), - EncryptFlag :: boolean() . - -crypto_init(Ref, EncryptFlag) when is_reference(Ref), - is_atom(EncryptFlag) -> - case ng_crypto_init_nif(Ref, <<>>, <<>>, EncryptFlag) of - {error,Error} -> - {error,Error}; - R when is_reference(R) -> - R - end. - -%%%---------------------------------------------------------------- -%%% -%%% Encrypt/decrypt a sequence of bytes. The sum of the sizes -%%% of all blocks must be an integer multiple of the crypto's -%%% blocksize. -%%% - --spec crypto_update(State, Data) -> Result | {error,term()} - when State :: crypto_state(), - Data :: iodata(), - Result :: binary() . -crypto_update(State, Data0) -> - case iolist_to_binary(Data0) of - <<>> -> - <<>>; % Known to fail on OpenSSL 0.9.8h - Data -> - ng_crypto_update_nif(State, Data) - end. - - -%%%---------------------------------------------------------------- -%%% -%%% Encrypt/decrypt one set bytes. -%%% The size must be an integer multiple of the crypto's blocksize. -%%% - --spec crypto_one_shot(Cipher, Key, IV, Data, EncryptFlag) -> Result | {error,term()} - when Cipher :: stream_cipher() - | block_cipher_with_iv() - | block_cipher_without_iv(), - Key :: iodata(), - IV :: iodata() | undefined, - Data :: iodata(), - EncryptFlag :: boolean(), - Result :: binary() . -crypto_one_shot(Cipher, Key, undefined, Data, EncryptFlag) -> - crypto_one_shot(Cipher, Key, <<>>, Data, EncryptFlag); - -crypto_one_shot(Cipher, Key, IV, Data0, EncryptFlag) -> - case iolist_to_binary(Data0) of - <<>> -> - <<>>; % Known to fail on OpenSSL 0.9.8h - Data -> - ng_crypto_one_shot_nif(Cipher, iolist_to_binary(Key), iolist_to_binary(IV), Data, EncryptFlag) - end. - -%%%---------------------------------------------------------------- -%%% NIFs - --spec ng_crypto_init_nif(atom(), binary(), binary(), boolean()|undefined ) -> crypto_state() | {error,term()} - ; (crypto_state(), <<>>, <<>>, boolean()) -> crypto_state() | {error,term()} . -ng_crypto_init_nif(_Cipher, _Key, _IVec, _EncryptFlg) -> ?nif_stub. - - --spec ng_crypto_update_nif(crypto_state(), binary()) -> binary() | {error,term()} . -ng_crypto_update_nif(_State, _Data) -> ?nif_stub. - - --spec ng_crypto_one_shot_nif(atom(), binary(), binary(), binary(), boolean() ) -> binary() | {error,term()}. -ng_crypto_one_shot_nif(_Cipher, _Key, _IVec, _Data, _EncryptFlg) -> ?nif_stub. - -%%%---------------------------------------------------------------- -%%% Cipher aliases -%%% -prepend_cipher_aliases(L) -> - [des3_cbc, des_ede3, des_ede3_cbf, des3_cbf, des3_cfb, aes_cbc128, aes_cbc256 | L]. - -%%%---- des_ede3_cbc -alias(des3_cbc) -> des_ede3_cbc; -alias(des_ede3) -> des_ede3_cbc; -%%%---- des_ede3_cfb -alias(des_ede3_cbf) -> des_ede3_cfb; -alias(des3_cbf) -> des_ede3_cfb; -alias(des3_cfb) -> des_ede3_cfb; -%%%---- aes_*_cbc -alias(aes_cbc128) -> aes_128_cbc; -alias(aes_cbc256) -> aes_256_cbc; - -alias(Alg) -> Alg. -- cgit v1.2.3 From 3f8f8054254cee6bf401e1e83662e05029bde750 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Fri, 8 Mar 2019 10:42:25 +0100 Subject: crypto: Exceptions as error return in api_ng --- lib/crypto/src/crypto.erl | 120 +++++++++++++++++++--------------------------- 1 file changed, 50 insertions(+), 70 deletions(-) (limited to 'lib/crypto/src') diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl index b4e2582fc6..bd04daee5e 100644 --- a/lib/crypto/src/crypto.erl +++ b/lib/crypto/src/crypto.erl @@ -538,6 +538,13 @@ poly1305(Key, Data) -> %%% %%%================================================================ +-define(COMPAT(CALL), + try CALL + catch + error:{E,_Reason} when E==notsup ; E==badarg -> + error(E) + end). + -spec cipher_info(Type) -> map() when Type :: block_cipher_with_iv() | aead_cipher() | block_cipher_without_iv(). @@ -545,7 +552,6 @@ cipher_info(Type) -> cipher_info_nif(Type). %%%---- Block ciphers - %%%---------------------------------------------------------------- -spec block_encrypt(Type::block_cipher_with_iv(), Key::key()|des3_key(), Ivec::binary(), PlainText::iodata()) -> binary(); (Type::aead_cipher(), Key::iodata(), Ivec::binary(), {AAD::binary(), PlainText::iodata()}) -> @@ -573,13 +579,13 @@ do_block_encrypt(Type, Key, Ivec, Data) when Type =:= aes_gcm; end; do_block_encrypt(Type, Key, Ivec, PlainText) -> - crypto_one_shot(Type, Key, Ivec, PlainText, true). + ?COMPAT(crypto_one_shot(Type, Key, Ivec, PlainText, true)). -spec block_encrypt(Type::block_cipher_without_iv(), Key::key(), PlainText::iodata()) -> binary(). block_encrypt(Type, Key, PlainText) -> - crypto_one_shot(Type, Key, <<>>, PlainText, true). + ?COMPAT(crypto_one_shot(Type, Key, <<>>, PlainText, true)). %%%---------------------------------------------------------------- %%%---------------------------------------------------------------- @@ -599,13 +605,13 @@ do_block_decrypt(Type, Key, Ivec, {AAD, Data, Tag}) when Type =:= aes_gcm; aead_decrypt(Type, Key, Ivec, AAD, Data, Tag); do_block_decrypt(Type, Key, Ivec, Data) -> - crypto_one_shot(Type, Key, Ivec, Data, false). + ?COMPAT(crypto_one_shot(Type, Key, Ivec, Data, false)). -spec block_decrypt(Type::block_cipher_without_iv(), Key::key(), Data::iodata()) -> binary(). block_decrypt(Type, Key, Data) -> - crypto_one_shot(Type, Key, <<>>, Data, false). + ?COMPAT(crypto_one_shot(Type, Key, <<>>, Data, false)). %%%-------- Stream ciphers API @@ -625,15 +631,11 @@ block_decrypt(Type, Key, Data) -> -spec stream_init(Type, Key, IVec) -> State | no_return() when Type :: stream_cipher_iv(), Key :: iodata(), - IVec :: binary(), + IVec ::binary(), State :: stream_state() . stream_init(Type, Key, IVec) when is_binary(IVec) -> - case crypto_init(Type, Key, IVec) of - {ok,Ref} -> - {Type, {Ref,flg_undefined}}; - {error,_} -> - error(badarg) - end. + Ref = ?COMPAT(crypto_init(Type, Key, IVec)), + {Type, {Ref,flg_undefined}}. -spec stream_init(Type, Key) -> State | no_return() @@ -641,12 +643,8 @@ stream_init(Type, Key, IVec) when is_binary(IVec) -> Key :: iodata(), State :: stream_state() . stream_init(rc4 = Type, Key) -> - case crypto_init(Type, Key, undefined) of - {ok,Ref} -> - {Type, {Ref,flg_undefined}}; - {error,_} -> - error(badarg) - end. + Ref = ?COMPAT(crypto_init(Type, Key, undefined)), + {Type, {Ref,flg_undefined}}. %%%---- stream_encrypt -spec stream_encrypt(State, PlainText) -> {NewState, CipherText} | no_return() @@ -655,7 +653,7 @@ stream_init(rc4 = Type, Key) -> NewState :: stream_state(), CipherText :: iodata() . stream_encrypt(State, Data) -> - crypto_stream_emulate(State, Data, true). + crypto_stream_emulate(State, Data, true). %%%---- stream_decrypt -spec stream_decrypt(State, CipherText) -> {NewState, PlainText} | no_return() @@ -664,24 +662,17 @@ stream_encrypt(State, Data) -> NewState :: stream_state(), PlainText :: iodata() . stream_decrypt(State, Data) -> - crypto_stream_emulate(State, Data, false). + crypto_stream_emulate(State, Data, false). %%%-------- helpers -crypto_stream_emulate({Cipher,{Ref,flg_undefined}}, Data, EncryptFlag) when is_reference(Ref) -> - case crypto_init(Ref, EncryptFlag) of - {error,_} -> - error(badarg); - MaybeNewRef when is_reference(MaybeNewRef) -> - crypto_stream_emulate({Cipher,MaybeNewRef}, Data, EncryptFlag) - end; +crypto_stream_emulate({Cipher,{Ref0,flg_undefined}}, Data, EncryptFlag) when is_reference(Ref0) -> + ?COMPAT(begin + Ref = crypto_init(Ref0, EncryptFlag), + {{Cipher,Ref}, crypto_update(Ref, Data)} + end); crypto_stream_emulate({Cipher,Ref}, Data, _) when is_reference(Ref) -> - case crypto_update(Ref, Data) of - {error,_} -> - error(badarg); - Bin when is_binary(Bin) -> - {{Cipher,Ref},Bin} - end. + ?COMPAT({{Cipher,Ref}, crypto_update(Ref, Data)}). %%%---------------------------------------------------------------- -spec next_iv(Type:: cbc_cipher(), Data) -> NextIVec when % Type :: cbc_cipher(), %des_cbc | des3_cbc | aes_cbc | aes_ige, @@ -724,7 +715,7 @@ next_iv(Type, Data, _Ivec) -> %%% Create and initialize a new state for encryption or decryption %%% --spec crypto_init(Cipher, Key, IV, EncryptFlag) -> {ok,State} | {error,term()} +-spec crypto_init(Cipher, Key, IV, EncryptFlag) -> State | ng_crypto_error() when Cipher :: stream_cipher() | block_cipher_with_iv() | block_cipher_without_iv(), @@ -736,18 +727,12 @@ crypto_init(Cipher, Key, undefined, EncryptFlag) -> crypto_init(Cipher, Key, <<>>, EncryptFlag); crypto_init(Cipher, Key, IV, EncryptFlag) -> - case ng_crypto_init_nif(alias(Cipher), - iolist_to_binary(Key), - iolist_to_binary(IV), - EncryptFlag) of - Ref when is_reference(Ref) -> - {ok,Ref}; - {error,Error} -> - {error,Error} - end. + ng_crypto_init_nif(alias(Cipher), + iolist_to_binary(Key), iolist_to_binary(IV), + EncryptFlag). --spec crypto_init(Cipher, Key, IV) -> {ok,State} | {error,term()} +-spec crypto_init(Cipher, Key, IV) -> State | ng_crypto_error() when Cipher :: stream_cipher() | block_cipher_with_iv() | block_cipher_without_iv(), @@ -755,32 +740,23 @@ crypto_init(Cipher, Key, IV, EncryptFlag) -> IV :: iodata() | undefined, State :: crypto_state() . crypto_init(Cipher, Key, undefined) -> - crypto_init(Cipher, Key, <<>>); - -crypto_init(Cipher, Key, IV) when is_atom(Cipher) -> - case ng_crypto_init_nif(alias(Cipher), - iolist_to_binary(Key), - iolist_to_binary(IV), - undefined) of - Ref when is_reference(Ref) -> - {ok,Ref}; - {error,Error} -> - {error,Error} - end. + ng_crypto_init_nif(alias(Cipher), + iolist_to_binary(Key), <<>>, + undefined); +crypto_init(Cipher, Key, IV) -> + ng_crypto_init_nif(alias(Cipher), + iolist_to_binary(Key), iolist_to_binary(IV), + undefined). --spec crypto_init(Ref, EncryptFlag) -> crypto_state() | {error,term()} + +-spec crypto_init(Ref, EncryptFlag) -> crypto_state() | ng_crypto_error() when Ref :: crypto_state(), EncryptFlag :: boolean() . crypto_init(Ref, EncryptFlag) when is_reference(Ref), is_atom(EncryptFlag) -> - case ng_crypto_init_nif(Ref, <<>>, <<>>, EncryptFlag) of - {error,Error} -> - {error,Error}; - R when is_reference(R) -> - R - end. + ng_crypto_init_nif(Ref, <<>>, <<>>, EncryptFlag). %%%---------------------------------------------------------------- %%% @@ -789,7 +765,7 @@ crypto_init(Ref, EncryptFlag) when is_reference(Ref), %%% blocksize. %%% --spec crypto_update(State, Data) -> Result | {error,term()} +-spec crypto_update(State, Data) -> Result | ng_crypto_error() when State :: crypto_state(), Data :: iodata(), Result :: binary() . @@ -808,7 +784,7 @@ crypto_update(State, Data0) -> %%% The size must be an integer multiple of the crypto's blocksize. %%% --spec crypto_one_shot(Cipher, Key, IV, Data, EncryptFlag) -> Result | {error,term()} +-spec crypto_one_shot(Cipher, Key, IV, Data, EncryptFlag) -> Result | ng_crypto_error() when Cipher :: stream_cipher() | block_cipher_with_iv() | block_cipher_without_iv(), @@ -825,22 +801,26 @@ crypto_one_shot(Cipher, Key, IV, Data0, EncryptFlag) -> <<>> -> <<>>; % Known to fail on OpenSSL 0.9.8h Data -> - ng_crypto_one_shot_nif(Cipher, iolist_to_binary(Key), iolist_to_binary(IV), Data, EncryptFlag) + ng_crypto_one_shot_nif(alias(Cipher), + iolist_to_binary(Key), iolist_to_binary(IV), Data, + EncryptFlag) end. %%%---------------------------------------------------------------- %%% NIFs --spec ng_crypto_init_nif(atom(), binary(), binary(), boolean()|undefined ) -> crypto_state() | {error,term()} - ; (crypto_state(), <<>>, <<>>, boolean()) -> crypto_state() | {error,term()} . +-type ng_crypto_error() :: no_return() . + +-spec ng_crypto_init_nif(atom(), binary(), binary(), boolean()|undefined ) -> crypto_state() | ng_crypto_error() + ; (crypto_state(), <<>>, <<>>, boolean()) -> crypto_state() | ng_crypto_error(). ng_crypto_init_nif(_Cipher, _Key, _IVec, _EncryptFlg) -> ?nif_stub. --spec ng_crypto_update_nif(crypto_state(), binary()) -> binary() | {error,term()} . +-spec ng_crypto_update_nif(crypto_state(), binary()) -> binary() | ng_crypto_error() . ng_crypto_update_nif(_State, _Data) -> ?nif_stub. --spec ng_crypto_one_shot_nif(atom(), binary(), binary(), binary(), boolean() ) -> binary() | {error,term()}. +-spec ng_crypto_one_shot_nif(atom(), binary(), binary(), binary(), boolean() ) -> binary() | ng_crypto_error(). ng_crypto_one_shot_nif(_Cipher, _Key, _IVec, _Data, _EncryptFlg) -> ?nif_stub. %%%---------------------------------------------------------------- -- cgit v1.2.3 From b13f268f3e67ebe357f2bd87879e57afb45f6414 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Mon, 11 Mar 2019 17:43:30 +0100 Subject: crypto: Remove compat specials from crypto_init --- lib/crypto/src/crypto.erl | 67 +++++++++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 34 deletions(-) (limited to 'lib/crypto/src') diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl index bd04daee5e..b53d83b851 100644 --- a/lib/crypto/src/crypto.erl +++ b/lib/crypto/src/crypto.erl @@ -56,8 +56,8 @@ ]). %% New interface --export([crypto_init/4, crypto_init/3, crypto_init/2, - crypto_update/2, +-export([crypto_init/4, + crypto_update/2, crypto_update/3, crypto_one_shot/5 ]). @@ -634,7 +634,10 @@ block_decrypt(Type, Key, Data) -> IVec ::binary(), State :: stream_state() . stream_init(Type, Key, IVec) when is_binary(IVec) -> - Ref = ?COMPAT(crypto_init(Type, Key, IVec)), + Ref = ?COMPAT(ng_crypto_init_nif(alias(Type), + iolist_to_binary(Key), iolist_to_binary(IVec), + undefined) + ), {Type, {Ref,flg_undefined}}. @@ -643,7 +646,10 @@ stream_init(Type, Key, IVec) when is_binary(IVec) -> Key :: iodata(), State :: stream_state() . stream_init(rc4 = Type, Key) -> - Ref = ?COMPAT(crypto_init(Type, Key, undefined)), + Ref = ?COMPAT(ng_crypto_init_nif(alias(Type), + iolist_to_binary(Key), <<>>, + undefined) + ), {Type, {Ref,flg_undefined}}. %%%---- stream_encrypt @@ -667,7 +673,7 @@ stream_decrypt(State, Data) -> %%%-------- helpers crypto_stream_emulate({Cipher,{Ref0,flg_undefined}}, Data, EncryptFlag) when is_reference(Ref0) -> ?COMPAT(begin - Ref = crypto_init(Ref0, EncryptFlag), + Ref = ng_crypto_init_nif(Ref0, <<>>, <<>>, EncryptFlag), {{Cipher,Ref}, crypto_update(Ref, Data)} end); @@ -724,40 +730,16 @@ next_iv(Type, Data, _Ivec) -> EncryptFlag :: boolean(), State :: crypto_state() . crypto_init(Cipher, Key, undefined, EncryptFlag) -> - crypto_init(Cipher, Key, <<>>, EncryptFlag); + %% The IV is supposed to be supplied by calling crypto_update/3 + ng_crypto_init_nif(alias(Cipher), + iolist_to_binary(Key), undefined, + EncryptFlag); crypto_init(Cipher, Key, IV, EncryptFlag) -> ng_crypto_init_nif(alias(Cipher), iolist_to_binary(Key), iolist_to_binary(IV), EncryptFlag). - --spec crypto_init(Cipher, Key, IV) -> State | ng_crypto_error() - when Cipher :: stream_cipher() - | block_cipher_with_iv() - | block_cipher_without_iv(), - Key :: iodata(), - IV :: iodata() | undefined, - State :: crypto_state() . -crypto_init(Cipher, Key, undefined) -> - ng_crypto_init_nif(alias(Cipher), - iolist_to_binary(Key), <<>>, - undefined); - -crypto_init(Cipher, Key, IV) -> - ng_crypto_init_nif(alias(Cipher), - iolist_to_binary(Key), iolist_to_binary(IV), - undefined). - - --spec crypto_init(Ref, EncryptFlag) -> crypto_state() | ng_crypto_error() - when Ref :: crypto_state(), - EncryptFlag :: boolean() . - -crypto_init(Ref, EncryptFlag) when is_reference(Ref), - is_atom(EncryptFlag) -> - ng_crypto_init_nif(Ref, <<>>, <<>>, EncryptFlag). - %%%---------------------------------------------------------------- %%% %%% Encrypt/decrypt a sequence of bytes. The sum of the sizes @@ -778,6 +760,20 @@ crypto_update(State, Data0) -> end. +-spec crypto_update(State, Data, IV) -> Result | ng_crypto_error() + when State :: crypto_state(), + Data :: iodata(), + IV :: iodata(), + Result :: binary() . +crypto_update(State, Data0, IV) -> + %% When State is from State = crypto_init(Cipher, Key, undefined, EncryptFlag) + case iolist_to_binary(Data0) of + <<>> -> + <<>>; % Known to fail on OpenSSL 0.9.8h + Data -> + ng_crypto_update_nif(State, Data, iolist_to_binary(IV)) + end. + %%%---------------------------------------------------------------- %%% %%% Encrypt/decrypt one set bytes. @@ -811,7 +807,7 @@ crypto_one_shot(Cipher, Key, IV, Data0, EncryptFlag) -> -type ng_crypto_error() :: no_return() . --spec ng_crypto_init_nif(atom(), binary(), binary(), boolean()|undefined ) -> crypto_state() | ng_crypto_error() +-spec ng_crypto_init_nif(atom(), binary(), binary()|undefined, boolean()|undefined ) -> crypto_state() | ng_crypto_error() ; (crypto_state(), <<>>, <<>>, boolean()) -> crypto_state() | ng_crypto_error(). ng_crypto_init_nif(_Cipher, _Key, _IVec, _EncryptFlg) -> ?nif_stub. @@ -819,6 +815,9 @@ ng_crypto_init_nif(_Cipher, _Key, _IVec, _EncryptFlg) -> ?nif_stub. -spec ng_crypto_update_nif(crypto_state(), binary()) -> binary() | ng_crypto_error() . ng_crypto_update_nif(_State, _Data) -> ?nif_stub. +-spec ng_crypto_update_nif(crypto_state(), binary(), binary()) -> binary() | ng_crypto_error() . +ng_crypto_update_nif(_State, _Data, _IV) -> ?nif_stub. + -spec ng_crypto_one_shot_nif(atom(), binary(), binary(), binary(), boolean() ) -> binary() | ng_crypto_error(). ng_crypto_one_shot_nif(_Cipher, _Key, _IVec, _Data, _EncryptFlg) -> ?nif_stub. -- cgit v1.2.3 From 5e0d5aab3f2a61cf9d4f72cead77594c5fdde793 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Mon, 11 Mar 2019 15:08:36 +0100 Subject: crypto: New function for SSL app --- lib/crypto/src/crypto.erl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/crypto/src') diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl index b53d83b851..4bceeb7510 100644 --- a/lib/crypto/src/crypto.erl +++ b/lib/crypto/src/crypto.erl @@ -56,7 +56,7 @@ ]). %% New interface --export([crypto_init/4, +-export([crypto_init/4, crypto_init/3, crypto_init/2, crypto_update/2, crypto_update/3, crypto_one_shot/5 ]). @@ -774,6 +774,7 @@ crypto_update(State, Data0, IV) -> ng_crypto_update_nif(State, Data, iolist_to_binary(IV)) end. + %%%---------------------------------------------------------------- %%% %%% Encrypt/decrypt one set bytes. -- cgit v1.2.3 From 5a313cb363e2f74ed0c602482c609fcc6dcc718a Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Tue, 12 Mar 2019 15:07:43 +0100 Subject: crypto: Rename SSL special functions to crypto_init_dyn_iv/3 and crypto_update_dyn_iv/3 --- lib/crypto/src/crypto.erl | 63 ++++++++++++++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 23 deletions(-) (limited to 'lib/crypto/src') diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl index 4bceeb7510..5cf34f8069 100644 --- a/lib/crypto/src/crypto.erl +++ b/lib/crypto/src/crypto.erl @@ -56,9 +56,11 @@ ]). %% New interface --export([crypto_init/4, crypto_init/3, crypto_init/2, - crypto_update/2, crypto_update/3, - crypto_one_shot/5 +-export([crypto_init/4, crypto_init/3, + crypto_update/2, + crypto_one_shot/5, + crypto_init_dyn_iv/3, + crypto_update_dyn_iv/3 ]). @@ -721,24 +723,39 @@ next_iv(Type, Data, _Ivec) -> %%% Create and initialize a new state for encryption or decryption %%% +-spec crypto_init(Cipher, Key, EncryptFlag) -> State | ng_crypto_error() + when Cipher :: block_cipher_without_iv() + | stream_cipher_no_iv(), + Key :: iodata(), + EncryptFlag :: boolean(), + State :: crypto_state() . +crypto_init(Cipher, Key, EncryptFlag) -> + %% The IV is supposed to be supplied by calling crypto_update/3 + ng_crypto_init_nif(alias(Cipher), iolist_to_binary(Key), <<>>, EncryptFlag). + + -spec crypto_init(Cipher, Key, IV, EncryptFlag) -> State | ng_crypto_error() - when Cipher :: stream_cipher() - | block_cipher_with_iv() - | block_cipher_without_iv(), + when Cipher :: stream_cipher_iv() + | block_cipher_with_iv(), Key :: iodata(), - IV :: iodata() | undefined, + IV :: iodata(), EncryptFlag :: boolean(), State :: crypto_state() . -crypto_init(Cipher, Key, undefined, EncryptFlag) -> - %% The IV is supposed to be supplied by calling crypto_update/3 - ng_crypto_init_nif(alias(Cipher), - iolist_to_binary(Key), undefined, - EncryptFlag); - crypto_init(Cipher, Key, IV, EncryptFlag) -> - ng_crypto_init_nif(alias(Cipher), - iolist_to_binary(Key), iolist_to_binary(IV), - EncryptFlag). + ng_crypto_init_nif(alias(Cipher), iolist_to_binary(Key), iolist_to_binary(IV), EncryptFlag). + + + +%%%---------------------------------------------------------------- +-spec crypto_init_dyn_iv(Cipher, Key, EncryptFlag) -> State | ng_crypto_error() + when Cipher :: stream_cipher_iv() + | block_cipher_with_iv(), + Key :: iodata(), + EncryptFlag :: boolean(), + State :: crypto_state() . +crypto_init_dyn_iv(Cipher, Key, EncryptFlag) -> + %% The IV is supposed to be supplied by calling crypto_update/3 + ng_crypto_init_nif(alias(Cipher), iolist_to_binary(Key), undefined, EncryptFlag). %%%---------------------------------------------------------------- %%% @@ -760,12 +777,13 @@ crypto_update(State, Data0) -> end. --spec crypto_update(State, Data, IV) -> Result | ng_crypto_error() - when State :: crypto_state(), - Data :: iodata(), - IV :: iodata(), - Result :: binary() . -crypto_update(State, Data0, IV) -> +%%%---------------------------------------------------------------- +-spec crypto_update_dyn_iv(State, Data, IV) -> Result | ng_crypto_error() + when State :: crypto_state(), + Data :: iodata(), + IV :: iodata(), + Result :: binary() . +crypto_update_dyn_iv(State, Data0, IV) -> %% When State is from State = crypto_init(Cipher, Key, undefined, EncryptFlag) case iolist_to_binary(Data0) of <<>> -> @@ -774,7 +792,6 @@ crypto_update(State, Data0, IV) -> ng_crypto_update_nif(State, Data, iolist_to_binary(IV)) end. - %%%---------------------------------------------------------------- %%% %%% Encrypt/decrypt one set bytes. -- cgit v1.2.3