diff options
author | Hans Nilsson <hans@erlang.org> | 2019-11-27 12:03:47 +0100 |
---|---|---|
committer | Hans Nilsson <hans@erlang.org> | 2019-11-27 12:03:47 +0100 |
commit | a09985fc298ead645210359f1fc2626da4ffe780 (patch) | |
tree | 3e954d068de4a538ea7ffe38011d5fd55244c710 | |
parent | 7e2ee5d8efa9d75688d649441ad524466375c034 (diff) | |
parent | 78241111e38a29934936ae11d37cebb308413b1a (diff) | |
download | erlang-a09985fc298ead645210359f1fc2626da4ffe780.tar.gz |
Merge branch 'hans/crypto/cuddle_tests' into maint
* hans/crypto/cuddle_tests:
crypto: Add prop__crypto_init_update to property tests
crypto: New common libfile for property tests in crypto
4 files changed, 180 insertions, 32 deletions
diff --git a/lib/crypto/test/crypto_property_test_SUITE.erl b/lib/crypto/test/crypto_property_test_SUITE.erl index 392976b765..75a3d4872f 100644 --- a/lib/crypto/test/crypto_property_test_SUITE.erl +++ b/lib/crypto/test/crypto_property_test_SUITE.erl @@ -24,7 +24,8 @@ -include_lib("common_test/include/ct.hrl"). -all() -> [encrypt_decrypt__crypto_one_time +all() -> [encrypt_decrypt__crypto_one_time, + prop__crypto_init_update ]. %%% First prepare Config and compile the property tests for the found tool: @@ -42,3 +43,8 @@ encrypt_decrypt__crypto_one_time(Config) -> crypto_ng_api:prop__crypto_one_time(), Config ). +prop__crypto_init_update(Config) -> + ct_property_test:quickcheck( + crypto_ng_api:prop__crypto_init_update(), + Config + ). diff --git a/lib/crypto/test/property_test/crypto_ng_api.erl b/lib/crypto/test/property_test/crypto_ng_api.erl index 85e48d231e..c3a21b0804 100644 --- a/lib/crypto/test/property_test/crypto_ng_api.erl +++ b/lib/crypto/test/property_test/crypto_ng_api.erl @@ -53,7 +53,9 @@ -endif. -endif. +-include("crypto_prop_generators.hrl"). +%%%================================================================ %%% Properties: prop__crypto_one_time() -> @@ -66,23 +68,17 @@ prop__crypto_one_time() -> ) ). -%%% Generators -text_plain() -> iolist(). - -cipher() -> oneof( non_aead_ciphers() -- [aes_ige256] ). - -key(Cipher) -> - %% Can't be shrinked - crypto:strong_rand_bytes( key_length(Cipher) ). - -iv(Cipher) -> - %% Can't be shrinked - crypto:strong_rand_bytes( iv_length(Cipher) ). +prop__crypto_init_update() -> + numtests(10000, + ?FORALL({TextPlain, Cipher, Key, IV}, ?LET(Ciph,cipher(), + {text_plain(), Ciph, key(Ciph), iv(Ciph)}), + equal(TextPlain, + full_blocks(TextPlain, Cipher), + decrypt_encrypt_init_update(Cipher, Key, IV, TextPlain)) + ) + ). -iolist() -> oneof([list( oneof([list(byte()), binary(), list(binary())])), - binary(1056) - ]). - +%%%================================================================ %%% Lib equal(_, T, T) -> true; @@ -94,28 +90,45 @@ equal(F, Tp, Td) -> false. -non_aead_ciphers() -> - [C || C <- crypto:supports(ciphers), - C =/= chacha20_poly1305, - begin - #{mode := Mode} = crypto:cipher_info(C), - not lists:member(Mode, [ccm_mode, gcm_mode]) - end]. - decrypt_encrypt_one_time(Cipher, Key, IV, TextPlain) -> + io:format("~p:~p Cipher: ~p, BlockSize: ~p, Key: ~p, IV: ~p, TextPlain: ~p (~p chunks)", + [?MODULE,?LINE, Cipher, block_size(Cipher), size(Key), size(IV), size(iolist_to_binary(TextPlain)), + num_chunks(TextPlain)]), TextCrypto = crypto:crypto_one_time(Cipher, Key, IV, TextPlain, true), - crypto:crypto_one_time(Cipher, Key, IV, TextCrypto, false). - + io:format("~p:~p TextCrypto: ~p", [?MODULE,?LINE, size(TextCrypto)]), + TextDecrypt = crypto:crypto_one_time(Cipher, Key, IV, TextCrypto, false), + io:format("~p:~p TextDecrypt: ~p", [?MODULE,?LINE, size(TextDecrypt)]), + TextDecrypt. + + +decrypt_encrypt_init_update(Cipher, Key, IV, TextPlain) when is_binary(TextPlain) -> + decrypt_encrypt_init_update(Cipher, Key, IV, [TextPlain]); + +decrypt_encrypt_init_update(Cipher, Key, IV, TextPlain) -> + io:format("~p:~p Cipher: ~p, BlockSize: ~p, Key: ~p, IV: ~p, TextPlain: ~p (~p chunks)", + [?MODULE,?LINE, Cipher, block_size(Cipher), size(Key), size(IV), size(iolist_to_binary(TextPlain)), + num_chunks(TextPlain)]), + Cenc = crypto:crypto_init(Cipher, Key, IV, true), + TextOut = lists:foldl(fun(TextIn, TextOutAcc) -> + [crypto:crypto_update(Cenc,TextIn) | TextOutAcc] + end, [], TextPlain), + TextCrypto = lists:reverse(TextOut), + io:format("~p:~p TextCrypto: ~p", + [?MODULE,?LINE, size(iolist_to_binary(TextCrypto))]), + Cdec = crypto:crypto_init(Cipher, Key, IV, false), + TextDec = lists:foldl(fun(TextC, TextDecAcc) -> + [crypto:crypto_update(Cdec,TextC) | TextDecAcc] + end, [], TextCrypto), + iolist_to_binary(lists:reverse(TextDec)). + full_blocks(TextPlain, Cipher) -> TextPlainBin = iolist_to_binary(TextPlain), {Head,_Tail} = split_binary(TextPlainBin, (size(TextPlainBin) - num_rest_bytes(TextPlainBin,Cipher))), Head. -num_rest_bytes(Bin, Cipher) -> size(Bin) rem block_size(Cipher). - -block_size(Cipher) -> maps:get(block_size, crypto:cipher_info(Cipher)). +num_chunks(B) when is_binary(B) -> 1; +num_chunks(L) when is_list(L) -> length(L). -key_length(Cipher) -> maps:get(key_length, crypto:cipher_info(Cipher)). +num_rest_bytes(Bin, Cipher) -> size(Bin) rem block_size(Cipher). -iv_length(Cipher) -> maps:get(iv_length, crypto:cipher_info(Cipher)). diff --git a/lib/crypto/test/property_test/crypto_prop_generators.erl b/lib/crypto/test/property_test/crypto_prop_generators.erl new file mode 100644 index 0000000000..5a53a000f0 --- /dev/null +++ b/lib/crypto/test/property_test/crypto_prop_generators.erl @@ -0,0 +1,93 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2004-2017. All Rights Reserved. +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%% +%% %CopyrightEnd% +%% +%% + +-module(crypto_prop_generators). + +-compile(export_all). + +-proptest(eqc). +-proptest([triq,proper]). + +-ifndef(EQC). +-ifndef(PROPER). +-ifndef(TRIQ). +%%-define(EQC,true). +-define(PROPER,true). +%%-define(TRIQ,true). +-endif. +-endif. +-endif. + +-ifdef(EQC). +-include_lib("eqc/include/eqc.hrl"). +-define(MOD_eqc,eqc). + +-else. +-ifdef(PROPER). +-include_lib("proper/include/proper.hrl"). +-define(MOD_eqc,proper). +-else. +-ifdef(TRIQ). +-define(MOD_eqc,triq). +-include_lib("triq/include/triq.hrl"). + +-endif. +-endif. +-endif. + +%%%================================================================ +%%% Generators + +text_plain() -> iolist(). + +cipher() -> oneof( non_aead_ciphers() -- [aes_ige256] ). + +key(Cipher) -> + %% Can't be shrinked + crypto:strong_rand_bytes( key_length(Cipher) ). + +iv(Cipher) -> + %% Can't be shrinked + crypto:strong_rand_bytes( iv_length(Cipher) ). + +iolist() -> frequency([{5, list( oneof([list(byte()), + binary(), + list(binary())]))}, + {1, mybinary(50000)} + ]). + +mybinary(MaxSize) -> ?LET(Sz, integer(0,MaxSize), binary(Sz)). + + +%%%================================================================ +non_aead_ciphers() -> + [C || C <- crypto:supports(ciphers), + C =/= chacha20_poly1305, + begin + #{mode := Mode} = crypto:cipher_info(C), + not lists:member(Mode, [ccm_mode, gcm_mode]) + end]. + +block_size(Cipher) -> maps:get(block_size, crypto:cipher_info(Cipher)). + +key_length(Cipher) -> maps:get(key_length, crypto:cipher_info(Cipher)). + +iv_length(Cipher) -> maps:get(iv_length, crypto:cipher_info(Cipher)). diff --git a/lib/crypto/test/property_test/crypto_prop_generators.hrl b/lib/crypto/test/property_test/crypto_prop_generators.hrl new file mode 100644 index 0000000000..56a762e651 --- /dev/null +++ b/lib/crypto/test/property_test/crypto_prop_generators.hrl @@ -0,0 +1,36 @@ +%%% +%%% %CopyrightBegin% +%%% +%%% Copyright Ericsson AB 2004-2017. All Rights Reserved. +%%% +%%% Licensed under the Apache License, Version 2.0 (the "License"); +%%% you may not use this file except in compliance with the License. +%%% You may obtain a copy of the License at +%%% +%%% http://www.apache.org/licenses/LICENSE-2.0 +%%% +%%% Unless required by applicable law or agreed to in writing, software +%%% distributed under the License is distributed on an "AS IS" BASIS, +%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%%% See the License for the specific language governing permissions and +%%% limitations under the License. +%%% +%%% %CopyrightEnd% +%%% +%%% + + +-import(crypto_prop_generators, + [ + text_plain/0, + cipher/0, + key/1, + iv/1, + iolist/0, + mybinary/1, + + non_aead_ciphers/0, + block_size/1, + key_length/1, + iv_length/1 + ]). |