1%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 1999-2020. All Rights Reserved.
5%%
6%% Licensed under the Apache License, Version 2.0 (the "License");
7%% you may not use this file except in compliance with the License.
8%% You may obtain a copy of the License at
9%%
10%%     http://www.apache.org/licenses/LICENSE-2.0
11%%
12
13%% distributed under the License is distributed on an "AS IS" BASIS,
14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15%% See the License for the specific language governing permissions and
16%% limitations under the License.
17%%
18%% %CopyrightEnd%
19%%
20-module(crypto_SUITE).
21
22-include_lib("common_test/include/ct.hrl").
23
24%% Note: This directive should only be used in test suites.
25-compile(export_all).
26%%--------------------------------------------------------------------
27%% Common Test interface functions -----------------------------------
28%%--------------------------------------------------------------------
29
30suite() -> [{ct_hooks,[ts_install_cth]}].
31
32all() ->
33    [app,
34     {group, api_errors},
35     appup,
36     {group, fips},
37     {group, non_fips},
38     ec_key_padding,
39     mod_pow,
40     exor,
41     rand_uniform,
42     rand_threads,
43     rand_plugin,
44     rand_plugin_s,
45     cipher_info,
46     hash_info
47    ].
48
49-define(NEW_CIPHER_TYPE_SCHEMA,
50        {group, des_ede3_cbc},
51        {group, des_ede3_cfb},
52        {group, aes_128_cbc},
53        {group, aes_192_cbc},
54        {group, aes_256_cbc},
55        {group, aes_128_ctr},
56        {group, aes_192_ctr},
57        {group, aes_256_ctr},
58        {group, aes_128_ccm},
59        {group, aes_192_ccm},
60        {group, aes_256_ccm},
61        {group, aes_128_ecb},
62        {group, aes_192_ecb},
63        {group, aes_256_ecb},
64        {group, aes_128_gcm},
65        {group, aes_192_gcm},
66        {group, aes_256_gcm},
67        {group, des_ede3_cbc},
68        {group, des_ede3_cfb},
69        {group, aes_128_cfb128},
70        {group, aes_192_cfb128},
71        {group, aes_256_cfb128},
72        {group, aes_128_cfb8},
73        {group, aes_192_cfb8},
74        {group, aes_256_cfb8}
75       ).
76
77-define(RETIRED_TYPE_ALIASES,
78        {group, aes_cbc},
79        {group, aes_cbc128},
80        {group, aes_cbc256},
81        {group, aes_ccm},
82        {group, aes_ctr},
83        {group, aes_gcm},
84        {group, aes_ecb},
85        {group, des3_cfb},
86        {group, des3_cbc},
87        {group, des3_cbf},
88        {group, des_ede3},
89        {group, aes_cfb128},
90        {group, aes_cfb8}
91       ).
92
93groups() ->
94    [{non_fips, [], [
95                     {group, blake2b},
96                     {group, blake2s},
97                     {group, dss},
98                     {group, ecdsa},
99                     {group, ed25519},
100                     {group, ed448},
101                     {group, rsa},
102
103                     {group, md4},
104                     {group, md5},
105                     {group, ripemd160},
106                     {group, sha224},
107                     {group, sha256},
108                     {group, sha384},
109                     {group, sha3_224},
110                     {group, sha3_256},
111                     {group, sha3_384},
112                     {group, sha3_512},
113                     {group, sha512},
114                     {group, sha},
115                     {group, poly1305},
116
117                     {group, dh},
118                     {group, ecdh},
119                     {group, srp},
120
121		     {group, chacha20_poly1305},
122		     {group, chacha20},
123                     {group, blowfish_cbc},
124                     {group, blowfish_cfb64},
125                     {group, blowfish_ecb},
126                     {group, blowfish_ofb64},
127
128                     {group, aes_ige256},
129                     {group, des_cbc},
130                     {group, des_cfb},
131                     {group, rc2_cbc},
132                     {group, rc4},
133
134                     ?NEW_CIPHER_TYPE_SCHEMA,
135                     ?RETIRED_TYPE_ALIASES
136                    ]},
137     {fips, [], [
138                 {group, no_blake2b},
139                 {group, no_blake2s},
140                 {group, dss},
141                 {group, ecdsa},
142                 {group, no_ed25519},
143                 {group, no_ed448},
144                 {group, rsa},
145
146                 {group, no_md4},
147                 {group, no_md5},
148                 {group, no_ripemd160},
149                 {group, sha},
150                 {group, sha224},
151                 {group, sha256},
152                 {group, sha384},
153                 {group, sha512},
154                 {group, no_poly1305},
155
156                 {group, dh},
157                 {group, ecdh},
158                 {group, no_srp},
159
160		 {group, no_chacha20_poly1305},
161		 {group, no_chacha20},
162                 {group, no_blowfish_cbc},
163                 {group, no_blowfish_cfb64},
164                 {group, no_blowfish_ecb},
165                 {group, no_blowfish_ofb64},
166
167                 {group, no_aes_ige256},
168                 {group, no_des_cbc},
169                 {group, no_des_cfb},
170                 {group, no_rc2_cbc},
171                 {group, no_rc4},
172
173                 ?NEW_CIPHER_TYPE_SCHEMA,
174                 ?RETIRED_TYPE_ALIASES
175                ]},
176
177     {md4,                  [], [hash]},
178     {md5,                  [], [hash, hmac, hmac_update]},
179     {ripemd160,            [], [hash]},
180     {sha,                  [], [hash, hmac, hmac_update]},
181     {sha224,               [], [hash, hmac, hmac_update]},
182     {sha256,               [], [hash, hmac, hmac_update]},
183     {sha384,               [], [hash, hmac, hmac_update]},
184     {sha512,               [], [hash, hmac, hmac_update]},
185     {sha3_224,             [], [hash, hmac, hmac_update]},
186     {sha3_256,             [], [hash, hmac, hmac_update]},
187     {sha3_384,             [], [hash, hmac, hmac_update]},
188     {sha3_512,             [], [hash, hmac, hmac_update]},
189     {blake2b,              [], [hash, hmac, hmac_update]},
190     {blake2s,              [], [hash, hmac, hmac_update]},
191     {no_blake2b,           [], [no_hash, no_hmac]},
192     {no_blake2s,           [], [no_hash, no_hmac]},
193     {rsa,                  [], [sign_verify,
194                                 public_encrypt,
195                                 private_encrypt,
196                                 generate
197                                ]},
198     {dss,                  [], [sign_verify
199                                 %% Does not work yet:  ,public_encrypt, private_encrypt
200                                ]},
201     {ecdsa,                [], [sign_verify
202                                 %% Does not work yet:  ,public_encrypt, private_encrypt
203                                ]},
204     {ed25519,              [], [sign_verify
205                                 %% Does not work yet:  ,public_encrypt, private_encrypt
206                              ]},
207     {ed448,                [], [sign_verify
208                                 %% Does not work yet:  ,public_encrypt, private_encrypt
209                                ]},
210     {dh,                   [], [generate_compute, compute_bug]},
211     {ecdh,                 [], [use_all_elliptic_curves, compute, generate]},
212     {srp,                  [], [generate_compute]},
213     {des_cbc,              [], [block, api_ng, api_ng_one_shot, api_ng_tls]},
214     {des_cfb,              [], [block, api_ng, api_ng_one_shot, api_ng_tls]},
215     {des_ede3_cbc,         [], [block, api_ng, api_ng_one_shot, api_ng_tls]},
216     {des_ede3_cfb,         [], [block, api_ng, api_ng_one_shot, api_ng_tls]},
217     {rc2_cbc,              [], [block, api_ng, api_ng_one_shot, api_ng_tls]},
218     {aes_cfb8,             [], [block]},
219     {aes_128_cfb8,         [], [block, api_ng, api_ng_one_shot, api_ng_tls]},
220     {aes_192_cfb8,         [], [block, api_ng, api_ng_one_shot, api_ng_tls]},
221     {aes_256_cfb8,         [], [block, api_ng, api_ng_one_shot, api_ng_tls]},
222     {no_aes_cfb8,          [], [no_support, no_block]},
223     {aes_cfb128,           [], [block]},
224     {aes_128_cfb128,       [], [block, api_ng, api_ng_one_shot, api_ng_tls]},
225     {aes_192_cfb128,       [], [block, api_ng, api_ng_one_shot, api_ng_tls]},
226     {aes_256_cfb128,       [], [block, api_ng, api_ng_one_shot, api_ng_tls]},
227     {no_aes_cfb128,        [], [no_support, no_block]},
228     {aes_ige256,           [], [block]},
229     {no_aes_ige256,        [], [no_support, no_block]},
230     {blowfish_cbc,         [], [block, api_ng, api_ng_one_shot, api_ng_tls]},
231     {blowfish_ecb,         [], [block, api_ng, api_ng_one_shot]},
232     {blowfish_cfb64,       [], [block, api_ng, api_ng_one_shot, api_ng_tls]},
233     {blowfish_ofb64,       [], [block, api_ng, api_ng_one_shot, api_ng_tls]},
234     {rc4,                  [], [stream, api_ng, api_ng_one_shot, api_ng_tls]},
235     {aes_ctr,              [], [stream]},
236     {chacha20_poly1305,    [], [aead, aead_ng, aead_bad_tag]},
237     {chacha20,             [], [stream, api_ng, api_ng_one_shot, api_ng_tls]},
238     {poly1305,             [], [poly1305]},
239     {no_poly1305,          [], [no_poly1305]},
240     {no_aes_cfb128,        [], [no_support, no_block]},
241     {no_md4,               [], [no_support, no_hash]},
242     {no_md5,               [], [no_support, no_hash, no_hmac]},
243     {no_ed25519,           [], [no_support, no_sign_verify
244                                 %% Does not work yet:  ,public_encrypt, private_encrypt
245                                ]},
246     {no_ed448,             [], [no_support, no_sign_verify
247                                 %% Does not work yet:  ,public_encrypt, private_encrypt
248                                ]},
249     {no_ripemd160,         [], [no_support, no_hash]},
250     {no_srp,               [], [no_support, no_generate_compute]},
251     {no_des_cbc,           [], [no_support, no_block]},
252     {no_des_cfb,           [], [no_support, no_block]},
253     {no_blowfish_cbc,      [], [no_support, no_block]},
254     {no_blowfish_ecb,      [], [no_support, no_block]},
255     {no_blowfish_cfb64,    [], [no_support, no_block]},
256     {no_blowfish_ofb64,    [], [no_support, no_block]},
257     {no_aes_ige256,        [], [no_support, no_block]},
258     {no_chacha20_poly1305, [], [no_support, no_aead, no_aead_ng]},
259     {no_chacha20,          [], [no_support, no_stream_ivec]},
260     {no_rc2_cbc,           [], [no_support, no_block]},
261     {no_rc4,               [], [no_support, no_stream]},
262     {api_errors,           [], [api_errors_ecdh,
263                                 bad_combo,
264                                 bad_key_length,
265                                 bad_cipher_name,
266                                 bad_generate_key_name,
267                                 bad_hash_name,
268                                 bad_hmac_name,
269                                 bad_mac_name,
270                                 bad_sign_name,
271                                 bad_verify_name
272                                ]},
273
274     %% New cipher nameing schema
275     {des_ede3_cbc, [], [api_ng, api_ng_one_shot, api_ng_tls]},
276     {des_ede3_cfb, [], [api_ng, api_ng_one_shot, api_ng_tls]},
277     {aes_128_cbc,  [], [api_ng, api_ng_one_shot, api_ng_tls, cmac]},
278     {aes_192_cbc,  [], [api_ng, api_ng_one_shot, api_ng_tls]},
279     {aes_256_cbc,  [], [api_ng, api_ng_one_shot, api_ng_tls, cmac]},
280     {aes_128_ctr,  [], [api_ng, api_ng_one_shot, api_ng_tls]},
281     {aes_192_ctr,  [], [api_ng, api_ng_one_shot, api_ng_tls]},
282     {aes_256_ctr,  [], [api_ng, api_ng_one_shot, api_ng_tls]},
283     {aes_128_ccm,  [], [aead, aead_ng, aead_bad_tag]},
284     {aes_192_ccm,  [], [aead, aead_ng, aead_bad_tag]},
285     {aes_256_ccm,  [], [aead, aead_ng, aead_bad_tag]},
286     {aes_128_ecb,  [], [api_ng, api_ng_one_shot]},
287     {aes_192_ecb,  [], [api_ng, api_ng_one_shot]},
288     {aes_256_ecb,  [], [api_ng, api_ng_one_shot]},
289     {aes_128_gcm,  [], [aead, aead_ng, aead_bad_tag]},
290     {aes_192_gcm,  [], [aead, aead_ng, aead_bad_tag]},
291     {aes_256_gcm,  [], [aead, aead_ng, aead_bad_tag]},
292
293     %% Retired aliases
294     {aes_cbc,    [], [block]},
295     {aes_cbc128, [], [block]},
296     {aes_cbc256, [], [block]},
297     {aes_ccm,    [], [aead]},
298     {aes_ecb,    [], [block]},
299     {aes_gcm,    [], [aead]},
300     {des3_cbc,             [], [block]},
301     {des_ede3,             [], [block]},
302     {des3_cbf,             [], [block]},
303     {des3_cfb,             [], [block]}
304    ].
305
306%%-------------------------------------------------------------------
307init_per_suite(Config) ->
308    file:set_cwd(datadir(Config)),
309    {ok, _} = zip:unzip("KAT_AES.zip"),
310    {ok, _} = zip:unzip("aesmmt.zip"),
311    {ok, _} = zip:unzip("cmactestvectors.zip"),
312    {ok, _} = zip:unzip("gcmtestvectors.zip"),
313
314    try crypto:start() of
315	ok ->
316            catch ct:comment("~s",[element(3,hd(crypto:info_lib()))]),
317            catch ct:log("crypto:info_lib() -> ~p~n"
318                         "crypto:supports() -> ~p~n"
319                         "crypto:version()  -> ~p~n"
320                        ,[crypto:info_lib(), crypto:supports(), crypto:version()]),
321
322	    try crypto:strong_rand_bytes(1) of
323		_ ->
324		    Config
325	    catch error:low_entropy ->
326                    %% We are testing on an OS with low entropy in its random
327                    %% seed. So we have to seed it with a binary to get started.
328
329		    %% This is NOT how you want to do seeding, it is just here
330		    %% to make the tests pass. Check your OS manual for how you
331		    %% really want to seed.
332		    {H,M,L} = erlang:timestamp(),
333		    Bin = <<H:24,M:20,L:20>>,
334		    crypto:rand_seed(<< <<Bin/binary>> || _ <- lists:seq(1,16) >>),
335		    Config
336	    end
337    catch _:_ ->
338	    {fail, "Crypto did not start"}
339    end.
340
341end_per_suite(_Config) ->
342    application:stop(crypto).
343
344%%-------------------------------------------------------------------
345init_per_group(fips, Config) ->
346    try_enable_fips_mode(Config);
347init_per_group(non_fips, Config) ->
348    NonFIPSConfig = [{fips, false} | Config],
349    case crypto:info_fips() of
350        enabled ->
351            true = crypto:enable_fips_mode(false),
352            not_enabled = crypto:info_fips(),
353            NonFIPSConfig;
354        _NotEnabled ->
355            NonFIPSConfig
356    end;
357init_per_group(api_errors, Config) ->
358    Config;
359init_per_group(GroupName, Config) ->
360    case atom_to_list(GroupName) of
361        "no_" ++ TypeStr ->
362            %% Negated test case: check the algorithm is not supported
363            %% (e.g. due to FIPS mode limitations)
364            TypeAtom = list_to_atom(TypeStr),
365            [{type, TypeAtom} | group_config(TypeAtom, Config)];
366        _Other ->
367            %% Regular test case: skip if the algorithm is not supported
368            case is_supported(GroupName) of
369                true ->
370                    [{type, GroupName} | group_config(GroupName, Config)];
371                false ->
372                    {skip, "Group not supported"}
373            end
374    end.
375
376end_per_group(_GroupName, Config) ->
377    Config.
378
379init_per_testcase(info, Config) ->
380    Config;
381init_per_testcase(cmac, Config) ->
382    case is_supported(cmac) of
383        true ->
384            configure_mac(cmac, proplists:get_value(type,Config), Config);
385        false ->
386            {skip, "CMAC is not supported"}
387    end;
388init_per_testcase(generate, Config) ->
389    case proplists:get_value(type, Config) of
390	rsa ->
391	    % RSA key generation is a lengthy process, and is only available
392	    % if dirty CPU scheduler support was enabled for this runtime.
393	    case try erlang:system_info(dirty_cpu_schedulers) of
394		     N -> N > 0
395		 catch
396		     error:badarg -> false
397		 end of
398		true -> Config;
399		false -> {skip, "RSA key generation requires dirty scheduler support."}
400	    end;
401	_ -> Config
402    end;
403init_per_testcase(hmac, Config) ->
404    configure_mac(hmac, proplists:get_value(type,Config), Config);
405init_per_testcase(_Name,Config) ->
406    Config.
407
408end_per_testcase(info, Config) ->
409    Config;
410end_per_testcase(_Name,Config) ->
411    Config.
412
413%%--------------------------------------------------------------------
414%% Test Cases --------------------------------------------------------
415%%--------------------------------------------------------------------
416app() ->
417    [{doc, "Test that the crypto app file is ok"}].
418app(Config) when is_list(Config) ->
419    ok = ?t:app_test(crypto).
420%%--------------------------------------------------------------------
421appup() ->
422    [{doc, "Test that the crypto appup file is ok"}].
423appup(Config) when is_list(Config) ->
424    ok = ?t:appup_test(crypto).
425%%--------------------------------------------------------------------
426no_support() ->
427    [{doc, "Test an algorithm is not reported in the supported list"}].
428no_support(Config) when is_list(Config) ->
429    Type  = ?config(type, Config),
430    false = is_supported(Type).
431%%--------------------------------------------------------------------
432hash() ->
433    [{doc, "Test all different hash functions"}].
434hash(Config) when is_list(Config) ->
435    {Type, MsgsLE, Digests} = proplists:get_value(hash, Config),
436    Msgs = lazy_eval(MsgsLE),
437    [LongMsg | _] = lists:reverse(Msgs),
438    Inc = iolistify(LongMsg),
439    [IncrDigest | _] = lists:reverse(Digests),
440    hash(Type, Msgs, Digests),
441    hash(Type, lists:map(fun iolistify/1, Msgs), Digests),
442    hash_increment(Type, Inc, IncrDigest).
443%%--------------------------------------------------------------------
444no_hash() ->
445    [{doc, "Test all disabled hash functions"}].
446no_hash(Config) when is_list(Config) ->
447    Type = ?config(type, Config),
448    notsup(fun crypto:hash/2, [Type, <<"Hi There">>]),
449    notsup(fun crypto:hash_init/1, [Type]).
450%%--------------------------------------------------------------------
451hmac() ->
452     [{doc, "Test hmac function"}].
453hmac(Config) when is_list(Config) ->
454    Tuples = lazy_eval(proplists:get_value(hmac, Config)),
455    lists:foreach(fun hmac_check/1, Tuples),
456    lists:foreach(fun hmac_check/1, mac_listify(Tuples)).
457
458%%--------------------------------------------------------------------
459no_hmac() ->
460     [{doc, "Test all disabled hmac functions"}].
461no_hmac(Config) when is_list(Config) ->
462    Type = ?config(type, Config),
463    notsup(fun crypto:hmac/3, [Type, <<"Key">>, <<"Hi There">>]).
464
465%%--------------------------------------------------------------------
466hmac_update() ->
467     [{doc, "Test all incremental hmac functions"}].
468hmac_update(Config) ->
469    Type = ?config(type, Config),
470    hmac_increment(Type).
471
472%%--------------------------------------------------------------------
473no_hmac_update() ->
474     [{doc, "Test all disabled incremental hmac functions"}].
475no_hmac_update(Config) ->
476    Type = ?config(type, Config),
477    notsup(fun crypto:hmac_init/2, [Type, <<"Key">>]).
478
479%%--------------------------------------------------------------------
480cmac() ->
481     [{doc, "Test all different cmac functions"}].
482cmac(Config) when is_list(Config) ->
483    Pairs = lazy_eval(proplists:get_value(cmac, Config)),
484    lists:foreach(fun cmac_check/1, Pairs),
485    lists:foreach(fun cmac_check/1, mac_listify(Pairs)).
486
487%%--------------------------------------------------------------------
488poly1305() ->
489    [{doc, "Test poly1305 function"}].
490poly1305(Config) ->
491    lists:foreach(
492      fun({Key, Txt, Expect}) ->
493              case crypto:poly1305(Key,Txt) of
494                  Expect ->
495                      ok;
496                  Other ->
497                      ct:fail({{crypto, poly1305, [Key, Txt]}, {expected, Expect}, {got, Other}})
498              end
499      end, proplists:get_value(poly1305, Config)).
500
501%%--------------------------------------------------------------------
502no_poly1305() ->
503    [{doc, "Test disabled poly1305 function"}].
504no_poly1305(_Config) ->
505    Key = <<133,214,190,120,87,85,109,51,127,68,82,254,66,213,6,168,1,
506            3,128,138,251,13,178,253,74,191,246,175,65,73,245,27>>,
507    Txt = <<"Cryptographic Forum Research Group">>,
508    notsup(fun crypto:poly1305/2, [Key,Txt]).
509
510%%--------------------------------------------------------------------
511block() ->
512     [{doc, "Test block ciphers"}].
513block(Config) when is_list(Config) ->
514    [_|_] = Blocks = lazy_eval(proplists:get_value(cipher, Config)),
515    lists:foreach(fun block_cipher/1, Blocks),
516    lists:foreach(fun block_cipher/1, block_iolistify(Blocks)),
517    lists:foreach(fun block_cipher_increment/1, block_iolistify(Blocks)).
518
519%%--------------------------------------------------------------------
520no_block() ->
521     [{doc, "Test disabled block ciphers"}].
522no_block(Config) when is_list(Config) ->
523    [_|_] = Blocks = lazy_eval(proplists:get_value(cipher, Config)),
524    Args = case Blocks of
525	       [{_Type, _Key, _PlainText} = A | _] ->
526		   tuple_to_list(A);
527	       [{_Type, _Key, _IV, _PlainText} = A | _] ->
528		   tuple_to_list(A);
529	       [{Type, Key, IV, PlainText, _CipherText} | _] ->
530		   [Type, Key, IV, PlainText]
531	   end,
532    N = length(Args),
533    notsup(fun crypto:block_encrypt/N, Args),
534    notsup(fun crypto:block_decrypt/N, Args).
535%%--------------------------------------------------------------------
536api_ng() ->
537     [{doc, "Test new api"}].
538
539api_ng(Config) when is_list(Config) ->
540    [_|_] = Ciphers = lazy_eval(proplists:get_value(cipher, Config, [])),
541    lists:foreach(fun api_ng_cipher_increment/1, Ciphers ++ spec_0_bytes(Config)).
542
543api_ng_cipher_increment({Type, Key, PlainTexts}=_X) ->
544    ct:log("~p",[_X]),
545    api_ng_cipher_increment({Type, Key, <<>>, PlainTexts});
546
547api_ng_cipher_increment({Type, Key, IV, PlainTexts}=_X) ->
548    ct:log("~p",[_X]),
549    api_ng_cipher_increment({Type, Key, IV, PlainTexts, undefined});
550
551api_ng_cipher_increment({Type, Key, IV, PlainText0, ExpectedEncText}=_X) ->
552    ct:log("~p",[_X]),
553    PlainTexts = iolistify(PlainText0),
554    RefEnc = crypto:crypto_init(Type, Key, IV, true),
555    RefDec = crypto:crypto_init(Type, Key, IV, false),
556    EncTexts = api_ng_cipher_increment_loop(RefEnc, PlainTexts),
557    Enc = iolist_to_binary(EncTexts),
558    case ExpectedEncText of
559        undefined ->
560            ok;
561        Enc ->
562            ok;
563        _ ->
564            ct:log("encode~nIn: ~p~nExpected: ~p~nEnc: ~p~n", [{Type,Key,IV,PlainTexts}, ExpectedEncText, Enc]),
565            ct:fail("api_ng_cipher_increment (encode)",[])
566    end,
567    Plain = iolist_to_binary(PlainTexts),
568    case iolist_to_binary(api_ng_cipher_increment_loop(RefDec, EncTexts)) of
569        Plain ->
570            ok;
571        OtherPT ->
572            ct:log("decode~nIn: ~p~nExpected: ~p~nDec: ~p~n", [{Type,Key,IV,EncTexts}, Plain, OtherPT]),
573            ct:fail("api_ng_cipher_increment (encode)",[])
574    end.
575
576
577api_ng_cipher_increment_loop(Ref, InTexts) ->
578    lists:map(fun(Txt) ->
579                      try crypto:crypto_update(Ref, Txt)
580                      of
581                          Bin when is_binary(Bin) ->
582                              Bin
583                      catch
584                          error:Error ->
585                              ct:pal("Txt = ~p",[Txt]),
586                              ct:fail("~p",[Error])
587                      end
588              end, InTexts).
589
590%%--------------------------------------------------------------------
591%% Check that crypto do not core dump on early 0.9.8 cryptolibs
592spec_0_bytes(Config) ->
593    Type = proplists:get_value(type, Config),
594    #{iv_length := IVS, key_length := KS} = Spec = crypto:cipher_info(Type),
595    Key = <<0:KS/unit:8>>,
596    IV = <<0:IVS/unit:8>>,
597    spec_0_bytes(Type, Key, IV, Spec).
598
599
600spec_0_bytes(chacha20_poly1305, _, _, _) ->
601    [];
602spec_0_bytes(Type, Key, IV, #{mode := M}) when M == ccm_mode ;
603                                               M == gcm_mode ->
604    AAD = <<>>,
605    Plain = <<>>,
606    {_, Tag} = crypto:crypto_one_time_aead(Type, Key, IV, Plain, AAD, true),
607    [{Type, Key, Plain, IV, AAD, <<>>, Tag, []}];
608spec_0_bytes(Type, Key, IV, _Spec) ->
609    [{Type, Key, IV, <<>>, <<>>}].
610
611%%--------------------------------------------------------------------
612api_ng_one_shot() ->
613     [{doc, "Test new api"}].
614
615api_ng_one_shot(Config) when is_list(Config) ->
616    [_|_] = Ciphers = lazy_eval(proplists:get_value(cipher, Config, [])),
617    lists:foreach(fun do_api_ng_one_shot/1, Ciphers ++ spec_0_bytes(Config)).
618
619do_api_ng_one_shot({Type, Key, PlainTexts}=_X) ->
620    ct:log("~p",[_X]),
621    do_api_ng_one_shot({Type, Key, <<>>, PlainTexts});
622
623do_api_ng_one_shot({Type, Key, IV, PlainTexts}=_X) ->
624    ct:log("~p",[_X]),
625    do_api_ng_one_shot({Type, Key, IV, PlainTexts, undefined});
626
627do_api_ng_one_shot({Type, Key, IV, PlainText0, ExpectedEncText}=_X) ->
628    ct:log("~p",[_X]),
629    PlainText = iolist_to_binary(lazy_eval(PlainText0)),
630    EncTxt = crypto:crypto_one_time(Type, Key, IV, PlainText, true),
631    case ExpectedEncText of
632        undefined ->
633            ok;
634        EncTxt ->
635            ok;
636        _ ->
637            ct:log("encode~nIn: ~p~nExpected: ~p~nEnc: ~p~n", [{Type,Key,IV,PlainText}, ExpectedEncText, EncTxt]),
638            ct:fail("api_ng_one_time (encode)",[])
639    end,
640    case crypto:crypto_one_time(Type, Key, IV, EncTxt, false) of
641        PlainText ->
642            ok;
643        OtherPT ->
644            ct:log("decode~nIn: ~p~nExpected: ~p~nDec: ~p~n", [{Type,Key,IV,EncTxt}, PlainText, OtherPT]),
645            ct:fail("api_ng_one_time (decode)",[])
646    end.
647
648%%--------------------------------------------------------------------
649api_ng_tls() ->
650     [{doc, "Test special tls api"}].
651
652api_ng_tls(Config) when is_list(Config) ->
653    [_|_] = Ciphers = lazy_eval(proplists:get_value(cipher, Config, [])),
654    lists:foreach(fun do_api_ng_tls/1, Ciphers).
655
656
657do_api_ng_tls({Type, Key, PlainTexts}=_X) ->
658    ct:log("~p",[_X]),
659    do_api_ng_tls({Type, Key, <<>>, PlainTexts});
660
661do_api_ng_tls({Type, Key, IV, PlainTexts}=_X) ->
662    ct:log("~p",[_X]),
663    do_api_ng_tls({Type, Key, IV, PlainTexts, undefined});
664
665do_api_ng_tls({Type, Key, IV, PlainText0, ExpectedEncText}=_X) ->
666    ct:log("~p",[_X]),
667    PlainText = iolist_to_binary(lazy_eval(PlainText0)),
668    Renc = crypto:crypto_dyn_iv_init(Type, Key, true),
669    Rdec = crypto:crypto_dyn_iv_init(Type, Key, false),
670    EncTxt = crypto:crypto_dyn_iv_update(Renc, PlainText, IV),
671    case ExpectedEncText of
672        undefined ->
673            ok;
674        EncTxt ->
675            %% Now check that the state is NOT updated:
676            case crypto:crypto_dyn_iv_update(Renc, PlainText, IV) of
677                EncTxt ->
678                    ok;
679                EncTxt2 ->
680                    ct:log("2nd encode~nIn: ~p~nExpected: ~p~nEnc: ~p~n", [{Type,Key,IV,PlainText}, EncTxt, EncTxt2]),
681                    ct:fail("api_ng_tls (second encode)",[])
682            end;
683        OtherEnc ->
684            ct:log("1st encode~nIn: ~p~nExpected: ~p~nEnc: ~p~n", [{Type,Key,IV,PlainText}, ExpectedEncText, OtherEnc]),
685            ct:fail("api_ng_tls (encode)",[])
686    end,
687    case crypto:crypto_dyn_iv_update(Rdec, EncTxt, IV) of
688        PlainText ->
689            %% Now check that the state is NOT updated:
690            case crypto:crypto_dyn_iv_update(Rdec, EncTxt, IV) of
691                PlainText ->
692                    ok;
693                PlainText2 ->
694                    ct:log("2nd decode~nIn: ~p~nExpected: ~p~nDec: ~p~n", [{Type,Key,IV,EncTxt}, PlainText, PlainText2]),
695                    ct:fail("api_ng_tls (second decode)",[])
696            end;
697        OtherPT ->
698            ct:log("1st decode~nIn: ~p~nExpected: ~p~nDec: ~p~n", [{Type,Key,IV,EncTxt}, PlainText, OtherPT]),
699            ct:fail("api_ng_tlst (decode)",[])
700    end.
701
702%%--------------------------------------------------------------------
703ec_key_padding(_Config) ->
704    lists:foreach(fun test_ec_key_padding/1,
705                  crypto:supports(curves) -- [ed25519, ed448, x25519, x448]
706                 ).
707
708test_ec_key_padding(CurveName) ->
709    ExpectedSize = expected_ec_size(CurveName),
710    repeat(100, % Enough to provoke an error in the 85 curves
711               % With for example 1000, the total test time would be too large
712           fun() ->
713                   case crypto:generate_key(ecdh, CurveName) of
714                       {_PubKey, PrivKey} when byte_size(PrivKey) == ExpectedSize ->
715                           %% ct:pal("~p:~p Test ~p, size ~p, expected size ~p",
716                           %%        [?MODULE,?LINE, CurveName, byte_size(PrivKey), ExpectedSize]),
717                           ok;
718                       {_PubKey, PrivKey} ->
719                           ct:fail("Bad ~p size: ~p expected: ~p", [CurveName, byte_size(PrivKey), ExpectedSize]);
720                       Other ->
721                           ct:pal("~p:~p ~p", [?MODULE,?LINE,Other]),
722                           ct:fail("Bad public_key:generate_key result for ~p", [CurveName])
723                   end
724           end).
725
726repeat(Times, F) when Times > 0 -> F(), repeat(Times-1, F);
727repeat(_, _) -> ok.
728
729expected_ec_size(CurveName) when is_atom(CurveName) ->
730    expected_ec_size(crypto_ec_curves:curve(CurveName));
731expected_ec_size({{prime_field,_}, _, _, Order, _}) -> byte_size(Order);
732expected_ec_size({{characteristic_two_field, _, _}, _, _, Order, _}) -> size(Order).
733
734%%--------------------------------------------------------------------
735no_aead() ->
736     [{doc, "Test disabled aead ciphers"}].
737no_aead(Config) when is_list(Config) ->
738    EncArg4 =
739        case lazy_eval(proplists:get_value(cipher, Config)) of
740            [{Type, Key, PlainText, Nonce, AAD, CipherText, CipherTag, TagLen, _Info} | _] ->
741                {AAD, PlainText, TagLen};
742            [{Type, Key, PlainText, Nonce, AAD, CipherText, CipherTag, _Info} | _] ->
743                {AAD, PlainText}
744        end,
745    EncryptArgs = [Type, Key, Nonce, EncArg4],
746    DecryptArgs = [Type, Key, Nonce, {AAD, CipherText, CipherTag}],
747    notsup(fun crypto:block_encrypt/4, EncryptArgs),
748    notsup(fun crypto:block_decrypt/4, DecryptArgs).
749
750%%--------------------------------------------------------------------
751no_aead_ng() ->
752     [{doc, "Test disabled aead ciphers"}].
753no_aead_ng(Config) when is_list(Config) ->
754    {EncFun, EncryptArgs} =
755        case lazy_eval(proplists:get_value(cipher, Config)) of
756            [{Type, Key, PlainText, IV, AAD, CipherText, CipherTag, TagLen, _Info} | _] ->
757                {fun crypto:crypto_one_time_aead/7, [Type, Key, IV, PlainText, AAD, TagLen, true]};
758
759            [{Type, Key, PlainText, IV, AAD, CipherText, CipherTag, _Info} | _] ->
760                {fun crypto:crypto_one_time_aead/6, [Type, Key, IV, PlainText, AAD, true]}
761        end,
762    notsup(EncFun, EncryptArgs),
763
764    DecryptArgs = [Type, Key, IV, CipherText, AAD, CipherTag, false],
765    notsup(fun crypto:crypto_one_time_aead/7, DecryptArgs).
766
767%%--------------------------------------------------------------------
768stream() ->
769      [{doc, "Test stream ciphers"}].
770stream(Config) when is_list(Config) ->
771    [_|_] = Streams = lazy_eval(proplists:get_value(cipher, Config)),
772
773    lists:foreach(fun stream_cipher/1, Streams),
774    lists:foreach(fun stream_cipher/1, stream_iolistify(Streams)),
775    lists:foreach(fun stream_cipher_incment/1, stream_iolistify(Streams)).
776%%--------------------------------------------------------------------
777no_stream() ->
778      [{doc, "Test disabled stream ciphers"}].
779no_stream(Config) when is_list(Config) ->
780    Type = ?config(type, Config),
781    notsup(fun crypto:stream_init/2, [Type, <<"Key">>]).
782
783%%--------------------------------------------------------------------
784no_stream_ivec() ->
785      [{doc, "Test disabled stream ciphers that uses ivec"}].
786no_stream_ivec(Config) when is_list(Config) ->
787    Type = ?config(type, Config),
788    notsup(fun crypto:stream_init/3, [Type, <<"Key">>, <<"Ivec">>]).
789
790%%--------------------------------------------------------------------
791aead() ->
792      [{doc, "Test AEAD ciphers"}].
793aead(Config) when is_list(Config) ->
794    [_|_] = AEADs = lazy_eval(proplists:get_value(cipher, Config)),
795    FilteredAEADs =
796	case proplists:get_bool(fips, Config) of
797	    false ->
798		AEADs;
799	    true ->
800		%% In FIPS mode, the IV length must be at least 12 bytes.
801		lists:filter(
802		  fun(Tuple) ->
803			  IVLen = byte_size(element(4, Tuple)),
804			  IVLen >= 12
805		  end, AEADs)
806	end,
807    lists:foreach(fun aead_cipher/1, FilteredAEADs).
808
809%%--------------------------------------------------------------------
810aead_ng(Config) when is_list(Config) ->
811    [_|_] = AEADs = lazy_eval(proplists:get_value(cipher, Config)),
812    FilteredAEADs =
813	case proplists:get_bool(fips, Config) of
814	    false ->
815		AEADs;
816	    true ->
817		%% In FIPS mode, the IV length must be at least 12 bytes.
818		lists:filter(
819		  fun(Tuple) ->
820			  IVLen = byte_size(element(4, Tuple)),
821			  IVLen >= 12
822		  end, AEADs)
823	end,
824    lists:foreach(fun aead_cipher_ng/1, FilteredAEADs ++ spec_0_bytes(Config)).
825
826%%--------------------------------------------------------------------
827aead_bad_tag(Config) ->
828    [_|_] = AEADs = lazy_eval(proplists:get_value(cipher, Config)),
829    FilteredAEADs =
830	case proplists:get_bool(fips, Config) of
831	    false ->
832		AEADs;
833	    true ->
834		%% In FIPS mode, the IV length must be at least 12 bytes.
835		lists:filter(
836		  fun(Tuple) ->
837			  IVLen = byte_size(element(4, Tuple)),
838			  IVLen >= 12
839		  end, AEADs)
840	end,
841    lists:foreach(fun aead_cipher_bad_tag/1, FilteredAEADs).
842
843%%--------------------------------------------------------------------
844sign_verify() ->
845     [{doc, "Sign/verify digital signatures"}].
846sign_verify(Config) when is_list(Config) ->
847    SignVerify = proplists:get_value(sign_verify, Config),
848    lists:foreach(fun do_sign_verify/1, SignVerify).
849
850%%--------------------------------------------------------------------
851no_sign_verify() ->
852    [{doc, "Test disabled sign/verify digital signatures"}].
853no_sign_verify(Config) when is_list(Config) ->
854    [SignVerifyHd|_] = proplists:get_value(sign_verify, Config),
855    notsup(fun do_sign_verify/1, [SignVerifyHd]).
856
857%%--------------------------------------------------------------------
858public_encrypt() ->
859     [{doc, "Test public_encrypt/decrypt "}].
860public_encrypt(Config) when is_list(Config) ->
861    Params = proplists:get_value(pub_pub_encrypt, Config, []),
862    lists:foreach(fun do_public_encrypt/1, Params).
863
864%%--------------------------------------------------------------------
865private_encrypt() ->
866     [{doc, "Test private_encrypt/decrypt functions. "}].
867private_encrypt(Config) when is_list(Config) ->
868    Params = proplists:get_value(pub_priv_encrypt, Config, []),
869    lists:foreach(fun do_private_encrypt/1, Params).
870
871%%--------------------------------------------------------------------
872generate_compute() ->
873     [{doc, " Test crypto:genarate_key and crypto:compute_key"}].
874generate_compute(Config) when is_list(Config) ->
875    GenCom = proplists:get_value(generate_compute, Config),
876    lists:foreach(fun do_generate_compute/1, GenCom).
877%%--------------------------------------------------------------------
878compute_bug() ->
879    [{doc, "Test that it works even if the Secret is smaller than expected"}].
880compute_bug(_Config) ->
881    ExpectedSecret = <<118,89,171,16,156,18,156,103,189,134,130,49,28,144,111,241,247,82,79,32,228,11,209,141,119,176,251,80,105,143,235,251,203,121,223,211,129,3,233,133,45,2,31,157,24,111,5,75,153,66,135,185,128,115,229,178,216,39,73,52,80,151,8,241,34,52,226,71,137,167,53,48,59,224,175,154,89,110,76,83,24,117,149,21,72,6,186,78,149,74,188,56,98,244,30,77,108,248,88,194,195,237,23,51,20,242,254,123,21,12,209,74,217,168,230,65,7,60,211,139,128,239,234,153,22,229,180,59,159,121,41,156,121,200,177,130,163,162,54,224,93,1,94,11,177,254,118,28,156,26,116,10,207,145,219,166,214,189,214,230,221,170,228,15,69,88,31,68,94,255,113,58,49,82,86,192,248,176,131,133,39,186,194,172,206,84,184,16,66,68,153,128,178,227,27,118,52,130,122,92,24,222,102,195,221,207,255,13,152,175,65,32,167,84,54,244,243,109,244,18,234,16,159,224,188,2,106,123,27,17,131,171,226,34,111,251,62,119,155,124,221,124,254,62,97,167,1,105,116,98,98,19,197,30,72,180,79,221,100,134,120,117,124,85,73,132,224,223,222,41,155,137,218,130,238,237,157,161,134,150,69,206,91,141,17,89,120,218,235,229,37,150,76,197,7,157,56,144,42,203,137,100,200,72,141,194,239,1,67,236,238,183,48,214,75,76,108,235,3,237,67,40,137,45,182,236,246,37,116,103,144,237,142,211,88,233,11,24,21,218,41,245,250,51,130,250,104,74,189,17,69,145,70,50,50,215,253,155,10,128,41,114,185,211,82,164,72,92,17,145,104,66,6,140,226,80,43,62,1,166,216,153,118,96,15,147,126,137,118,191,192,75,149,241,206,18,92,17,154,215,219,18,6,139,190,103,210,156,184,29,224,213,157,60,112,189,104,220,125,40,186,50,119,17,143,136,149,38,74,107,21,192,59,61,59,42,231,144,59,175,3,176,87,23,16,122,54,31,82,34,230,211,44,81,41,47,86,37,228,175,130,148,88,136,131,254,241,202,99,199,175,1,141,215,124,155,120,43,141,89,11,140,120,141,29,35,82,219,155,204,75,12,66,241,253,33,250,84,24,85,68,13,80,85,142,227,34,139,26,146,24>>,
882    OthersPublicKey = 635619632099733175381667940709387641100492974601603060984753028943194386334921787463327680809776598322996634648015962954045728174069768874873236397421720142610982770302060309928552098274817978606093380781524199673890631795310930242601197479471368910519338301177304682162189801040921618559902948819107531088646753320486728060005223263561551402855338732899079439899705951063999951507319258050864346087428042978411873495523439615429804957374639092580169417598963105885529553632847023899713490485619763926900318508906706745060947269748612049634207985438016935262521715769812475329234748426647554362991758104620357149045960316987533503707855364806010494793980069245562784050236811004893018183726397041999426883788660276453352521120006817370050691205529335316794439089316232980047277245051173281601960196573681285904611182521967067911862467395705665888521948321299521549941618586026714676885890192323289343756440666276226084448279082483536164085883288884231665240707495770544705648564889889198060417915693315346959170105413290799314390963124178046425737828369059171472978294050322371452255088799865552038756937873388385970088906560408959959429398326288750834357514847891423941047433478384621074116184703014798814515161475596555032391555842,
883    MyPrivateKey = 387759582879975726965038486537011291913744975764132199838375902680222019267527675651273586836110220500657652661706223760165097275862806031329642160439090779625708664007910974206651834216043397115514725827856461492311499129200688538220719685637154290305617686974719521885238198226075381217068175824097878445476010193039590876624464274744156624589136789060427283492343902761765833713520850870233407503430180028104167029073459918756981323130062648615262139444306321256382009848217866984408901761817655567071716275177768316006340055589170095799943481591033461616307776069027985761229636731465482676467627154100912586936231051371168178564599296638350391246393336702334311781595616786107810962134407697848002331639021101685320844880636050048769216986088652236979636019052557155807310341483407890060105599892252118584570558049301477535792498672552850760356632076013402382600669875697284264329434950712239302528367835155163504374877787288116104285944993818319105835423479332617802010952731990182088670508346704423006877514817882782443833997288652405892920173712497948376815825396272381214976859009518623799156300136570204539240675245115597412280078940442452936425561984312708387584800789375684525365060589104566195610526570099527133097201479,
884    P = 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024329058480379,
885    G = 2,
886    DHParameters = [P, G],
887    case crypto:compute_key(dh, OthersPublicKey, MyPrivateKey, DHParameters) of
888        ExpectedSecret ->
889            ok;
890        Others ->
891            ct:log("Got ~p",[Others]),
892            {fail, "crypto:compute_key(dh,...) failed for the bug test"}
893    end.
894
895%%--------------------------------------------------------------------
896no_generate_compute() ->
897     [{doc, "Test crypto:genarate_key and crypto:compute_key "
898       "for disabled algorithms"}].
899no_generate_compute(Config) when is_list(Config) ->
900    %% This test is specific to the SRP protocol
901    srp = ?config(type, Config),
902    {srp,
903     UserPrivate, UserGenParams, UserComParams,
904     HostPublic, HostPrivate, HostGenParams, HostComParams,
905     _SessionKey} = srp3(),
906    UserPublic = HostPublic,                    % use a fake public key
907    notsup(fun crypto:generate_key/3, [srp, UserGenParams, UserPrivate]),
908    notsup(fun crypto:generate_key/3, [srp, HostGenParams, HostPrivate]),
909    notsup(fun crypto:compute_key/4,
910           [srp, HostPublic, {UserPublic, UserPrivate}, UserComParams]),
911    notsup(fun crypto:compute_key/4,
912           [srp, UserPublic, {HostPublic, HostPrivate}, HostComParams]).
913%%--------------------------------------------------------------------
914compute() ->
915     [{doc, " Test crypto:compute_key"}].
916compute(Config) when is_list(Config) ->
917    Gen = proplists:get_value(compute, Config),
918    lists:foreach(fun do_compute/1, Gen).
919%%--------------------------------------------------------------------
920use_all_elliptic_curves() ->
921    [{doc, " Test that all curves from crypto:ec_curves/0"}].
922use_all_elliptic_curves(_Config) ->
923    Msg = <<"hello world!">>,
924    Sups = crypto:supports(),
925    Curves = proplists:get_value(curves, Sups),
926    Hashs = proplists:get_value(hashs, Sups),
927    ct:log("Lib: ~p~nFIPS: ~p~nCurves:~n~p~nHashs: ~p", [crypto:info_lib(),
928                                                         crypto:info_fips(),
929                                                         Curves,
930                                                         Hashs]),
931    Results =
932        [{{Curve,Hash},
933          try
934              {Pub,Priv} = crypto:generate_key(ecdh, Curve),
935              true = is_binary(Pub),
936              true = is_binary(Priv),
937              Sig = crypto:sign(ecdsa, Hash, Msg, [Priv, Curve]),
938              crypto:verify(ecdsa, Hash, Msg, Sig, [Pub, Curve])
939          catch
940              C:E ->
941                  {C,E}
942          end}
943         || Curve <- Curves -- [ed25519, ed448, x25519, x448, ipsec3, ipsec4],
944            Hash <- Hashs -- [md4, md5, ripemd160, sha3_224, sha3_256, sha3_384, sha3_512, blake2b, blake2s]
945        ],
946    Fails =
947        lists:filter(fun({_,true}) -> false;
948                        (_) -> true
949                     end, Results),
950    case Fails of
951        [] ->
952            ok;
953        _ ->
954            ct:log("Fails:~n~p",[Fails]),
955            ct:fail("Bad curve(s)",[])
956    end.
957
958%%--------------------------------------------------------------------
959generate() ->
960     [{doc, " Test crypto:generate_key"}].
961generate(Config) when is_list(Config) ->
962    Gen = proplists:get_value(generate, Config),
963    lists:foreach(fun do_generate/1, Gen).
964%%--------------------------------------------------------------------
965mod_pow() ->
966    [{doc, "mod_pow testing (A ^ M % P with bignums)"}].
967mod_pow(Config) when is_list(Config) ->
968    mod_pow_aux_test(2, 5, 10, 8).
969%%--------------------------------------------------------------------
970exor() ->
971    [{doc, "Test the exor function"}].
972exor(Config) when is_list(Config) ->
973    do_exor(<<1, 2, 3, 4, 5, 6, 7, 8, 9, 10>>),
974    do_exor(term_to_binary(lists:seq(1, 1000000))).
975%%--------------------------------------------------------------------
976rand_uniform() ->
977    [{doc, "rand_uniform and random_bytes testing"}].
978rand_uniform(Config) when is_list(Config) ->
979    rand_uniform_aux_test(10),
980    10 = byte_size(crypto:strong_rand_bytes(10)).
981
982%%--------------------------------------------------------------------
983rand_threads() ->
984    [{doc, "strong_rand_bytes in parallel threads"}].
985rand_threads(Config) when is_list(Config) ->
986    %% This will crash the emulator on at least one version of libcrypto
987    %% with buggy multithreading in RAND_bytes().
988    %% The test needs to run at least a few minutes...
989    NofThreads = 4,
990    Fun = fun F() -> crypto:strong_rand_bytes(16), F() end,
991    PidRefs = [spawn_monitor(Fun) || _ <- lists:seq(1, NofThreads)],
992%%% The test case takes too much time to run.
993%%% Keep it around for reference by setting it down to just 10 seconds.
994%%%    receive after 10 * 60 * 1000 -> ok end, % 10 minutes
995    receive after 10 * 1000 -> ok end, % 10 seconds
996    spawn_link(fun () -> receive after 5000 -> exit(timeout) end end),
997    [exit(Pid, stop) || {Pid,_Ref} <- PidRefs],
998    [receive {'DOWN',Ref,_,_,stop} -> ok end || {_Pid,Ref} <- PidRefs],
999    ok.
1000
1001%%--------------------------------------------------------------------
1002rand_plugin() ->
1003    [{doc, "crypto rand plugin testing (implicit state / process dictionary)"}].
1004rand_plugin(Config) when is_list(Config) ->
1005    rand_plugin_aux(implicit_state).
1006
1007rand_plugin_s() ->
1008    [{doc, "crypto rand plugin testing (explicit state)"}].
1009rand_plugin_s(Config) when is_list(Config) ->
1010    rand_plugin_aux(explicit_state).
1011
1012%%--------------------------------------------------------------------
1013cipher_info() ->
1014    [{doc, "crypto cipher_info testing"}].
1015cipher_info(Config) when is_list(Config) ->
1016    #{type := _,key_length := _,iv_length := _,
1017        block_size := _,mode := _} = crypto:cipher_info(aes_128_cbc),
1018    {'EXIT',_} = (catch crypto:cipher_info(not_a_cipher)),
1019    case lists:foldl(fun(C,Ok) ->
1020                             try crypto:cipher_info(C)
1021                             of
1022                                 _ -> Ok
1023                             catch Cls:Exc ->
1024                                     ct:pal("~p:~p ~p",[Cls,Exc,C]),
1025                                     false
1026                             end
1027                     end,
1028                     true,
1029crypto:supports(ciphers)) of
1030%%                     proplists:get_value(ciphers, crypto:supports())) of
1031        true ->
1032            ok;
1033        false ->
1034            ct:fail('Cipher unsupported',[])
1035    end.
1036
1037
1038%%--------------------------------------------------------------------
1039hash_info() ->
1040    [{doc, "crypto hash_info testing"}].
1041hash_info(Config) when is_list(Config) ->
1042    #{type := _,size := _,block_size := _} = crypto:hash_info(sha256),
1043    {'EXIT',_} = (catch crypto:hash_info(not_a_hash)),
1044    lists:foreach(fun(H) -> crypto:hash_info(H) end,
1045        proplists:get_value(hashs, crypto:supports())).
1046
1047%%--------------------------------------------------------------------
1048%% Internal functions ------------------------------------------------
1049%%--------------------------------------------------------------------
1050hash(_, [], []) ->
1051    ok;
1052hash(Type, [Msg | RestMsg], [Digest| RestDigest]) ->
1053    case crypto:hash(Type, Msg) of
1054	Digest ->
1055	    hash(Type, RestMsg, RestDigest);
1056	Other ->
1057	    ct:fail({{crypto, hash, [Type, Msg]}, {expected, Digest}, {got, Other}})
1058    end.
1059
1060hash_increment(Type, Increments, Digest) ->
1061    State = crypto:hash_init(Type),
1062    case hash_increment(State, Increments) of
1063	Digest ->
1064	    ok;
1065	Other ->
1066	    ct:fail({{crypto, "hash_init/update/final", [Type, Increments]}, {expected, Digest}, {got, Other}})
1067    end.
1068
1069hash_increment(State, []) ->
1070    crypto:hash_final(State);
1071hash_increment(State0, [Increment | Rest]) ->
1072    State = crypto:hash_update(State0, Increment),
1073    hash_increment(State, Rest).
1074
1075
1076%%%----------------------------------------------------------------
1077hmac_check({hmac, sha=Type, Key, <<"Test With Truncation">>=Data, Expected}) ->
1078    do_hmac_check(Type, Key, Data, 20, Expected);
1079hmac_check({hmac, Type, Key, <<"Test With Truncation">>=Data, Expected}) ->
1080    do_hmac_check(Type, Key, Data, 16, Expected);
1081hmac_check({hmac, Type, Key, Data, Expected}) ->
1082    do_hmac_check(Type, Key, Data, Expected).
1083
1084
1085do_hmac_check(Type, Key, Data, Expected) ->
1086    try crypto:hmac(Type, Key, Data)
1087    of
1088	Expected ->
1089	    ok;
1090	Other ->
1091	    ct:fail({{crypto,hmac,[Type,Key,Data]}, {expected,Expected}, {got,Other}})
1092    catch
1093        error:notsup ->
1094            ct:fail("HMAC ~p not supported", [Type]);
1095        Class:Cause ->
1096            ct:fail({{crypto,hmac,[Type,Key,Data]}, {expected,Expected}, {got,{Class,Cause}}})
1097    end.
1098
1099do_hmac_check(Type, Key, Data, MacLength, Expected) ->
1100    try crypto:hmac(Type, Key, Data, MacLength)
1101    of
1102	Expected ->
1103	    ok;
1104	Other ->
1105	    ct:fail({{crypto,hmac,[Type,Key,Data,MacLength]}, {expected,Expected}, {got,Other}})
1106    catch
1107        error:notsup ->
1108            ct:fail("HMAC ~p not supported", [Type]);
1109        Class:Cause ->
1110            ct:fail({{crypto,hmac,[Type,Key,Data,MacLength]}, {expected,Expected}, {got,{Class,Cause}}})
1111    end.
1112
1113
1114%%%----------------------------------------------------------------
1115hmac_increment(Type) ->
1116    Key = hmac_key(Type),
1117    Increments = hmac_inc(Type),
1118    Expected = crypto:hmac(Type, Key, lists:flatten(Increments)),
1119    State = crypto:hmac_init(Type, Key),
1120    case hmac_increment(State, Increments) of
1121	Expected ->
1122	    ok;
1123	Other ->
1124	    ct:fail({{crypto, "hmac_init/update/final", [Type, Increments]}, {expected, Expected}, {got, Other}})
1125    end.
1126
1127hmac_increment(State, []) ->
1128    crypto:hmac_final(State);
1129hmac_increment(State0, [Increment | Rest]) ->
1130    State = crypto:hmac_update(State0, Increment),
1131    hmac_increment(State, Rest).
1132
1133%%%----------------------------------------------------------------
1134cmac_check({cmac, Type, Key, Text, CMac}) ->
1135    ExpCMac = iolist_to_binary(CMac),
1136    case crypto:cmac(Type, Key, Text) of
1137        ExpCMac ->
1138            ok;
1139        Other ->
1140            ct:fail({{crypto, cmac, [Type, Key, Text]}, {expected, ExpCMac}, {got, Other}})
1141    end;
1142cmac_check({cmac, Type, Key, Text, Size, CMac}) ->
1143    ExpCMac = iolist_to_binary(CMac),
1144    case crypto:cmac(Type, Key, Text, Size) of
1145        ExpCMac ->
1146            ok;
1147        Other ->
1148            ct:fail({{crypto, cmac, [Type, Key, Text, Size]}, {expected, ExpCMac}, {got, Other}})
1149    end.
1150
1151
1152mac_check({MacType, SubType, Key, Text, Mac}) ->
1153    ExpMac = iolist_to_binary(Mac),
1154    case crypto:mac(MacType, SubType, Key, Text) of
1155        ExpMac ->
1156            ok;
1157        Other ->
1158            ct:fail({{crypto, mac, [MacType, SubType, Key, Text]}, {expected, ExpMac}, {got, Other}})
1159    end;
1160mac_check({MacType, SubType, Key, Text, Size, Mac}) ->
1161    ExpMac = iolist_to_binary(Mac),
1162    case crypto:mac(MacType, SubType, Key, Text, Size) of
1163        ExpMac ->
1164            ok;
1165        Other ->
1166            ct:fail({{crypto, mac, [MacType, SubType, Key, Text]}, {expected, ExpMac}, {got, Other}})
1167    end.
1168
1169
1170block_cipher({Type, Key,  PlainText}) ->
1171    Plain = iolist_to_binary(PlainText),
1172    CipherText = crypto:block_encrypt(Type, Key, PlainText),
1173    case crypto:block_decrypt(Type, Key, CipherText) of
1174	Plain ->
1175	    ok;
1176	Other ->
1177	    ct:fail({{crypto, block_decrypt, [Type, Key, CipherText]}, {expected, Plain}, {got, Other}})
1178    end;
1179
1180block_cipher({Type, Key,  IV, PlainText}) ->
1181    Plain = iolist_to_binary(PlainText),
1182    CipherText = crypto:block_encrypt(Type, Key, IV, PlainText),
1183    case crypto:block_decrypt(Type, Key, IV, CipherText) of
1184	Plain ->
1185	    ok;
1186	Other ->
1187	    ct:fail({{crypto, block_decrypt, [Type, Key, IV, CipherText]}, {expected, Plain}, {got, Other}})
1188    end;
1189
1190block_cipher({Type, Key, IV, PlainText, CipherText}) ->
1191    Plain = iolist_to_binary(PlainText),
1192    case crypto:block_encrypt(Type, Key, IV, Plain) of
1193	CipherText ->
1194	    ok;
1195	Other0 ->
1196	    ct:fail({{crypto, block_encrypt, [Type, Key, IV, Plain]}, {expected, CipherText}, {got, Other0}})
1197    end,
1198    case crypto:block_decrypt(Type, Key, IV, CipherText) of
1199	Plain ->
1200	    ok;
1201	Other1 ->
1202	    ct:fail({{crypto, block_decrypt, [Type, Key, IV, CipherText]}, {expected, Plain}, {got, Other1}})
1203    end.
1204
1205block_cipher_increment({Type, Key, IV, PlainTexts}) when Type == des_cbc ;
1206                                                         Type == des3_cbc ;
1207                                                         Type == aes_128_cbc ;
1208                                                         Type == aes_192_cbc ;
1209                                                         Type == aes_256_cbc
1210                                                         ->
1211    block_cipher_increment(Type, Key, IV, IV, PlainTexts, iolist_to_binary(PlainTexts), []);
1212block_cipher_increment({Type, Key, IV, PlainTexts, CipherText}) when Type == des_cbc;
1213                                                                     Type == des_ede3_cbc ;
1214                                                                     Type == des3_cbc ;
1215                                                                     Type == des_ede3 ;
1216                                                                     Type == des_ede3_cfb ;
1217                                                                     Type == des_ede3_cbf ;
1218                                                                     Type == des3_cbf ;
1219                                                                     Type == des3_cfb
1220                                                                     ->
1221    block_cipher_increment(Type, Key, IV, IV, PlainTexts, iolist_to_binary(PlainTexts), CipherText, []);
1222block_cipher_increment({Type, Key, IV, PlainTexts, _CipherText}) when Type == aes_128_cbc ;
1223                                                                      Type == aes_192_cbc ;
1224                                                                      Type == aes_256_cbc
1225                                                                      ->
1226    Plain = iolist_to_binary(PlainTexts),
1227    Blocks = [iolistify(Block) || << Block:128/bitstring >> <= Plain],
1228    block_cipher_increment(Type, Key, IV, IV, Blocks, Plain, []);
1229block_cipher_increment({_Type, _, _, _, _}) ->
1230    ok;
1231block_cipher_increment({_Type, _, _, _}) ->
1232    ok;
1233block_cipher_increment({_,_,_}) ->
1234    ok.
1235block_cipher_increment(Type, Key, IV0, _IV, [], Plain, Acc) ->
1236    CipherText = iolist_to_binary(lists:reverse(Acc)),
1237    case crypto:block_decrypt(Type, Key, IV0, CipherText) of
1238	Plain ->
1239	    ok;
1240	Other ->
1241	    ct:fail({{crypto, block_decrypt, [Type, Key, IV0, CipherText]}, {expected, Plain}, {got, Other}})
1242    end;
1243block_cipher_increment(Type, Key, IV0, IV, [PlainText | PlainTexts], Plain, Acc) ->
1244    CipherText = crypto:block_encrypt(Type, Key, IV, PlainText),
1245    NextIV = crypto:next_iv(Type, CipherText),
1246    block_cipher_increment(Type, Key, IV0, NextIV, PlainTexts, Plain, [CipherText | Acc]).
1247block_cipher_increment(Type, Key, IV0, _IV, [], _Plain, CipherText, Acc) ->
1248    case iolist_to_binary(lists:reverse(Acc)) of
1249	CipherText ->
1250	    ok;
1251	Other ->
1252	    ct:fail({{crypto, block_decrypt, [Type, Key, IV0, CipherText]}, {expected, CipherText}, {got, Other}})
1253    end;
1254block_cipher_increment(Type, Key, IV0, IV, [PlainText | PlainTexts], Plain, CipherText, Acc) ->
1255    CT = crypto:block_encrypt(Type, Key, IV, PlainText),
1256    NextIV = crypto:next_iv(Type, CT),
1257    block_cipher_increment(Type, Key, IV0, NextIV, PlainTexts, Plain, CipherText, [CT | Acc]).
1258
1259stream_cipher({Type, Key, PlainText0}) ->
1260    PlainText = lazy_eval(PlainText0),
1261    Plain = iolist_to_binary(lazy_eval(PlainText)),
1262    StateE = crypto:stream_init(Type, Key),
1263    StateD = crypto:stream_init(Type, Key),
1264    {_, CipherText} = crypto:stream_encrypt(StateE, PlainText),
1265    case crypto:stream_decrypt(StateD, CipherText) of
1266	{_, Plain} ->
1267	    ok;
1268	Other ->
1269	    ct:fail({{crypto, stream_decrypt, [StateD, CipherText]}, {expected, PlainText}, {got, Other}})
1270    end;
1271stream_cipher({Type, Key, IV, PlainText0}) ->
1272    PlainText = lazy_eval(PlainText0),
1273    Plain = iolist_to_binary(PlainText),
1274    StateE = crypto:stream_init(Type, Key, IV),
1275    StateD = crypto:stream_init(Type, Key, IV),
1276    {_, CipherText} = crypto:stream_encrypt(StateE, PlainText),
1277    case crypto:stream_decrypt(StateD, CipherText) of
1278	{_, Plain} ->
1279	    ok;
1280	Other ->
1281	    ct:fail({{crypto, stream_decrypt, [StateD, CipherText]}, {expected, PlainText}, {got, Other}})
1282    end;
1283stream_cipher({Type, Key, IV, PlainText0, CipherText}) ->
1284    PlainText = lazy_eval(PlainText0),
1285    Plain = iolist_to_binary(PlainText),
1286    StateE = crypto:stream_init(Type, Key, IV),
1287    StateD = crypto:stream_init(Type, Key, IV),
1288    case crypto:stream_encrypt(StateE, PlainText) of
1289        {_, CipherText} ->
1290            ok;
1291        {_, Other0} ->
1292            ct:fail({{crypto, stream_encrypt, [StateE, Type, Key, IV, Plain]}, {expected, CipherText}, {got, Other0}})
1293    end,
1294    case crypto:stream_decrypt(StateD, CipherText) of
1295        {_, Plain} ->
1296            ok;
1297        Other1 ->
1298            ct:fail({{crypto, stream_decrypt, [StateD, CipherText]}, {expected, PlainText}, {got, Other1}})
1299    end.
1300
1301stream_cipher_incment({Type, Key, PlainTexts}) ->
1302    StateE = crypto:stream_init(Type, Key),
1303    StateD = crypto:stream_init(Type, Key),
1304    stream_cipher_incment_loop(StateE, StateD, PlainTexts, [], iolist_to_binary(PlainTexts));
1305stream_cipher_incment({Type, Key, IV, PlainTexts}) ->
1306    StateE = crypto:stream_init(Type, Key, IV),
1307    StateD = crypto:stream_init(Type, Key, IV),
1308    stream_cipher_incment_loop(StateE, StateD, PlainTexts, [], iolist_to_binary(PlainTexts));
1309stream_cipher_incment({Type, Key, IV, PlainTexts, _CipherText}) ->
1310    stream_cipher_incment({Type, Key, IV, PlainTexts}).
1311
1312stream_cipher_incment_loop(_State, OrigState, [], Acc, Plain) ->
1313    CipherText = iolist_to_binary(lists:reverse(Acc)),
1314    case crypto:stream_decrypt(OrigState, CipherText) of
1315	{_, Plain} ->
1316	    ok;
1317	Other ->
1318	    ct:fail({{crypto, stream_decrypt, [OrigState, CipherText]}, {expected, Plain}, {got, Other}})
1319    end;
1320stream_cipher_incment_loop(State0, OrigState, [PlainText | PlainTexts], Acc, Plain) ->
1321    {State, CipherText} = crypto:stream_encrypt(State0, PlainText),
1322    stream_cipher_incment_loop(State, OrigState, PlainTexts, [CipherText | Acc], Plain).
1323
1324aead_cipher({Type, Key, PlainText, IV, AAD, CipherText, CipherTag, Info}) ->
1325    Plain = iolist_to_binary(PlainText),
1326    case crypto:block_encrypt(Type, Key, IV, {AAD, Plain}) of
1327	{CipherText, CipherTag} ->
1328	    ok;
1329	Other0 ->
1330	    ct:fail({{crypto,
1331                      block_encrypt,
1332                      [{info,Info}, {key,Key}, {pt,PlainText}, {iv,IV}, {aad,AAD}, {ct,CipherText}, {tag,CipherTag}]},
1333                     {expected, {CipherText, CipherTag}},
1334                     {got, Other0}})
1335    end,
1336    case crypto:block_decrypt(Type, Key, IV, {AAD, CipherText, CipherTag}) of
1337	Plain ->
1338	    ok;
1339	Other1 ->
1340	    ct:fail({{crypto,
1341                      block_decrypt,
1342                      [{info,Info}, {key,Key}, {pt,PlainText}, {iv,IV}, {aad,AAD}, {ct,CipherText}, {tag,CipherTag}]},
1343                     {expected, Plain},
1344                     {got, Other1}})
1345    end;
1346aead_cipher({Type, Key, PlainText, IV, AAD, CipherText, CipherTag, TagLen, Info}) ->
1347    <<TruncatedCipherTag:TagLen/binary, _/binary>> = CipherTag,
1348    Plain = iolist_to_binary(PlainText),
1349    try crypto:block_encrypt(Type, Key, IV, {AAD, Plain, TagLen}) of
1350	{CipherText, TruncatedCipherTag} ->
1351	    ok;
1352	Other0 ->
1353	    ct:fail({{crypto,
1354                      block_encrypt,
1355                      [{info,Info}, {key,Key}, {pt,PlainText}, {iv,IV}, {aad,AAD}, {ct,CipherText}, {tag,CipherTag}, {taglen,TagLen}]},
1356                     {expected, {CipherText, TruncatedCipherTag}},
1357                     {got, Other0}})
1358    catch
1359        error:E ->
1360            ct:log("~p",[{Type, Key, PlainText, IV, AAD, CipherText, CipherTag, TagLen, Info}]),
1361            try crypto:crypto_one_time_aead(Type, Key, IV, PlainText, AAD, TagLen, true)
1362            of
1363                RR ->
1364                    ct:log("Works: ~p",[RR])
1365            catch
1366                CC:EE ->
1367                    ct:log("~p:~p", [CC,EE])
1368            end,
1369            ct:fail("~p",[E])
1370    end,
1371    case crypto:block_decrypt(Type, Key, IV, {AAD, CipherText, TruncatedCipherTag}) of
1372	Plain ->
1373	    ok;
1374	Other1 ->
1375	    ct:fail({{crypto,
1376                      block_decrypt,
1377                      [{info,Info}, {key,Key}, {pt,PlainText}, {iv,IV}, {aad,AAD}, {ct,CipherText}, {tag,CipherTag},
1378                       {truncated,TruncatedCipherTag}]},
1379                     {expected, Plain},
1380                     {got, Other1}})
1381    end.
1382
1383aead_cipher_ng({Type, Key, PlainText, IV, AAD, CipherText, CipherTag, Info}) ->
1384    Plain = iolist_to_binary(PlainText),
1385    case crypto:crypto_one_time_aead(Type, Key, IV, PlainText, AAD, true) of
1386	{CipherText, CipherTag} ->
1387	    ok;
1388	Other0 ->
1389	    ct:fail({{crypto,
1390                      block_encrypt,
1391                      [{info,Info}, {key,Key}, {pt,PlainText}, {iv,IV}, {aad,AAD}, {ct,CipherText}, {tag,CipherTag}]},
1392                     {expected, {CipherText, CipherTag}},
1393                     {got, Other0}})
1394    end,
1395    case crypto:crypto_one_time_aead(Type, Key, IV, CipherText, AAD, CipherTag, false) of
1396	Plain ->
1397	    ok;
1398	Other1 ->
1399	    ct:fail({{crypto,
1400                      block_decrypt,
1401                      [{info,Info}, {key,Key}, {pt,PlainText}, {iv,IV}, {aad,AAD}, {ct,CipherText}, {tag,CipherTag}]},
1402                     {expected, Plain},
1403                     {got, Other1}})
1404    end;
1405aead_cipher_ng({Type, Key, PlainText, IV, AAD, CipherText, CipherTag, TagLen, Info}) ->
1406    <<TruncatedCipherTag:TagLen/binary, _/binary>> = CipherTag,
1407    Plain = iolist_to_binary(PlainText),
1408    try crypto:crypto_one_time_aead(Type, Key, IV, PlainText, AAD, TagLen, true) of
1409	{CipherText, TruncatedCipherTag} ->
1410	    ok;
1411	Other0 ->
1412	    ct:fail({{crypto,
1413                      block_encrypt,
1414                      [{info,Info}, {key,Key}, {pt,PlainText}, {iv,IV}, {aad,AAD}, {ct,CipherText}, {tag,CipherTag}, {taglen,TagLen}]},
1415                     {expected, {CipherText, TruncatedCipherTag}},
1416                     {got, Other0}})
1417    catch
1418        error:E ->
1419            ct:log("~p",[{Type, Key, PlainText, IV, AAD, CipherText, CipherTag, TagLen, Info}]),
1420            try crypto:crypto_one_time_aead(Type, Key, IV, PlainText, AAD, TagLen, true)
1421            of
1422                RR ->
1423                    ct:log("Works: ~p",[RR])
1424            catch
1425                CC:EE ->
1426                    ct:log("~p:~p", [CC,EE])
1427            end,
1428            ct:fail("~p",[E])
1429    end,
1430    case crypto:crypto_one_time_aead(Type, Key, IV, CipherText, AAD, TruncatedCipherTag, false) of
1431	Plain ->
1432	    ok;
1433	Other1 ->
1434	    ct:fail({{crypto,
1435                      block_decrypt,
1436                      [{info,Info}, {key,Key}, {pt,PlainText}, {iv,IV}, {aad,AAD}, {ct,CipherText}, {tag,CipherTag},
1437                       {truncated,TruncatedCipherTag}]},
1438                     {expected, Plain},
1439                     {got, Other1}})
1440    end.
1441
1442mk_bad_tag(CipherTag) ->
1443    case <<0:(size(CipherTag))/unit:8>> of
1444        CipherTag -> % The correct tag may happen to be a suite of zeroes
1445            <<1:(size(CipherTag))/unit:8>>;
1446        X ->
1447            X
1448    end.
1449
1450aead_cipher_bad_tag({Type, Key, PlainText, IV, AAD, CipherText, CipherTag, Info}) ->
1451    Plain = iolist_to_binary(PlainText),
1452    BadTag = mk_bad_tag(CipherTag),
1453    case crypto:crypto_one_time_aead(Type, Key, IV, CipherText, AAD, BadTag, false) of
1454	error ->
1455            ok;
1456	Plain ->
1457            ct:log("~p:~p~n info: ~p~n key: ~p~n pt: ~p~n iv: ~p~n aad: ~p~n ct: ~p~n tag: ~p~n bad tag: ~p~n",
1458                   [?MODULE,?LINE,Info, Key, PlainText, IV, AAD, CipherText, CipherTag, BadTag]),
1459            ct:fail("Didn't fail on bad tag")
1460    end;
1461aead_cipher_bad_tag({Type, Key, PlainText, IV, AAD, CipherText, CipherTag, TagLen, Info}) ->
1462    Plain = iolist_to_binary(PlainText),
1463    <<TruncatedCipherTag:TagLen/binary, _/binary>> = CipherTag,
1464    BadTruncatedTag = mk_bad_tag(TruncatedCipherTag),
1465    case  crypto:crypto_one_time_aead(Type, Key, IV, CipherText, AAD, BadTruncatedTag, false) of
1466	error ->
1467	    ok;
1468	Plain ->
1469            ct:log("~p:~p~n info: ~p~n key: ~p~n pt: ~p~n iv: ~p~n aad: ~p~n ct: ~p~n tag: ~p~n bad tag: ~p~n",
1470                   [Info, Key, PlainText, IV, AAD, CipherText, TruncatedCipherTag, BadTruncatedTag]),
1471            ct:fail("Didn't fail on bad tag")
1472    end.
1473
1474do_sign_verify({Type, undefined=Hash, Private, Public, Msg, Signature}) ->
1475    case crypto:sign(eddsa, Hash, Msg, [Private,Type]) of
1476        Signature ->
1477            ct:log("OK crypto:sign(eddsa, ~p, Msg, [Private,~p])", [Hash,Type]),
1478            case crypto:verify(eddsa, Hash, Msg, Signature, [Public,Type]) of
1479                true ->
1480                    ct:log("OK crypto:verify(eddsa, ~p, Msg, Signature, [Public,~p])", [Hash,Type]),
1481                    negative_verify(eddsa, Hash, Msg, <<10,20>>, [Public,Type]);
1482                false ->
1483                    ct:log("ERROR crypto:verify(eddsa, ~p, Msg= ~p, Signature= ~p, [Public= ~p,~p])",
1484                           [Hash,Msg,Signature,Public,Type]),
1485                    ct:fail({{crypto, verify, [eddsa, Hash, Msg, Signature, [Public,Type]]}})
1486            end;
1487        ErrorSig ->
1488            ct:log("ERROR crypto:sign(~p, ~p, ..., [Private= ~p,~p])", [eddsa,Hash,Private,Type]),
1489            ct:log("ERROR crypto:verify(eddsa, ~p, Msg= ~p, [Public= ~p,~p])~n"
1490                   "ErrorSig   = ~p~n"
1491                   "CorrectSig = ~p~n"
1492                  ,
1493                   [Hash,Msg,Public,Type,ErrorSig,Signature]),
1494            ct:fail({{crypto, sign, [Type, Hash, Msg, ErrorSig, [Private]]}})
1495    end;
1496
1497do_sign_verify({Type, Hash, Public, Private, Msg}) ->
1498    Signature = crypto:sign(Type, Hash, Msg, Private),
1499    case crypto:verify(Type, Hash, Msg, Signature, Public) of
1500	true ->
1501            ct:log("OK crypto:sign(~p, ~p, ..., ..., ...)", [Type,Hash]),
1502	    negative_verify(Type, Hash, Msg, <<10,20>>, Public);
1503	false ->
1504            ct:log("ERROR crypto:sign(~p, ~p, ..., ..., ...)", [Type,Hash]),
1505	    ct:fail({{crypto, verify, [Type, Hash, Msg, Signature, Public]}})
1506    end;
1507do_sign_verify({Type, Hash, Public, Private, Msg, Options}) ->
1508    LibVer =
1509        case crypto:info_lib() of
1510            [{<<"OpenSSL">>,Ver,<<"OpenSSL",_/binary>>}] -> Ver;
1511            _ -> infinity
1512        end,
1513    Pad = proplists:get_value(rsa_padding, Options),
1514    NotSupLow = lists:member(Pad, [rsa_pkcs1_pss_padding]),
1515    try
1516        crypto:sign(Type, Hash, Msg, Private, Options)
1517    of
1518        Signature ->
1519            case crypto:verify(Type, Hash, Msg, Signature, Public, Options) of
1520                true ->
1521                    ct:log("OK crypto:sign(~p, ~p, ..., ..., ..., ~p)", [Type,Hash,Options]),
1522                    negative_verify(Type, Hash, Msg, <<10,20>>, Public, Options);
1523                false ->
1524                    ct:log("ERROR crypto:sign(~p, ~p, ..., ..., ..., ~p)", [Type,Hash,Options]),
1525                    ct:fail({{crypto, verify, [Type, Hash, Msg, Signature, Public, Options]}})
1526            end
1527    catch
1528        error:notsup when NotSupLow == true,
1529                          is_integer(LibVer),
1530                          LibVer < 16#10001000 ->
1531            %% Those opts where introduced in 1.0.1
1532            ct:log("notsup but OK in old cryptolib crypto:sign(~p, ~p, ..., ..., ..., ~p)",
1533                   [Type,Hash,Options]),
1534            true;
1535        C:E ->
1536            ct:log("~p:~p  crypto:sign(~p, ~p, ..., ..., ..., ~p)", [C,E,Type,Hash,Options]),
1537            ct:fail({{crypto, sign_verify, [LibVer, Type, Hash, Msg, Public, Options]}})
1538    end.
1539
1540negative_verify(Type, Hash, Msg, Signature, Public) ->
1541    case crypto:verify(Type, Hash, Msg, Signature, Public) of
1542	true ->
1543	    ct:fail({{crypto, verify, [Type, Hash, Msg, Signature, Public]}, should_fail});
1544	false ->
1545	    ok
1546    end.
1547
1548negative_verify(Type, Hash, Msg, Signature, Public, Options) ->
1549    case crypto:verify(Type, Hash, Msg, Signature, Public, Options) of
1550	true ->
1551	    ct:fail({{crypto, verify, [Type, Hash, Msg, Signature, Public, Options]}, should_fail});
1552	false ->
1553	    ok
1554    end.
1555
1556do_public_encrypt({Type, Public, Private, Msg, Padding}) ->
1557    try
1558        crypto:public_encrypt(Type, Msg, Public, Padding)
1559    of
1560        PublicEcn ->
1561            try
1562                crypto:private_decrypt(Type, PublicEcn, Private, Padding)
1563            of
1564                Msg ->
1565                    ok;
1566                Other ->
1567                    ct:fail({{crypto, private_decrypt, [Type, PublicEcn, Private, Padding]}, {expected, Msg}, {got, Other}})
1568            catch
1569                CC:EE ->
1570                    ct:fail({{crypto, private_decrypt, [Type, PublicEcn, Private, Padding]}, {expected, Msg}, {got, {CC,EE}}})
1571            end
1572    catch
1573        CC:EE ->
1574            ct:fail({{crypto, public_encrypt, [Type, Msg, Public, Padding]}, {got, {CC,EE}}})
1575    end.
1576
1577
1578do_private_encrypt({Type, Public, Private, Msg, Padding}) ->
1579    try
1580        crypto:private_encrypt(Type, Msg, Private, Padding)
1581    of
1582        PrivEcn ->
1583            try
1584                crypto:public_decrypt(Type, PrivEcn, Public, Padding)
1585            of
1586                Msg ->
1587                    ok;
1588                Other ->
1589                    ct:fail({{crypto, public_decrypt, [Type, PrivEcn, Public, Padding]}, {expected, Msg}, {got, Other}})
1590            catch
1591                CC:EE ->
1592                    ct:fail({{crypto, public_decrypt, [Type, PrivEcn, Public, Padding]}, {expected, Msg}, {got, {CC,EE}}})
1593            end
1594    catch
1595        CC:EE ->
1596            ct:fail({{crypto, private_encrypt, [Type, Msg, Private, Padding]}, {got, {CC,EE}}})
1597    end.
1598
1599do_generate_compute({srp = Type, UserPrivate, UserGenParams, UserComParams,
1600		     HostPublic, HostPrivate, HostGenParams, HostComParam, SessionKey}) ->
1601    {UserPublic, UserPrivate} = crypto:generate_key(Type, UserGenParams, UserPrivate),
1602    {HostPublic, HostPrivate} = crypto:generate_key(Type, HostGenParams, HostPrivate),
1603    SessionKey = crypto:compute_key(Type, HostPublic, {UserPublic, UserPrivate},
1604     				    UserComParams),
1605    SessionKey = crypto:compute_key(Type, UserPublic, {HostPublic, HostPrivate},
1606				    HostComParam);
1607do_generate_compute({dh, P, G}) ->
1608    {UserPub, UserPriv} = crypto:generate_key(dh, [P, G]),
1609    {HostPub, HostPriv} = crypto:generate_key(dh, [P, G]),
1610    SharedSecret = crypto:compute_key(dh, HostPub, UserPriv, [P, G]),
1611    SharedSecret = crypto:compute_key(dh, UserPub, HostPriv, [P, G]).
1612
1613do_compute({ecdh = Type, Pub, Priv, Curve, SharedSecret}) ->
1614    Secret = crypto:compute_key(Type, Pub, Priv, Curve),
1615     case Secret of
1616	 SharedSecret ->
1617	     ok;
1618	 Other ->
1619	     ct:fail({{crypto, compute_key, [Type, Pub, Priv, Curve]}, {expected, SharedSecret}, {got, Other}})
1620     end.
1621
1622do_generate({ecdh = Type, Curve, Priv, Pub}) ->
1623    case crypto:generate_key(Type, Curve, Priv) of
1624	{Pub, _} ->
1625	    ok;
1626	{Other, _} ->
1627	    ct:fail({{crypto, generate_key, [Type, Priv, Curve]}, {expected, Pub}, {got, Other}})
1628    end;
1629do_generate({rsa = Type, Mod, Exp}) ->
1630    case crypto:info_fips() of
1631        enabled when Mod < 3072 ->
1632            ct:log("SKIP do_generate ~p FIPS=~p, Mod=~p  Exp=~p", [Type, enabled, Mod, Exp]),
1633            {skip, "FIPS violation"};
1634        FIPS ->
1635            ct:log("do_generate ~p FIPS=~p, Mod=~p  Exp=~p", [Type, FIPS, Mod, Exp]),
1636            {Pub,Priv} = crypto:generate_key(Type, {Mod,Exp}),
1637            do_sign_verify({rsa, sha256, Pub, Priv, rsa_plain()})
1638    end.
1639
1640notsup(Fun, Args) ->
1641    Result =
1642        try
1643            {error, {return, apply(Fun, Args)}}
1644        catch
1645            error:notsup ->
1646                ok;
1647            error: {notsup, _, _} ->
1648                ok;
1649            Class:Error ->
1650                {error, {Class, Error}}
1651        end,
1652    case Result of
1653        ok ->
1654            ok;
1655        {error, Value} ->
1656            {module, Module} = erlang:fun_info(Fun, module),
1657            {name,   Name}   = erlang:fun_info(Fun, name),
1658            ct:fail({{Module, Name, Args}, {expected, {error, notsup}}, {got, Value}})
1659    end.
1660
1661hexstr2point(X, Y) ->
1662    <<4:8, (hexstr2bin(X))/binary, (hexstr2bin(Y))/binary>>.
1663
1664hexstr2bin(S) when is_binary(S) ->
1665    list_to_binary(hexstr2list(binary_to_list(S)));
1666hexstr2bin(S) ->
1667    list_to_binary(hexstr2list(S)).
1668
1669hexstr2list([$ |T]) ->
1670    hexstr2list(T);
1671hexstr2list([X,Y|T]) ->
1672    [mkint(X)*16 + mkint(Y) | hexstr2list(T)];
1673hexstr2list([]) ->
1674    [].
1675mkint(C) when $0 =< C, C =< $9 ->
1676    C - $0;
1677mkint(C) when $A =< C, C =< $F ->
1678    C - $A + 10;
1679mkint(C) when $a =< C, C =< $f ->
1680    C - $a + 10.
1681
1682bin2hexstr(B) when is_binary(B) ->
1683    io_lib:format("~.16b",[crypto:bytes_to_integer(B)]).
1684
1685decstr2int(S) when is_binary(S) ->
1686    list_to_integer(binary:bin_to_list(S));
1687decstr2int(S) ->
1688    list_to_integer(S).
1689
1690is_supported(Group) ->
1691    lists:member(Group, lists:append([Algo ||  {_, Algo}  <- crypto:supports()])).
1692
1693mac_listify(Blocks) ->
1694    lists:map(fun do_mac_listify/1, Blocks).
1695block_iolistify(Blocks) ->
1696    lists:map(fun do_block_iolistify/1, Blocks).
1697stream_iolistify(Streams) ->
1698    lists:map(fun do_stream_iolistify/1, Streams).
1699
1700do_mac_listify({MType, Type, Key, Text, CMac}) ->
1701    {MType, Type, iolistify(Key), iolistify(Text), CMac};
1702do_mac_listify({MType, Type, Key, Text, Size, CMac}) ->
1703    {MType, Type, iolistify(Key), iolistify(Text), Size, CMac}.
1704
1705do_stream_iolistify({Type, Key, PlainText}) ->
1706    {Type, iolistify(Key), iolistify(PlainText)};
1707do_stream_iolistify({Type, Key, IV, PlainText}) ->
1708    {Type, iolistify(Key), IV, iolistify(PlainText)};
1709do_stream_iolistify({Type, Key, IV, PlainText, CipherText}) ->
1710    {Type, iolistify(Key), IV, iolistify(PlainText), CipherText}.
1711do_block_iolistify({Type, Key, IV, PlainText}) when Type == des_cbc ;
1712                                                    Type == des_ede3_cbc ;
1713                                                    Type == des3_cbc ;
1714                                                    Type == des_ede3 ;
1715                                                    Type == des_ede3_cfb ;
1716                                                    Type == des_ede3_cbf ;
1717                                                    Type == des3_cbf ;
1718                                                    Type == des3_cfb
1719                                                    ->
1720    {Type, Key, IV, des_iolistify(PlainText)};
1721do_block_iolistify({Type, Key, PlainText}) ->
1722    {Type, iolistify(Key), iolistify(PlainText)};
1723do_block_iolistify({Type, Key, IV, PlainText}) ->
1724    {Type, iolistify(Key), IV, iolistify(PlainText)};
1725do_block_iolistify({Type, Key, IV, PlainText, CipherText}) ->
1726    {Type, iolistify(Key), IV, iolistify(PlainText), CipherText}.
1727
1728iolistify(X) ->
1729    iolistify1(lazy_eval(X)).
1730
1731iolistify1(<<"Test With Truncation">>)->
1732    %% Do not iolistify as it spoils this special case
1733    <<"Test With Truncation">>;
1734iolistify1(Msg) when is_binary(Msg) ->
1735    Length = erlang:byte_size(Msg),
1736    Split = Length div 2,
1737    List0 = binary_to_list(Msg),
1738   case lists:split(Split, List0) of
1739       {[Element | List1], List2} ->
1740	   [[Element], List1, List2];
1741       {List1, List2}->
1742	   [List1, List2]
1743   end;
1744iolistify1(Msg) when is_list(Msg) ->
1745    iolistify1(list_to_binary(Msg)).
1746
1747des_iolistify(Msg) ->
1748    des_iolist(erlang:byte_size(Msg) div 8, Msg, []).
1749
1750des_iolist(1, Msg, Acc) ->
1751    lists:reverse([Msg | Acc]);
1752des_iolist(Split, Msg, Acc) ->
1753    <<Part:8/binary, Rest/binary>> = Msg,
1754    des_iolist(Split-1, Rest, [Part | Acc]).
1755
1756%%--------------------------------------------------------------------
1757mod_pow_aux_test(_, _, _, 0) ->
1758    ok;
1759mod_pow_aux_test(B, E, M, N) ->
1760    Result = crypto:bytes_to_integer(crypto:mod_pow(B, E, M)),
1761    Result = ipow(B, E, M),
1762    mod_pow_aux_test(B, E*E+1, M*M+1, N-1).
1763
1764%% mod_exp in erlang (copied from jungerl's ssh_math.erl)
1765ipow(A, B, M) when M > 0, B >= 0 ->
1766    if A == 1 ->
1767 	    1;
1768       true ->
1769 	    ipow(A, B, M, 1)
1770    end.
1771
1772ipow(A, 1, M, Prod) ->
1773    (A*Prod) rem M;
1774ipow(_A, 0, _M, Prod) ->
1775    Prod;
1776ipow(A, B, M, Prod)  ->
1777    B1 = B bsr 1,
1778    A1 = (A*A) rem M,
1779    if B - B1 == B1 ->
1780	    ipow(A1, B1, M, Prod);
1781       true ->
1782	    ipow(A1, B1, M, (A*Prod) rem M)
1783    end.
1784
1785do_exor(B) ->
1786    Z1 = zero_bin(B),
1787    Z1 = crypto:exor(B, B),
1788    B1 = crypto:strong_rand_bytes(100),
1789    B2 = crypto:strong_rand_bytes(100),
1790    Z2 = zero_bin(B1),
1791    Z2 = crypto:exor(B1, B1),
1792    Z2 = crypto:exor(B2, B2),
1793    R = xor_bytes(B1, B2),
1794    R = crypto:exor(B1, B2).
1795
1796zero_bin(N) when is_integer(N) ->
1797    N8 = N * 8,
1798    <<0:N8/integer>>;
1799zero_bin(B) when is_binary(B) ->
1800    zero_bin(size(B)).
1801xor_bytes(Bin1, Bin2) when is_binary(Bin1), is_binary(Bin2) ->
1802    L1 = binary_to_list(Bin1),
1803    L2 = binary_to_list(Bin2),
1804    list_to_binary(xor_bytes(L1, L2));
1805xor_bytes(L1, L2) ->
1806    xor_bytes(L1, L2, []).
1807
1808xor_bytes([], [], Acc) ->
1809    lists:reverse(Acc);
1810xor_bytes([N1 | Tl1], [N2 | Tl2], Acc) ->
1811    xor_bytes(Tl1, Tl2, [N1 bxor N2 | Acc]).
1812rand_uniform_aux_test(0) ->
1813    ok;
1814rand_uniform_aux_test(N) ->
1815    L = N*1000,
1816    H = N*100000+1,
1817    crypto_rand_uniform(L, H),
1818    crypto_rand_uniform(-L, L),
1819    crypto_rand_uniform(-H, -L),
1820    crypto_rand_uniform(-H, L),
1821    rand_uniform_aux_test(N-1).
1822
1823crypto_rand_uniform(L,H) ->
1824    R1 = (L-1) + rand:uniform(H-L),
1825    case (R1 >= L) and (R1 < H) of
1826	true  ->
1827	    ok;
1828	false ->
1829	    ct:fail({"Not in interval", R1, L, H})
1830    end.
1831
1832foldallmap(_Fun, AccN, []) ->
1833    {true, AccN};
1834foldallmap(Fun, AccN, [H|T]) ->
1835    case Fun(H, AccN) of
1836        {true, AccM} -> foldallmap(Fun, AccM, T);
1837        {{false, Result}, AccM} -> {Result, AccM}
1838    end.
1839
1840allmap(_Fun, []) ->
1841    true;
1842allmap(Fun, [H|T]) ->
1843    case Fun(H) of
1844        true -> allmap(Fun, T);
1845        {false, Result} -> Result
1846    end.
1847
1848rand_plugin_aux(StateType) ->
1849    {Seeder, SeedExporter, FloatGenerator, IntegerGenerator} = rand_plugin_functions(StateType),
1850    State0 = Seeder(),
1851    {crypto, no_seed} = SeedExporter(State0),
1852    {FloatTestResult, State1} = rand_plugin_aux_floats(State0, FloatGenerator),
1853    case FloatTestResult of
1854        true ->
1855            {IntegerTestResult, _State2} = rand_plugin_aux_integers(State1, IntegerGenerator),
1856            IntegerTestResult;
1857        {false, _} ->
1858            FloatTestResult
1859    end.
1860
1861% returns {Seeder, SeedExporter, FloatGenerator, IntegerGenerator} with consistent signatures
1862rand_plugin_functions(implicit_state) ->
1863    {fun () -> crypto:rand_seed(), implicit_state end,
1864     fun (implicit_state) -> rand:export_seed() end,
1865     fun (implicit_state) -> {rand:uniform(), implicit_state} end,
1866     fun (N, implicit_state) -> {rand:uniform(N), implicit_state} end};
1867rand_plugin_functions(explicit_state) ->
1868    {fun crypto:rand_seed_s/0,
1869     fun rand:export_seed_s/1,
1870     fun rand:uniform_s/1,
1871     fun rand:uniform_s/2}.
1872
1873rand_plugin_aux_floats(State0, FloatGenerator) ->
1874    {FloatSamples, State1} =
1875        lists:mapfoldl(
1876          fun (_, StateAcc) ->
1877                  FloatGenerator(StateAcc)
1878          end,
1879          State0,
1880          lists:seq(1, 10000)),
1881
1882    {allmap(
1883       fun (V) ->
1884               (V >= 0.0 andalso V < 1.0)
1885               orelse {false, ct:fail({"Float sample not in interval", V, 0.0, 1.0})}
1886       end,
1887       FloatSamples),
1888     State1}.
1889
1890rand_plugin_aux_integers(State0, IntegerGenerator) ->
1891    MaxIntegerCeiling = 1 bsl 32,
1892    {IntegerCeilings, State1} =
1893        lists:mapfoldl(
1894          fun (_, StateAcc) ->
1895                  IntegerGenerator(MaxIntegerCeiling, StateAcc)
1896          end,
1897          State0,
1898          lists:seq(1, 100)),
1899
1900    foldallmap(
1901      fun (Ceiling, StateAcc) ->
1902              case Ceiling >= 1 andalso Ceiling =< MaxIntegerCeiling of
1903                  false ->
1904                      {{false, ct:fail({"Integer ceiling not in interval",
1905                                        Ceiling, 1, MaxIntegerCeiling})},
1906                       StateAcc};
1907                  true ->
1908                      foldallmap(
1909                        fun (_, SubStateAcc) ->
1910                                {Sample, NewSubStateAcc} = IntegerGenerator(Ceiling, SubStateAcc),
1911                                case Sample >= 1 andalso Sample =< Ceiling of
1912                                    false ->
1913                                        {{false, ct:fail({"Integer sample not in interval",
1914                                                          Sample, 1, Ceiling})},
1915                                         NewSubStateAcc};
1916                                    true ->
1917                                        {true, NewSubStateAcc}
1918                                end
1919                        end,
1920                        StateAcc,
1921                        lists:seq(1, 100))
1922              end
1923      end,
1924      State1,
1925      IntegerCeilings).
1926
1927%%--------------------------------------------------------------------
1928%% Test data ------------------------------------------------
1929%%--------------------------------------------------------------------
1930group_config(md4 = Type, Config) ->
1931    Msgs = rfc_1321_msgs(),
1932    Digests = rfc_1321_md4_digests(),
1933    [{hash, {Type, Msgs, Digests}} | Config];
1934group_config(md5 = Type, Config) ->
1935    Msgs = rfc_1321_msgs(),
1936    Digests = rfc_1321_md5_digests(),
1937    [{hash, {Type, Msgs, Digests}} | Config];
1938group_config(ripemd160 = Type, Config) ->
1939    Msgs = ripemd160_msgs(),
1940    Digests = ripemd160_digests(),
1941   [{hash, {Type, Msgs, Digests}} | Config];
1942group_config(sha = Type, Config) ->
1943    Msgs = [rfc_4634_test1(), rfc_4634_test2_1(),long_msg()],
1944    Digests = rfc_4634_sha_digests() ++ [long_sha_digest()],
1945    [{hash, {Type, Msgs, Digests}} | Config];
1946group_config(sha224 = Type, Config) ->
1947    Msgs = [rfc_4634_test1(), rfc_4634_test2_1()],
1948    Digests = rfc_4634_sha224_digests(),
1949    [{hash, {Type, Msgs, Digests}} | Config];
1950group_config(sha256 = Type, Config) ->
1951    Msgs =   [rfc_4634_test1(), rfc_4634_test2_1(), long_msg()],
1952    Digests = rfc_4634_sha256_digests()  ++ [long_sha256_digest()],
1953    [{hash, {Type, Msgs, Digests}} | Config];
1954group_config(sha384 = Type, Config) ->
1955    Msgs =  [rfc_4634_test1(), rfc_4634_test2(), long_msg()],
1956    Digests = rfc_4634_sha384_digests()  ++ [long_sha384_digest()],
1957    [{hash, {Type, Msgs, Digests}} | Config];
1958group_config(sha512 = Type, Config) ->
1959    Msgs =  [rfc_4634_test1(), rfc_4634_test2(), long_msg()],
1960    Digests = rfc_4634_sha512_digests() ++ [long_sha512_digest()],
1961    [{hash, {Type, Msgs, Digests}} | Config];
1962group_config(sha3_224 = Type, Config) ->
1963    {Msgs,Digests} = sha3_test_vectors(Type),
1964    [{hash, {Type, Msgs, Digests}} | Config];
1965group_config(sha3_256 = Type, Config) ->
1966    {Msgs,Digests} = sha3_test_vectors(Type),
1967    [{hash, {Type, Msgs, Digests}} | Config];
1968group_config(sha3_384 = Type, Config) ->
1969    {Msgs,Digests} = sha3_test_vectors(Type),
1970    [{hash, {Type, Msgs, Digests}} | Config];
1971group_config(sha3_512 = Type, Config) ->
1972    {Msgs,Digests} = sha3_test_vectors(Type),
1973    [{hash, {Type, Msgs, Digests}} | Config];
1974group_config(blake2b = Type, Config) ->
1975    {Msgs, Digests} = blake2_test_vectors(Type),
1976    [{hash, {Type, Msgs, Digests}} | Config];
1977group_config(blake2s = Type, Config) ->
1978    {Msgs, Digests} = blake2_test_vectors(Type),
1979    [{hash, {Type, Msgs, Digests}} | Config];
1980group_config(rsa, Config) ->
1981    Msg = rsa_plain(),
1982    Public = rsa_public(),
1983    Private = rsa_private(),
1984    PublicS = rsa_public_stronger(),
1985    PrivateS = rsa_private_stronger(),
1986    MsgPubEnc = <<"7896345786348 Asldi">>,
1987    SignVerify_OptsToTry = [[{rsa_padding, rsa_x931_padding}],
1988                            [{rsa_padding, rsa_pkcs1_padding}],
1989                            [{rsa_padding, rsa_pkcs1_pss_padding}],
1990                            [{rsa_padding, rsa_pkcs1_pss_padding}, {rsa_pss_saltlen, -2}],
1991                            [{rsa_padding, rsa_pkcs1_pss_padding}, {rsa_pss_saltlen, 5}],
1992                            [{rsa_padding, rsa_pkcs1_pss_padding}, {rsa_mgf1_md,sha}],
1993                            [{rsa_padding, rsa_pkcs1_pss_padding}, {rsa_mgf1_md,sha}, {rsa_pss_saltlen, 5}]
1994                           ],
1995    PrivEnc_OptsToTry = [rsa_pkcs1_padding,              % Compatibility
1996                         [{rsa_pad, rsa_pkcs1_padding}], % Compatibility
1997                         [{rsa_padding, rsa_pkcs1_padding}],
1998                         [{rsa_padding,rsa_x931_padding}]
1999                        ],
2000    PubEnc_OptsToTry = [rsa_pkcs1_padding,              % Compatibility
2001                 [{rsa_pad, rsa_pkcs1_padding}], % Compatibility
2002                 [{rsa_padding, rsa_pkcs1_padding}],
2003                 [{rsa_padding,rsa_pkcs1_oaep_padding}],
2004                 [{rsa_padding,rsa_pkcs1_oaep_padding}, {rsa_oaep_label, <<"Hej hopp">>}],
2005                 [{rsa_padding,rsa_pkcs1_oaep_padding}, {rsa_oaep_md,sha}],
2006                 [{rsa_padding,rsa_pkcs1_oaep_padding}, {rsa_oaep_md,sha}, {rsa_oaep_label, <<"Hej hopp">>}],
2007                 [{rsa_padding,rsa_pkcs1_oaep_padding}, {rsa_mgf1_md,sha}],
2008                 [{rsa_padding,rsa_pkcs1_oaep_padding}, {rsa_mgf1_md,sha}, {rsa_oaep_label, <<"Hej hopp">>}],
2009                 [{rsa_padding,rsa_pkcs1_oaep_padding}, {rsa_mgf1_md,sha}, {rsa_oaep_md,sha}, {rsa_oaep_label, <<"Hej hopp">>}]
2010                 ],
2011    [{sign_verify,      rsa_sign_verify_tests(Config, Msg, Public, Private, PublicS, PrivateS, SignVerify_OptsToTry)},
2012     {pub_priv_encrypt, gen_rsa_pub_priv_tests(PublicS, PrivateS, MsgPubEnc, PrivEnc_OptsToTry)},
2013     {pub_pub_encrypt,  gen_rsa_pub_priv_tests(PublicS, PrivateS, MsgPubEnc, PubEnc_OptsToTry)},
2014     {generate, [{rsa, 1024, 3},  {rsa, 2048, 17},  {rsa, 3072, 65537}]}
2015     | Config];
2016group_config(dss = Type, Config) ->
2017    Msg = dss_plain(),
2018    Public = dss_params() ++ [dss_public()],
2019    Private = dss_params() ++ [dss_private()],
2020    SupportedHashs = proplists:get_value(hashs, crypto:supports(), []),
2021    DssHashs =
2022        case crypto:info_lib() of
2023            [{<<"OpenSSL">>,LibVer,_}] when is_integer(LibVer), LibVer > 16#10001000 ->
2024                [sha, sha224, sha256, sha384, sha512];
2025            [{<<"OpenSSL">>,LibVer,_}] when is_integer(LibVer), LibVer > 16#10000000 ->
2026                [sha, sha224, sha256];
2027            _Else ->
2028                [sha]
2029        end,
2030    SignVerify = [{Type, Hash, Public, Private, Msg}
2031                  || Hash <- DssHashs,
2032                     lists:member(Hash, SupportedHashs)],
2033    MsgPubEnc = <<"7896345786348 Asldi">>,
2034    PubPrivEnc = [{dss, Public, Private, MsgPubEnc, []}],
2035    [{sign_verify, SignVerify}, {pub_priv_encrypt, PubPrivEnc}  | Config];
2036group_config(ecdsa = Type, Config) ->
2037    {Private, Public} = ec_key_named(),
2038    Msg = ec_msg(),
2039    SupportedHashs = proplists:get_value(hashs, crypto:supports(), []),
2040    DssHashs = [sha, sha224, sha256, sha384, sha512],
2041    SignVerify = [{Type, Hash, Public, Private, Msg}
2042                  || Hash <- DssHashs,
2043                     lists:member(Hash, SupportedHashs)],
2044    MsgPubEnc = <<"7896345786348 Asldi">>,
2045    PubPrivEnc = [{ecdsa, Public, Private, MsgPubEnc, []}],
2046    [{sign_verify, SignVerify}, {pub_priv_encrypt, PubPrivEnc} | Config];
2047group_config(Type, Config) when Type == ed25519 ; Type == ed448 ->
2048    TestVectors = eddsa(Type),
2049    [{sign_verify,TestVectors} | Config];
2050group_config(srp, Config) ->
2051    GenerateCompute = [srp3(), srp6(), srp6a(), srp6a_smaller_prime()],
2052    [{generate_compute, GenerateCompute} | Config];
2053group_config(ecdh, Config) ->
2054    Compute = ecdh(),
2055    Generate = ecc(),
2056    [{compute, Compute}, {generate, Generate} | Config];
2057group_config(dh, Config) ->
2058    GenerateCompute = [dh()],
2059    [{generate_compute, GenerateCompute} | Config];
2060group_config(poly1305, Config) ->
2061    V = [%% {Key, Txt, Expect}
2062         {%% RFC7539 2.5.2
2063           crypto_SUITE:hexstr2bin("85d6be7857556d337f4452fe42d506a80103808afb0db2fd4abff6af4149f51b"),
2064           <<"Cryptographic Forum Research Group">>,
2065           crypto_SUITE:hexstr2bin("a8061dc1305136c6c22b8baf0c0127a9")
2066         }
2067        ],
2068    [{poly1305,V} | Config];
2069
2070group_config(F, Config) ->
2071    TestVectors = fun() -> ?MODULE:F(Config) end,
2072    [{cipher, TestVectors} | Config].
2073
2074
2075configure_mac(MacType, SubType, Config) ->
2076    case do_configure_mac(MacType, SubType, Config) of
2077        undefined ->
2078            {skip, io:format("No ~p test vectors for ~p", [MacType, SubType])};
2079        Pairs ->
2080            [{MacType, Pairs} | Config]
2081    end.
2082
2083do_configure_mac(hmac, Type, _Config) ->
2084    case Type of
2085        md5 ->
2086            Keys = rfc_2202_md5_keys() ++ [long_hmac_key(md5)],
2087            Data = rfc_2202_msgs() ++ [long_msg()],
2088            Hmac = rfc_2202_hmac_md5()  ++ [long_hmac(md5)],
2089            zip3_special(hmac, Type, Keys, Data, Hmac);
2090        sha ->
2091            Keys = rfc_2202_sha_keys() ++ [long_hmac_key(sha)],
2092            Data = rfc_2202_msgs() ++ [long_msg()],
2093            Hmac = rfc_2202_hmac_sha()  ++ [long_hmac(sha)],
2094            zip3_special(hmac, Type, Keys, Data, Hmac);
2095        sha224 ->
2096            Keys = rfc_4231_keys(),
2097            Data = rfc_4231_msgs(),
2098            Hmac = rfc4231_hmac_sha224(),
2099            zip3_special(hmac, Type, Keys, Data, Hmac);
2100        sha256 ->
2101            Keys = rfc_4231_keys() ++ [long_hmac_key(sha256)],
2102            Data = rfc_4231_msgs()  ++ [long_msg()],
2103            Hmac = rfc4231_hmac_sha256()  ++ [long_hmac(sha256)],
2104            zip3_special(hmac, Type, Keys, Data, Hmac);
2105        sha384 ->
2106            Keys = rfc_4231_keys() ++ [long_hmac_key(sha384)],
2107            Data = rfc_4231_msgs()  ++ [long_msg()],
2108            Hmac = rfc4231_hmac_sha384()  ++ [long_hmac(sha384)],
2109            zip3_special(hmac, Type, Keys, Data, Hmac);
2110        sha512 ->
2111            Keys = rfc_4231_keys() ++ [long_hmac_key(sha512)],
2112            Data = rfc_4231_msgs() ++ [long_msg()],
2113            Hmac = rfc4231_hmac_sha512() ++ [long_hmac(sha512)],
2114            zip3_special(hmac, Type, Keys, Data, Hmac);
2115        sha3_224 ->
2116            hmac_sha3(Type);
2117        sha3_256 ->
2118            hmac_sha3(Type);
2119        sha3_384 ->
2120            hmac_sha3(Type);
2121        sha3_512 ->
2122            hmac_sha3(Type);
2123        blake2b ->
2124            blake2_hmac(Type);
2125        blake2s ->
2126            blake2_hmac(Type);
2127        _ ->
2128            undefined
2129    end;
2130do_configure_mac(cmac, Cipher, Config) ->
2131    case Cipher of
2132        aes_128_cbc ->
2133            fun() -> read_rsp(Config, Cipher,  ["CMACGenAES128.rsp", "CMACVerAES128.rsp"]) end;
2134        aes_256_cbc ->
2135            fun() -> read_rsp(Config, Cipher,  ["CMACGenAES256.rsp", "CMACVerAES256.rsp"]) end;
2136        _ ->
2137            undefined
2138    end.
2139
2140
2141zip3_special(Type, SubType, As, Bs, Cs) ->
2142    [{Type, SubType, A, B, C}
2143     || {A,B,C} <- lists:zip3(As, Bs, Cs)].
2144
2145
2146rsa_sign_verify_tests(Config, Msg, Public, Private, PublicS, PrivateS, OptsToTry) ->
2147        case ?config(fips, Config) of
2148            true ->
2149                %% Use only the strong keys in FIPS mode
2150                rsa_sign_verify_tests(Msg,
2151                                      PublicS, PrivateS,
2152                                      PublicS, PrivateS,
2153                                      OptsToTry);
2154            false ->
2155                rsa_sign_verify_tests(Msg,
2156                                      Public,  Private,
2157                                      PublicS, PrivateS,
2158                                      OptsToTry)
2159        end.
2160
2161rsa_sign_verify_tests(Msg, Public, Private, PublicS, PrivateS, OptsToTry) ->
2162    gen_rsa_sign_verify_tests([md5, ripemd160, sha, sha224, sha256], Msg, Public, Private,
2163                              [undefined | OptsToTry]) ++
2164	gen_rsa_sign_verify_tests([sha384, sha512], Msg, PublicS, PrivateS,
2165                                  [undefined | OptsToTry]).
2166
2167gen_rsa_sign_verify_tests(Hashs, Msg, Public, Private, Opts) ->
2168    SupOpts = proplists:get_value(rsa_opts, crypto:supports(), []),
2169    lists:foldr(fun(Hash, Acc0) ->
2170	case is_supported(Hash) of
2171	    true ->
2172		lists:foldr(fun
2173		    (undefined, Acc1) ->
2174			[{rsa, Hash, Public, Private, Msg} | Acc1];
2175		    ([{rsa_padding, rsa_x931_padding} | _], Acc1)
2176			    when Hash =:= md5
2177			    orelse Hash =:= ripemd160
2178			    orelse Hash =:= sha224 ->
2179			Acc1;
2180		    (Opt, Acc1) ->
2181                        case rsa_opt_is_supported(Opt, SupOpts) of
2182                            true ->
2183                                [{rsa, Hash, Public, Private, Msg, Opt} | Acc1];
2184                            false ->
2185                                Acc1
2186                        end
2187		end, Acc0, Opts);
2188	    false ->
2189		Acc0
2190	end
2191    end, [], Hashs).
2192
2193
2194gen_rsa_pub_priv_tests(Public, Private, Msg, OptsToTry) ->
2195    SupOpts = proplists:get_value(rsa_opts, crypto:supports(), []),
2196    lists:foldr(fun(Opt, Acc) ->
2197                        case rsa_opt_is_supported(Opt, SupOpts) of
2198                            true ->
2199                                [{rsa, Public, Private, Msg, Opt} | Acc];
2200                            false ->
2201                                Acc
2202                        end
2203                end, [], OptsToTry).
2204
2205
2206rsa_opt_is_supported([_|_]=Opt, Sup) ->
2207    lists:all(fun(O) -> rsa_opt_is_supported(O,Sup) end, Opt);
2208rsa_opt_is_supported({A,B}, Sup) ->
2209    rsa_opt_is_supported(A,Sup) orelse rsa_opt_is_supported(B,Sup);
2210rsa_opt_is_supported(Opt, Sup) ->
2211    lists:member(Opt, Sup).
2212
2213
2214rfc_1321_msgs() ->
2215    [<<"">>,
2216     <<"a">>,
2217     <<"abc">>,
2218     <<"message digest">>,
2219     <<"abcdefghijklmnopqrstuvwxyz">>,
2220     <<"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789">>,
2221     <<"12345678901234567890123456789012345678901234567890123456789012345678901234567890">>
2222    ].
2223
2224rfc_1321_md4_digests() ->
2225    [hexstr2bin("31d6cfe0d16ae931b73c59d7e0c089c0"),
2226     hexstr2bin("bde52cb31de33e46245e05fbdbd6fb24"),
2227     hexstr2bin("a448017aaf21d8525fc10ae87aa6729d"),
2228     hexstr2bin("d9130a8164549fe818874806e1c7014b"),
2229     hexstr2bin("d79e1c308aa5bbcdeea8ed63df412da9"),
2230     hexstr2bin("043f8582f241db351ce627e153e7f0e4"),
2231     hexstr2bin("e33b4ddc9c38f2199c3e7b164fcc0536")].
2232
2233rfc_1321_md5_digests() ->
2234    [hexstr2bin("d41d8cd98f00b204e9800998ecf8427e"),
2235     hexstr2bin("0cc175b9c0f1b6a831c399e269772661"),
2236     hexstr2bin("900150983cd24fb0d6963f7d28e17f72"),
2237     hexstr2bin("f96b697d7cb7938d525a2f31aaf161d0"),
2238     hexstr2bin("c3fcd3d76192e4007dfb496cca67e13b"),
2239     hexstr2bin("d174ab98d277d9f5a5611c2c9f419d9f"),
2240     hexstr2bin("57edf4a22be3c955ac49da2e2107b67a")].
2241
2242
2243%% BLAKE2 re-use SHA3 test vectors.
2244blake2_test_vectors(blake2b) ->
2245    {sha3_msgs(),
2246     [ <<186,128,165,63,152,28,77,13,106,39,151,182,159,18,246,233,76,33,47,20,104,90,196,183,75,18,187,111,219,255,162,209,125,135,197,57,42,171,121,45,194,82,213,222,69,51,204,149,24,211,138,168,219,241,146,90,185,35,134,237,212,0,153,35>>
2247     , <<120,106,2,247,66,1,89,3,198,198,253,133,37,82,210,114,145,47,71,64,225,88,71,97,138,134,226,23,247,31,84,25,210,94,16,49,175,238,88,83,19,137,100,68,147,78,176,75,144,58,104,91,20,72,183,85,213,111,112,26,254,155,226,206>>
2248     , <<114,133,255,62,139,215,104,214,155,230,43,59,241,135,101,163,37,145,127,169,116,74,194,245,130,162,8,80,188,43,17,65,237,27,62,69,40,89,90,204,144,119,43,223,45,55,220,138,71,19,11,68,243,58,2,232,115,14,90,216,225,102,232,136>>
2249     , <<206,116,26,197,147,15,227,70,129,17,117,197,34,123,183,191,205,71,244,38,18,250,228,108,8,9,81,79,158,14,58,17,238,23,115,40,113,71,205,234,238,223,245,7,9,170,113,99,65,254,101,36,15,74,214,119,125,107,250,249,114,110,94,82>>
2250     , <<152,251,62,251,114,6,253,25,235,246,155,111,49,44,247,182,78,59,148,219,225,161,113,7,145,57,117,167,147,241,119,225,208,119,96,157,127,186,54,60,187,160,13,5,247,170,78,79,168,113,93,100,40,16,76,10,117,100,59,15,243,253,62,175>>
2251     ]};
2252blake2_test_vectors(blake2s) ->
2253    {sha3_msgs(),
2254     [ <<80,140,94,140,50,124,20,226,225,167,43,163,78,235,69,47,55,69,139,32,158,214,58,41,77,153,155,76,134,103,89,130>>
2255     , <<105,33,122,48,121,144,128,148,225,17,33,208,66,53,74,124,31,85,182,72,44,161,165,30,27,37,13,253,30,208,238,249>>
2256     , <<111,77,245,17,106,111,51,46,218,177,217,225,14,232,125,246,85,123,234,182,37,157,118,99,243,188,213,114,44,19,241,137>>
2257     , <<53,141,210,237,7,128,212,5,78,118,203,111,58,91,206,40,65,232,226,245,71,67,29,77,9,219,33,182,109,148,31,199>>
2258     , <<190,192,192,230,205,229,182,122,203,115,184,31,121,166,122,64,121,174,28,96,218,201,210,102,26,241,142,159,139,80,223,165>>
2259     ]}.
2260
2261blake2_hmac(Type) ->
2262    [{hmac, Type, hexstr2bin(K), hexstr2bin(D), H}
2263     || {{K, D}, H} <- lists:zip(blake2_hmac_key_data(), blake2_hmac_hmac(Type)) ].
2264
2265blake2_hmac_key_data() ->
2266    [ {"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b 0b0b0b0b",
2267       "4869205468657265"}
2268    , {"4a656665",
2269      "7768617420646f2079612077616e7420 666f72206e6f7468696e673f"}
2270    , {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaa",
2271      "dddddddddddddddddddddddddddddddd dddddddddddddddddddddddddddddddd dddddddddddddddddddddddddddddddd dddd"}
2272    , {"0102030405060708090a0b0c0d0e0f10 111213141516171819",
2273      "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd cdcd"}
2274    , {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaa",
2275      "54657374205573696e67204c61726765 72205468616e20426c6f636b2d53697a 65204b6579202d2048617368204b6579 204669727374"}
2276    , {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaa",
2277      "54657374205573696e67204c61726765 72205468616e20426c6f636b2d53697a 65204b6579202d2048617368204b6579 204669727374"}
2278    , {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaa",
2279      "54686973206973206120746573742075 73696e672061206c6172676572207468 616e20626c6f636b2d73697a65206b65 7920616e642061206c61726765722074 68616e20626c6f636b2d73697a652064 6174612e20546865206b6579206e6565 647320746f2062652068617368656420 6265666f7265206265696e6720757365 642062792074686520484d414320616c 676f726974686d2e"}
2280    , {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaa",
2281      "54686973206973206120746573742075 73696e672061206c6172676572207468 616e20626c6f636b2d73697a65206b65 7920616e642061206c61726765722074 68616e20626c6f636b2d73697a652064 6174612e20546865206b6579206e6565 647320746f2062652068617368656420 6265666f7265206265696e6720757365 642062792074686520484d414320616c 676f726974686d2e"}
2282    ].
2283
2284blake2_hmac_hmac(blake2b) ->
2285    [ <<53,138,106,24,73,36,137,79,195,75,238,86,128,238,223,87,216,74,55,187,56,131,47,40,142,59,39,220,99,169,140,200,201,30,118,218,71,107,80,139,198,178,212,8,162,72,133,116,82,144,110,74,32,180,140,107,75,85,210,223,15,225,221,36>>
2286    , <<111,248,132,248,221,194,166,88,107,60,152,164,205,110,189,241,78,193,2,4,182,113,0,115,235,88,101,173,227,122,38,67,184,128,124,19,53,209,7,236,219,159,254,174,182,130,140,70,37,186,23,44,102,55,158,252,210,34,194,222,17,114,122,180>>
2287    , <<244,59,198,44,122,153,53,60,59,44,96,232,239,36,251,189,66,233,84,120,102,220,156,91,228,237,198,244,167,212,188,10,198,32,194,198,0,52,208,64,240,219,175,134,249,233,205,120,145,160,149,89,94,237,85,226,169,150,33,95,12,21,192,24>>
2288    , <<229,219,182,222,47,238,66,161,202,160,110,78,123,132,206,64,143,250,92,74,157,226,99,46,202,118,156,222,136,117,1,76,114,208,114,15,234,245,63,118,230,161,128,53,127,82,141,123,244,132,250,58,20,232,204,31,15,59,173,167,23,180,52,145>>
2289    , <<165,75,41,67,178,162,2,39,212,28,164,108,9,69,175,9,188,31,174,251,47,73,137,76,35,174,188,85,127,183,156,72,137,220,167,68,8,220,134,80,134,102,122,237,238,74,49,133,197,58,73,200,11,129,76,76,88,19,234,12,139,56,168,248>>
2290    , <<180,214,140,139,182,82,151,170,52,132,168,110,29,51,183,138,70,159,33,234,170,158,212,218,159,236,145,218,71,23,34,61,44,15,163,134,170,47,209,241,255,207,89,23,178,103,84,96,53,237,48,238,164,178,19,162,133,148,211,211,169,179,140,170>>
2291    , <<171,52,121,128,166,75,94,130,93,209,14,125,50,253,67,160,26,142,109,234,38,122,185,173,125,145,53,36,82,102,24,146,83,17,175,188,176,196,149,25,203,235,221,112,149,64,168,215,37,251,145,26,194,174,233,178,163,170,67,215,150,18,51,147>>
2292    , <<97,220,242,140,166,12,169,92,130,89,147,39,171,215,169,161,152,111,242,219,211,199,73,69,198,227,35,186,203,76,159,26,94,103,82,93,20,186,141,98,36,177,98,229,102,23,21,37,83,3,69,169,178,86,8,178,125,251,163,180,146,115,213,6>>
2293    ];
2294blake2_hmac_hmac(blake2s) ->
2295    [ <<101,168,183,197,204,145,54,212,36,232,44,55,226,112,126,116,233,19,192,101,91,153,199,95,64,237,243,135,69,58,50,96>>
2296    , <<144,182,40,30,47,48,56,201,5,106,240,180,167,231,99,202,230,254,93,158,180,56,106,14,201,82,55,137,12,16,79,240>>
2297    , <<252,196,245,149,41,80,46,52,195,216,218,63,253,171,130,150,106,44,182,55,255,94,155,215,1,19,92,46,148,105,231,144>>
2298    , <<70,68,52,220,190,206,9,93,69,106,29,98,214,236,86,248,152,230,37,163,158,92,82,189,249,77,175,17,27,173,131,170>>
2299    , <<210,61,121,57,79,83,213,54,160,150,230,81,68,71,238,170,187,5,222,208,27,227,44,25,55,218,106,143,113,3,188,78>>
2300    , <<92,76,83,46,110,69,89,83,133,78,21,16,149,38,110,224,127,213,88,129,190,223,139,57,8,217,95,13,190,54,159,234>>
2301    , <<203,96,246,167,145,241,64,191,138,162,229,31,243,88,205,178,204,92,3,51,4,91,127,183,122,186,122,179,176,207,178,55>>
2302    , <<190,53,233,217,99,171,215,108,1,184,171,181,22,36,240,209,16,96,16,92,213,22,16,58,114,241,117,214,211,189,30,202>>
2303    ].
2304
2305%%% https://www.di-mgt.com.au/sha_testvectors.html
2306sha3_msgs() ->
2307    ["abc",
2308     "",
2309     "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", % length 448 bits
2310     "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", % length 896 bits
2311     lists:duplicate(1000000,$a)
2312    ].
2313
2314sha3_test_vectors(sha3_224) ->
2315    {sha3_msgs(),
2316     [hexstr2bin("e642824c3f8cf24a d09234ee7d3c766f c9a3a5168d0c94ad 73b46fdf"),
2317      hexstr2bin("6b4e03423667dbb7 3b6e15454f0eb1ab d4597f9a1b078e3f 5b5a6bc7"),
2318      hexstr2bin("8a24108b154ada21 c9fd5574494479ba 5c7e7ab76ef264ea d0fcce33"),
2319      hexstr2bin("543e6868e1666c1a 643630df77367ae5 a62a85070a51c14c bf665cbc"),
2320      hexstr2bin("d69335b93325192e 516a912e6d19a15c b51c6ed5c15243e7 a7fd653c")
2321     ]
2322    };
2323sha3_test_vectors(sha3_256) ->
2324    {sha3_msgs(),
2325     [hexstr2bin("3a985da74fe225b2 045c172d6bd390bd 855f086e3e9d525b 46bfe24511431532"),
2326      hexstr2bin("a7ffc6f8bf1ed766 51c14756a061d662 f580ff4de43b49fa 82d80a4b80f8434a"),
2327      hexstr2bin("41c0dba2a9d62408 49100376a8235e2c 82e1b9998a999e21 db32dd97496d3376"),
2328      hexstr2bin("916f6061fe879741 ca6469b43971dfdb 28b1a32dc36cb325 4e812be27aad1d18"),
2329      hexstr2bin("5c8875ae474a3634 ba4fd55ec85bffd6 61f32aca75c6d699 d0cdcb6c115891c1")
2330     ]
2331    };
2332sha3_test_vectors(sha3_384) ->
2333    {sha3_msgs(),
2334     [hexstr2bin("ec01498288516fc9 26459f58e2c6ad8d f9b473cb0fc08c25 96da7cf0e49be4b2 98d88cea927ac7f5 39f1edf228376d25"),
2335      hexstr2bin("0c63a75b845e4f7d 01107d852e4c2485 c51a50aaaa94fc61 995e71bbee983a2a c3713831264adb47 fb6bd1e058d5f004"),
2336      hexstr2bin("991c665755eb3a4b 6bbdfb75c78a492e 8c56a22c5c4d7e42 9bfdbc32b9d4ad5a a04a1f076e62fea1 9eef51acd0657c22"),
2337      hexstr2bin("79407d3b5916b59c 3e30b09822974791 c313fb9ecc849e40 6f23592d04f625dc 8c709b98b43b3852 b337216179aa7fc7"),
2338      hexstr2bin("eee9e24d78c18553 37983451df97c8ad 9eedf256c6334f8e 948d252d5e0e7684 7aa0774ddb90a842 190d2c558b4b8340")
2339     ]
2340    };
2341sha3_test_vectors(sha3_512) ->
2342    {sha3_msgs(),
2343     [hexstr2bin("b751850b1a57168a 5693cd924b6b096e 08f621827444f70d 884f5d0240d2712e 10e116e9192af3c9 1a7ec57647e39340 57340b4cf408d5a5 6592f8274eec53f0"),
2344      hexstr2bin("a69f73cca23a9ac5 c8b567dc185a756e 97c982164fe25859 e0d1dcc1475c80a6 15b2123af1f5f94c 11e3e9402c3ac558 f500199d95b6d3e3 01758586281dcd26"),
2345      hexstr2bin("04a371e84ecfb5b8 b77cb48610fca818 2dd457ce6f326a0f d3d7ec2f1e91636d ee691fbe0c985302 ba1b0d8dc78c0863 46b533b49c030d99 a27daf1139d6e75e"),
2346      hexstr2bin("afebb2ef542e6579 c50cad06d2e578f9 f8dd6881d7dc824d 26360feebf18a4fa 73e3261122948efc fd492e74e82e2189 ed0fb440d187f382 270cb455f21dd185"),
2347      hexstr2bin("3c3a876da14034ab 60627c077bb98f7e 120a2a5370212dff b3385a18d4f38859 ed311d0a9d5141ce 9cc5c66ee689b266 a8aa18ace8282a0e 0db596c90b0a7b87")
2348     ]
2349    }.
2350
2351
2352
2353%%% http://www.wolfgang-ehrhardt.de/hmac-sha3-testvectors.html
2354
2355hmac_sha3(Type) ->
2356    N = case Type of
2357            sha3_224 -> 1;
2358            sha3_256 -> 2;
2359            sha3_384 -> 3;
2360            sha3_512 -> 4
2361        end,
2362    [{hmac, Type, hexstr2bin(Key), hexstr2bin(Data), hexstr2bin(element(N,Hmacs))}
2363     || {Key,Data,Hmacs} <- hmac_sha3_data()].
2364
2365hmac_sha3_data() ->
2366    [
2367     {"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b 0b0b0b0b",
2368      "4869205468657265",
2369      {"3b16546bbc7be2706a031dcafd56373d 9884367641d8c59af3c860f7",
2370       "ba85192310dffa96e2a3a40e69774351 140bb7185e1202cdcc917589f95e16bb",
2371       "68d2dcf7fd4ddd0a2240c8a437305f61 fb7334cfb5d0226e1bc27dc10a2e723a 20d370b47743130e26ac7e3d532886bd",
2372       "eb3fbd4b2eaab8f5c504bd3a41465aac ec15770a7cabac531e482f860b5ec7ba 47ccb2c6f2afce8f88d22b6dc61380f2 3a668fd3888bb80537c0a0b86407689e"
2373      }},
2374
2375     {"4a656665",
2376      "7768617420646f2079612077616e7420 666f72206e6f7468696e673f",
2377      {"7fdb8dd88bd2f60d1b798634ad386811 c2cfc85bfaf5d52bbace5e66",
2378       "c7d4072e788877ae3596bbb0da73b887 c9171f93095b294ae857fbe2645e1ba5",
2379       "f1101f8cbf9766fd6764d2ed61903f21 ca9b18f57cf3e1a23ca13508a93243ce 48c045dc007f26a21b3f5e0e9df4c20a",
2380       "5a4bfeab6166427c7a3647b747292b83 84537cdb89afb3bf5665e4c5e709350b 287baec921fd7ca0ee7a0c31d022a95e 1fc92ba9d77df883960275beb4e62024"
2381       }},
2382
2383     {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaa",
2384      "dddddddddddddddddddddddddddddddd dddddddddddddddddddddddddddddddd dddddddddddddddddddddddddddddddd dddd",
2385      {"676cfc7d16153638780390692be142d2 df7ce924b909c0c08dbfdc1a",
2386       "84ec79124a27107865cedd8bd82da996 5e5ed8c37b0ac98005a7f39ed58a4207",
2387       "275cd0e661bb8b151c64d288f1f782fb 91a8abd56858d72babb2d476f0458373 b41b6ab5bf174bec422e53fc3135ac6e",
2388       "309e99f9ec075ec6c6d475eda1180687 fcf1531195802a99b5677449a8625182 851cb332afb6a89c411325fbcbcd42af cb7b6e5aab7ea42c660f97fd8584bf03"
2389       }},
2390
2391     {"0102030405060708090a0b0c0d0e0f10 111213141516171819",
2392      "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd cdcd",
2393      {"a9d7685a19c4e0dbd9df2556cc8a7d2a 7733b67625ce594c78270eeb",
2394       "57366a45e2305321a4bc5aa5fe2ef8a9 21f6af8273d7fe7be6cfedb3f0aea6d7",
2395       "3a5d7a879702c086bc96d1dd8aa15d9c 46446b95521311c606fdc4e308f4b984 da2d0f9449b3ba8425ec7fb8c31bc136",
2396       "b27eab1d6e8d87461c29f7f5739dd58e 98aa35f8e823ad38c5492a2088fa0281 993bbfff9a0e9c6bf121ae9ec9bb09d8 4a5ebac817182ea974673fb133ca0d1d"
2397       }},
2398
2399     %% {"0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c 0c0c0c0c",
2400     %%  "546573742057697468205472756e6361 74696f6e",
2401     %%  {"49fdd3abd005ebb8ae63fea946d1883c",
2402     %%   "6e02c64537fb118057abb7fb66a23b3c",
2403     %%   "47c51ace1ffacffd7494724682615783",
2404     %%   "0fa7475948f43f48ca0516671e18978c"
2405     %%   }},
2406
2407     {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaa",
2408      "54657374205573696e67204c61726765 72205468616e20426c6f636b2d53697a 65204b6579202d2048617368204b6579 204669727374",
2409      {"b4a1f04c00287a9b7f6075b313d279b8 33bc8f75124352d05fb9995f",
2410       "ed73a374b96c005235f948032f09674a 58c0ce555cfc1f223b02356560312c3b",
2411       "0fc19513bf6bd878037016706a0e57bc 528139836b9a42c3d419e498e0e1fb96 16fd669138d33a1105e07c72b6953bcc",
2412       "00f751a9e50695b090ed6911a4b65524 951cdc15a73a5d58bb55215ea2cd839a c79d2b44a39bafab27e83fde9e11f634 0b11d991b1b91bf2eee7fc872426c3a4"
2413       }},
2414
2415     {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaa",
2416      "54657374205573696e67204c61726765 72205468616e20426c6f636b2d53697a 65204b6579202d2048617368204b6579 204669727374",
2417      {
2418       "b96d730c148c2daad8649d83defaa371 9738d34775397b7571c38515",
2419       "a6072f86de52b38bb349fe84cd6d97fb 6a37c4c0f62aae93981193a7229d3467",
2420       "713dff0302c85086ec5ad0768dd65a13 ddd79068d8d4c6212b712e4164944911 1480230044185a99103ed82004ddbfcc",
2421       "b14835c819a290efb010ace6d8568dc6 b84de60bc49b004c3b13eda763589451 e5dd74292884d1bdce64e6b919dd61dc 9c56a282a81c0bd14f1f365b49b83a5b"
2422      }},
2423
2424     {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaa",
2425      "54686973206973206120746573742075 73696e672061206c6172676572207468 616e20626c6f636b2d73697a65206b65 7920616e642061206c61726765722074 68616e20626c6f636b2d73697a652064 6174612e20546865206b6579206e6565 647320746f2062652068617368656420 6265666f7265206265696e6720757365 642062792074686520484d414320616c 676f726974686d2e",
2426      {
2427       "05d8cd6d00faea8d1eb68ade28730bbd 3cbab6929f0a086b29cd62a0",
2428       "65c5b06d4c3de32a7aef8763261e49ad b6e2293ec8e7c61e8de61701fc63e123",
2429       "026fdf6b50741e373899c9f7d5406d4e b09fc6665636fc1a530029ddf5cf3ca5 a900edce01f5f61e2f408cdf2fd3e7e8",
2430       "38a456a004bd10d32c9ab83366841128 62c3db61adcca31829355eaf46fd5c73 d06a1f0d13fec9a652fb3811b577b1b1 d1b9789f97ae5b83c6f44dfcf1d67eba"
2431       }},
2432
2433     {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaa",
2434      "54686973206973206120746573742075 73696e672061206c6172676572207468 616e20626c6f636b2d73697a65206b65 7920616e642061206c61726765722074 68616e20626c6f636b2d73697a652064 6174612e20546865206b6579206e6565 647320746f2062652068617368656420 6265666f7265206265696e6720757365 642062792074686520484d414320616c 676f726974686d2e",
2435      {
2436       "c79c9b093424e588a9878bbcb089e018 270096e9b4b1a9e8220c866a",
2437       "e6a36d9b915f86a093cac7d110e9e04c f1d6100d30475509c2475f571b758b5a",
2438       "cad18a8ff6c4cc3ad487b95f9769e9b6 1c062aefd6952569e6e6421897054cfc 70b5fdc6605c18457112fc6aaad45585",
2439       "dc030ee7887034f32cf402df34622f31 1f3e6cf04860c6bbd7fa488674782b46 59fdbdf3fd877852885cfe6e22185fe7 b2ee952043629bc9d5f3298a41d02c66"
2440       }}
2441    %%,
2442
2443    %%  {"4a656665",
2444    %%   "'11001' or LSB 13 or MSB c8",
2445    %%   {
2446     %% "5f8c0ea7fafecd0c3463aad09742cece  b142fe0ab6f4539438c59de8",
2447     %% "ec8222773fac68b3d3dcb182aec8b050  7ace4448d20a1147e682118da4e3f44c",
2448     %% "21fbd3bf3ebba3cfc9ef64c0591c92c5  acb265e92d8761d1f91a52a103a6c796  94cfd67a9a2ac1324f02fea63b81effc",
2449     %% "27f9388c1567ef4ef200602a6cf871d6  8a6fb048d4737ac4418a2f021289d13d  1fd1120fecb9cf964c5b117ab5b11c61  4b2da39dadd51f2f5e22aaccec7d576e"
2450     %%   }}
2451    ].
2452
2453
2454
2455rfc_4634_test1() ->
2456    <<"abc">>.
2457rfc_4634_test2_1() ->
2458    <<"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq">>.
2459rfc_4634_test2_2a() ->
2460    <<"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn">>.
2461rfc_4634_test2_2b() ->
2462    <<"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu">>.
2463rfc_4634_test2() ->
2464    A2 =rfc_4634_test2_2a(),
2465    B2 = rfc_4634_test2_2b(),
2466    <<A2/binary, B2/binary>>.
2467
2468rfc_4634_sha_digests()->
2469     [hexstr2bin("A9993E364706816ABA3E25717850C26C9CD0D89D"),
2470      hexstr2bin("84983E441C3BD26EBAAE4AA1F95129E5E54670F1")].
2471rfc_4634_sha224_digests() ->
2472     [hexstr2bin("23097D223405D8228642A477BDA255B32AADBCE4BDA0B3F7E36C9DA7"),
2473      hexstr2bin("75388B16512776CC5DBA5DA1FD890150B0C6455CB4F58B1952522525")].
2474rfc_4634_sha256_digests() ->
2475    [
2476     hexstr2bin("BA7816BF8F01CFEA4141"
2477		"40DE5DAE2223B00361A396177A9CB410FF61F20015AD"),
2478     hexstr2bin("248D6A61D20638B8"
2479		"E5C026930C3E6039A33CE45964FF2167F6ECEDD419DB06C1")
2480    ].
2481rfc_4634_sha384_digests() ->
2482    [hexstr2bin("CB00753F45A35E8BB5A03D699AC65007272C32AB0EDED1631A8B605A43FF5BED8086072BA1E7CC2358BAECA134C825A7"),
2483     hexstr2bin("09330C33F71147E83D192FC782CD1B4753111B173B3B05D22FA08086E3B0F712FCC7C71A557E2DB966C3E9FA91746039")
2484    ].
2485rfc_4634_sha512_digests() ->
2486    [hexstr2bin("DDAF35A193617ABACC417349AE20413112E6FA4E89A97EA2"
2487		"0A9EEEE64B55D39A2192992A274FC1A836BA3C23A3FEEBBD"
2488		"454D4423643CE80E2A9AC94FA54CA49F"),
2489     hexstr2bin("8E959B75DAE313DA8CF4F72814FC143F8F7779C6EB9F7FA17299AEADB6889018501D289E4900F7E4331B99DEC4B5433AC7D329EEB6DD26545E96E55B874BE909")].
2490
2491long_msg() ->
2492    fun() -> lists:duplicate(1000000, $a) end.
2493
2494%% Passing huge terms (like long_msg/0) through config causes excessive memory
2495%% consumption and long runtimes in the test server. This results in test_server
2496%% crash with 'no_answer_from_tc_supervisor' sometimes on some machines.
2497%% Therefore lazy evaluation when test case has started.
2498lazy_eval(F) when is_function(F) -> F();
2499lazy_eval(Lst)  when is_list(Lst) -> lists:map(fun lazy_eval/1, Lst);
2500lazy_eval(Tpl) when is_tuple(Tpl) -> list_to_tuple(lists:map(fun lazy_eval/1, tuple_to_list(Tpl)));
2501lazy_eval(Term) -> Term.
2502
2503long_sha_digest() ->
2504    hexstr2bin("34aa973c" "d4c4daa4" "f61eeb2b" "dbad2731" "6534016f").
2505
2506long_sha256_digest() ->
2507    hexstr2bin("cdc76e5c" "9914fb92" "81a1c7e2" "84d73e67" "f1809a48" "a497200e" "046d39cc" "c7112cd0").
2508
2509long_sha384_digest() ->
2510    hexstr2bin("9d0e1809716474cb" "086e834e310a4a1c" "ed149e9c00f24852" "7972cec5704c2a5b"
2511	       "07b8b3dc38ecc4eb" "ae97ddd87f3d8985").
2512
2513long_sha512_digest() ->
2514    hexstr2bin("e718483d0ce76964" "4e2e42c7bc15b463" "8e1f98b13b204428" "5632a803afa973eb"
2515	       "de0ff244877ea60a" "4cb0432ce577c31b" "eb009c5c2c49aa2e" "4eadb217ad8cc09b").
2516
2517ripemd160_msgs() ->
2518    [<<"">>,
2519     <<"a">>,
2520     <<"abc">>,
2521     <<"message digest">>,
2522     <<"abcdefghijklmnopqrstuvwxyz">>,
2523     <<"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq">>,
2524     <<"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789">>
2525    ].
2526
2527ripemd160_digests() ->
2528    [hexstr2bin("9c1185a5c5e9fc54612808977ee8f548b2258d31"),
2529     hexstr2bin("0bdc9d2d256b3ee9daae347be6f4dc835a467ffe"),
2530     hexstr2bin("8eb208f7e05d987a9b044a8e98c6b087f15a0bfc"),
2531     hexstr2bin("5d0689ef49d2fae572b881b123a85ffa21595f36"),
2532     hexstr2bin("f71c27109c692c1b56bbdceb5b9d2865b3708dbc"),
2533     hexstr2bin("12a053384a9c0c88e405a06c27dcf49ada62eb2b"),
2534     hexstr2bin("b0e20b6e3116640286ed3a87a5713079b21f5189")
2535    ].
2536
2537ripemd160_incr_msgs() ->
2538     [<<"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefg">>,<<"hijklmnopqrstuvwxyz0123456789">>].
2539ripemd160_incr_digest() ->
2540    hexstr2bin("b0e20b6e3116640286ed3a87a5713079b21f5189").
2541
2542rfc_2202_md5_keys() ->
2543    [binary:copy(<<16#0b>>, 16),
2544     <<"Jefe">>,
2545     binary:copy(<<16#aa>>, 16),
2546     list_to_binary(lists:seq(1, 16#19)),
2547     binary:copy(<<16#0c>>, 16),
2548     binary:copy(<<16#aa>>, 80),
2549     binary:copy(<<16#aa>>, 80)].
2550
2551rfc_2202_sha_keys() ->
2552    [binary:copy(<<16#0b>>, 20),
2553     <<"Jefe">>,
2554     binary:copy(<<16#aa>>, 20),
2555     list_to_binary(lists:seq(1, 16#19)),
2556     binary:copy(<<16#0c>>, 20),
2557     binary:copy(<<16#aa>>, 80),
2558     binary:copy(<<16#aa>>, 80)].
2559
2560rfc_2202_msgs()->
2561    [<<"Hi There">>,
2562     <<"what do ya want for nothing?">>,
2563     binary:copy(<<16#dd>>, 50),
2564     binary:copy(<<16#cd>>, 50),
2565     <<"Test With Truncation">>,
2566     <<"Test Using Larger Than Block-Size Key - Hash Key First">>,
2567     <<"Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data">>
2568    ].
2569
2570hmac_key(md5) ->
2571    [<<"A fine speach">>, <<"by a fine man!">>];
2572hmac_key(_) ->
2573    hexstr2bin("00010203101112132021222330313233"
2574	       "04050607141516172425262734353637"
2575	       "08090a0b18191a1b28292a2b38393a3b"
2576	       "0c0d0e0f1c1d1e1f2c2d2e2f3c3d3e3f").
2577hmac_inc(_) ->
2578    [<<"Sampl">>, <<"e #1">>].
2579
2580%% https://www.cosic.esat.kuleuven.be/nessie/testvectors/
2581long_hmac_key(Type) when Type == sha384;
2582			 Type == sha512 ->
2583    hexstr2bin("00112233445566778899AABBCCDDEEFF"
2584	       "0123456789ABCDEF0011223344556677"
2585	       "8899AABBCCDDEEFF0123456789ABCDEF"
2586	       "00112233445566778899AABBCCDDEEFF");
2587long_hmac_key(_) ->
2588    hexstr2bin("0123456789ABCDEF0123456789ABCDEF"
2589	       "0123456789ABCDEF0123456789ABCDEF"
2590	       "0123456789ABCDEF0123456789ABCDEF"
2591	       "0123456789ABCDEF0123456789ABCDEF").
2592long_hmac(md5) ->
2593    hexstr2bin("82FDDA30202CB6ACC6F24D4F8A50EB7A");
2594long_hmac(sha) ->
2595    hexstr2bin("61D1D0B6459860755FDA892938C23DD401E54A7E");
2596long_hmac(sha256) ->
2597    hexstr2bin("50008B8DC7ED3926936347FDC1A01E9D"
2598	       "5220C6CC4B038B482C0F28A4CD88CA37");
2599long_hmac(sha384) ->
2600    hexstr2bin("C1EB08DAFA015833D3FC6B29A387558B"
2601	       "3F6FA1524AA1A8EB64798D5A76A39D6E"
2602	       "A1465525342E060EE996277B4FFCDDC9");
2603long_hmac(sha512) ->
2604    hexstr2bin("D116BF471AAE1264854F1906025E846A"
2605	       "61618A965FCA30B695220EA2D6E547E3"
2606	       "F3B5A4B54E6778928C26D5D3D810498E"
2607	       "8DF86CB3CC1E9F66A00419B13B6B0C9A").
2608
2609rfc_2202_hmac_md5() ->
2610    [
2611     hexstr2bin("9294727a3638bb1c13f48ef8158bfc9d"),
2612     hexstr2bin("750c783e6ab0b503eaa86e310a5db738"),
2613     hexstr2bin("56be34521d144c88dbb8c733f0e8b3f6"),
2614     hexstr2bin("697eaf0aca3a3aea3a75164746ffaa79"),
2615     hexstr2bin("56461ef2342edc00f9bab995690efd4c"),
2616     hexstr2bin("6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd"),
2617     hexstr2bin("6f630fad67cda0ee1fb1f562db3aa53e")
2618    ].
2619
2620rfc_2202_hmac_sha() ->
2621    [
2622     hexstr2bin("b617318655057264e28bc0b6fb378c8ef146be00"),
2623     hexstr2bin("effcdf6ae5eb2fa2d27416d5f184df9c259a7c79"),
2624     hexstr2bin("125d7342b9ac11cd91a39af48aa17b4f63f175d3"),
2625     hexstr2bin("4c9007f4026250c6bc8414f9bf50c86c2d7235da"),
2626     hexstr2bin("4c1a03424b55e07fe7f27be1d58bb9324a9a5a04"),
2627     hexstr2bin("aa4ae5e15272d00e95705637ce8a3b55ed402112"),
2628     hexstr2bin("e8e99d0f45237d786d6bbaa7965c7808bbff1a91")
2629    ].
2630
2631
2632rfc_4231_keys() ->
2633    [binary:copy(<<16#0b>>, 20),
2634     <<"Jefe">>,
2635     binary:copy(<<16#aa>>, 20),
2636     list_to_binary(lists:seq(1, 16#19)),
2637     binary:copy(<<16#0c>>, 20),
2638     binary:copy(<<16#aa>>, 131),
2639     binary:copy(<<16#aa>>, 131)
2640    ].
2641
2642rfc_4231_msgs() ->
2643    [<<"Hi There">>,
2644     <<"what do ya want for nothing?">>,
2645     binary:copy(<<16#dd>>, 50),
2646     binary:copy(<<16#cd>>, 50),
2647     <<"Test With Truncation">>,
2648     <<"Test Using Larger Than Block-Size Key - Hash Key First">>,
2649     <<"This is a test using a larger than block-size key and a larger t",
2650       "han block-size data. The key needs to be hashed before being use",
2651       "d by the HMAC algorithm.">>
2652    ].
2653
2654rfc4231_hmac_sha224() ->
2655    [hexstr2bin("896fb1128abbdf196832107cd49df33f"
2656		       "47b4b1169912ba4f53684b22"),
2657     hexstr2bin("a30e01098bc6dbbf45690f3a7e9e6d0f"
2658		       "8bbea2a39e6148008fd05e44"),
2659     hexstr2bin("7fb3cb3588c6c1f6ffa9694d7d6ad264"
2660		       "9365b0c1f65d69d1ec8333ea"),
2661     hexstr2bin("6c11506874013cac6a2abc1bb382627c"
2662		       "ec6a90d86efc012de7afec5a"),
2663     hexstr2bin("0e2aea68a90c8d37c988bcdb9fca6fa8"),
2664     hexstr2bin("95e9a0db962095adaebe9b2d6f0dbce2"
2665		       "d499f112f2d2b7273fa6870e"),
2666     hexstr2bin("3a854166ac5d9f023f54d517d0b39dbd"
2667		"946770db9c2b95c9f6f565d1")].
2668rfc4231_hmac_sha256() ->
2669    [hexstr2bin("b0344c61d8db38535ca8afceaf0bf12b"
2670		"881dc200c9833da726e9376c2e32cff7"),
2671     hexstr2bin("5bdcc146bf60754e6a042426089575c7"
2672		"5a003f089d2739839dec58b964ec3843"),
2673     hexstr2bin("773ea91e36800e46854db8ebd09181a7"
2674		"2959098b3ef8c122d9635514ced565fe"),
2675    hexstr2bin("82558a389a443c0ea4cc819899f2083a"
2676	       "85f0faa3e578f8077a2e3ff46729665b"),
2677     hexstr2bin("a3b6167473100ee06e0c796c2955552b"),
2678     hexstr2bin("60e431591ee0b67f0d8a26aacbf5b77f"
2679		"8e0bc6213728c5140546040f0ee37f54"),
2680     hexstr2bin("9b09ffa71b942fcb27635fbcd5b0e944"
2681		"bfdc63644f0713938a7f51535c3a35e2")].
2682
2683rfc4231_hmac_sha384() ->
2684    [hexstr2bin("afd03944d84895626b0825f4ab46907f"
2685		"15f9dadbe4101ec682aa034c7cebc59c"
2686		"faea9ea9076ede7f4af152e8b2fa9cb6"),
2687     hexstr2bin("af45d2e376484031617f78d2b58a6b1b"
2688		"9c7ef464f5a01b47e42ec3736322445e"
2689	       "8e2240ca5e69e2c78b3239ecfab21649"),
2690     hexstr2bin("88062608d3e6ad8a0aa2ace014c8a86f"
2691	       "0aa635d947ac9febe83ef4e55966144b"
2692		"2a5ab39dc13814b94e3ab6e101a34f27"),
2693     hexstr2bin("3e8a69b7783c25851933ab6290af6ca7"
2694		"7a9981480850009cc5577c6e1f573b4e"
2695		"6801dd23c4a7d679ccf8a386c674cffb"),
2696     hexstr2bin("3abf34c3503b2a23a46efc619baef897"),
2697     hexstr2bin("4ece084485813e9088d2c63a041bc5b4"
2698		"4f9ef1012a2b588f3cd11f05033ac4c6"
2699		"0c2ef6ab4030fe8296248df163f44952"),
2700     hexstr2bin("6617178e941f020d351e2f254e8fd32c"
2701		"602420feb0b8fb9adccebb82461e99c5"
2702		"a678cc31e799176d3860e6110c46523e")].
2703rfc4231_hmac_sha512() ->
2704    [hexstr2bin("87aa7cdea5ef619d4ff0b4241a1d6cb0"
2705		"2379f4e2ce4ec2787ad0b30545e17cde"
2706		"daa833b7d6b8a702038b274eaea3f4e4"
2707		"be9d914eeb61f1702e696c203a126854"),
2708     hexstr2bin("164b7a7bfcf819e2e395fbe73b56e0a3"
2709		"87bd64222e831fd610270cd7ea250554"
2710		"9758bf75c05a994a6d034f65f8f0e6fd"
2711		"caeab1a34d4a6b4b636e070a38bce737"),
2712     hexstr2bin("fa73b0089d56a284efb0f0756c890be9"
2713		"b1b5dbdd8ee81a3655f83e33b2279d39"
2714		"bf3e848279a722c806b485a47e67c807"
2715		"b946a337bee8942674278859e13292fb"),
2716     hexstr2bin("b0ba465637458c6990e5a8c5f61d4af7"
2717		"e576d97ff94b872de76f8050361ee3db"
2718		"a91ca5c11aa25eb4d679275cc5788063"
2719		"a5f19741120c4f2de2adebeb10a298dd"),
2720     hexstr2bin("415fad6271580a531d4179bc891d87a6"),
2721     hexstr2bin("80b24263c7c1a3ebb71493c1dd7be8b4"
2722		"9b46d1f41b4aeec1121b013783f8f352"
2723		"6b56d037e05f2598bd0fd2215d6a1e52"
2724		"95e64f73f63f0aec8b915a985d786598"),
2725     hexstr2bin("e37b6a775dc87dbaa4dfa9f96e5e3ffd"
2726		"debd71f8867289865df5a32d20cdc944"
2727		"b6022cac3c4982b10d5eeb55c3e4de15"
2728		"134676fb6de0446065c97440fa8c6a58")].
2729des_cbc(_) ->
2730    [{des_cbc,
2731     hexstr2bin("0123456789abcdef"),
2732     hexstr2bin("1234567890abcdef"),
2733     <<"Now is the time for all ">> }].
2734
2735des_cfb(_) ->
2736    [{des_cfb,
2737     hexstr2bin("0123456789abcdef"),
2738     hexstr2bin("1234567890abcdef"),
2739     <<"Now is the">>}].
2740
2741des3_cbc(_) ->
2742    [{des3_cbc,
2743     [hexstr2bin("0123456789abcdef"),
2744      hexstr2bin("fedcba9876543210"),
2745      hexstr2bin("0f2d4b6987a5c3e1")],
2746     hexstr2bin("1234567890abcdef"),
2747     <<"Now is the time for all ">>
2748     }].
2749
2750des_ede3(_) ->
2751    [{des_ede3,
2752     [hexstr2bin("8000000000000000"),
2753      hexstr2bin("4000000000000000"),
2754      hexstr2bin("2000000000000000")],
2755      hexstr2bin("7AD16FFB79C45926"),
2756      hexstr2bin("0000000000000000")
2757     }].
2758
2759des_ede3_cbc(_) ->
2760    [{des_ede3_cbc,
2761     [hexstr2bin("0123456789abcdef"),
2762      hexstr2bin("fedcba9876543210"),
2763      hexstr2bin("0f2d4b6987a5c3e1")],
2764     hexstr2bin("1234567890abcdef"),
2765     <<"Now is the time for all ">>
2766     },
2767     {des_ede3_cbc,
2768     [hexstr2bin("8000000000000000"),
2769      hexstr2bin("4000000000000000"),
2770      hexstr2bin("2000000000000000")],
2771      hexstr2bin("7AD16FFB79C45926"),
2772      hexstr2bin("0000000000000000")
2773     }].
2774
2775des3_cbf(_) ->
2776    [{des3_cbf,
2777     [hexstr2bin("0123456789abcdef"),
2778      hexstr2bin("fedcba9876543210"),
2779      hexstr2bin("0f2d4b6987a5c3e1")],
2780     hexstr2bin("1234567890abcdef"),
2781     <<"Now is the time for all ">>
2782     }].
2783
2784des3_cfb(_) ->
2785    [{des3_cfb,
2786     [hexstr2bin("0123456789abcdef"),
2787      hexstr2bin("fedcba9876543210"),
2788      hexstr2bin("0f2d4b6987a5c3e1")],
2789     hexstr2bin("1234567890abcdef"),
2790     <<"Now is the time for all ">>
2791     }].
2792
2793des_ede3_cfb(_) ->
2794    [{des_ede3_cfb,
2795     [hexstr2bin("0123456789abcdef"),
2796      hexstr2bin("fedcba9876543210"),
2797      hexstr2bin("0f2d4b6987a5c3e1")],
2798     hexstr2bin("1234567890abcdef"),
2799     <<"Now is the time for all ">>
2800     }].
2801
2802rc2_cbc(_) ->
2803    [{rc2_cbc,
2804     <<146,210,160,124,215,227,153,239,227,17,222,140,3,93,27,191>>,
2805      <<72,91,135,182,25,42,35,210>>,
2806     <<36,245,206,158,168,230,58,69,148,137,32,192,250,41,237,181,181,251, 192,2,175,135,177,171,57,30,111,117,159,149,15,28,88,158,28,81,28,115, 85,219,241,82,117,222,91,85,73,117,164,25,182,52,191,64,123,57,26,19, 211,27,253,31,194,219,231,104,247,240,172,130,119,21,225,154,101,247, 32,216,42,216,133,169,78,22,97,27,227,26,196,224,172,168,17,9,148,55, 203,91,252,40,61,226,236,221,215,160,78,63,13,181,68,57,196,241,185, 207, 116,129,152,237,60,139,247,153,27,146,161,246,222,98,185,222,152, 187,135, 236,86,34,7,110,91,230,173,34,160,242,202,222,121,127,181,140, 101,203,195, 190,88,250,86,147,127,87,72,126,171,16,71,47,110,248,88, 14,29,143,161,152, 129,236,148,22,152,186,208,119,70,8,174,193,203,100, 193,203,200,117,102,242, 134,142,96,125,135,200,217,190,76,117,50,70, 209,186,101,241,200,91,40,193,54, 90,195,38,47,59,197,38,234,86,223,16, 51,253,204,129,20,171,66,21,241,26,135,216, 196,114,110,91,15,53,40, 164,201,136,113,95,247,51,181,208,241,68,168,98,151,36, 155,72,24,57, 42,191,14,125,204,10,167,214,233,138,115,125,234,121,134,227,26,247, 77,200,117,110,117,111,168,156,206,67,159,149,189,173,150,193,91,199, 216,153,22, 189,137,185,89,160,13,131,132,58,109,28,110,246,252,251,14, 232,91,38,52,29,101,188,69,123,50,0,130,178,93,73,239,118,7,77,35,59, 253,10,159,45,86,142,37,78,232,48>>
2807     }].
2808
2809%% AES CBC test vectors from http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
2810aes_cbc(Config) ->
2811    %% RETIRED aes_*_cbc
2812    read_rsp(Config, aes_cbc,
2813            ["CBCVarTxt128.rsp", "CBCVarKey128.rsp", "CBCGFSbox128.rsp", "CBCKeySbox128.rsp",
2814             "CBCVarTxt192.rsp", "CBCVarKey192.rsp", "CBCGFSbox192.rsp", "CBCKeySbox192.rsp",
2815             "CBCVarTxt256.rsp", "CBCVarKey256.rsp", "CBCGFSbox256.rsp", "CBCKeySbox256.rsp",
2816             "CBCMMT128.rsp", "CBCMMT192.rsp", "CBCMMT256.rsp"
2817            ]).
2818
2819aes_cbc128(Config) ->
2820    %% RETIRED aes_128_cbc
2821    read_rsp(Config, aes_cbc128,
2822             ["CBCVarTxt128.rsp", "CBCVarKey128.rsp", "CBCGFSbox128.rsp", "CBCKeySbox128.rsp",
2823              "CBCMMT128.rsp"]).
2824
2825aes_cbc256(Config) ->
2826    %% RETIRED aes_256_cbc
2827    read_rsp(Config, aes_cbc256,
2828             ["CBCVarTxt256.rsp", "CBCVarKey256.rsp", "CBCGFSbox256.rsp", "CBCKeySbox256.rsp",
2829              "CBCMMT256.rsp"]).
2830
2831aes_128_cbc(Config) ->
2832    read_rsp(Config, aes_128_cbc,
2833             ["CBCVarTxt128.rsp", "CBCVarKey128.rsp", "CBCGFSbox128.rsp", "CBCKeySbox128.rsp",
2834              "CBCMMT128.rsp"]).
2835
2836aes_192_cbc(Config) ->
2837    read_rsp(Config, aes_192_cbc,
2838             ["CBCVarTxt192.rsp", "CBCVarKey192.rsp", "CBCGFSbox192.rsp", "CBCKeySbox192.rsp",
2839              "CBCMMT192.rsp"]).
2840
2841aes_256_cbc(Config) ->
2842    read_rsp(Config, aes_256_cbc,
2843             ["CBCVarTxt256.rsp", "CBCVarKey256.rsp", "CBCGFSbox256.rsp", "CBCKeySbox256.rsp",
2844              "CBCMMT256.rsp"]).
2845
2846aes_ecb(Config) ->
2847    read_rsp(Config, aes_ecb,
2848             ["ECBVarTxt128.rsp", "ECBVarKey128.rsp", "ECBGFSbox128.rsp", "ECBKeySbox128.rsp",
2849              "ECBVarTxt192.rsp", "ECBVarKey192.rsp", "ECBGFSbox192.rsp", "ECBKeySbox192.rsp",
2850              "ECBVarTxt256.rsp", "ECBVarKey256.rsp", "ECBGFSbox256.rsp", "ECBKeySbox256.rsp",
2851              "ECBMMT128.rsp", "ECBMMT192.rsp", "ECBMMT256.rsp"]).
2852
2853aes_128_ecb(Config) ->
2854    read_rsp(Config, aes_128_ecb,
2855             ["ECBVarTxt128.rsp", "ECBVarKey128.rsp", "ECBGFSbox128.rsp", "ECBKeySbox128.rsp",
2856              "ECBMMT128.rsp"]).
2857
2858aes_192_ecb(Config) ->
2859    read_rsp(Config, aes_192_ecb,
2860             ["ECBVarTxt192.rsp", "ECBVarKey192.rsp", "ECBGFSbox192.rsp", "ECBKeySbox192.rsp",
2861              "ECBMMT192.rsp"]).
2862
2863aes_256_ecb(Config) ->
2864    read_rsp(Config, aes_256_ecb,
2865             ["ECBVarTxt256.rsp", "ECBVarKey256.rsp", "ECBGFSbox256.rsp", "ECBKeySbox256.rsp",
2866              "ECBMMT256.rsp"]).
2867
2868aes_ige256(_) ->
2869    [{aes_ige256,
2870      hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
2871      hexstr2bin("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F"),
2872      hexstr2bin("6bc1bee22e409f96e93d7e117393172a")},
2873      {aes_ige256,
2874       hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
2875       hexstr2bin("4D0F9E735749215C05CB20DA00F7814B77D33F8A668BEBBAC1739AB20302D4FE"),
2876       hexstr2bin("ae2d8a571e03ac9c9eb76fac45af8e51")},
2877      {aes_ige256,
2878       hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
2879       hexstr2bin("2A5569424DAE1ACEABDEEA108DB4606AE21A9227CAB5F55BF52535CFA2B34717"),
2880       hexstr2bin("30c81c46a35ce411e5fbc1191a0a52ef")},
2881      {aes_ige256,
2882       hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
2883       hexstr2bin("15D5A583D2D668E518E683D9BDF1B6D0E0C3B1E5D5C1D51E964822E1ADE88DFA"),
2884       hexstr2bin("f69f2445df4f9b17ad2b417be66c3710")}
2885     ].
2886
2887aes_cfb8(Config) ->
2888    read_rsp(Config, aes_cfb8,
2889             ["CFB8VarTxt128.rsp", "CFB8VarKey128.rsp", "CFB8GFSbox128.rsp", "CFB8KeySbox128.rsp",
2890              "CFB8VarTxt192.rsp", "CFB8VarKey192.rsp", "CFB8GFSbox192.rsp", "CFB8KeySbox192.rsp",
2891              "CFB8VarTxt256.rsp", "CFB8VarKey256.rsp", "CFB8GFSbox256.rsp", "CFB8KeySbox256.rsp",
2892              "CFB8MMT128.rsp", "CFB8MMT192.rsp", "CFB8MMT256.rsp"]).
2893
2894aes_128_cfb8(Config) ->
2895    read_rsp(Config, aes_128_cfb8,
2896             ["CFB8VarTxt128.rsp", "CFB8VarKey128.rsp", "CFB8GFSbox128.rsp", "CFB8KeySbox128.rsp",
2897              "CFB8MMT128.rsp"]).
2898
2899aes_192_cfb8(Config) ->
2900    read_rsp(Config, aes_192_cfb8,
2901             ["CFB8VarTxt192.rsp", "CFB8VarKey192.rsp", "CFB8GFSbox192.rsp", "CFB8KeySbox192.rsp",
2902              "CFB8MMT192.rsp"]).
2903
2904aes_256_cfb8(Config) ->
2905    read_rsp(Config, aes_256_cfb8,
2906             ["CFB8VarTxt256.rsp", "CFB8VarKey256.rsp", "CFB8GFSbox256.rsp", "CFB8KeySbox256.rsp",
2907              "CFB8MMT256.rsp"]).
2908
2909
2910aes_cfb128(Config) ->
2911    read_rsp(Config, aes_cfb128,
2912             ["CFB128VarTxt128.rsp", "CFB128VarKey128.rsp", "CFB128GFSbox128.rsp", "CFB128KeySbox128.rsp",
2913              "CFB128VarTxt192.rsp", "CFB128VarKey192.rsp", "CFB128GFSbox192.rsp", "CFB128KeySbox192.rsp",
2914              "CFB128VarTxt256.rsp", "CFB128VarKey256.rsp", "CFB128GFSbox256.rsp", "CFB128KeySbox256.rsp",
2915              "CFB128MMT128.rsp", "CFB128MMT192.rsp", "CFB128MMT256.rsp"]).
2916
2917aes_128_cfb128(Config) ->
2918    read_rsp(Config, aes_128_cfb128,
2919             ["CFB128VarTxt128.rsp", "CFB128VarKey128.rsp", "CFB128GFSbox128.rsp", "CFB128KeySbox128.rsp",
2920              "CFB128MMT128.rsp"]).
2921
2922aes_192_cfb128(Config) ->
2923    read_rsp(Config, aes_192_cfb128,
2924             ["CFB128VarTxt192.rsp", "CFB128VarKey192.rsp", "CFB128GFSbox192.rsp", "CFB128KeySbox192.rsp",
2925              "CFB128MMT192.rsp"]).
2926
2927aes_256_cfb128(Config) ->
2928    read_rsp(Config, aes_256_cfb128,
2929             ["CFB128VarTxt256.rsp", "CFB128VarKey256.rsp", "CFB128GFSbox256.rsp", "CFB128KeySbox256.rsp",
2930              "CFB128MMT256.rsp"]).
2931
2932
2933blowfish_cbc(_) ->
2934    [{blowfish_cbc,
2935      hexstr2bin("0123456789ABCDEFF0E1D2C3B4A59687"),
2936      hexstr2bin("FEDCBA9876543210"),
2937      hexstr2bin("37363534333231204E6F77206973207468652074696D6520666F722000000000")
2938     }].
2939
2940blowfish_ecb(_) ->
2941    [
2942     {blowfish_ecb,
2943      hexstr2bin("0000000000000000"),
2944      hexstr2bin("0000000000000000")},
2945     {blowfish_ecb,
2946      hexstr2bin("FFFFFFFFFFFFFFFF"),
2947      hexstr2bin("FFFFFFFFFFFFFFFF")},
2948     {blowfish_ecb,
2949      hexstr2bin("3000000000000000"),
2950      hexstr2bin("1000000000000001")},
2951     {blowfish_ecb,
2952      hexstr2bin("1111111111111111"),
2953      hexstr2bin("1111111111111111")},
2954     {blowfish_ecb,
2955      hexstr2bin("0123456789ABCDEF"),
2956      hexstr2bin("1111111111111111")},
2957     {blowfish_ecb,
2958      hexstr2bin("0000000000000000"),
2959      hexstr2bin("0000000000000000")},
2960     {blowfish_ecb,
2961      hexstr2bin("FEDCBA9876543210"),
2962      hexstr2bin("0123456789ABCDEF")},
2963     {blowfish_ecb,
2964      hexstr2bin("7CA110454A1A6E57"),
2965      hexstr2bin("01A1D6D039776742")},
2966     {blowfish_ecb,
2967      hexstr2bin("0131D9619DC1376E"),
2968      hexstr2bin("5CD54CA83DEF57DA")},
2969     {blowfish_ecb,
2970      hexstr2bin("07A1133E4A0B2686"),
2971      hexstr2bin("0248D43806F67172")},
2972     {blowfish_ecb,
2973      hexstr2bin("3849674C2602319E"),
2974      hexstr2bin("51454B582DDF440A")},
2975     {blowfish_ecb,
2976      hexstr2bin("04B915BA43FEB5B6"),
2977      hexstr2bin("42FD443059577FA2")},
2978     {blowfish_ecb,
2979      hexstr2bin("0113B970FD34F2CE"),
2980      hexstr2bin("059B5E0851CF143A")},
2981     {blowfish_ecb,
2982      hexstr2bin("0170F175468FB5E6"),
2983      hexstr2bin("0756D8E0774761D2")},
2984     {blowfish_ecb,
2985      hexstr2bin("43297FAD38E373FE"),
2986      hexstr2bin("762514B829BF486A")},
2987     {blowfish_ecb,
2988      hexstr2bin("07A7137045DA2A16"),
2989      hexstr2bin("3BDD119049372802")},
2990     {blowfish_ecb,
2991      hexstr2bin("04689104C2FD3B2F"),
2992      hexstr2bin("26955F6835AF609A")},
2993     {blowfish_ecb,
2994      hexstr2bin("37D06BB516CB7546"),
2995      hexstr2bin("164D5E404F275232")},
2996     {blowfish_ecb,
2997      hexstr2bin("1F08260D1AC2465E"),
2998      hexstr2bin("6B056E18759F5CCA")},
2999     {blowfish_ecb,
3000      hexstr2bin("584023641ABA6176"),
3001      hexstr2bin("004BD6EF09176062")},
3002     {blowfish_ecb,
3003      hexstr2bin("025816164629B007"),
3004      hexstr2bin("480D39006EE762F2")},
3005     {blowfish_ecb,
3006      hexstr2bin("49793EBC79B3258F"),
3007      hexstr2bin("437540C8698F3CFA")},
3008     {blowfish_ecb,
3009      hexstr2bin("018310DC409B26D6"),
3010      hexstr2bin("1D9D5C5018F728C2")},
3011     {blowfish_ecb,
3012      hexstr2bin("1C587F1C13924FEF"),
3013      hexstr2bin("305532286D6F295A")},
3014     {blowfish_ecb,
3015      hexstr2bin("0101010101010101"),
3016      hexstr2bin("0123456789ABCDEF")},
3017     {blowfish_ecb,
3018      hexstr2bin("1F1F1F1F0E0E0E0E"),
3019      hexstr2bin("0123456789ABCDEF")},
3020     {blowfish_ecb,
3021      hexstr2bin("E0FEE0FEF1FEF1FE"),
3022      hexstr2bin("0123456789ABCDEF")},
3023     {blowfish_ecb,
3024      hexstr2bin("0000000000000000"),
3025      hexstr2bin("FFFFFFFFFFFFFFFF")},
3026     {blowfish_ecb,
3027      hexstr2bin("FFFFFFFFFFFFFFFF"),
3028      hexstr2bin("0000000000000000")},
3029     {blowfish_ecb,
3030      hexstr2bin("0123456789ABCDEF"),
3031      hexstr2bin("0000000000000000")},
3032     {blowfish_ecb,
3033      hexstr2bin("FEDCBA9876543210"),
3034      hexstr2bin("FFFFFFFFFFFFFFFF")}
3035    ].
3036
3037blowfish_cfb64(_) ->
3038    [{blowfish_cfb64,
3039      hexstr2bin("0123456789ABCDEFF0E1D2C3B4A59687"),
3040      hexstr2bin("FEDCBA9876543210"),
3041      hexstr2bin("37363534333231204E6F77206973207468652074696D6520666F722000")
3042     }].
3043blowfish_ofb64(_) ->
3044    [{blowfish_ofb64,
3045      hexstr2bin("0123456789ABCDEFF0E1D2C3B4A59687"),
3046      hexstr2bin("FEDCBA9876543210"),
3047      hexstr2bin("37363534333231204E6F77206973207468652074696D6520666F722000")
3048     }].
3049
3050rc4(_) ->
3051    [{rc4, <<"apaapa">>, <<"Yo baby yo">>},
3052     {rc4, <<"apaapa">>, list_to_binary(lists:seq(0, 255))},
3053     {rc4, <<"apaapa">>, long_msg()}
3054    ].
3055
3056aes_ctr(_) ->
3057    [  %% F.5.3  CTR-AES192.Encrypt
3058       {aes_ctr, hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"),
3059	hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"),
3060	hexstr2bin("6bc1bee22e409f96e93d7e117393172a")},
3061       {aes_ctr, hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"),
3062	hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdff00"),
3063	hexstr2bin("ae2d8a571e03ac9c9eb76fac45af8e51")},
3064       {aes_ctr, hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"),
3065	hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdff01"),
3066	hexstr2bin("30c81c46a35ce411e5fbc1191a0a52ef") },
3067       {aes_ctr, hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"),
3068	hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdff02"),
3069	hexstr2bin("f69f2445df4f9b17ad2b417be66c3710")},
3070
3071       %% F.5.3  CTR-AES192.Encrypt
3072       {aes_ctr, hexstr2bin("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"),
3073	hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"),
3074	hexstr2bin("6bc1bee22e409f96e93d7e117393172a")},
3075       {aes_ctr, hexstr2bin("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"),
3076	hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdff00"),
3077	hexstr2bin("ae2d8a571e03ac9c9eb76fac45af8e51")},
3078       {aes_ctr, hexstr2bin("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"),
3079	hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdff01"),
3080	hexstr2bin("30c81c46a35ce411e5fbc1191a0a52ef")},
3081       {aes_ctr, hexstr2bin("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"),
3082	hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdff02"),
3083	hexstr2bin("f69f2445df4f9b17ad2b417be66c3710")},
3084
3085       %% F.5.5  CTR-AES256.Encrypt
3086       {aes_ctr, hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
3087	hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"),
3088	hexstr2bin("6bc1bee22e409f96e93d7e117393172a")},
3089       {aes_ctr, hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
3090	hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdff00"),
3091	hexstr2bin("ae2d8a571e03ac9c9eb76fac45af8e51")},
3092       {aes_ctr, hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
3093	hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdff01"),
3094	hexstr2bin("30c81c46a35ce411e5fbc1191a0a52ef")},
3095       {aes_ctr, hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
3096	hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdff02"),
3097	hexstr2bin("f69f2445df4f9b17ad2b417be66c3710")},
3098
3099       {aes_ctr,  hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
3100	hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"),
3101	long_msg()}
3102    ].
3103
3104
3105aes_128_ctr(_) ->
3106    [  %% F.5.3  CTR-AES192.Encrypt
3107       {aes_128_ctr, hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"),
3108	hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"),
3109	hexstr2bin("6bc1bee22e409f96e93d7e117393172a")},
3110       {aes_128_ctr, hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"),
3111	hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdff00"),
3112	hexstr2bin("ae2d8a571e03ac9c9eb76fac45af8e51")},
3113       {aes_128_ctr, hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"),
3114	hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdff01"),
3115	hexstr2bin("30c81c46a35ce411e5fbc1191a0a52ef") },
3116       {aes_128_ctr, hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"),
3117	hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdff02"),
3118	hexstr2bin("f69f2445df4f9b17ad2b417be66c3710")}
3119    ].
3120
3121aes_192_ctr(_) ->
3122    [ %% F.5.3  CTR-AES192.Encrypt
3123      {aes_192_ctr, hexstr2bin("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"),
3124       hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"),
3125       hexstr2bin("6bc1bee22e409f96e93d7e117393172a")},
3126      {aes_192_ctr, hexstr2bin("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"),
3127       hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdff00"),
3128       hexstr2bin("ae2d8a571e03ac9c9eb76fac45af8e51")},
3129      {aes_192_ctr, hexstr2bin("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"),
3130       hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdff01"),
3131	hexstr2bin("30c81c46a35ce411e5fbc1191a0a52ef")},
3132      {aes_192_ctr, hexstr2bin("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"),
3133       hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdff02"),
3134       hexstr2bin("f69f2445df4f9b17ad2b417be66c3710")}
3135    ].
3136
3137aes_256_ctr(_) ->
3138    [ %% F.5.5  CTR-AES256.Encrypt
3139      {aes_256_ctr, hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
3140       hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"),
3141       hexstr2bin("6bc1bee22e409f96e93d7e117393172a")},
3142      {aes_256_ctr, hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
3143       hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdff00"),
3144       hexstr2bin("ae2d8a571e03ac9c9eb76fac45af8e51")},
3145      {aes_256_ctr, hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
3146       hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdff01"),
3147       hexstr2bin("30c81c46a35ce411e5fbc1191a0a52ef")},
3148      {aes_256_ctr, hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
3149       hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdff02"),
3150       hexstr2bin("f69f2445df4f9b17ad2b417be66c3710")},
3151
3152      {aes_256_ctr,  hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
3153       hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"),
3154       long_msg()}
3155    ].
3156
3157
3158aes_gcm(Config) ->
3159    %% RETIRED aes_*_gcm
3160    read_rsp(Config, aes_gcm,
3161             ["gcmDecrypt128.rsp",
3162              "gcmDecrypt192.rsp",
3163              "gcmDecrypt256.rsp",
3164              "gcmEncryptExtIV128.rsp",
3165              "gcmEncryptExtIV192.rsp",
3166              "gcmEncryptExtIV256.rsp"]).
3167
3168aes_128_gcm(Config) ->
3169   read_rsp(Config, aes_128_gcm,
3170            ["gcmDecrypt128.rsp",
3171             "gcmEncryptExtIV128.rsp"]).
3172
3173aes_192_gcm(Config) ->
3174   read_rsp(Config, aes_192_gcm,
3175            ["gcmDecrypt192.rsp",
3176             "gcmEncryptExtIV192.rsp"]).
3177
3178aes_256_gcm(Config) ->
3179   read_rsp(Config, aes_256_gcm,
3180            ["gcmDecrypt256.rsp",
3181             "gcmEncryptExtIV256.rsp"]).
3182
3183
3184aes_ccm(Config) ->
3185    %% RETIRED aes_*_ccm
3186    read_rsp(Config, aes_ccm,
3187             ["VADT128.rsp", "VADT192.rsp", "VADT256.rsp",
3188              "VNT128.rsp",  "VNT192.rsp",  "VNT256.rsp",
3189              "VPT128.rsp",  "VPT192.rsp",  "VPT256.rsp"
3190             ]).
3191
3192aes_128_ccm(Config) ->
3193    read_rsp(Config, aes_128_ccm,
3194            ["VADT128.rsp", "VNT128.rsp", "VPT128.rsp"]).
3195
3196aes_192_ccm(Config) ->
3197   read_rsp(Config, aes_192_ccm,
3198            ["VADT192.rsp", "VNT192.rsp", "VPT192.rsp"]).
3199
3200aes_256_ccm(Config) ->
3201   read_rsp(Config, aes_256_ccm,
3202            ["VADT256.rsp", "VNT256.rsp", "VPT256.rsp"]).
3203
3204
3205
3206%% https://tools.ietf.org/html/rfc7539#appendix-A.5
3207chacha20_poly1305(_) ->
3208    [
3209     {chacha20_poly1305,
3210      hexstr2bin("1c9240a5eb55d38af333888604f6b5f0"                      %% Key
3211			"473917c1402b80099dca5cbc207075c0"),
3212      hexstr2bin("496e7465726e65742d44726166747320"                      %% PlainText
3213      "61726520647261667420646f63756d65"
3214      "6e74732076616c696420666f72206120"
3215      "6d6178696d756d206f6620736978206d"
3216      "6f6e74687320616e64206d6179206265"
3217      "20757064617465642c207265706c6163"
3218      "65642c206f72206f62736f6c65746564"
3219      "206279206f7468657220646f63756d65"
3220      "6e747320617420616e792074696d652e"
3221      "20497420697320696e617070726f7072"
3222      "6961746520746f2075736520496e7465"
3223      "726e65742d4472616674732061732072"
3224      "65666572656e6365206d617465726961"
3225      "6c206f7220746f206369746520746865"
3226      "6d206f74686572207468616e20617320"
3227      "2fe2809c776f726b20696e2070726f67"
3228      "726573732e2fe2809d"),
3229      hexstr2bin("000000000102030405060708"),                            %% Nonce
3230      hexstr2bin("f33388860000000000004e91"),                            %% AAD
3231      hexstr2bin("64a0861575861af460f062c79be643bd"                      %% CipherText
3232      "5e805cfd345cf389f108670ac76c8cb2"
3233      "4c6cfc18755d43eea09ee94e382d26b0"
3234      "bdb7b73c321b0100d4f03b7f355894cf"
3235      "332f830e710b97ce98c8a84abd0b9481"
3236      "14ad176e008d33bd60f982b1ff37c855"
3237      "9797a06ef4f0ef61c186324e2b350638"
3238      "3606907b6a7c02b0f9f6157b53c867e4"
3239      "b9166c767b804d46a59b5216cde7a4e9"
3240      "9040c5a40433225ee282a1b0a06c523e"
3241      "af4534d7f83fa1155b0047718cbc546a"
3242      "0d072b04b3564eea1b422273f548271a"
3243      "0bb2316053fa76991955ebd63159434e"
3244      "cebb4e466dae5a1073a6727627097a10"
3245      "49e617d91d361094fa68f0ff77987130"
3246      "305beaba2eda04df997b714d6c6f2c29"
3247      "a6ad5cb4022b02709b"),
3248      hexstr2bin("eead9d67890cbb22392336fea1851f38"),                    %% CipherTag
3249      no_info
3250      }
3251    ].
3252
3253
3254chacha20(_) ->
3255%%% chacha20 (no mode) test vectors from RFC 7539 A.2
3256    [
3257     %% Test Vector #1:
3258     {chacha20,
3259      hexstr2bin("00000000000000000000000000000000"
3260                 "00000000000000000000000000000000"),                    %% Key
3261      hexstr2bin("00000000" % Initial counter = 0, little-endian
3262                 "000000000000000000000000"),                            %% IV
3263      hexstr2bin("00000000000000000000000000000000"                      %% PlainText
3264                 "00000000000000000000000000000000"
3265                 "00000000000000000000000000000000"
3266                 "00000000000000000000000000000000"),
3267      hexstr2bin("76b8e0ada0f13d90405d6ae55386bd28"                      %% CipherText
3268                 "bdd219b8a08ded1aa836efcc8b770dc7"
3269                 "da41597c5157488d7724e03fb8d84a37"
3270                 "6a43b8f41518a11cc387b669b2ee6586")},
3271     %% Test Vector #2:
3272     {chacha20,
3273      hexstr2bin("00000000000000000000000000000000"
3274                 "00000000000000000000000000000001"),                    %% Key
3275      hexstr2bin("01000000" % Initial counter = 1, little-endian
3276                 "000000000000000000000002"),                            %% IV
3277      hexstr2bin("416e79207375626d697373696f6e2074"                      %% PlainText
3278                 "6f20746865204945544620696e74656e"
3279                 "6465642062792074686520436f6e7472"
3280                 "696275746f7220666f72207075626c69"
3281                 "636174696f6e20617320616c6c206f72"
3282                 "2070617274206f6620616e2049455446"
3283                 "20496e7465726e65742d447261667420"
3284                 "6f722052464320616e6420616e792073"
3285                 "746174656d656e74206d616465207769"
3286                 "7468696e2074686520636f6e74657874"
3287                 "206f6620616e20494554462061637469"
3288                 "7669747920697320636f6e7369646572"
3289                 "656420616e20224945544620436f6e74"
3290                 "7269627574696f6e222e205375636820"
3291                 "73746174656d656e747320696e636c75"
3292                 "6465206f72616c2073746174656d656e"
3293                 "747320696e2049455446207365737369"
3294                 "6f6e732c2061732077656c6c20617320"
3295                 "7772697474656e20616e6420656c6563"
3296                 "74726f6e696320636f6d6d756e696361"
3297                 "74696f6e73206d61646520617420616e"
3298                 "792074696d65206f7220706c6163652c"
3299                 "20776869636820617265206164647265"
3300                 "7373656420746f"),
3301      hexstr2bin("a3fbf07df3fa2fde4f376ca23e827370"                      %% CipherText
3302                 "41605d9f4f4f57bd8cff2c1d4b7955ec"
3303                 "2a97948bd3722915c8f3d337f7d37005"
3304                 "0e9e96d647b7c39f56e031ca5eb6250d"
3305                 "4042e02785ececfa4b4bb5e8ead0440e"
3306                 "20b6e8db09d881a7c6132f420e527950"
3307                 "42bdfa7773d8a9051447b3291ce1411c"
3308                 "680465552aa6c405b7764d5e87bea85a"
3309                 "d00f8449ed8f72d0d662ab052691ca66"
3310                 "424bc86d2df80ea41f43abf937d3259d"
3311                 "c4b2d0dfb48a6c9139ddd7f76966e928"
3312                 "e635553ba76c5c879d7b35d49eb2e62b"
3313                 "0871cdac638939e25e8a1e0ef9d5280f"
3314                 "a8ca328b351c3c765989cbcf3daa8b6c"
3315                 "cc3aaf9f3979c92b3720fc88dc95ed84"
3316                 "a1be059c6499b9fda236e7e818b04b0b"
3317                 "c39c1e876b193bfe5569753f88128cc0"
3318                 "8aaa9b63d1a16f80ef2554d7189c411f"
3319                 "5869ca52c5b83fa36ff216b9c1d30062"
3320                 "bebcfd2dc5bce0911934fda79a86f6e6"
3321                 "98ced759c3ff9b6477338f3da4f9cd85"
3322                 "14ea9982ccafb341b2384dd902f3d1ab"
3323                 "7ac61dd29c6f21ba5b862f3730e37cfd"
3324                 "c4fd806c22f221")},
3325     %%Test Vector #3:
3326     {chacha20,
3327      hexstr2bin("1c9240a5eb55d38af333888604f6b5f0"
3328                 "473917c1402b80099dca5cbc207075c0"),                    %% Key
3329      hexstr2bin("2a000000" % Initial counter = 42 (decimal), little-endian
3330                 "000000000000000000000002"),                            %% IV
3331      hexstr2bin("2754776173206272696c6c69672c2061"                      %% PlainText
3332                 "6e642074686520736c6974687920746f"
3333                 "7665730a446964206779726520616e64"
3334                 "2067696d626c6520696e207468652077"
3335                 "6162653a0a416c6c206d696d73792077"
3336                 "6572652074686520626f726f676f7665"
3337                 "732c0a416e6420746865206d6f6d6520"
3338                 "7261746873206f757467726162652e"),
3339      hexstr2bin("62e6347f95ed87a45ffae7426f27a1df"                      %% CipherText
3340                 "5fb69110044c0d73118effa95b01e5cf"
3341                 "166d3df2d721caf9b21e5fb14c616871"
3342                 "fd84c54f9d65b283196c7fe4f60553eb"
3343                 "f39c6402c42234e32a356b3e764312a6"
3344                 "1a5532055716ead6962568f87d3f3f77"
3345                 "04c6a8d1bcd1bf4d50d6154b6da731b1"
3346                 "87b58dfd728afa36757a797ac188d1")}
3347    ].
3348
3349
3350rsa_plain() ->
3351    <<"7896345786348756234 Hejsan Svejsan, erlang crypto debugger"
3352      "09812312908312378623487263487623412039812 huagasd">>.
3353rsa_public() ->
3354    [65537, 7919488123861148172698919999061127847747888703039837999377650217570191053151807772962118671509138346758471459464133273114654252861270845708312601272799123].
3355rsa_private() ->
3356    rsa_public() ++ [7531712708607620783801185371644749935066152052780368689827275932079815492940396744378735701395659435842364793962992309884847527234216715366607660219930945].
3357
3358rsa_public_stronger() ->
3359    [65537, 24629450921918866883077380602720734920775458960049554761386137065662137652635369332143446151320538248280934442179850504891395344346514465469955766163141133564033962851182759993807898821114734943339732032639891483186089941567854227407119560631150779000222837755424893038740314247760600374970909894211201220612920040986106639419467243909950276018045907029941478599124238353052062083560294570722081552510960894164859765695309596889747541376908786225647625736062865138957717982693312699025417086612046330464651009693307624955796202070510577399561730651967517158452930742355327167632521808183383868100102455048819375344881].
3360
3361rsa_private_stronger() ->
3362    rsa_public_stronger() ++ [13565232776562604620467234237694854016819673873109064019820773052201665024482754648718278717031083946624786145611240731564761987114634269887293030432042088547345315212418830656522115993209293567218379960177754901461542373481136856927955012596579314262051109321754382091434920473734937991286600905464814063189230779981494358415076362038786197620360127262110530926733754185204773610295221669711309000953136320804528874719105049753061737780710448207922456570922652651354760939379096788728229638142403068102990416717272880560951246813789730402978652924934794503277969128609831043469924881848849409122972426787999886557185].
3363
3364dss_plain() ->
3365    rsa_plain().
3366dss_public() ->
3367    25854665488880835237281628794585130313500176551981812527054397586638455298000483144002221850980183404910190346416063318160497344811383498859129095184158800144312512447497510551471331451396405348497845813002058423110442376886564659959543650802132345311573634832461635601376738282831340827591903548964194832978.
3368dss_private() ->
3369    441502407453038284293378221372000880210588566361.
3370dss_params() ->
3371    [109799869232806890760655301608454668257695818999841877165019612946154359052535682480084145133201304812979481136659521529774182959764860329095546511521488413513097576425638476458000255392402120367876345280670101492199681798674053929238558140260669578407351853803102625390950534052428162468100618240968893110797,
3372     1349199015905534965792122312016505075413456283393,
3373     18320614775012672475365915366944922415598782131828709277168615511695849821411624805195787607930033958243224786899641459701930253094446221381818858674389863050420226114787005820357372837321561754462061849169568607689530279303056075793886577588606958623645901271866346406773590024901668622321064384483571751669].
3374
3375ec_key_named() ->
3376    Curve = hd(crypto:ec_curves()),
3377    {D2_pub, D2_priv} = crypto:generate_key(ecdh, Curve),
3378    {[D2_priv, Curve], [D2_pub, Curve]}.
3379
3380ec_msg() ->
3381    <<99,234,6,64,190,237,201,99,80,248,58,40,70,45,149,218,5,246,242,63>>.
3382
3383srp3() ->
3384    Username = <<"alice">>,
3385    Password = <<"password123">>,
3386    Salt = hexstr2bin("2857827A19266A1F2BC6"),
3387    Prime = hexstr2bin("EEAF0AB9ADB38DD69C33F80AFA8FC5E86072618775FF3C0B9EA2314C"
3388		       "9C256576D674DF7496EA81D3383B4813D692C6E0E0D5D8E250B98BE4"
3389		       "8E495C1D6089DAD15DC7D7B46154D6B6CE8EF4AD69B15D4982559B29"
3390		       "7BCF1885C529F566660E57EC68EDBC3C05726CC02FD4CBF4976EAA9A"
3391		       "FD5138FE8376435B9FC61D2FC0EB06E3"),
3392    Generator = <<2>>,
3393    Version = '3',
3394    Scrambler = hexstr2bin("02E2476A"),
3395
3396    %% X = hexstr2bin("96E54AB0CD4C5123EDCFA4A1502918AAD3C9E2A8"),
3397    Verifier = hexstr2bin("96EB5F13621D911AA1CA405DE9C64217D4108EEEECAFFE500034FE0E"
3398			  "C031E42C8714667C161BCE0E7996F7DDE1B63824C130D2D7286C08C0"
3399			  "49758420735961347112AE102A3F23B3F687F8FEE0DF2BFAF933C608"
3400			  "D6FE5B5EEE3116FE54016E065BF8E8C9FDBBC08719231AC215149140"
3401			  "519E8FDD9AA4F410C28A58AF42974D2D"),
3402    ClientPrivate = hexstr2bin("6411DE75538BED8170677D577D0608F39112BC95B503C447EB6AC945"
3403			  "49C75C7B"),
3404    ServerPrivate = hexstr2bin("85E44A6F694DBE676145DB245A045CD37C99F05C562C7840A31F270D"
3405			  "9AADCF8B"),
3406    ClientPublic = hexstr2bin("B22B1FFA2244B8CB94F3A9080F419CAEAB0DBA93EA1965B5E84587EE"
3407			 "55C79E7A118865DC59B9D0353362C2A8261E7C1B0D221A0E233C2AD1"
3408			 "640DACBB8664CBC9733EAC392DA7800142860380C3FC573C3C064329"
3409			 "CF54063FD114C7210E9CB3A611EA8002B1844B698F930D95D143899B"
3410			 "948A090E0C25938E5F84067D1883DC63"),
3411    ServerPublic = hexstr2bin("93A8C4D8B7F7395ADCFD4ABA37B015124513D3F37B3E85EB23064BE5"
3412			 "F53C0AE32FFB9D8C0AA0DCFFA74D632DD67DEBB5C35AAE9812286CC8"
3413			 "C43CC176ECBC6D3F447594D9554E995B2509127BF88FADDDA4982D03"
3414			 "8EC3001320712D3B1269308CE70F319B2295FA57674F03A2D993CFB1"
3415			 "F84C35B7D0C012FA73CD4C8F7D5A71C7"),
3416
3417    SessionKey = hexstr2bin("C29A986C4D521BBC66428ED11D994CD7431574A6184B83CDCC345092"
3418			    "791E75748A1D38CAC4BD14760F0D2694B711236419240FF2F172454C"
3419			    "46ABF4FF39498DAFDD2C82924F7D7BD76CDFCE688C77D93F18A65409"
3420			    "9176A9192615DC0277AE7C12F1F6A7F6563FCA11675D809AF578BDE5"
3421			    "2B51E05D440B63099A017A0B45044801"),
3422    UserPassHash = crypto:hash(sha, [Salt, crypto:hash(sha, [Username, <<$:>>, Password])]),
3423    Verifier = crypto:mod_pow(Generator, UserPassHash, Prime),
3424    ClientPublic = crypto:mod_pow(Generator, ClientPrivate, Prime),
3425    srp(ClientPrivate, Generator, Prime, Version, Verifier, ServerPublic, ServerPrivate, UserPassHash, Scrambler, SessionKey).
3426
3427srp6() ->
3428    Username = <<"alice">>,
3429    Password = <<"password123">>,
3430    Salt = hexstr2bin("2857827A19266A1F2BC6"),
3431    Prime = hexstr2bin("EEAF0AB9ADB38DD69C33F80AFA8FC5E86072618775FF3C0B9EA2314C"
3432		       "9C256576D674DF7496EA81D3383B4813D692C6E0E0D5D8E250B98BE4"
3433		       "8E495C1D6089DAD15DC7D7B46154D6B6CE8EF4AD69B15D4982559B29"
3434		       "7BCF1885C529F566660E57EC68EDBC3C05726CC02FD4CBF4976EAA9A"
3435		       "FD5138FE8376435B9FC61D2FC0EB06E3"),
3436    Generator = <<2>>,
3437    Version = '6',
3438    Scrambler = hexstr2bin("0A2534C0BF52A0DA9001EEC62CF2A546AB0908A7"),
3439    Verifier = hexstr2bin("96EB5F13621D911AA1CA405DE9C64217D4108EEEECAFFE500034FE0E"
3440			  "C031E42C8714667C161BCE0E7996F7DDE1B63824C130D2D7286C08C0"
3441			  "49758420735961347112AE102A3F23B3F687F8FEE0DF2BFAF933C608"
3442			  "D6FE5B5EEE3116FE54016E065BF8E8C9FDBBC08719231AC215149140"
3443			  "519E8FDD9AA4F410C28A58AF42974D2D"),
3444    ClientPrivate = hexstr2bin("6411DE75538BED8170677D577D0608F39112BC95B503C447EB6AC945"
3445			  "49C75C7B"),
3446    ServerPrivate = hexstr2bin("85E44A6F694DBE676145DB245A045CD37C99F05C562C7840A31F270D"
3447			  "9AADCF8B"),
3448    ClientPublic = hexstr2bin("B22B1FFA2244B8CB94F3A9080F419CAEAB0DBA93EA1965B5E84587EE"
3449			 "55C79E7A118865DC59B9D0353362C2A8261E7C1B0D221A0E233C2AD1"
3450			 "640DACBB8664CBC9733EAC392DA7800142860380C3FC573C3C064329"
3451			 "CF54063FD114C7210E9CB3A611EA8002B1844B698F930D95D143899B"
3452			 "948A090E0C25938E5F84067D1883DC63"),
3453    ServerPublic = hexstr2bin("D2D07845CE7ECDB9845DD36B10ACD3598CC29049DE9F467F84CE16B6"
3454			 "D97A6DC567AF8B0F9FEDF74962400AD5C357951E64E67B641246F264"
3455			 "C8DE6D9A72E554D6C8D3194548780A0C438A0FCC509CA88A14AA1DEB"
3456			 "C0F09E4B37A965D1545DB4AD361346F3189B0EA569C06D326C4E4797"
3457			 "9E381C748293B7C0591BE0BE419E053E"),
3458
3459    SessionKey = hexstr2bin("19D22C19612874EBF1F2581F8EFCFDC44C6FDA3B87B0A73823D7E962"
3460				 "554295D4E48D3A336523ADBDDD0EC8FB0F02687109E97E01C17C93CC"
3461				 "7216F9CD8A4AC39F0429857D8D1023066614BDFCBCB89F59A0FEB81C"
3462				 "72E992AAD89095A84B6A5FADA152369AB1E350A03693BEF044DF3EDF"
3463				 "0C34741F4696C30E9F675D09F58ACBEB"),
3464    UserPassHash = crypto:hash(sha, [Salt, crypto:hash(sha, [Username, <<$:>>, Password])]),
3465    Verifier = crypto:mod_pow(Generator, UserPassHash, Prime),
3466    ClientPublic = crypto:mod_pow(Generator, ClientPrivate, Prime),
3467    srp(ClientPrivate, Generator, Prime, Version, Verifier, ServerPublic, ServerPrivate, UserPassHash, Scrambler, SessionKey).
3468
3469
3470srp6a_smaller_prime() ->
3471    Username = <<"alice">>,
3472    Password = <<"password123">>,
3473    Salt = <<"mystrongsalt">>,
3474    Prime = hexstr2bin("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7"),
3475    Generator = <<7>>,
3476    Version = '6a',
3477    Scrambler = hexstr2bin("18DE4A002AD05EF464B19AE2B6929F9B1319C7AA"),
3478    Verifier = hexstr2bin("867401D5DE10964768184EAF246B322760C847604075FA66A4423907"
3479			  "8428BCA5"),
3480    ClientPrivate = hexstr2bin("C49F832EE8D67ECF9E7F2785EB0622D8B3FE2344C00F96E1AEF4103C"
3481			  "A44D51F9"),
3482    ServerPrivate = hexstr2bin("6C78CCEAAEC15E69068A87795B2A20ED7B45CFC5A254EBE2F17F144A"
3483			  "4D99DB18"),
3484    ClientPublic = hexstr2bin("2452A57166BBBF690DB77539BAF9C57CD1ED99D5AA15ED925AD9B5C3"
3485			  "64BBEDFF"),
3486    ServerPublic = hexstr2bin("2C0464DE84B91E4963A3546CAC0EFE55F31F49208C3F0AD7EE55F444"
3487			  "8F38BA7F"),
3488
3489    SessionKey = hexstr2bin("65581B2302580BD26F522A5A421CF969B9CCBCE4051196B034A2A9D22065D848"),
3490    UserPassHash = crypto:hash(sha, [Salt, crypto:hash(sha, [Username, <<$:>>, Password])]),
3491    Verifier = crypto:mod_pow(Generator, UserPassHash, Prime),
3492    ClientPublic = crypto:mod_pow(Generator, ClientPrivate, Prime),
3493    srp(ClientPrivate, Generator, Prime, Version, Verifier, ServerPublic, ServerPrivate, UserPassHash, Scrambler, SessionKey).
3494
3495srp6a() ->
3496    Username = <<"alice">>,
3497    Password = <<"password123">>,
3498    Salt = hexstr2bin("BEB25379D1A8581EB5A727673A2441EE"),
3499    Prime = hexstr2bin("EEAF0AB9ADB38DD69C33F80AFA8FC5E86072618775FF3C0B9EA2314C"
3500		       "9C256576D674DF7496EA81D3383B4813D692C6E0E0D5D8E250B98BE4"
3501		       "8E495C1D6089DAD15DC7D7B46154D6B6CE8EF4AD69B15D4982559B29"
3502		       "7BCF1885C529F566660E57EC68EDBC3C05726CC02FD4CBF4976EAA9A"
3503		       "FD5138FE8376435B9FC61D2FC0EB06E3"),
3504    Generator = <<2>>,
3505    Version = '6a',
3506    Scrambler = hexstr2bin("CE38B9593487DA98554ED47D70A7AE5F462EF019"),
3507    Verifier = hexstr2bin("7E273DE8696FFC4F4E337D05B4B375BEB0DDE1569E8FA00A9886D812"
3508			  "9BADA1F1822223CA1A605B530E379BA4729FDC59F105B4787E5186F5"
3509			  "C671085A1447B52A48CF1970B4FB6F8400BBF4CEBFBB168152E08AB5"
3510			  "EA53D15C1AFF87B2B9DA6E04E058AD51CC72BFC9033B564E26480D78"
3511			  "E955A5E29E7AB245DB2BE315E2099AFB"),
3512    ClientPrivate = hexstr2bin("60975527035CF2AD1989806F0407210BC81EDC04E2762A56AFD529DD"
3513			  "DA2D4393"),
3514    ServerPrivate = hexstr2bin("E487CB59D31AC550471E81F00F6928E01DDA08E974A004F49E61F5D1"
3515			  "05284D20"),
3516    ClientPublic = hexstr2bin("61D5E490F6F1B79547B0704C436F523DD0E560F0C64115BB72557EC4"
3517			      "4352E8903211C04692272D8B2D1A5358A2CF1B6E0BFCF99F921530EC"
3518			      "8E39356179EAE45E42BA92AEACED825171E1E8B9AF6D9C03E1327F44"
3519			      "BE087EF06530E69F66615261EEF54073CA11CF5858F0EDFDFE15EFEA"
3520			      "B349EF5D76988A3672FAC47B0769447B"),
3521    ServerPublic = hexstr2bin("BD0C61512C692C0CB6D041FA01BB152D4916A1E77AF46AE105393011"
3522			      "BAF38964DC46A0670DD125B95A981652236F99D9B681CBF87837EC99"
3523			      "6C6DA04453728610D0C6DDB58B318885D7D82C7F8DEB75CE7BD4FBAA"
3524			      "37089E6F9C6059F388838E7A00030B331EB76840910440B1B27AAEAE"
3525			      "EB4012B7D7665238A8E3FB004B117B58"),
3526
3527    SessionKey = hexstr2bin("B0DC82BABCF30674AE450C0287745E7990A3381F63B387AAF271A10D"
3528			    "233861E359B48220F7C4693C9AE12B0A6F67809F0876E2D013800D6C"
3529			    "41BB59B6D5979B5C00A172B4A2A5903A0BDCAF8A709585EB2AFAFA8F"
3530			    "3499B200210DCC1F10EB33943CD67FC88A2F39A4BE5BEC4EC0A3212D"
3531			    "C346D7E474B29EDE8A469FFECA686E5A"),
3532    UserPassHash = crypto:hash(sha, [Salt, crypto:hash(sha, [Username, <<$:>>, Password])]),
3533    Verifier = crypto:mod_pow(Generator, UserPassHash, Prime),
3534    ClientPublic = crypto:mod_pow(Generator, ClientPrivate, Prime),
3535    srp(ClientPrivate, Generator, Prime, Version, Verifier, ServerPublic, ServerPrivate, UserPassHash, Scrambler, SessionKey).
3536
3537srp(ClientPrivate, Generator, Prime, Version, Verifier, ServerPublic, ServerPrivate, UserPassHash, Scrambler, SessionKey)->
3538    {srp, ClientPrivate,
3539     {user, [Generator, Prime, Version]}, {user, [UserPassHash, Prime, Generator, Version, Scrambler]},
3540     ServerPublic, ServerPrivate, {host, [Verifier, Generator, Prime, Version]},
3541     {host, [Verifier, Prime, Version, Scrambler]},
3542     SessionKey}.
3543
3544eddsa(ed25519) ->
3545    %% https://tools.ietf.org/html/rfc8032#section-7.1
3546    %% {ALGORITHM, (SHA)}, SECRET KEY, PUBLIC KEY,  MESSAGE, SIGNATURE}
3547    [
3548     %% TEST 1
3549     {ed25519, undefined,
3550      hexstr2bin("9d61b19deffd5a60ba844af492ec2cc4"
3551                 "4449c5697b326919703bac031cae7f60"),
3552      hexstr2bin("d75a980182b10ab7d54bfed3c964073a"
3553                 "0ee172f3daa62325af021a68f707511a"),
3554      hexstr2bin(""),
3555      hexstr2bin("e5564300c360ac729086e2cc806e828a"
3556                 "84877f1eb8e5d974d873e06522490155"
3557                 "5fb8821590a33bacc61e39701cf9b46b"
3558                 "d25bf5f0595bbe24655141438e7a100b")},
3559     %% TEST 2
3560     {ed25519, undefined,
3561      hexstr2bin("4ccd089b28ff96da9db6c346ec114e0f"
3562                 "5b8a319f35aba624da8cf6ed4fb8a6fb"),
3563      hexstr2bin("3d4017c3e843895a92b70aa74d1b7ebc"
3564                 "9c982ccf2ec4968cc0cd55f12af4660c"),
3565      hexstr2bin("72"),
3566      hexstr2bin("92a009a9f0d4cab8720e820b5f642540"
3567                 "a2b27b5416503f8fb3762223ebdb69da"
3568                 "085ac1e43e15996e458f3613d0f11d8c"
3569                 "387b2eaeb4302aeeb00d291612bb0c00")},
3570     %% TEST 3
3571     {ed25519, undefined,
3572      hexstr2bin("c5aa8df43f9f837bedb7442f31dcb7b1"
3573                 "66d38535076f094b85ce3a2e0b4458f7"),
3574      hexstr2bin("fc51cd8e6218a1a38da47ed00230f058"
3575                 "0816ed13ba3303ac5deb911548908025"),
3576      hexstr2bin("af82"),
3577      hexstr2bin("6291d657deec24024827e69c3abe01a3"
3578                 "0ce548a284743a445e3680d7db5ac3ac"
3579                 "18ff9b538d16f290ae67f760984dc659"
3580                 "4a7c15e9716ed28dc027beceea1ec40a")},
3581     %% TEST 1024
3582     {ed25519, undefined,
3583      hexstr2bin("f5e5767cf153319517630f226876b86c"
3584                 "8160cc583bc013744c6bf255f5cc0ee5"),
3585      hexstr2bin("278117fc144c72340f67d0f2316e8386"
3586                 "ceffbf2b2428c9c51fef7c597f1d426e"),
3587      hexstr2bin("08b8b2b733424243760fe426a4b54908"
3588                 "632110a66c2f6591eabd3345e3e4eb98"
3589                 "fa6e264bf09efe12ee50f8f54e9f77b1"
3590                 "e355f6c50544e23fb1433ddf73be84d8"
3591                 "79de7c0046dc4996d9e773f4bc9efe57"
3592                 "38829adb26c81b37c93a1b270b20329d"
3593                 "658675fc6ea534e0810a4432826bf58c"
3594                 "941efb65d57a338bbd2e26640f89ffbc"
3595                 "1a858efcb8550ee3a5e1998bd177e93a"
3596                 "7363c344fe6b199ee5d02e82d522c4fe"
3597                 "ba15452f80288a821a579116ec6dad2b"
3598                 "3b310da903401aa62100ab5d1a36553e"
3599                 "06203b33890cc9b832f79ef80560ccb9"
3600                 "a39ce767967ed628c6ad573cb116dbef"
3601                 "efd75499da96bd68a8a97b928a8bbc10"
3602                 "3b6621fcde2beca1231d206be6cd9ec7"
3603                 "aff6f6c94fcd7204ed3455c68c83f4a4"
3604                 "1da4af2b74ef5c53f1d8ac70bdcb7ed1"
3605                 "85ce81bd84359d44254d95629e9855a9"
3606                 "4a7c1958d1f8ada5d0532ed8a5aa3fb2"
3607                 "d17ba70eb6248e594e1a2297acbbb39d"
3608                 "502f1a8c6eb6f1ce22b3de1a1f40cc24"
3609                 "554119a831a9aad6079cad88425de6bd"
3610                 "e1a9187ebb6092cf67bf2b13fd65f270"
3611                 "88d78b7e883c8759d2c4f5c65adb7553"
3612                 "878ad575f9fad878e80a0c9ba63bcbcc"
3613                 "2732e69485bbc9c90bfbd62481d9089b"
3614                 "eccf80cfe2df16a2cf65bd92dd597b07"
3615                 "07e0917af48bbb75fed413d238f5555a"
3616                 "7a569d80c3414a8d0859dc65a46128ba"
3617                 "b27af87a71314f318c782b23ebfe808b"
3618                 "82b0ce26401d2e22f04d83d1255dc51a"
3619                 "ddd3b75a2b1ae0784504df543af8969b"
3620                 "e3ea7082ff7fc9888c144da2af58429e"
3621                 "c96031dbcad3dad9af0dcbaaaf268cb8"
3622                 "fcffead94f3c7ca495e056a9b47acdb7"
3623                 "51fb73e666c6c655ade8297297d07ad1"
3624                 "ba5e43f1bca32301651339e22904cc8c"
3625                 "42f58c30c04aafdb038dda0847dd988d"
3626                 "cda6f3bfd15c4b4c4525004aa06eeff8"
3627                 "ca61783aacec57fb3d1f92b0fe2fd1a8"
3628                 "5f6724517b65e614ad6808d6f6ee34df"
3629                 "f7310fdc82aebfd904b01e1dc54b2927"
3630                 "094b2db68d6f903b68401adebf5a7e08"
3631                 "d78ff4ef5d63653a65040cf9bfd4aca7"
3632                 "984a74d37145986780fc0b16ac451649"
3633                 "de6188a7dbdf191f64b5fc5e2ab47b57"
3634                 "f7f7276cd419c17a3ca8e1b939ae49e4"
3635                 "88acba6b965610b5480109c8b17b80e1"
3636                 "b7b750dfc7598d5d5011fd2dcc5600a3"
3637                 "2ef5b52a1ecc820e308aa342721aac09"
3638                 "43bf6686b64b2579376504ccc493d97e"
3639                 "6aed3fb0f9cd71a43dd497f01f17c0e2"
3640                 "cb3797aa2a2f256656168e6c496afc5f"
3641                 "b93246f6b1116398a346f1a641f3b041"
3642                 "e989f7914f90cc2c7fff357876e506b5"
3643                 "0d334ba77c225bc307ba537152f3f161"
3644                 "0e4eafe595f6d9d90d11faa933a15ef1"
3645                 "369546868a7f3a45a96768d40fd9d034"
3646                 "12c091c6315cf4fde7cb68606937380d"
3647                 "b2eaaa707b4c4185c32eddcdd306705e"
3648                 "4dc1ffc872eeee475a64dfac86aba41c"
3649                 "0618983f8741c5ef68d3a101e8a3b8ca"
3650                 "c60c905c15fc910840b94c00a0b9d0"),
3651      hexstr2bin("0aab4c900501b3e24d7cdf4663326a3a"
3652                 "87df5e4843b2cbdb67cbf6e460fec350"
3653                 "aa5371b1508f9f4528ecea23c436d94b"
3654                 "5e8fcd4f681e30a6ac00a9704a188a03")},
3655     %% TEST SHA(abc)
3656     {ed25519, undefined,
3657      hexstr2bin("833fe62409237b9d62ec77587520911e"
3658                 "9a759cec1d19755b7da901b96dca3d42"),
3659      hexstr2bin("ec172b93ad5e563bf4932c70e1245034"
3660                 "c35467ef2efd4d64ebf819683467e2bf"),
3661      hexstr2bin("ddaf35a193617abacc417349ae204131"
3662                 "12e6fa4e89a97ea20a9eeee64b55d39a"
3663                 "2192992a274fc1a836ba3c23a3feebbd"
3664                 "454d4423643ce80e2a9ac94fa54ca49f"),
3665      hexstr2bin("dc2a4459e7369633a52b1bf277839a00"
3666                 "201009a3efbf3ecb69bea2186c26b589"
3667                 "09351fc9ac90b3ecfdfbc7c66431e030"
3668                 "3dca179c138ac17ad9bef1177331a704")}
3669    ];
3670
3671eddsa(ed448) ->
3672    %% https://tools.ietf.org/html/rfc8032#section-7.4
3673    [{ed448, undefined,
3674      hexstr2bin("6c82a562cb808d10d632be89c8513ebf"
3675                 "6c929f34ddfa8c9f63c9960ef6e348a3"
3676                 "528c8a3fcc2f044e39a3fc5b94492f8f"
3677                 "032e7549a20098f95b"),
3678      hexstr2bin("5fd7449b59b461fd2ce787ec616ad46a"
3679                 "1da1342485a70e1f8a0ea75d80e96778"
3680                 "edf124769b46c7061bd6783df1e50f6c"
3681                 "d1fa1abeafe8256180"),
3682      hexstr2bin(""),
3683      hexstr2bin("533a37f6bbe457251f023c0d88f976ae"
3684                 "2dfb504a843e34d2074fd823d41a591f"
3685                 "2b233f034f628281f2fd7a22ddd47d78"
3686                 "28c59bd0a21bfd3980ff0d2028d4b18a"
3687                 "9df63e006c5d1c2d345b925d8dc00b41"
3688                 "04852db99ac5c7cdda8530a113a0f4db"
3689                 "b61149f05a7363268c71d95808ff2e65"
3690                 "2600")},
3691     %% 1 octet
3692     {ed448, undefined,
3693      hexstr2bin("c4eab05d357007c632f3dbb48489924d"
3694                 "552b08fe0c353a0d4a1f00acda2c463a"
3695                 "fbea67c5e8d2877c5e3bc397a659949e"
3696                 "f8021e954e0a12274e"),
3697      hexstr2bin("43ba28f430cdff456ae531545f7ecd0a"
3698                 "c834a55d9358c0372bfa0c6c6798c086"
3699                 "6aea01eb00742802b8438ea4cb82169c"
3700                 "235160627b4c3a9480"),
3701      hexstr2bin("03"),
3702      hexstr2bin("26b8f91727bd62897af15e41eb43c377"
3703                 "efb9c610d48f2335cb0bd0087810f435"
3704                 "2541b143c4b981b7e18f62de8ccdf633"
3705                 "fc1bf037ab7cd779805e0dbcc0aae1cb"
3706                 "cee1afb2e027df36bc04dcecbf154336"
3707                 "c19f0af7e0a6472905e799f1953d2a0f"
3708                 "f3348ab21aa4adafd1d234441cf807c0"
3709                 "3a00")},
3710
3711     %% %% 1 octet (with context)
3712     %% {ed448, undefined,
3713     %%  hexstr2bin("c4eab05d357007c632f3dbb48489924d"
3714     %%             "552b08fe0c353a0d4a1f00acda2c463a"
3715     %%             "fbea67c5e8d2877c5e3bc397a659949e"
3716     %%             "f8021e954e0a12274e"),
3717     %%  hexstr2bin("43ba28f430cdff456ae531545f7ecd0a"
3718     %%             "c834a55d9358c0372bfa0c6c6798c086"
3719     %%             "6aea01eb00742802b8438ea4cb82169c"
3720     %%             "235160627b4c3a9480"),
3721     %%  hexstr2bin("03"),
3722     %%  hexstr2bin("666f6f"), % Context
3723     %%  hexstr2bin("d4f8f6131770dd46f40867d6fd5d5055"
3724     %%             "de43541f8c5e35abbcd001b32a89f7d2"
3725     %%             "151f7647f11d8ca2ae279fb842d60721"
3726     %%             "7fce6e042f6815ea000c85741de5c8da"
3727     %%             "1144a6a1aba7f96de42505d7a7298524"
3728     %%             "fda538fccbbb754f578c1cad10d54d0d"
3729     %%             "5428407e85dcbc98a49155c13764e66c"
3730     %%             "3c00")},
3731
3732     %% 11 octets
3733     {ed448, undefined,
3734      hexstr2bin("cd23d24f714274e744343237b93290f5"
3735                 "11f6425f98e64459ff203e8985083ffd"
3736                 "f60500553abc0e05cd02184bdb89c4cc"
3737                 "d67e187951267eb328"),
3738      hexstr2bin("dcea9e78f35a1bf3499a831b10b86c90"
3739                 "aac01cd84b67a0109b55a36e9328b1e3"
3740                 "65fce161d71ce7131a543ea4cb5f7e9f"
3741                 "1d8b00696447001400"),
3742      hexstr2bin("0c3e544074ec63b0265e0c"),
3743      hexstr2bin("1f0a8888ce25e8d458a21130879b840a"
3744                 "9089d999aaba039eaf3e3afa090a09d3"
3745                 "89dba82c4ff2ae8ac5cdfb7c55e94d5d"
3746                 "961a29fe0109941e00b8dbdeea6d3b05"
3747                 "1068df7254c0cdc129cbe62db2dc957d"
3748                 "bb47b51fd3f213fb8698f064774250a5"
3749                 "028961c9bf8ffd973fe5d5c206492b14"
3750                 "0e00")},
3751     %% 12 octets
3752     {ed448, undefined,
3753      hexstr2bin("258cdd4ada32ed9c9ff54e63756ae582"
3754                 "fb8fab2ac721f2c8e676a72768513d93"
3755                 "9f63dddb55609133f29adf86ec9929dc"
3756                 "cb52c1c5fd2ff7e21b"),
3757      hexstr2bin("3ba16da0c6f2cc1f30187740756f5e79"
3758                 "8d6bc5fc015d7c63cc9510ee3fd44adc"
3759                 "24d8e968b6e46e6f94d19b945361726b"
3760                 "d75e149ef09817f580"),
3761      hexstr2bin("64a65f3cdedcdd66811e2915"),
3762      hexstr2bin("7eeeab7c4e50fb799b418ee5e3197ff6"
3763                 "bf15d43a14c34389b59dd1a7b1b85b4a"
3764                 "e90438aca634bea45e3a2695f1270f07"
3765                 "fdcdf7c62b8efeaf00b45c2c96ba457e"
3766                 "b1a8bf075a3db28e5c24f6b923ed4ad7"
3767                 "47c3c9e03c7079efb87cb110d3a99861"
3768                 "e72003cbae6d6b8b827e4e6c143064ff"
3769                 "3c00")},
3770     %% 13 octets
3771     {ed448, undefined,
3772      hexstr2bin("7ef4e84544236752fbb56b8f31a23a10"
3773                 "e42814f5f55ca037cdcc11c64c9a3b29"
3774                 "49c1bb60700314611732a6c2fea98eeb"
3775                 "c0266a11a93970100e"),
3776      hexstr2bin("b3da079b0aa493a5772029f0467baebe"
3777                 "e5a8112d9d3a22532361da294f7bb381"
3778                 "5c5dc59e176b4d9f381ca0938e13c6c0"
3779                 "7b174be65dfa578e80"),
3780      hexstr2bin("64a65f3cdedcdd66811e2915e7"),
3781      hexstr2bin("6a12066f55331b6c22acd5d5bfc5d712"
3782                 "28fbda80ae8dec26bdd306743c5027cb"
3783                 "4890810c162c027468675ecf645a8317"
3784                 "6c0d7323a2ccde2d80efe5a1268e8aca"
3785                 "1d6fbc194d3f77c44986eb4ab4177919"
3786                 "ad8bec33eb47bbb5fc6e28196fd1caf5"
3787                 "6b4e7e0ba5519234d047155ac727a105"
3788                 "3100")},
3789     %% 64 octets
3790     {ed448, undefined,
3791      hexstr2bin("d65df341ad13e008567688baedda8e9d"
3792                 "cdc17dc024974ea5b4227b6530e339bf"
3793                 "f21f99e68ca6968f3cca6dfe0fb9f4fa"
3794                 "b4fa135d5542ea3f01"),
3795      hexstr2bin("df9705f58edbab802c7f8363cfe5560a"
3796                 "b1c6132c20a9f1dd163483a26f8ac53a"
3797                 "39d6808bf4a1dfbd261b099bb03b3fb5"
3798                 "0906cb28bd8a081f00"),
3799      hexstr2bin("bd0f6a3747cd561bdddf4640a332461a"
3800                 "4a30a12a434cd0bf40d766d9c6d458e5"
3801                 "512204a30c17d1f50b5079631f64eb31"
3802                 "12182da3005835461113718d1a5ef944"),
3803      hexstr2bin("554bc2480860b49eab8532d2a533b7d5"
3804                 "78ef473eeb58c98bb2d0e1ce488a98b1"
3805                 "8dfde9b9b90775e67f47d4a1c3482058"
3806                 "efc9f40d2ca033a0801b63d45b3b722e"
3807                 "f552bad3b4ccb667da350192b61c508c"
3808                 "f7b6b5adadc2c8d9a446ef003fb05cba"
3809                 "5f30e88e36ec2703b349ca229c267083"
3810                 "3900")},
3811     %% 256 octets
3812     {ed448, undefined,
3813      hexstr2bin("2ec5fe3c17045abdb136a5e6a913e32a"
3814                 "b75ae68b53d2fc149b77e504132d3756"
3815                 "9b7e766ba74a19bd6162343a21c8590a"
3816                 "a9cebca9014c636df5"),
3817      hexstr2bin("79756f014dcfe2079f5dd9e718be4171"
3818                 "e2ef2486a08f25186f6bff43a9936b9b"
3819                 "fe12402b08ae65798a3d81e22e9ec80e"
3820                 "7690862ef3d4ed3a00"),
3821      hexstr2bin("15777532b0bdd0d1389f636c5f6b9ba7"
3822                 "34c90af572877e2d272dd078aa1e567c"
3823                 "fa80e12928bb542330e8409f31745041"
3824                 "07ecd5efac61ae7504dabe2a602ede89"
3825                 "e5cca6257a7c77e27a702b3ae39fc769"
3826                 "fc54f2395ae6a1178cab4738e543072f"
3827                 "c1c177fe71e92e25bf03e4ecb72f47b6"
3828                 "4d0465aaea4c7fad372536c8ba516a60"
3829                 "39c3c2a39f0e4d832be432dfa9a706a6"
3830                 "e5c7e19f397964ca4258002f7c0541b5"
3831                 "90316dbc5622b6b2a6fe7a4abffd9610"
3832                 "5eca76ea7b98816af0748c10df048ce0"
3833                 "12d901015a51f189f3888145c03650aa"
3834                 "23ce894c3bd889e030d565071c59f409"
3835                 "a9981b51878fd6fc110624dcbcde0bf7"
3836                 "a69ccce38fabdf86f3bef6044819de11"),
3837      hexstr2bin("c650ddbb0601c19ca11439e1640dd931"
3838                 "f43c518ea5bea70d3dcde5f4191fe53f"
3839                 "00cf966546b72bcc7d58be2b9badef28"
3840                 "743954e3a44a23f880e8d4f1cfce2d7a"
3841                 "61452d26da05896f0a50da66a239a8a1"
3842                 "88b6d825b3305ad77b73fbac0836ecc6"
3843                 "0987fd08527c1a8e80d5823e65cafe2a"
3844                 "3d00")},
3845     %% 1023 octets
3846     {ed448, undefined,
3847      hexstr2bin("872d093780f5d3730df7c212664b37b8"
3848                 "a0f24f56810daa8382cd4fa3f77634ec"
3849                 "44dc54f1c2ed9bea86fafb7632d8be19"
3850                 "9ea165f5ad55dd9ce8"),
3851      hexstr2bin("a81b2e8a70a5ac94ffdbcc9badfc3feb"
3852                 "0801f258578bb114ad44ece1ec0e799d"
3853                 "a08effb81c5d685c0c56f64eecaef8cd"
3854                 "f11cc38737838cf400"),
3855      hexstr2bin("6ddf802e1aae4986935f7f981ba3f035"
3856                 "1d6273c0a0c22c9c0e8339168e675412"
3857                 "a3debfaf435ed651558007db4384b650"
3858                 "fcc07e3b586a27a4f7a00ac8a6fec2cd"
3859                 "86ae4bf1570c41e6a40c931db27b2faa"
3860                 "15a8cedd52cff7362c4e6e23daec0fbc"
3861                 "3a79b6806e316efcc7b68119bf46bc76"
3862                 "a26067a53f296dafdbdc11c77f7777e9"
3863                 "72660cf4b6a9b369a6665f02e0cc9b6e"
3864                 "dfad136b4fabe723d2813db3136cfde9"
3865                 "b6d044322fee2947952e031b73ab5c60"
3866                 "3349b307bdc27bc6cb8b8bbd7bd32321"
3867                 "9b8033a581b59eadebb09b3c4f3d2277"
3868                 "d4f0343624acc817804728b25ab79717"
3869                 "2b4c5c21a22f9c7839d64300232eb66e"
3870                 "53f31c723fa37fe387c7d3e50bdf9813"
3871                 "a30e5bb12cf4cd930c40cfb4e1fc6225"
3872                 "92a49588794494d56d24ea4b40c89fc0"
3873                 "596cc9ebb961c8cb10adde976a5d602b"
3874                 "1c3f85b9b9a001ed3c6a4d3b1437f520"
3875                 "96cd1956d042a597d561a596ecd3d173"
3876                 "5a8d570ea0ec27225a2c4aaff26306d1"
3877                 "526c1af3ca6d9cf5a2c98f47e1c46db9"
3878                 "a33234cfd4d81f2c98538a09ebe76998"
3879                 "d0d8fd25997c7d255c6d66ece6fa56f1"
3880                 "1144950f027795e653008f4bd7ca2dee"
3881                 "85d8e90f3dc315130ce2a00375a318c7"
3882                 "c3d97be2c8ce5b6db41a6254ff264fa6"
3883                 "155baee3b0773c0f497c573f19bb4f42"
3884                 "40281f0b1f4f7be857a4e59d416c06b4"
3885                 "c50fa09e1810ddc6b1467baeac5a3668"
3886                 "d11b6ecaa901440016f389f80acc4db9"
3887                 "77025e7f5924388c7e340a732e554440"
3888                 "e76570f8dd71b7d640b3450d1fd5f041"
3889                 "0a18f9a3494f707c717b79b4bf75c984"
3890                 "00b096b21653b5d217cf3565c9597456"
3891                 "f70703497a078763829bc01bb1cbc8fa"
3892                 "04eadc9a6e3f6699587a9e75c94e5bab"
3893                 "0036e0b2e711392cff0047d0d6b05bd2"
3894                 "a588bc109718954259f1d86678a579a3"
3895                 "120f19cfb2963f177aeb70f2d4844826"
3896                 "262e51b80271272068ef5b3856fa8535"
3897                 "aa2a88b2d41f2a0e2fda7624c2850272"
3898                 "ac4a2f561f8f2f7a318bfd5caf969614"
3899                 "9e4ac824ad3460538fdc25421beec2cc"
3900                 "6818162d06bbed0c40a387192349db67"
3901                 "a118bada6cd5ab0140ee273204f628aa"
3902                 "d1c135f770279a651e24d8c14d75a605"
3903                 "9d76b96a6fd857def5e0b354b27ab937"
3904                 "a5815d16b5fae407ff18222c6d1ed263"
3905                 "be68c95f32d908bd895cd76207ae7264"
3906                 "87567f9a67dad79abec316f683b17f2d"
3907                 "02bf07e0ac8b5bc6162cf94697b3c27c"
3908                 "d1fea49b27f23ba2901871962506520c"
3909                 "392da8b6ad0d99f7013fbc06c2c17a56"
3910                 "9500c8a7696481c1cd33e9b14e40b82e"
3911                 "79a5f5db82571ba97bae3ad3e0479515"
3912                 "bb0e2b0f3bfcd1fd33034efc6245eddd"
3913                 "7ee2086ddae2600d8ca73e214e8c2b0b"
3914                 "db2b047c6a464a562ed77b73d2d841c4"
3915                 "b34973551257713b753632efba348169"
3916                 "abc90a68f42611a40126d7cb21b58695"
3917                 "568186f7e569d2ff0f9e745d0487dd2e"
3918                 "b997cafc5abf9dd102e62ff66cba87"),
3919      hexstr2bin("e301345a41a39a4d72fff8df69c98075"
3920                 "a0cc082b802fc9b2b6bc503f926b65bd"
3921                 "df7f4c8f1cb49f6396afc8a70abe6d8a"
3922                 "ef0db478d4c6b2970076c6a0484fe76d"
3923                 "76b3a97625d79f1ce240e7c576750d29"
3924                 "5528286f719b413de9ada3e8eb78ed57"
3925                 "3603ce30d8bb761785dc30dbc320869e"
3926                 "1a00")}
3927    ].
3928
3929ecdh() ->
3930    %% http://csrc.nist.gov/groups/STM/cavp/
3931    Curves = crypto:ec_curves() ++
3932        [X  || X <- proplists:get_value(curves, crypto:supports(), []),
3933               lists:member(X, [x25519,x448])],
3934    TestCases =
3935        [{ecdh, hexstr2point("42ea6dd9969dd2a61fea1aac7f8e98edcc896c6e55857cc0", "dfbe5d7c61fac88b11811bde328e8a0d12bf01a9d204b523"),
3936          hexstr2bin("f17d3fea367b74d340851ca4270dcb24c271f445bed9d527"),
3937          secp192r1,
3938          hexstr2bin("803d8ab2e5b6e6fca715737c3a82f7ce3c783124f6d51cd0")},
3939         {ecdh, hexstr2point("deb5712fa027ac8d2f22c455ccb73a91e17b6512b5e030e7", "7e2690a02cc9b28708431a29fb54b87b1f0c14e011ac2125"),
3940          hexstr2bin("56e853349d96fe4c442448dacb7cf92bb7a95dcf574a9bd5"),
3941          secp192r1,
3942          hexstr2bin("c208847568b98835d7312cef1f97f7aa298283152313c29d")},
3943         {ecdh, hexstr2point("af33cd0629bc7e996320a3f40368f74de8704fa37b8fab69abaae280", "882092ccbba7930f419a8a4f9bb16978bbc3838729992559a6f2e2d7"),
3944          hexstr2bin("8346a60fc6f293ca5a0d2af68ba71d1dd389e5e40837942df3e43cbd"),
3945          secp224r1,
3946          hexstr2bin("7d96f9a3bd3c05cf5cc37feb8b9d5209d5c2597464dec3e9983743e8")},
3947         {ecdh, hexstr2point("13bfcd4f8e9442393cab8fb46b9f0566c226b22b37076976f0617a46", "eeb2427529b288c63c2f8963c1e473df2fca6caa90d52e2f8db56dd4"),
3948          hexstr2bin("043cb216f4b72cdf7629d63720a54aee0c99eb32d74477dac0c2f73d"),
3949          secp224r1,
3950          hexstr2bin("ee93ce06b89ff72009e858c68eb708e7bc79ee0300f73bed69bbca09")},
3951         {ecdh, hexstr2point("700c48f77f56584c5cc632ca65640db91b6bacce3a4df6b42ce7cc838833d287", "db71e509e3fd9b060ddb20ba5c51dcc5948d46fbf640dfe0441782cab85fa4ac"),
3952          hexstr2bin("7d7dc5f71eb29ddaf80d6214632eeae03d9058af1fb6d22ed80badb62bc1a534"),
3953          secp256r1,
3954          hexstr2bin("46fc62106420ff012e54a434fbdd2d25ccc5852060561e68040dd7778997bd7b")},
3955         {ecdh, hexstr2point("809f04289c64348c01515eb03d5ce7ac1a8cb9498f5caa50197e58d43a86a7ae", "b29d84e811197f25eba8f5194092cb6ff440e26d4421011372461f579271cda3"),
3956          hexstr2bin("38f65d6dce47676044d58ce5139582d568f64bb16098d179dbab07741dd5caf5"),
3957          secp256r1,
3958          hexstr2bin("057d636096cb80b67a8c038c890e887d1adfa4195e9b3ce241c8a778c59cda67")},
3959         {ecdh, hexstr2point("a7c76b970c3b5fe8b05d2838ae04ab47697b9eaf52e764592efda27fe7513272734466b400091adbf2d68c58e0c50066", "ac68f19f2e1cb879aed43a9969b91a0839c4c38a49749b661efedf243451915ed0905a32b060992b468c64766fc8437a"),
3960          hexstr2bin("3cc3122a68f0d95027ad38c067916ba0eb8c38894d22e1b15618b6818a661774ad463b205da88cf699ab4d43c9cf98a1"),
3961          secp384r1,
3962          hexstr2bin("5f9d29dc5e31a163060356213669c8ce132e22f57c9a04f40ba7fcead493b457e5621e766c40a2e3d4d6a04b25e533f1")},
3963         {ecdh, hexstr2point("30f43fcf2b6b00de53f624f1543090681839717d53c7c955d1d69efaf0349b7363acb447240101cbb3af6641ce4b88e0", "25e46c0c54f0162a77efcc27b6ea792002ae2ba82714299c860857a68153ab62e525ec0530d81b5aa15897981e858757"),
3964          hexstr2bin("92860c21bde06165f8e900c687f8ef0a05d14f290b3f07d8b3a8cc6404366e5d5119cd6d03fb12dc58e89f13df9cd783"),
3965          secp384r1,
3966          hexstr2bin("a23742a2c267d7425fda94b93f93bbcc24791ac51cd8fd501a238d40812f4cbfc59aac9520d758cf789c76300c69d2ff")},
3967         {ecdh, hexstr2point("00685a48e86c79f0f0875f7bc18d25eb5fc8c0b07e5da4f4370f3a9490340854334b1e1b87fa395464c60626124a4e70d0f785601d37c09870ebf176666877a2046d", "01ba52c56fc8776d9e8f5db4f0cc27636d0b741bbe05400697942e80b739884a83bde99e0f6716939e632bc8986fa18dccd443a348b6c3e522497955a4f3c302f676"),
3968          hexstr2bin("017eecc07ab4b329068fba65e56a1f8890aa935e57134ae0ffcce802735151f4eac6564f6ee9974c5e6887a1fefee5743ae2241bfeb95d5ce31ddcb6f9edb4d6fc47"),
3969          secp521r1,
3970          hexstr2bin("005fc70477c3e63bc3954bd0df3ea0d1f41ee21746ed95fc5e1fdf90930d5e136672d72cc770742d1711c3c3a4c334a0ad9759436a4d3c5bf6e74b9578fac148c831")},
3971         {ecdh, hexstr2point("01df277c152108349bc34d539ee0cf06b24f5d3500677b4445453ccc21409453aafb8a72a0be9ebe54d12270aa51b3ab7f316aa5e74a951c5e53f74cd95fc29aee7a", "013d52f33a9f3c14384d1587fa8abe7aed74bc33749ad9c570b471776422c7d4505d9b0a96b3bfac041e4c6a6990ae7f700e5b4a6640229112deafa0cd8bb0d089b0"),
3972          hexstr2bin("00816f19c1fb10ef94d4a1d81c156ec3d1de08b66761f03f06ee4bb9dcebbbfe1eaa1ed49a6a990838d8ed318c14d74cc872f95d05d07ad50f621ceb620cd905cfb8"),
3973          secp521r1,
3974          hexstr2bin("000b3920ac830ade812c8f96805da2236e002acbbf13596a9ab254d44d0e91b6255ebf1229f366fb5a05c5884ef46032c26d42189273ca4efa4c3db6bd12a6853759")},
3975
3976         %% RFC-6954, Appendix A
3977         {ecdh, hexstr2point("A9C21A569759DA95E0387041184261440327AFE33141CA04B82DC92E",
3978                             "98A0F75FBBF61D8E58AE5511B2BCDBE8E549B31E37069A2825F590C1"),
3979          hexstr2bin("6060552303899E2140715816C45B57D9B42204FB6A5BF5BEAC10DB00"),
3980          brainpoolP224r1,
3981          hexstr2bin("1A4BFE705445120C8E3E026699054104510D119757B74D5FE2462C66")},
3982         {ecdh, hexstr2point("034A56C550FF88056144E6DD56070F54B0135976B5BF77827313F36B",
3983                             "75165AD99347DC86CAAB1CBB579E198EAF88DC35F927B358AA683681"),
3984          hexstr2bin("39F155483CEE191FBECFE9C81D8AB1A03CDA6790E7184ACE44BCA161"),
3985          brainpoolP224r1,
3986          hexstr2bin("1A4BFE705445120C8E3E026699054104510D119757B74D5FE2462C66")},
3987         {ecdh, hexstr2point("44106E913F92BC02A1705D9953A8414DB95E1AAA49E81D9E85F929A8E3100BE5",
3988                             "8AB4846F11CACCB73CE49CBDD120F5A900A69FD32C272223F789EF10EB089BDC"),
3989          hexstr2bin("55E40BC41E37E3E2AD25C3C6654511FFA8474A91A0032087593852D3E7D76BD3"),
3990          brainpoolP256r1,
3991          hexstr2bin("89AFC39D41D3B327814B80940B042590F96556EC91E6AE7939BCE31F3A18BF2B")},
3992         {ecdh, hexstr2point("8D2D688C6CF93E1160AD04CC4429117DC2C41825E1E9FCA0ADDD34E6F1B39F7B",
3993                             "990C57520812BE512641E47034832106BC7D3E8DD0E4C7F1136D7006547CEC6A"),
3994          hexstr2bin("81DB1EE100150FF2EA338D708271BE38300CB54241D79950F77B063039804F1D"),
3995          brainpoolP256r1,
3996          hexstr2bin("89AFC39D41D3B327814B80940B042590F96556EC91E6AE7939BCE31F3A18BF2B")},
3997         {ecdh, hexstr2point("68B665DD91C195800650CDD363C625F4E742E8134667B767B1B476793588F885AB698C852D4A6E77A252D6380FCAF068",
3998                             "55BC91A39C9EC01DEE36017B7D673A931236D2F1F5C83942D049E3FA20607493E0D038FF2FD30C2AB67D15C85F7FAA59"),
3999          hexstr2bin("032640BC6003C59260F7250C3DB58CE647F98E1260ACCE4ACDA3DD869F74E01F8BA5E0324309DB6A9831497ABAC96670"),
4000          brainpoolP384r1,
4001          hexstr2bin("0BD9D3A7EA0B3D519D09D8E48D0785FB744A6B355E6304BC51C229FBBCE239BBADF6403715C35D4FB2A5444F575D4F42")},
4002         {ecdh, hexstr2point("4D44326F269A597A5B58BBA565DA5556ED7FD9A8A9EB76C25F46DB69D19DC8CE6AD18E404B15738B2086DF37E71D1EB4",
4003                             "62D692136DE56CBE93BF5FA3188EF58BC8A3A0EC6C1E151A21038A42E9185329B5B275903D192F8D4E1F32FE9CC78C48"),
4004          hexstr2bin("1E20F5E048A5886F1F157C74E91BDE2B98C8B52D58E5003D57053FC4B0BD65D6F15EB5D1EE1610DF870795143627D042"),
4005          brainpoolP384r1,
4006          hexstr2bin("0BD9D3A7EA0B3D519D09D8E48D0785FB744A6B355E6304BC51C229FBBCE239BBADF6403715C35D4FB2A5444F575D4F42")},
4007         {ecdh, hexstr2point("0A420517E406AAC0ACDCE90FCD71487718D3B953EFD7FBEC5F7F27E28C6149999397E91E029E06457DB2D3E640668B392C2A7E737A7F0BF04436D11640FD09FD",
4008                             "72E6882E8DB28AAD36237CD25D580DB23783961C8DC52DFA2EC138AD472A0FCEF3887CF62B623B2A87DE5C588301EA3E5FC269B373B60724F5E82A6AD147FDE7"),
4009          hexstr2bin("230E18E1BCC88A362FA54E4EA3902009292F7F8033624FD471B5D8ACE49D12CFABBC19963DAB8E2F1EBA00BFFB29E4D72D13F2224562F405CB80503666B25429"),
4010          brainpoolP512r1,
4011          hexstr2bin("A7927098655F1F9976FA50A9D566865DC530331846381C87256BAF3226244B76D36403C024D7BBF0AA0803EAFF405D3D24F11A9B5C0BEF679FE1454B21C4CD1F")},
4012         {ecdh, hexstr2point("9D45F66DE5D67E2E6DB6E93A59CE0BB48106097FF78A081DE781CDB31FCE8CCBAAEA8DD4320C4119F1E9CD437A2EAB3731FA9668AB268D871DEDA55A5473199F",
4013                             "2FDC313095BCDD5FB3A91636F07A959C8E86B5636A1E930E8396049CB481961D365CC11453A06C719835475B12CB52FC3C383BCE35E27EF194512B71876285FA"),
4014          hexstr2bin("16302FF0DBBB5A8D733DAB7141C1B45ACBC8715939677F6A56850A38BD87BD59B09E80279609FF333EB9D4C061231FB26F92EEB04982A5F1D1764CAD57665422"),
4015          brainpoolP512r1,
4016          hexstr2bin("A7927098655F1F9976FA50A9D566865DC530331846381C87256BAF3226244B76D36403C024D7BBF0AA0803EAFF405D3D24F11A9B5C0BEF679FE1454B21C4CD1F")},
4017
4018         %% RFC 7748, 6.1
4019         {ecdh,
4020          16#8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a,
4021          16#5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb,
4022          x25519,
4023          hexstr2bin("4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742")},
4024         {ecdh,
4025          16#de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f,
4026          16#77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a,
4027          x25519,
4028          hexstr2bin("4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742")},
4029
4030         %% RFC 7748, 6.2
4031         {ecdh,
4032          16#9b08f7cc31b7e3e67d22d5aea121074a273bd2b83de09c63faa73d2c22c5d9bbc836647241d953d40c5b12da88120d53177f80e532c41fa0,
4033          16#1c306a7ac2a0e2e0990b294470cba339e6453772b075811d8fad0d1d6927c120bb5ee8972b0d3e21374c9c921b09d1b0366f10b65173992d,
4034          x448,
4035          hexstr2bin("07fff4181ac6cc95ec1c16a94a0f74d12da232ce40a77552281d282bb60c0b56fd2464c335543936521c24403085d59a449a5037514a879d")},
4036         {ecdh,
4037          16#3eb7a829b0cd20f5bcfc0b599b6feccf6da4627107bdb0d4f345b43027d8b972fc3e34fb4232a13ca706dcb57aec3dae07bdc1c67bf33609,
4038          16#9a8f4925d1519f5775cf46b04b5800d4ee9ee8bae8bc5565d498c28dd9c9baf574a9419744897391006382a6f127ab1d9ac2d8c0a598726b,
4039          x448,
4040          hexstr2bin("07fff4181ac6cc95ec1c16a94a0f74d12da232ce40a77552281d282bb60c0b56fd2464c335543936521c24403085d59a449a5037514a879d")}
4041        ],
4042    lists:filter(fun ({_Type, _Pub, _Priv, Curve, _SharedSecret}) ->
4043                         lists:member(Curve, Curves)
4044                 end,
4045                 TestCases).
4046
4047dh() ->
4048    {dh, 90970053988169282502023478715631717259407236400413906591937635666709823903223997309250405131675572047545403771567755831138144089197560332757755059848492919215391041119286178688014693040542889497092308638580104031455627238700168892909539193174537248629499995652186913900511641708112112482297874449292467498403, 2}.
4049
4050
4051
4052rsa_oaep() ->
4053    %% ftp://ftp.rsa.com/pub/rsalabs/tmp/pkcs1v15crypt-vectors.txt
4054    Public = [hexstr2bin("010001"),
4055	      hexstr2bin("a8b3b284af8eb50b387034a860f146c4919f318763cd6c5598c8ae4811a1e0abc4c7e0b082d693a5e7fced675cf4668512772c0cbc64a742c6c630f533c8cc72f62ae833c40bf25842e984bb78bdbf97c0107d55bdb662f5c4e0fab9845cb5148ef7392dd3aaff93ae1e6b667bb3d4247616d4f5ba10d4cfd226de88d39f16fb")],
4056    Private = Public ++ [hexstr2bin("53339cfdb79fc8466a655c7316aca85c55fd8f6dd898fdaf119517ef4f52e8fd8e258df93fee180fa0e4ab29693cd83b152a553d4ac4d1812b8b9fa5af0e7f55fe7304df41570926f3311f15c4d65a732c483116ee3d3d2d0af3549ad9bf7cbfb78ad884f84d5beb04724dc7369b31def37d0cf539e9cfcdd3de653729ead5d1"),
4057			 hexstr2bin("d32737e7267ffe1341b2d5c0d150a81b586fb3132bed2f8d5262864a9cb9f30af38be448598d413a172efb802c21acf1c11c520c2f26a471dcad212eac7ca39d"),
4058			 hexstr2bin("cc8853d1d54da630fac004f471f281c7b8982d8224a490edbeb33d3e3d5cc93c4765703d1dd791642f1f116a0dd852be2419b2af72bfe9a030e860b0288b5d77"),
4059			 hexstr2bin("0e12bf1718e9cef5599ba1c3882fe8046a90874eefce8f2ccc20e4f2741fb0a33a3848aec9c9305fbecbd2d76819967d4671acc6431e4037968db37878e695c1"),
4060			 hexstr2bin("95297b0f95a2fa67d00707d609dfd4fc05c89dafc2ef6d6ea55bec771ea333734d9251e79082ecda866efef13c459e1a631386b7e354c899f5f112ca85d71583"),
4061			 hexstr2bin("4f456c502493bdc0ed2ab756a3a6ed4d67352a697d4216e93212b127a63d5411ce6fa98d5dbefd73263e3728142743818166ed7dd63687dd2a8ca1d2f4fbd8e1")],
4062    %%Msg = hexstr2bin("6628194e12073db03ba94cda9ef9532397d50dba79b987004afefe34"),
4063    Msg =  hexstr2bin("750c4047f547e8e41411856523298ac9bae245efaf1397fbe56f9dd5"),
4064    {rsa, Public, Private, Msg, [{rsa_padding, rsa_pkcs1_oaep_padding}]}.
4065
4066rsa_oaep_label() ->
4067    Public = [hexstr2bin("010001"),
4068	      hexstr2bin("a8b3b284af8eb50b387034a860f146c4919f318763cd6c5598c8ae4811a1e0abc4c7e0b082d693a5e7fced675cf4668512772c0cbc64a742c6c630f533c8cc72f62ae833c40bf25842e984bb78bdbf97c0107d55bdb662f5c4e0fab9845cb5148ef7392dd3aaff93ae1e6b667bb3d4247616d4f5ba10d4cfd226de88d39f16fb")],
4069    Private = Public ++ [hexstr2bin("53339cfdb79fc8466a655c7316aca85c55fd8f6dd898fdaf119517ef4f52e8fd8e258df93fee180fa0e4ab29693cd83b152a553d4ac4d1812b8b9fa5af0e7f55fe7304df41570926f3311f15c4d65a732c483116ee3d3d2d0af3549ad9bf7cbfb78ad884f84d5beb04724dc7369b31def37d0cf539e9cfcdd3de653729ead5d1"),
4070			 hexstr2bin("d32737e7267ffe1341b2d5c0d150a81b586fb3132bed2f8d5262864a9cb9f30af38be448598d413a172efb802c21acf1c11c520c2f26a471dcad212eac7ca39d"),
4071			 hexstr2bin("cc8853d1d54da630fac004f471f281c7b8982d8224a490edbeb33d3e3d5cc93c4765703d1dd791642f1f116a0dd852be2419b2af72bfe9a030e860b0288b5d77"),
4072			 hexstr2bin("0e12bf1718e9cef5599ba1c3882fe8046a90874eefce8f2ccc20e4f2741fb0a33a3848aec9c9305fbecbd2d76819967d4671acc6431e4037968db37878e695c1"),
4073			 hexstr2bin("95297b0f95a2fa67d00707d609dfd4fc05c89dafc2ef6d6ea55bec771ea333734d9251e79082ecda866efef13c459e1a631386b7e354c899f5f112ca85d71583"),
4074			 hexstr2bin("4f456c502493bdc0ed2ab756a3a6ed4d67352a697d4216e93212b127a63d5411ce6fa98d5dbefd73263e3728142743818166ed7dd63687dd2a8ca1d2f4fbd8e1")],
4075    Msg = hexstr2bin("750c4047f547e8e41411856523298ac9bae245efaf1397fbe56f9dd5"),
4076    Lbl = hexstr2bin("1332a67ca7088f75c9b8fb5e3d072882"),
4077    {rsa, Public, Private, Msg, [{rsa_padding, rsa_pkcs1_oaep_padding}, {rsa_oaep_label, Lbl}]}.
4078
4079rsa_oaep256() ->
4080    Public = [hexstr2bin("010001"),
4081	      hexstr2bin("a8b3b284af8eb50b387034a860f146c4919f318763cd6c5598c8ae4811a1e0abc4c7e0b082d693a5e7fced675cf4668512772c0cbc64a742c6c630f533c8cc72f62ae833c40bf25842e984bb78bdbf97c0107d55bdb662f5c4e0fab9845cb5148ef7392dd3aaff93ae1e6b667bb3d4247616d4f5ba10d4cfd226de88d39f16fb")],
4082    Private = Public ++ [hexstr2bin("53339cfdb79fc8466a655c7316aca85c55fd8f6dd898fdaf119517ef4f52e8fd8e258df93fee180fa0e4ab29693cd83b152a553d4ac4d1812b8b9fa5af0e7f55fe7304df41570926f3311f15c4d65a732c483116ee3d3d2d0af3549ad9bf7cbfb78ad884f84d5beb04724dc7369b31def37d0cf539e9cfcdd3de653729ead5d1"),
4083			 hexstr2bin("d32737e7267ffe1341b2d5c0d150a81b586fb3132bed2f8d5262864a9cb9f30af38be448598d413a172efb802c21acf1c11c520c2f26a471dcad212eac7ca39d"),
4084			 hexstr2bin("cc8853d1d54da630fac004f471f281c7b8982d8224a490edbeb33d3e3d5cc93c4765703d1dd791642f1f116a0dd852be2419b2af72bfe9a030e860b0288b5d77"),
4085			 hexstr2bin("0e12bf1718e9cef5599ba1c3882fe8046a90874eefce8f2ccc20e4f2741fb0a33a3848aec9c9305fbecbd2d76819967d4671acc6431e4037968db37878e695c1"),
4086			 hexstr2bin("95297b0f95a2fa67d00707d609dfd4fc05c89dafc2ef6d6ea55bec771ea333734d9251e79082ecda866efef13c459e1a631386b7e354c899f5f112ca85d71583"),
4087			 hexstr2bin("4f456c502493bdc0ed2ab756a3a6ed4d67352a697d4216e93212b127a63d5411ce6fa98d5dbefd73263e3728142743818166ed7dd63687dd2a8ca1d2f4fbd8e1")],
4088    Msg = hexstr2bin("750c4047f547e8e41411856523298ac9bae245efaf1397fbe56f9dd5"),
4089    {rsa, Public, Private, Msg, [{rsa_padding, rsa_pkcs1_oaep_padding}, {rsa_oaep_md, sha256}]}.
4090
4091ecc() ->
4092%%               http://point-at-infinity.org/ecc/nisttv
4093%%
4094%% Test vectors for the NIST elliptic curves P192, P224, P256, P384, P521,
4095%% B163, B233, B283, B409, B571, K163, K233, K283, K409 and K571. For more
4096%% information about the curves see
4097%%       http://csrc.nist.gov/encryption/dss/ecdsa/NISTReCur.pdf
4098%%
4099    Curves = crypto:ec_curves(),
4100    TestCases =
4101        [{ecdh,secp192r1,1,
4102          hexstr2point("188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012",
4103                       "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811")},
4104         {ecdh,secp192r1,2,
4105          hexstr2point("DAFEBF5828783F2AD35534631588A3F629A70FB16982A888",
4106                       "DD6BDA0D993DA0FA46B27BBC141B868F59331AFA5C7E93AB")},
4107         {ecdh,secp192r1,3,
4108          hexstr2point("76E32A2557599E6EDCD283201FB2B9AADFD0D359CBB263DA",
4109                       "782C37E372BA4520AA62E0FED121D49EF3B543660CFD05FD")},
4110         {ecdh,secp192r1,4,
4111          hexstr2point("35433907297CC378B0015703374729D7A4FE46647084E4BA",
4112                       "A2649984F2135C301EA3ACB0776CD4F125389B311DB3BE32")}],
4113    lists:filter(fun ({_Type, Curve, _Priv, _Pub}) ->
4114                         lists:member(Curve, Curves)
4115                 end,
4116                 TestCases).
4117
4118int_to_bin(X) when X < 0 -> int_to_bin_neg(X, []);
4119int_to_bin(X) -> int_to_bin_pos(X, []).
4120
4121int_to_bin_pos(0,Ds=[_|_]) ->
4122    list_to_binary(Ds);
4123int_to_bin_pos(X,Ds) ->
4124    int_to_bin_pos(X bsr 8, [(X band 255)|Ds]).
4125
4126int_to_bin_neg(-1, Ds=[MSB|_]) when MSB >= 16#80 ->
4127    list_to_binary(Ds);
4128int_to_bin_neg(X,Ds) ->
4129    int_to_bin_neg(X bsr 8, [(X band 255)|Ds]).
4130
4131datadir(Config) ->
4132    proplists:get_value(data_dir, Config).
4133
4134-define(KiB, 1024).
4135-define(MiB, (1024 * 1024)).
4136-define(GiB, (1024 * 1024 * 1024)).
4137
4138fmt_words(Words) ->
4139    BSize = Words * erlang:system_info(wordsize),
4140    if BSize < ?KiB ->
4141            integer_to_list(BSize);
4142       BSize < ?MiB ->
4143            io_lib:format("~8.2fKiB (~8w)", [BSize / ?KiB, BSize]);
4144       BSize < ?GiB ->
4145            io_lib:format("~8.2fMiB (~8w)", [BSize / ?MiB, BSize]);
4146       true ->
4147            io_lib:format("~8.2fGiB (~8w)", [BSize / ?GiB, BSize])
4148    end.
4149
4150log_rsp_size(Label, Term) ->
4151    S = erts_debug:size(Term),
4152    ct:log("~s: ~w test(s), Memory used: ~s",
4153           [Label, length(Term), fmt_words(S)]).
4154
4155read_rsp(Config, Type, Files) ->
4156    Tests =
4157        lists:foldl(
4158          fun(FileName, Acc) ->
4159                  NewAcc = read_rsp_file(filename:join(datadir(Config), FileName),
4160                                         Type, Acc),
4161                  ct:log("~p: ~p tests read.~n",[FileName,length(NewAcc)-length(Acc)]),
4162                  NewAcc
4163          end, [], Files),
4164    log_rsp_size(Type, Tests),
4165    Tests.
4166
4167read_rsp_file(FileName, Type, Acc) ->
4168    case file:read_file(FileName) of
4169        {ok, Raw} ->
4170            Split = binary:split(Raw, [<<"\r">>, <<"\n">>], [global, trim_all]),
4171            parse_rsp(Type, Split, #{file => FileName}, Acc);
4172        Other ->
4173            ct:fail("~p ~p",[FileName, Other])
4174    end.
4175
4176parse_rsp(_Type, [], _State, Acc) ->
4177    Acc;
4178parse_rsp(_Type, [<<"DECRYPT">>|_], _State, Acc) ->
4179    Acc;
4180parse_rsp(_Type, [<<"ENCRYPT">>|_], _State, Acc) ->
4181    Acc;
4182%% AES format
4183parse_rsp(Type, [<<"COUNT = ", _/binary>>,
4184                 <<"KEY = ", Key/binary>>,
4185                 <<"PLAINTEXT = ", PlainText/binary>>,
4186                 <<"CIPHERTEXT = ", CipherText/binary>>|Next], State, Acc) ->
4187    parse_rsp(Type, Next, State,
4188              [{Type, hexstr2bin(Key),
4189                hexstr2bin(PlainText), hexstr2bin(CipherText)}|Acc]);
4190parse_rsp(Type, [<<"COUNT = ", _/binary>>,
4191                 <<"KEY = ", Key/binary>>,
4192                 <<"IV = ", IV/binary>>,
4193                 <<"PLAINTEXT = ", PlainText/binary>>,
4194                 <<"CIPHERTEXT = ", CipherText/binary>>|Next], State, Acc) ->
4195    parse_rsp(Type, Next, State,
4196              [{Type, hexstr2bin(Key), hexstr2bin(IV),
4197                hexstr2bin(PlainText), hexstr2bin(CipherText)}|Acc]);
4198%% CMAC format
4199parse_rsp(Type, [<<"Count = ", _/binary>>,
4200                 <<"Klen = ", _/binary>>,
4201                 <<"Mlen = ", Mlen/binary>>,
4202                 <<"Tlen = ", Tlen/binary>>,
4203                 <<"Key = ", Key/binary>>,
4204                 <<"Msg = ", Msg/binary>>,
4205                 <<"Mac = ", MAC/binary>>|Rest], State, Acc) ->
4206    case Rest of
4207        [<<"Result = P">>|Next] ->
4208            parse_rsp_cmac(Type, Key, Msg, Mlen, Tlen, MAC, Next, State, Acc);
4209        [<<"Result = ", _/binary>>|Next] ->
4210            parse_rsp(Type, Next, State, Acc);
4211        _ ->
4212            parse_rsp_cmac(Type, Key, Msg, Mlen, Tlen, MAC, Rest, State, Acc)
4213    end;
4214%% GCM format decode format
4215parse_rsp(Type, [<<"Count = ", Count/binary>>,
4216                 <<"Key = ", Key/binary>>,
4217                 <<"IV = ",  IV/binary>>,
4218                 <<"CT = ",  CipherText/binary>>,
4219                 <<"AAD = ", AAD/binary>>,
4220                 <<"Tag = ", CipherTag0/binary>>,
4221                 <<"PT = ",  PlainText/binary>>|Next], #{file:=File}=State, Acc) ->
4222    CipherTag = hexstr2bin(CipherTag0),
4223    TestCase = {Type,
4224                hexstr2bin(Key),
4225                hexstr2bin(PlainText),
4226                hexstr2bin(IV),
4227                hexstr2bin(AAD),
4228                hexstr2bin(CipherText),
4229                CipherTag,
4230                size(CipherTag),
4231                {File,decstr2int(Count)}},
4232    parse_rsp(Type, Next, State, [TestCase|Acc]);
4233%% GCM format encode format
4234parse_rsp(Type, [<<"Count = ", Count/binary>>,
4235                 <<"Key = ", Key/binary>>,
4236                 <<"IV = ",  IV/binary>>,
4237                 <<"PT = ",  PlainText/binary>>,
4238                 <<"AAD = ", AAD/binary>>,
4239                 <<"CT = ",  CipherText/binary>>,
4240                 <<"Tag = ", CipherTag0/binary>>|Next], #{file:=File}=State, Acc) ->
4241    CipherTag = hexstr2bin(CipherTag0),
4242    TestCase = {Type,
4243                hexstr2bin(Key),
4244                hexstr2bin(PlainText),
4245                hexstr2bin(IV),
4246                hexstr2bin(AAD),
4247                hexstr2bin(CipherText),
4248                CipherTag,
4249                size(CipherTag),
4250                {File,decstr2int(Count)}},
4251    parse_rsp(Type, Next, State, [TestCase|Acc]);
4252%% CCM-VADT format
4253parse_rsp(Type, [<<"[Alen = ", AlenB0/binary>>|Next], State0, Acc) ->
4254    AlenSize = size(AlenB0) - 1, % remove closing ']'
4255    Alen = decstr2int(<<AlenB0:AlenSize/binary>>),
4256    State = State0#{alen => Alen},
4257    parse_rsp(Type, Next, State, Acc);
4258parse_rsp(Type, [<<"[Nlen = ", NlenB0/binary>>|Next], State0, Acc) ->
4259    NlenSize = size(NlenB0) - 1, % remove closing ']'
4260    Nlen = decstr2int(<<NlenB0:NlenSize/binary>>),
4261    State = State0#{nlen => Nlen},
4262    parse_rsp(Type, Next, State, Acc);
4263parse_rsp(Type, [<<"[Plen = ", PlenB0/binary>>|Next], State0, Acc) ->
4264    PlenSize = size(PlenB0) - 1, % remove closing ']'
4265    Plen = decstr2int(<<PlenB0:PlenSize/binary>>),
4266    State = State0#{plen => Plen},
4267    parse_rsp(Type, Next, State, Acc);
4268parse_rsp(Type, [<<"[Tlen = ", TlenB0/binary>>|Next], State0, Acc) ->
4269    TlenSize = size(TlenB0) - 1, % remove closing ']'
4270    Tlen = decstr2int(<<TlenB0:TlenSize/binary>>),
4271    State = State0#{tlen => Tlen},
4272    parse_rsp(Type, Next, State, Acc);
4273parse_rsp(Type, [<<"Alen = ", B/binary>>|Next], State0, Acc) ->
4274    State = State0#{alen => decstr2int(B)},
4275    parse_rsp(Type, Next, State, Acc);
4276parse_rsp(Type, [<<"Plen = ", B/binary>>|Next], State0, Acc) ->
4277    State = State0#{plen => decstr2int(B)},
4278    parse_rsp(Type, Next, State, Acc);
4279parse_rsp(Type, [<<"Count = ", B/binary>>|Next], State0, Acc) ->
4280    State = State0#{count => B},
4281    parse_rsp(Type, Next, State, Acc);
4282parse_rsp(Type, [<<"Nlen = ", B/binary>>|Next], State0, Acc) ->
4283    State = State0#{nlen => decstr2int(B)},
4284    parse_rsp(Type, Next, State, Acc);
4285parse_rsp(Type, [<<"Tlen = ", B/binary>>|Next], State0, Acc) ->
4286    State = State0#{tlen => decstr2int(B)},
4287    parse_rsp(Type, Next, State, Acc);
4288parse_rsp(Type, [<<"Key = ",Key/binary>>|Next], State0, Acc) ->
4289    State = State0#{key => hexstr2bin(Key)},
4290    parse_rsp(Type, Next, State, Acc);
4291parse_rsp(Type, [<<"Nonce = ",Nonce/binary>>|Next], State0, Acc) ->
4292    State = State0#{nonce => hexstr2bin(Nonce)},
4293    parse_rsp(Type, Next, State, Acc);
4294parse_rsp(Type, [<<"Adata = ",Adata/binary>>|Next], State0, Acc) ->
4295    State = State0#{adata => hexstr2bin(Adata)},
4296    parse_rsp(Type, Next, State, Acc);
4297parse_rsp(Type, [<<"Payload = ",Payload/binary>>|Next], State0, Acc) ->
4298    State = State0#{payload => hexstr2bin(Payload)},
4299    parse_rsp(Type, Next, State, Acc);
4300parse_rsp(Type,
4301          [<<"CT = ", CT/binary>>|Next],
4302          #{count := Count,
4303            file := File,
4304            alen := Alen,
4305            plen := Plen,
4306            nlen := _Nlen,
4307            tlen := Tlen,
4308            key := Key,
4309            nonce := IV,
4310            adata := Adata,
4311            payload := Payload
4312           } = State, Acc) ->
4313    AAD = <<Adata:Alen/binary>>,
4314    PlainText = <<Payload:Plen/binary>>,
4315    <<CipherText:Plen/binary, CipherTag:Tlen/binary>> = hexstr2bin(CT),
4316    TestCase = {Type,
4317                Key,
4318                PlainText,
4319                IV,
4320                AAD,
4321                CipherText,
4322                CipherTag,
4323                Tlen,
4324                {File,decstr2int(Count)}},
4325    parse_rsp(Type, Next, State, [TestCase|Acc]);
4326parse_rsp(Type, [_|Next], State, Acc) ->
4327    parse_rsp(Type, Next, State, Acc).
4328
4329
4330parse_rsp_cmac(Type, Key0, Msg0, Mlen0, Tlen, MAC0, Next, State, Acc) ->
4331    Key = hexstr2bin(Key0),
4332    Mlen = binary_to_integer(Mlen0),
4333    <<Msg:Mlen/bytes, _/binary>> = hexstr2bin(Msg0),
4334    MAC = hexstr2bin(MAC0),
4335    case binary_to_integer(Tlen) of
4336        0 ->
4337            parse_rsp(Type, Next, State, [{cmac, Type, Key, Msg, MAC}|Acc]);
4338        I ->
4339            parse_rsp(Type, Next, State, [{cmac, Type, Key, Msg, I, MAC}|Acc])
4340    end.
4341
4342api_errors_ecdh(Config) when is_list(Config) ->
4343    %% Check that we don't segfault when fed garbage.
4344    Test = fun(Others, Curve) ->
4345                   {_Pub, Priv} = crypto:generate_key(ecdh, Curve),
4346                   crypto:compute_key(ecdh, Others, Priv, Curve)
4347           end,
4348    Others = [gurka, 0, <<0>>],
4349    Curves = [gaffel, 0, sect571r1],
4350    [_= (catch Test(O, C)) || O <- Others, C <- Curves],
4351    ok.
4352
4353
4354%%%----- Tests for bad algorithm name as argument
4355-define(chk_api_name(Call, Expect),
4356        %% Check that we don't segfault on bad names
4357        (fun() -> % avoid binding vars
4358                 try
4359                     Call
4360                 catch
4361                     Expect -> ok;
4362
4363                     Class:Reason:Stack ->
4364                         ct:log("~p:~p~n~p", [Class,Reason,Stack]),
4365                         ct:fail("Bad respons for bad name")
4366                 end
4367         end)()
4368       ).
4369
4370bad_combo(_Config) ->
4371    ?chk_api_name(crypto:crypto_dyn_iv_init(des_ede3_cbc, <<>>, []),
4372                  error:_).
4373
4374bad_key_length(_Config) ->
4375    ?chk_api_name(crypto:crypto_dyn_iv_init(des_ede3_cbc, <<1>>, true),
4376                  error:{error,{"api_ng.c",_},"Can't initialize context, key_length"}).
4377
4378bad_cipher_name(_Config) ->
4379    ?chk_api_name(crypto:crypto_init(foobar, <<1:128>>, true),
4380                  error:{badarg,{"api_ng.c",_Line},"Unknown cipher"}).
4381
4382bad_generate_key_name(_Config) ->
4383    ?chk_api_name(crypto:generate_key(foobar, [1024]),
4384                  error:function_clause).
4385
4386bad_hash_name(_Config) ->
4387    ?chk_api_name(crypto:hash_init(foobar),
4388                  error:badarg).
4389
4390bad_hmac_name(_Config) ->
4391    ?chk_api_name(crypto:hmac(foobar, <<1:1024>>, "nothing"),
4392                  error:badarg).
4393
4394bad_mac_name(_Config) ->
4395    ?chk_api_name(crypto:mac(foobar, <<1:1024>>, "nothing"),
4396                  error:function_clause).
4397
4398bad_sign_name(_Config) ->
4399    ?chk_api_name(crypto:sign(rsa, foobar, "nothing", <<1:1024>>),
4400                  error:badarg),
4401    ?chk_api_name(crypto:sign(foobar, sha, "nothing", <<1:1024>>),
4402                  error:badarg).
4403
4404bad_verify_name(_Config) ->
4405    ?chk_api_name(crypto:verify(rsa, foobar, "nothing","nothing",  <<1:1024>>),
4406                  error:badarg),
4407    ?chk_api_name(crypto:verify(foobar, sha, "nothing", "nothing", <<1:1024>>),
4408                  error:badarg).
4409
4410
4411%%%----------------------------------------------------------------
4412try_enable_fips_mode(Config) ->
4413    FIPSConfig = [{fips, true} | Config],
4414    case crypto:info_fips() of
4415        enabled ->
4416            FIPSConfig;
4417        not_enabled ->
4418            %% Erlang/crypto configured with --enable-fips
4419            case crypto:enable_fips_mode(true) of
4420		true ->
4421                    %% and also the cryptolib is fips enabled
4422		    enabled = crypto:info_fips(),
4423		    FIPSConfig;
4424		false ->
4425                    try
4426                        [{_,_,Inf}] = crypto:info_lib(),
4427                        re:run(Inf, "(F|f)(I|i)(P|p)(S|s)")
4428                    of
4429                        nomatch ->
4430                            {skip, "FIPS mode not supported in cryptolib"};
4431                        {match,_} ->
4432                            {fail, "Failed to enable FIPS mode"}
4433                    catch
4434                        _:_ ->
4435                            {fail, "Failed to check cryptolib info"}
4436                    end,
4437		    {skip, "FIPS mode not supported in cryptolib"}
4438	    end;
4439        not_supported ->
4440            {skip, "FIPS mode not supported"}
4441    end.
4442