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%% Unless required by applicable law or agreed to in writing, software
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
21%% Purpose : Main Crypto API module.
22
23-module(crypto).
24
25-export([start/0, stop/0, info/0, info_lib/0, info_fips/0, supports/0, enable_fips_mode/1,
26         version/0, bytes_to_integer/1]).
27-export([cipher_info/1, hash_info/1]).
28-export([hash/2, hash_init/1, hash_update/2, hash_final/1]).
29-export([sign/4, sign/5, verify/5, verify/6]).
30-export([generate_key/2, generate_key/3, compute_key/4]).
31-export([exor/2, strong_rand_bytes/1, mod_pow/3]).
32-export([rand_seed/0, rand_seed_alg/1, rand_seed_alg/2]).
33-export([rand_seed_s/0, rand_seed_alg_s/1, rand_seed_alg_s/2]).
34-export([rand_plugin_next/1]).
35-export([rand_plugin_aes_next/1, rand_plugin_aes_jump/1]).
36-export([rand_plugin_uniform/1]).
37-export([rand_plugin_uniform/2]).
38-export([rand_cache_plugin_next/1]).
39-export([rand_uniform/2]).
40-export([public_encrypt/4, private_decrypt/4]).
41-export([private_encrypt/4, public_decrypt/4]).
42-export([privkey_to_pubkey/2]).
43-export([ec_curve/1, ec_curves/0]).
44-export([rand_seed/1]).
45
46%%%----------------------------------------------------------------
47%% Removed functions.
48%%
49%% Old interface. Now implemented with the New interface.
50%% Removed in OTP-24.0 See OTP-16232 (deprecation) and OTP-16656 (removal)
51
52-removed([{next_iv, '_', "see the 'New and Old API' chapter of the CRYPTO User's guide"},
53          {hmac, 3, "use crypto:mac/4 instead"},
54          {hmac, 4, "use crypto:macN/5 instead"},
55          {hmac_init, 2, "use crypto:mac_init/3 instead"},
56          {hmac_update, 2, "use crypto:mac_update/2 instead"},
57          {hmac_final, 1, "use crypto:mac_final/1 instead"},
58          {hmac_final_n, 2, "use crypto:mac_finalN/2 instead"},
59          {cmac, 3, "use crypto:mac/4 instead"},
60          {cmac, 4, "use crypto:macN/5 instead"},
61          {poly1305, 2, "use crypto:mac/3 instead"},
62          {stream_init, '_', "use crypto:crypto_init/3 + crypto:crypto_update/2 + "
63                             "crypto:crypto_final/1 or crypto:crypto_one_time/4 instead"},
64          {stream_encrypt, 2, "use crypto:crypto_update/2 instead"},
65          {stream_decrypt, 2, "use crypto:crypto_update/2 instead"},
66          {block_encrypt, 3,  "use crypto:crypto_one_time/4 or crypto:crypto_init/3 + "
67                              "crypto:crypto_update/2 + crypto:crypto_final/1 instead"},
68          {block_encrypt, 4,  "use crypto:crypto_one_time/5, crypto:crypto_one_time_aead/6,7 "
69                              "or crypto:crypto_(dyn_iv)?_init + "
70                              "crypto:crypto_(dyn_iv)?_update + crypto:crypto_final instead"},
71          {block_decrypt, 3,  "use crypto:crypto_one_time/4 or crypto:crypto_init/3 + "
72                              "crypto:crypto_update/2 + crypto:crypto_final/1 instead"},
73          {block_decrypt, 4,  "use crypto:crypto_one_time/5, crypto:crypto_one_time_aead/6,7 "
74                              "or crypto:crypto_(dyn_iv)?_init + "
75                              "crypto:crypto_(dyn_iv)?_update + crypto:crypto_final instead"}
76         ]).
77
78-removed_type([{retired_cbc_cipher_aliases, 0, "Use aes_*_cbc or des_ede3_cbc"},
79               {retired_cfb_cipher_aliases, 0, "Use aes_*_cfb8, aes_*_cfb128 or des_ede3_cfb"},
80               {retired_ctr_cipher_aliases, 0, "Use aes_*_ctr"},
81               {retired_ecb_cipher_aliases, 0, "Use aes_*_ecb"},
82               {stream_state, 0, "see the 'New and Old API' chapter of the CRYPTO User's guide"},
83               {hmac_state,   0, "see the 'New and Old API' chapter of the CRYPTO User's guide"}
84              ]).
85
86%%%----------------------------------------------------------------
87%% New interface
88-export([crypto_init/4, crypto_init/3,
89         crypto_update/2,
90
91         crypto_one_time/4, crypto_one_time/5,
92         crypto_one_time_aead/6, crypto_one_time_aead/7,
93
94         crypto_dyn_iv_init/3,
95         crypto_dyn_iv_update/3,
96         crypto_final/1,
97         crypto_get_data/1,
98
99         supports/1,
100         mac/3, mac/4, macN/4, macN/5,
101         mac_init/2, mac_init/3, mac_update/2, mac_final/1, mac_finalN/2
102        ]).
103
104%%%----------------------------------------------------------------
105%% Engine
106-export([
107         engine_get_all_methods/0,
108         engine_load/3,
109         engine_load/4,
110         engine_unload/1,
111         engine_by_id/1,
112         engine_list/0,
113         engine_ctrl_cmd_string/3,
114         engine_ctrl_cmd_string/4,
115         engine_add/1,
116         engine_remove/1,
117         engine_get_id/1,
118         engine_get_name/1,
119         ensure_engine_loaded/2,
120         ensure_engine_loaded/3,
121         ensure_engine_unloaded/1,
122         ensure_engine_unloaded/2
123        ]).
124
125-export_type([ %% A minimum exported: only what public_key needs.
126               dh_private/0,
127               dh_public/0,
128               dss_digest_type/0,
129               ec_named_curve/0,
130               ecdsa_digest_type/0,
131               pk_encrypt_decrypt_opts/0,
132               pk_sign_verify_opts/0,
133               rsa_digest_type/0,
134               sha1/0,
135               sha2/0
136             ]).
137
138-export_type([engine_ref/0,
139              key_id/0,
140              password/0
141             ]).
142
143%%% Opaque types must be exported :(
144-export_type([
145              hash_state/0,
146              crypto_state/0,
147              mac_state/0
148             ]).
149
150%% Private. For tests.
151-export([packed_openssl_version/4, engine_methods_convert_to_bitmask/2,
152	 get_test_engine/0]).
153-export([rand_plugin_aes_jump_2pow20/1]).
154
155-deprecated({rand_uniform, 2, "use rand:uniform/1 instead"}).
156
157%% This should correspond to the similar macro in crypto.c
158-define(MAX_BYTES_TO_NIF, 20000). %%  Current value is: erlang:system_info(context_reductions) * 10
159
160%% Used by strong_rand_float/0
161-define(HALF_DBL_EPSILON, 1.1102230246251565e-16). % math:pow(2, -53)
162
163
164%%% ===== BEGIN NEW TYPING ====
165
166%%% Basic
167-type key_integer() :: integer() | binary(). % Always binary() when used as return value
168
169%%% Keys
170-type rsa_public() :: [key_integer()] . % [E, N]
171-type rsa_private() :: [key_integer()] . % [E, N, D] | [E, N, D, P1, P2, E1, E2, C]
172-type rsa_params() :: {ModulusSizeInBits::integer(), PublicExponent::key_integer()} .
173
174-type dss_public() :: [key_integer()] . % [P, Q, G, Y]
175-type dss_private() :: [key_integer()] . % [P, Q, G, X]
176
177-type ecdsa_public()  :: key_integer() .
178-type ecdsa_private() :: key_integer() .
179-type ecdsa_params()  :: ec_named_curve() | ec_explicit_curve() .
180
181-type eddsa_public()  :: key_integer() .
182-type eddsa_private() :: key_integer() .
183-type eddsa_params()  :: edwards_curve_ed() .
184
185-type srp_public() :: key_integer() .
186-type srp_private() :: key_integer() .
187-type srp_gen_params()  :: {user,srp_user_gen_params()}  | {host,srp_host_gen_params()}.
188-type srp_comp_params() :: {user,srp_user_comp_params()} | {host,srp_host_comp_params()}.
189-type srp_user_gen_params() :: list(binary() | atom() | list()) .
190-type srp_host_gen_params() :: list(binary() | atom() | list()) .
191-type srp_user_comp_params() :: list(binary() | atom()) .
192-type srp_host_comp_params() :: list(binary() | atom()) .
193
194-type dh_public() :: key_integer() .
195-type dh_private() :: key_integer() .
196-type dh_params() :: [key_integer()] . % [P, G] | [P, G, PrivateKeyBitLength]
197
198-type ecdh_public()  :: key_integer() .
199-type ecdh_private() :: key_integer() .
200-type ecdh_params()  :: ec_named_curve() | edwards_curve_dh() | ec_explicit_curve() .
201
202
203%%% Curves
204
205-type ec_explicit_curve() :: {Field :: ec_field(),
206                              Curve :: ec_curve(),
207                              BasePoint :: binary(),
208                              Order :: binary(),
209                              CoFactor :: none | % FIXME: Really?
210                                          binary()
211                             } .
212
213-type ec_curve() :: {A :: binary(),
214                     B :: binary(),
215                     Seed :: none | binary()
216                    } .
217
218-type ec_field() ::  ec_prime_field() | ec_characteristic_two_field() .
219
220-type ec_prime_field()              :: {prime_field, Prime :: integer()} .
221-type ec_characteristic_two_field() :: {characteristic_two_field, M :: integer(), Basis :: ec_basis()} .
222
223-type ec_basis() :: {tpbasis, K :: non_neg_integer()}
224                  | {ppbasis, K1 :: non_neg_integer(), K2 :: non_neg_integer(), K3 :: non_neg_integer()}
225                  |  onbasis .
226
227-type ec_named_curve() :: brainpoolP160r1
228                        | brainpoolP160t1
229                        | brainpoolP192r1
230                        | brainpoolP192t1
231                        | brainpoolP224r1
232                        | brainpoolP224t1
233                        | brainpoolP256r1
234                        | brainpoolP256t1
235                        | brainpoolP320r1
236                        | brainpoolP320t1
237                        | brainpoolP384r1
238                        | brainpoolP384t1
239                        | brainpoolP512r1
240                        | brainpoolP512t1
241                        | c2pnb163v1
242                        | c2pnb163v2
243                        | c2pnb163v3
244                        | c2pnb176v1
245                        | c2pnb208w1
246                        | c2pnb272w1
247                        | c2pnb304w1
248                        | c2pnb368w1
249                        | c2tnb191v1
250                        | c2tnb191v2
251                        | c2tnb191v3
252                        | c2tnb239v1
253                        | c2tnb239v2
254                        | c2tnb239v3
255                        | c2tnb359v1
256                        | c2tnb431r1
257                        | ipsec3
258                        | ipsec4
259                        | prime192v1
260                        | prime192v2
261                        | prime192v3
262                        | prime239v1
263                        | prime239v2
264                        | prime239v3
265                        | prime256v1
266                        | secp112r1
267                        | secp112r2
268                        | secp128r1
269                        | secp128r2
270                        | secp160k1
271                        | secp160r1
272                        | secp160r2
273                        | secp192k1
274                        | secp192r1
275                        | secp224k1
276                        | secp224r1
277                        | secp256k1
278                        | secp256r1
279                        | secp384r1
280                        | secp521r1
281                        | sect113r1
282                        | sect113r2
283                        | sect131r1
284                        | sect131r2
285                        | sect163k1
286                        | sect163r1
287                        | sect163r2
288                        | sect193r1
289                        | sect193r2
290                        | sect233k1
291                        | sect233r1
292                        | sect239k1
293                        | sect283k1
294                        | sect283r1
295                        | sect409k1
296                        | sect409r1
297                        | sect571k1
298                        | sect571r1
299                        | wtls1
300                        | wtls10
301                        | wtls11
302                        | wtls12
303                        | wtls3
304                        | wtls4
305                        | wtls5
306                        | wtls6
307                        | wtls7
308                        | wtls8
309                        | wtls9
310                          .
311
312-type edwards_curve_dh() :: x25519 | x448 .
313
314-type edwards_curve_ed() :: ed25519 | ed448 .
315
316%%%----------------------------------------------------------------
317%%% New cipher schema
318%%%
319-type cipher() :: cipher_no_iv()
320                | cipher_iv()
321                | cipher_aead() .
322
323-type cipher_no_iv() :: aes_128_ecb
324                      | aes_192_ecb
325                      | aes_256_ecb
326                      | aes_ecb
327
328                      | blowfish_ecb
329                      | des_ecb
330                      | rc4 .
331
332-type cipher_iv() :: aes_128_cbc
333                   | aes_192_cbc
334                   | aes_256_cbc
335                   | aes_cbc
336
337                   | aes_128_cfb128
338                   | aes_192_cfb128
339                   | aes_256_cfb128
340                   | aes_cfb128
341
342                   | aes_128_cfb8
343                   | aes_192_cfb8
344                   | aes_256_cfb8
345                   | aes_cfb8
346
347                   | aes_128_ctr
348                   | aes_192_ctr
349                   | aes_256_ctr
350                   | aes_ctr
351
352                   | blowfish_cbc
353                   | blowfish_cfb64
354                   | blowfish_ofb64
355                   | chacha20
356                   | des_ede3_cbc
357                   | des_ede3_cfb
358
359                   | des_cbc
360                   | des_cfb
361                   | rc2_cbc .
362
363
364-type cipher_aead() :: aes_128_ccm
365                     | aes_192_ccm
366                     | aes_256_ccm
367                     | aes_ccm
368
369                     | aes_128_gcm
370                     | aes_192_gcm
371                     | aes_256_gcm
372                     | aes_gcm
373
374                     | chacha20_poly1305 .
375
376
377%%%----------------------------------------------------------------
378
379-type rsa_digest_type()   :: sha1() | sha2() | md5 | ripemd160 .
380-type dss_digest_type()   :: sha1() | sha2() .
381-type ecdsa_digest_type() :: sha1() | sha2() .
382
383-type sha1() :: sha .
384-type sha2() :: sha224 | sha256 | sha384 | sha512 .
385-type sha3() :: sha3_224 | sha3_256 | sha3_384 | sha3_512 .
386-type blake2() :: blake2b | blake2s .
387
388-type compatibility_only_hash() :: md5 | md4 .
389
390-type crypto_integer() :: binary() | integer().
391
392%%%
393%% Exceptions
394%%   error:badarg
395%%   error:notsup
396-type run_time_error() :: any().
397
398%% Exceptions
399%%   error:{badarg,Reason::term()}
400%%   error:{notsup,Reason::term()}
401%%   error:{error,Reason::term()}
402-type descriptive_error() :: any() .
403
404
405%%--------------------------------------------------------------------
406%%
407%% Make the new descriptive_error() look like the old run_time_error()
408%%
409-define(COMPAT(CALL),
410        try begin CALL end
411        catch
412            error:{error, {_File,_Line}, _Reason} ->
413                error(badarg);
414            error:{E, {_File,_Line}, _Reason} when E==notsup ; E==badarg ->
415                error(E)
416        end).
417
418%%--------------------------------------------------------------------
419-compile(no_native).
420-on_load(on_load/0).
421-define(CRYPTO_NIF_VSN,302).
422
423-define(nif_stub,nif_stub_error(?LINE)).
424nif_stub_error(Line) ->
425    erlang:nif_error({nif_not_loaded,module,?MODULE,line,Line}).
426
427%%--------------------------------------------------------------------
428%%% API
429%%--------------------------------------------------------------------
430%% Crypto app version history:
431%% (no version): Driver implementation
432%% 2.0         : NIF implementation, requires OTP R14
433
434%% When generating documentation from crypto.erl, the macro ?CRYPTO_VSN is not defined.
435%% That causes the doc generation to stop...
436-ifndef(CRYPTO_VSN).
437-define(CRYPTO_VSN, "??").
438-endif.
439version() -> ?CRYPTO_VSN.
440
441-spec start() -> ok | {error, Reason::term()}.
442start() ->
443    application:start(crypto).
444
445-spec stop() -> ok | {error, Reason::term()}.
446stop() ->
447    application:stop(crypto).
448
449-spec supports() -> [Support]
450                        when Support :: {hashs,   Hashs}
451                                      | {ciphers, Ciphers}
452                                      | {public_keys, PKs}
453                                      | {macs,    Macs}
454                                      | {curves,  Curves}
455                                      | {rsa_opts, RSAopts},
456                             Hashs :: [sha1() | sha2() | sha3() | blake2() | ripemd160 | compatibility_only_hash()],
457                             Ciphers :: [cipher()],
458                             PKs :: [rsa | dss | ecdsa | dh | ecdh | eddh | ec_gf2m],
459                             Macs :: [hmac | cmac | poly1305],
460                             Curves :: [ec_named_curve() | edwards_curve_dh() | edwards_curve_ed()],
461                             RSAopts :: [rsa_sign_verify_opt() | rsa_opt()] .
462supports() ->
463     [{hashs,       supports(hashs)},
464      {ciphers,     supports(ciphers)}
465      | [{T,supports(T)} || T <- [public_keys,
466                                  macs,
467                                  curves,
468                                  rsa_opts]
469        ]
470     ].
471
472
473-spec supports(Type) -> Support
474                        when Type :: hashs
475			           | ciphers
476                                   | public_keys
477                                   | macs
478                                   | curves
479                                   | rsa_opts,
480			     Support :: Hashs
481                                      | Ciphers
482                                      | PKs
483                                      | Macs
484                                      | Curves
485                                      | RSAopts,
486                             Hashs :: [sha1() | sha2() | sha3() | blake2() | ripemd160 | compatibility_only_hash()],
487                             Ciphers :: [cipher()],
488                             PKs :: [rsa | dss | ecdsa | dh | ecdh | eddh | ec_gf2m],
489                             Macs :: [hmac | cmac | poly1305],
490                             Curves :: [ec_named_curve() | edwards_curve_dh() | edwards_curve_ed()],
491                             RSAopts :: [rsa_sign_verify_opt() | rsa_opt()] .
492
493-define(CURVES, '$curves$').
494
495supports(hashs)       -> hash_algorithms();
496supports(public_keys) -> pubkey_algorithms();
497supports(ciphers)     -> cipher_algorithms();
498supports(macs)        -> mac_algorithms();
499supports(curves)      -> curve_algorithms();
500supports(rsa_opts)    -> rsa_opts_algorithms().
501
502
503-spec info_lib() -> [{Name,VerNum,VerStr}] when Name :: binary(),
504                                                VerNum :: integer(),
505                                                VerStr :: binary() .
506info_lib() -> ?nif_stub.
507
508%% info/0 and info_nif/0 are experimental. May disapear or change without warning.
509info() -> info_nif().
510info_nif() -> ?nif_stub.
511
512
513-spec info_fips() -> not_supported | not_enabled | enabled.
514
515info_fips() -> ?nif_stub.
516
517-spec enable_fips_mode(Enable) -> Result when Enable :: boolean(),
518                                              Result :: boolean().
519enable_fips_mode(Enable) ->
520    enable_fips_mode_nif(Enable).
521
522enable_fips_mode_nif(_) -> ?nif_stub.
523
524%%%================================================================
525%%%
526%%% Hashing
527%%%
528%%%================================================================
529
530-type hash_algorithm() :: sha1() | sha2() | sha3() | blake2() | ripemd160 | compatibility_only_hash() .
531
532-spec hash_info(Type) -> Result | run_time_error()
533                             when Type :: hash_algorithm(),
534                                  Result :: #{size := integer(),
535                                              block_size := integer(),
536                                              type := integer()
537                                             } .
538hash_info(Type) ->
539    notsup_to_error(hash_info_nif(Type)).
540
541-spec hash(Type, Data) -> Digest when Type :: hash_algorithm(),
542                                      Data :: iodata(),
543                                      Digest :: binary().
544hash(Type, Data) ->
545    Data1 = iolist_to_binary(Data),
546    MaxBytes = max_bytes(),
547    hash(Type, Data1, erlang:byte_size(Data1), MaxBytes).
548
549-opaque hash_state() :: reference().
550
551-spec hash_init(Type) -> State when Type :: hash_algorithm(),
552                                    State :: hash_state().
553hash_init(Type) ->
554    notsup_to_error(hash_init_nif(Type)).
555
556-spec hash_update(State, Data) -> NewState when State :: hash_state(),
557                                                NewState :: hash_state(),
558                                                Data :: iodata() .
559hash_update(Context, Data) ->
560    Data1 = iolist_to_binary(Data),
561    MaxBytes = max_bytes(),
562    hash_update(Context, Data1, erlang:byte_size(Data1), MaxBytes).
563
564-spec hash_final(State) -> Digest when  State :: hash_state(),
565                                        Digest :: binary().
566hash_final(Context) ->
567    notsup_to_error(hash_final_nif(Context)).
568
569%%%================================================================
570%%%
571%%% MACs (Message Authentication Codes)
572%%%
573%%%================================================================
574
575-type hmac_hash_algorithm() ::  sha1() | sha2() | sha3() | compatibility_only_hash().
576
577-type cmac_cipher_algorithm() :: aes_128_cbc    | aes_192_cbc    | aes_256_cbc    | aes_cbc
578                               | aes_128_cfb128 | aes_192_cfb128 | aes_256_cfb128 | aes_cfb128
579                               | aes_128_cfb8   | aes_192_cfb8   | aes_256_cfb8   | aes_cfb8
580                               | blowfish_cbc
581                               | des_cbc | des_ede3_cbc
582                               | rc2_cbc
583                                 .
584
585%%%----------------------------------------------------------------
586%%% Calculate MAC for the whole text at once
587
588-spec mac(Type :: poly1305, Key, Data) -> Mac | descriptive_error()
589                     when Key :: iodata(),
590                          Data :: iodata(),
591                          Mac :: binary().
592
593mac(poly1305, Key, Data) -> mac(poly1305, undefined, Key, Data).
594
595
596-spec mac(Type, SubType, Key, Data) -> Mac | descriptive_error()
597                     when Type :: hmac | cmac | poly1305,
598                          SubType :: hmac_hash_algorithm() | cmac_cipher_algorithm() | undefined,
599                          Key :: iodata(),
600                          Data :: iodata(),
601                          Mac :: binary().
602
603mac(Type, SubType, Key0, Data) ->
604    Key = iolist_to_binary(Key0),
605    mac_nif(Type, alias(SubType,Key), Key, Data).
606
607
608
609-spec macN(Type :: poly1305, Key, Data, MacLength) -> Mac | descriptive_error()
610                     when Key :: iodata(),
611                          Data :: iodata(),
612                          Mac :: binary(),
613                          MacLength :: pos_integer().
614
615macN(Type, Key, Data, MacLength) ->
616    macN(Type, undefined, Key, Data, MacLength).
617
618
619-spec macN(Type, SubType, Key, Data, MacLength) -> Mac | descriptive_error()
620                     when Type :: hmac | cmac | poly1305,
621                          SubType :: hmac_hash_algorithm() | cmac_cipher_algorithm() | undefined,
622                          Key :: iodata(),
623                          Data :: iodata(),
624                          Mac :: binary(),
625                          MacLength :: pos_integer().
626
627macN(Type, SubType, Key, Data, MacLength) ->
628    erlang:binary_part(mac(Type,SubType,Key,Data), 0, MacLength).
629
630
631%%%----------------------------------------------------------------
632%%% Calculate the MAC by uppdating by pieces of the text
633
634-opaque mac_state() :: reference() .
635
636-spec mac_init(Type :: poly1305, Key) -> State | descriptive_error()
637                          when Key :: iodata(),
638                               State :: mac_state() .
639mac_init(poly1305, Key) ->
640    mac_init_nif(poly1305, undefined, Key).
641
642
643-spec mac_init(Type, SubType, Key) -> State | descriptive_error()
644                          when Type :: hmac | cmac | poly1305,
645                               SubType :: hmac_hash_algorithm() | cmac_cipher_algorithm() | undefined,
646                               Key :: iodata(),
647                               State :: mac_state() .
648mac_init(Type, SubType, Key0) ->
649    Key = iolist_to_binary(Key0),
650    mac_init_nif(Type, alias(SubType,Key), Key).
651
652
653-spec mac_update(State0, Data) -> State | descriptive_error()
654                     when Data :: iodata(),
655                          State0 :: mac_state(),
656                          State :: mac_state().
657mac_update(Ref, Data) ->
658    mac_update_nif(Ref, Data).
659
660
661
662-spec mac_final(State) -> Mac | descriptive_error()
663                              when State :: mac_state(),
664                                   Mac :: binary().
665mac_final(Ref) ->
666    mac_final_nif(Ref).
667
668
669-spec mac_finalN(State, MacLength) -> Mac | descriptive_error()
670                              when State :: mac_state(),
671                                   MacLength :: pos_integer(),
672                                   Mac :: binary().
673mac_finalN(Ref, MacLength) ->
674    erlang:binary_part(mac_final(Ref), 0, MacLength).
675
676
677%%%----------------------------------------------------------------
678%%% NIFs for the functions above
679
680mac_nif(_Type, _SubType, _Key, _Data) -> ?nif_stub.
681
682mac_init_nif(_Type, _SubType, _Key) -> ?nif_stub.
683mac_update_nif(_Ref, _Data) -> ?nif_stub.
684mac_final_nif(_Ref) -> ?nif_stub.
685
686%%%================================================================
687%%%
688%%% The "Old API", kept for compatibility
689%%%
690%%%================================================================
691
692%%%----------------------------------------------------------------
693%%% Ciphers
694
695
696%%%---- Cipher info
697-spec cipher_info(Type) -> Result | run_time_error()
698                               when Type :: cipher(),
699                                    Result :: #{key_length := integer(),
700                                                iv_length := integer(),
701                                                block_size := integer(),
702                                                mode := CipherModes,
703                                                type := undefined | integer(),
704                                                prop_aead := boolean()
705                                               },
706                                    CipherModes :: undefined
707                                                 | cbc_mode
708                                                 | ccm_mode
709                                                 | cfb_mode
710                                                 | ctr_mode
711                                                 | ecb_mode
712                                                 | gcm_mode
713                                                 | ige_mode
714                                                 | ocb_mode
715                                                 | ofb_mode
716                                                 | wrap_mode
717                                                 | xts_mode
718                                                   .
719
720cipher_info(Type) ->
721    try cipher_info_nif(Type)
722    catch
723        %% These ciphers are not available via the EVP interface on older cryptolibs.
724        error:notsup when Type == aes_128_ctr ->
725            #{block_size => 1,iv_length => 16,key_length => 16,mode => ctr_mode,type => undefined};
726
727        error:notsup when Type == aes_192_ctr ->
728            #{block_size => 1,iv_length => 16,key_length => 24,mode => ctr_mode,type => undefined};
729
730        error:notsup when Type == aes_256_ctr ->
731            #{block_size => 1,iv_length => 16,key_length => 32,mode => ctr_mode,type => undefined};
732
733        error:badarg ->
734            %% Maybe an alias: we don't know the key length..
735            case alias1(Type, 16) of
736                Type ->
737                    %% Not found, propagate
738                    error(badarg);
739                NewType ->
740                    cipher_info(NewType)
741            end
742    end.
743
744%%%================================================================
745%%%
746%%% Encrypt/decrypt, The "New API"
747%%%
748%%%================================================================
749
750-opaque crypto_state() :: reference() .
751
752-type crypto_opts() :: boolean()
753                     | [ crypto_opt() ] .
754-type crypto_opt() :: {encrypt,boolean()}
755                    | {padding, padding()} .
756-type padding() :: cryptolib_padding() | otp_padding().
757-type cryptolib_padding() :: none | pkcs_padding .
758-type otp_padding() :: zero | random .
759
760
761%%%----------------------------------------------------------------
762%%%
763%%% Create and initialize a new state for encryption or decryption
764%%%
765
766-spec crypto_init(Cipher, Key, FlagOrOptions) -> State | descriptive_error()
767                                                   when Cipher :: cipher_no_iv(),
768                                                        Key :: iodata(),
769                                                        FlagOrOptions :: crypto_opts() | boolean(),
770                                                        State :: crypto_state() .
771crypto_init(Cipher, Key, FlagOrOptions) ->
772    ng_crypto_init_nif(Cipher,
773                       iolist_to_binary(Key),
774                       <<>>,
775                       get_crypto_opts(FlagOrOptions)).
776
777
778-spec crypto_init(Cipher, Key, IV, FlagOrOptions) -> State | descriptive_error()
779                                                       when Cipher :: cipher_iv(),
780                                                            Key :: iodata(),
781                                                            IV :: iodata(),
782                                                            FlagOrOptions :: crypto_opts(),
783                                                            State :: crypto_state() .
784crypto_init(Cipher, Key, IV, FlagOrOptions) ->
785    ng_crypto_init_nif(Cipher,
786                       iolist_to_binary(Key),
787                       iolist_to_binary(IV),
788                       get_crypto_opts(FlagOrOptions)).
789
790%%%----------------------------------------------------------------
791get_crypto_opts(Options) when is_list(Options) ->
792    lists:foldl(fun chk_opt/2,
793                #{encrypt => true,
794                  padding => undefined
795                 },
796                Options);
797get_crypto_opts(Flag) when is_boolean(Flag) ->
798    #{encrypt => Flag,
799      padding => undefined
800     };
801get_crypto_opts(X) ->
802    error({badarg,{bad_option,X}}).
803
804
805chk_opt({Tag,Val}, A) ->
806    case ok_opt(Tag,Val) of
807        true ->
808            A#{Tag => Val};
809        false ->
810            error({badarg,{bad_option,{Tag,Val}}})
811    end;
812chk_opt(X, _) ->
813    error({badarg,{bad_option,X}}).
814
815
816ok_opt(encrypt, V) -> lists:member(V, [true, false, undefined]);
817ok_opt(padding, V) -> lists:member(V, [none, pkcs_padding, zero, random, undefined]);
818ok_opt(_, _) -> false.
819
820%%%----------------------------------------------------------------
821-spec crypto_dyn_iv_init(Cipher, Key, FlagOrOptions) -> State | descriptive_error()
822                                                          when Cipher :: cipher_iv(),
823                                                               Key :: iodata(),
824                                                               FlagOrOptions :: crypto_opts() | boolean(),
825                                                               State :: crypto_state() .
826crypto_dyn_iv_init(Cipher, Key, FlagOrOptions) ->
827    %% The IV is supposed to be supplied by calling crypto_update/3
828    ng_crypto_init_nif(Cipher,
829                       iolist_to_binary(Key),
830                       undefined,
831                       get_crypto_opts(FlagOrOptions)).
832
833%%%----------------------------------------------------------------
834%%%
835%%% Encrypt/decrypt a sequence of bytes.  The sum of the sizes
836%%% of all blocks must be an integer multiple of the crypto's
837%%% blocksize.
838%%%
839
840-spec crypto_update(State, Data) -> Result | descriptive_error()
841                            when State :: crypto_state(),
842                                 Data :: iodata(),
843                                 Result :: binary() .
844crypto_update(State, Data) ->
845    ng_crypto_update_nif(State, iolist_to_binary(Data)).
846
847%%%----------------------------------------------------------------
848-spec crypto_dyn_iv_update(State, Data, IV) -> Result | descriptive_error()
849                                                   when State :: crypto_state(),
850                                                        Data :: iodata(),
851                                                        IV :: iodata(),
852                                                        Result :: binary() .
853crypto_dyn_iv_update(State, Data, IV) ->
854    ng_crypto_update_nif(State, iolist_to_binary(Data), iolist_to_binary(IV)).
855
856%%%----------------------------------------------------------------
857%%%
858%%% Finalize encrypt/decrypt bytes.  If the size of the bytes in
859%%% to crypto_uptate was not an integer number of blocks, the rest
860%%% is returned from this function.
861
862-spec crypto_final(State) -> FinalResult | descriptive_error()
863                            when State :: crypto_state(),
864                                 FinalResult :: binary() .
865crypto_final(State) ->
866    ng_crypto_final_nif(State).
867
868%%%----------------------------------------------------------------
869%%%
870%%% Get result of padding etc
871
872-spec crypto_get_data(State) -> Result
873                            when State :: crypto_state(),
874                                 Result :: map() .
875crypto_get_data(State) ->
876    ng_crypto_get_data_nif(State).
877
878%%%----------------------------------------------------------------
879%%%
880%%% Encrypt/decrypt one set bytes.
881%%% The size must be an integer multiple of the crypto's blocksize.
882%%%
883
884-spec crypto_one_time(Cipher, Key, Data, FlagOrOptions) ->
885                             Result | descriptive_error()
886                                 when Cipher :: cipher_no_iv(),
887                                      Key :: iodata(),
888                                      Data :: iodata(),
889                                      FlagOrOptions :: crypto_opts() | boolean(),
890                                      Result :: binary() .
891
892crypto_one_time(Cipher, Key, Data, FlagOrOptions) ->
893    ng_crypto_one_time_nif(Cipher,
894                           iolist_to_binary(Key),
895                           <<>>,
896                           iolist_to_binary(Data),
897                           get_crypto_opts(FlagOrOptions)).
898
899
900-spec crypto_one_time(Cipher, Key, IV, Data, FlagOrOptions) ->
901                             Result | descriptive_error()
902                                 when Cipher :: cipher_iv(),
903                                      Key :: iodata(),
904                                      IV :: iodata(),
905                                      Data :: iodata(),
906                                      FlagOrOptions :: crypto_opts() | boolean(),
907                                      Result :: binary() .
908
909crypto_one_time(Cipher, Key, IV, Data, FlagOrOptions) ->
910    ng_crypto_one_time_nif(Cipher,
911                           iolist_to_binary(Key),
912                           iolist_to_binary(IV),
913                           iolist_to_binary(Data),
914                           get_crypto_opts(FlagOrOptions)).
915
916%%%----------------------------------------------------------------
917-spec crypto_one_time_aead(Cipher, Key, IV, InText, AAD, EncFlag::true) ->
918                             Result | descriptive_error()
919                                 when Cipher :: cipher_aead(),
920                                      Key :: iodata(),
921                                      IV :: iodata(),
922                                      InText :: iodata(),
923                                      AAD :: iodata(),
924                                      Result :: EncryptResult,
925                                      EncryptResult :: {OutCryptoText, OutTag},
926                                      OutCryptoText :: binary(),
927                                      OutTag :: binary().
928
929crypto_one_time_aead(Cipher, Key, IV, PlainText, AAD, true) ->
930    crypto_one_time_aead(Cipher, Key, IV, PlainText, AAD, aead_tag_len(Cipher), true).
931
932
933-spec crypto_one_time_aead(Cipher, Key, IV, InText, AAD, TagOrTagLength, EncFlag) ->
934                             Result | descriptive_error()
935                                 when Cipher :: cipher_aead(),
936                                      Key :: iodata(),
937                                      IV :: iodata(),
938                                      InText :: iodata(),
939                                      AAD :: iodata(),
940                                      TagOrTagLength :: EncryptTagLength | DecryptTag,
941                                      EncryptTagLength :: non_neg_integer(), % or pos_integer() 1..
942                                      DecryptTag :: iodata(),
943                                      EncFlag :: boolean(),
944                                      Result :: EncryptResult | DecryptResult,
945                                      EncryptResult :: {OutCryptoText, OutTag},
946                                      DecryptResult :: OutPlainText | error,
947                                      OutCryptoText :: binary(),
948                                      OutTag :: binary(),
949                                      OutPlainText :: binary().
950
951crypto_one_time_aead(Cipher, Key, IV, TextIn, AAD, TagOrTagLength, EncFlg) ->
952    aead_cipher(Cipher, iolist_to_binary(Key), IV,
953                TextIn, AAD, TagOrTagLength, EncFlg).
954
955
956aead_tag_len(aes_ccm    ) -> 12;
957aead_tag_len(aes_128_ccm) -> 12;
958aead_tag_len(aes_192_ccm) -> 12;
959aead_tag_len(aes_256_ccm) -> 12;
960aead_tag_len(aes_gcm    ) -> 16;
961aead_tag_len(aes_128_gcm) -> 16;
962aead_tag_len(aes_192_gcm) -> 16;
963aead_tag_len(aes_256_gcm) -> 16;
964aead_tag_len(chacha20_poly1305) -> 16;
965aead_tag_len(_) ->
966    error({badarg, "Not an AEAD cipher"}).
967
968%%%----------------------------------------------------------------
969%%% Cipher NIFs
970
971ng_crypto_init_nif(Cipher, Key, IVec, #{encrypt := EncryptFlag,
972                                        padding := Padding}) ->
973    ng_crypto_init_nif(alias(Cipher,Key), Key, IVec, EncryptFlag, Padding).
974
975ng_crypto_init_nif(_Cipher, _Key, _IVec, _EncryptFlag, _Padding) -> ?nif_stub.
976
977
978ng_crypto_update_nif(_State, _Data) -> ?nif_stub.
979ng_crypto_update_nif(_State, _Data, _IV) -> ?nif_stub.
980
981ng_crypto_final_nif(_State) -> ?nif_stub.
982
983ng_crypto_get_data_nif(_State) -> ?nif_stub.
984
985ng_crypto_one_time_nif(Cipher, Key, IVec, Data,  #{encrypt := EncryptFlag,
986                                                   padding := Padding}) ->
987    ng_crypto_one_time_nif(alias(Cipher,Key), Key, IVec, Data, EncryptFlag, Padding).
988
989ng_crypto_one_time_nif(_Cipher, _Key, _IVec, _Data, _EncryptFlag, _Padding) -> ?nif_stub.
990
991%% The default tag length is EVP_GCM_TLS_TAG_LEN(16),
992aead_cipher(Cipher, Key, IVec, AAD, In, TagOrLength, EncFlg) ->
993    aead_cipher_nif(alias(Cipher,Key), Key, IVec, AAD, In, TagOrLength, EncFlg).
994
995aead_cipher_nif(_Type, _Key, _Ivec, _AAD, _In, _TagOrTagLength, _EncFlg) -> ?nif_stub.
996
997cipher_info_nif(_Type) -> ?nif_stub.
998
999%%%----------------------------------------------------------------
1000%%% Cipher aliases
1001%%%
1002
1003alias(aes_cbc, Key)    -> alias1(aes_cbc, size(Key));
1004alias(aes_cfb8, Key)   -> alias1(aes_cfb8, size(Key));
1005alias(aes_cfb128, Key) -> alias1(aes_cfb128, size(Key));
1006alias(aes_ctr, Key)    -> alias1(aes_ctr, size(Key));
1007alias(aes_ecb, Key)    -> alias1(aes_ecb, size(Key));
1008alias(aes_gcm, Key)    -> alias1(aes_gcm, size(Key));
1009alias(aes_ccm, Key)    -> alias1(aes_ccm, size(Key));
1010alias(Alg, _) -> Alg.
1011
1012
1013alias1(aes_cbc, 16)  -> aes_128_cbc;
1014alias1(aes_cbc, 24)  -> aes_192_cbc;
1015alias1(aes_cbc, 32)  -> aes_256_cbc;
1016
1017alias1(aes_cfb8, 16)  -> aes_128_cfb8;
1018alias1(aes_cfb8, 24)  -> aes_192_cfb8;
1019alias1(aes_cfb8, 32)  -> aes_256_cfb8;
1020
1021alias1(aes_cfb128, 16)  -> aes_128_cfb128;
1022alias1(aes_cfb128, 24)  -> aes_192_cfb128;
1023alias1(aes_cfb128, 32)  -> aes_256_cfb128;
1024
1025alias1(aes_ctr, 16)  -> aes_128_ctr;
1026alias1(aes_ctr, 24)  -> aes_192_ctr;
1027alias1(aes_ctr, 32)  -> aes_256_ctr;
1028
1029alias1(aes_ecb, 16)  -> aes_128_ecb;
1030alias1(aes_ecb, 24)  -> aes_192_ecb;
1031alias1(aes_ecb, 32)  -> aes_256_ecb;
1032
1033alias1(aes_gcm, 16)  -> aes_128_gcm;
1034alias1(aes_gcm, 24)  -> aes_192_gcm;
1035alias1(aes_gcm, 32)  -> aes_256_gcm;
1036
1037alias1(aes_ccm, 16)  -> aes_128_ccm;
1038alias1(aes_ccm, 24)  -> aes_192_ccm;
1039alias1(aes_ccm, 32)  -> aes_256_ccm;
1040
1041alias1(Alg, _) -> Alg.
1042
1043%%%================================================================
1044%%%
1045%%% RAND - pseudo random numbers using RN_ and BN_ functions in crypto lib
1046%%%
1047%%%================================================================
1048-type rand_cache_seed() ::
1049        nonempty_improper_list(non_neg_integer(), binary()).
1050
1051-spec strong_rand_bytes(N::non_neg_integer()) -> binary().
1052strong_rand_bytes(Bytes) ->
1053    case strong_rand_bytes_nif(Bytes) of
1054        false -> erlang:error(low_entropy);
1055        Bin -> Bin
1056    end.
1057strong_rand_bytes_nif(_Bytes) -> ?nif_stub.
1058
1059
1060-spec rand_seed() -> rand:state().
1061rand_seed() ->
1062    rand:seed(rand_seed_s()).
1063
1064-spec rand_seed_s() -> rand:state().
1065rand_seed_s() ->
1066    rand_seed_alg_s(?MODULE).
1067
1068-spec rand_seed_alg(Alg :: atom()) ->
1069                           {rand:alg_handler(),
1070                            atom() | rand_cache_seed()}.
1071rand_seed_alg(Alg) ->
1072    rand:seed(rand_seed_alg_s(Alg)).
1073
1074-spec rand_seed_alg(Alg :: atom(), Seed :: term()) ->
1075                           {rand:alg_handler(),
1076                            atom() | rand_cache_seed()}.
1077rand_seed_alg(Alg, Seed) ->
1078    rand:seed(rand_seed_alg_s(Alg, Seed)).
1079
1080-define(CRYPTO_CACHE_BITS, 56).
1081-define(CRYPTO_AES_BITS, 58).
1082
1083-spec rand_seed_alg_s(Alg :: atom()) ->
1084                             {rand:alg_handler(),
1085                              atom() | rand_cache_seed()}.
1086rand_seed_alg_s({AlgHandler, _AlgState} = State) when is_map(AlgHandler) ->
1087    State;
1088rand_seed_alg_s({Alg, AlgState}) when is_atom(Alg) ->
1089    {mk_alg_handler(Alg),AlgState};
1090 rand_seed_alg_s(Alg) when is_atom(Alg) ->
1091    {mk_alg_handler(Alg),mk_alg_state(Alg)}.
1092%%
1093-spec rand_seed_alg_s(Alg :: atom(), Seed :: term()) ->
1094                             {rand:alg_handler(),
1095                              atom() | rand_cache_seed()}.
1096rand_seed_alg_s(Alg, Seed) when is_atom(Alg) ->
1097    {mk_alg_handler(Alg),mk_alg_state({Alg,Seed})}.
1098
1099mk_alg_handler(?MODULE = Alg) ->
1100    #{ type => Alg,
1101       bits => 64,
1102       next => fun ?MODULE:rand_plugin_next/1,
1103       uniform => fun ?MODULE:rand_plugin_uniform/1,
1104       uniform_n => fun ?MODULE:rand_plugin_uniform/2};
1105mk_alg_handler(crypto_cache = Alg) ->
1106    #{ type => Alg,
1107       bits => ?CRYPTO_CACHE_BITS,
1108       next => fun ?MODULE:rand_cache_plugin_next/1};
1109mk_alg_handler(crypto_aes = Alg) ->
1110    #{ type => Alg,
1111       bits => ?CRYPTO_AES_BITS,
1112       next => fun ?MODULE:rand_plugin_aes_next/1,
1113       jump => fun ?MODULE:rand_plugin_aes_jump/1}.
1114
1115mk_alg_state(?MODULE) ->
1116    no_seed;
1117mk_alg_state(crypto_cache) ->
1118    CacheBits = ?CRYPTO_CACHE_BITS,
1119    BytesPerWord = (CacheBits + 7) div 8,
1120    GenBytes =
1121        ((rand_cache_size() + (2*BytesPerWord - 1)) div BytesPerWord)
1122        * BytesPerWord,
1123    {CacheBits, GenBytes, <<>>};
1124mk_alg_state({crypto_aes,Seed}) ->
1125    %% 16 byte words (128 bit crypto blocks)
1126    GenWords = (rand_cache_size() + 31) div 16,
1127    Key = crypto:hash(sha256, Seed),
1128    {F,Count} = longcount_seed(Seed),
1129    {Key,GenWords,F,Count}.
1130
1131rand_cache_size() ->
1132    DefaultCacheSize = 1024,
1133    CacheSize =
1134        application:get_env(crypto, rand_cache_size, DefaultCacheSize),
1135    if
1136        is_integer(CacheSize), 0 =< CacheSize ->
1137            CacheSize;
1138        true ->
1139            DefaultCacheSize
1140    end.
1141
1142rand_plugin_next(Seed) ->
1143    {bytes_to_integer(strong_rand_range(1 bsl 64)), Seed}.
1144
1145rand_plugin_uniform(State) ->
1146    {strong_rand_float(), State}.
1147
1148rand_plugin_uniform(Max, State) ->
1149    {bytes_to_integer(strong_rand_range(Max)) + 1, State}.
1150
1151
1152rand_cache_plugin_next({CacheBits, GenBytes, <<>>}) ->
1153    rand_cache_plugin_next(
1154      {CacheBits, GenBytes, strong_rand_bytes(GenBytes)});
1155rand_cache_plugin_next({CacheBits, GenBytes, Cache}) ->
1156    <<I:CacheBits, NewCache/binary>> = Cache,
1157    {I, {CacheBits, GenBytes, NewCache}}.
1158
1159
1160%% Encrypt 128 bit counter values and use the 58 lowest
1161%% encrypted bits as random numbers.
1162%%
1163%% The 128 bit counter is handled as 4 32 bit words
1164%% to avoid bignums.  Generate a bunch of numbers
1165%% at the time and cache them.
1166%%
1167-dialyzer({no_improper_lists, rand_plugin_aes_next/1}).
1168rand_plugin_aes_next([V|Cache]) ->
1169    {V,Cache};
1170rand_plugin_aes_next({Key,GenWords,F,Count}) ->
1171    rand_plugin_aes_next(Key, GenWords, F, Count);
1172rand_plugin_aes_next({Key,GenWords,F,_JumpBase,Count}) ->
1173    rand_plugin_aes_next(Key, GenWords, F, Count).
1174%%
1175rand_plugin_aes_next(Key, GenWords, F, Count) ->
1176    {Cleartext,NewCount} = aes_cleartext(<<>>, F, Count, GenWords),
1177    Encrypted = block_encrypt(Key, Cleartext),
1178    [V|Cache] = aes_cache(Encrypted, {Key,GenWords,F,Count,NewCount}),
1179    {V,Cache}.
1180
1181block_encrypt(Key, Data) ->
1182    Cipher = case size(Key) of
1183                 16 -> aes_128_ecb;
1184                 24 -> aes_192_ecb;
1185                 32 -> aes_256_ecb;
1186                 _ -> error(badarg)
1187             end,
1188    try
1189        crypto_one_time(Cipher, Key, Data, true)
1190    catch
1191        error:{error, {_File,_Line}, _Reason} ->
1192            error(badarg);
1193        error:{E, {_File,_Line}, _Reason} when E==notsup ; E==badarg ->
1194            error(E)
1195    end.
1196
1197
1198%% A jump advances the counter 2^512 steps; the jump function
1199%% is applied to the jump base and then the number of used
1200%% numbers from the cache has to be wasted for the jump to be correct
1201%%
1202rand_plugin_aes_jump({#{type := crypto_aes} = Alg, Cache}) ->
1203    {Alg,rand_plugin_aes_jump(fun longcount_jump/1, 0, Cache)}.
1204%% Count cached words and subtract their number from jump
1205-dialyzer({no_improper_lists, rand_plugin_aes_jump/3}).
1206rand_plugin_aes_jump(Jump, J, [_|Cache]) ->
1207    rand_plugin_aes_jump(Jump, J + 1, Cache);
1208rand_plugin_aes_jump(Jump, J, {Key,GenWords,F,JumpBase, _Count}) ->
1209    rand_plugin_aes_jump(Jump, GenWords - J, Key, GenWords, F, JumpBase);
1210rand_plugin_aes_jump(Jump, 0, {Key,GenWords,F,JumpBase}) ->
1211    rand_plugin_aes_jump(Jump, 0, Key, GenWords, F, JumpBase).
1212%%
1213rand_plugin_aes_jump(Jump, Skip, Key, GenWords, F, JumpBase) ->
1214    Count = longcount_next_count(Skip, Jump(JumpBase)),
1215    {Key,GenWords,F,Count}.
1216
1217rand_plugin_aes_jump_2pow20(Cache) ->
1218    rand_plugin_aes_jump(fun longcount_jump_2pow20/1, 0, Cache).
1219
1220
1221longcount_seed(Seed) ->
1222    <<X:64, _:6, F:12, S2:58, S1:58, S0:58>> =
1223        crypto:hash(sha256, [Seed,<<"Xoroshiro928">>]),
1224    {F,rand:exro928_seed([S0,S1,S2|rand:seed58(13, X)])}.
1225
1226longcount_next_count(0, Count) ->
1227    Count;
1228longcount_next_count(N, Count) ->
1229    longcount_next_count(N - 1, rand:exro928_next_state(Count)).
1230
1231longcount_next(Count) ->
1232    rand:exro928_next(Count).
1233
1234longcount_jump(Count) ->
1235    rand:exro928_jump_2pow512(Count).
1236
1237longcount_jump_2pow20(Count) ->
1238    rand:exro928_jump_2pow20(Count).
1239
1240
1241%% Build binary with counter values to cache
1242aes_cleartext(Cleartext, _F, Count, 0) ->
1243    {Cleartext,Count};
1244aes_cleartext(Cleartext, F, Count, GenWords) ->
1245    {{S0,S1}, NewCount} = longcount_next(Count),
1246    aes_cleartext(
1247      <<Cleartext/binary, F:12, S1:58, S0:58>>,
1248      F, NewCount, GenWords - 1).
1249
1250%% Parse and cache encrypted counter values aka random numbers
1251-dialyzer({no_improper_lists, aes_cache/2}).
1252aes_cache(<<>>, Cache) ->
1253    Cache;
1254aes_cache(
1255  <<_:(128 - ?CRYPTO_AES_BITS), V:?CRYPTO_AES_BITS, Encrypted/binary>>,
1256  Cache) ->
1257    [V|aes_cache(Encrypted, Cache)].
1258
1259
1260strong_rand_range(Range) when is_integer(Range), Range > 0 ->
1261    BinRange = int_to_bin(Range),
1262    strong_rand_range(BinRange);
1263strong_rand_range(BinRange) when is_binary(BinRange) ->
1264    case strong_rand_range_nif(BinRange) of
1265        false ->
1266            erlang:error(low_entropy);
1267        <<BinResult/binary>> ->
1268            BinResult
1269    end.
1270strong_rand_range_nif(_BinRange) -> ?nif_stub.
1271
1272strong_rand_float() ->
1273    WholeRange = strong_rand_range(1 bsl 53),
1274    ?HALF_DBL_EPSILON * bytes_to_integer(WholeRange).
1275
1276-spec rand_uniform(crypto_integer(), crypto_integer()) ->
1277			  crypto_integer().
1278rand_uniform(From, To) when is_binary(From), is_binary(To) ->
1279    case rand_uniform_nif(From,To) of
1280	<<Len:32/integer, MSB, Rest/binary>> when MSB > 127 ->
1281	    <<(Len + 1):32/integer, 0, MSB, Rest/binary>>;
1282	Whatever ->
1283	    Whatever
1284    end;
1285rand_uniform(From,To) when is_integer(From),is_integer(To) ->
1286    if From < 0 ->
1287	    rand_uniform_pos(0, To - From) + From;
1288       true ->
1289	    rand_uniform_pos(From, To)
1290    end.
1291
1292rand_uniform_pos(From,To) when From < To ->
1293    BinFrom = mpint(From),
1294    BinTo = mpint(To),
1295    case rand_uniform(BinFrom, BinTo) of
1296        Result when is_binary(Result) ->
1297            erlint(Result);
1298        Other ->
1299            Other
1300    end;
1301rand_uniform_pos(_,_) ->
1302    error(badarg).
1303
1304rand_uniform_nif(_From,_To) -> ?nif_stub.
1305
1306
1307-spec rand_seed(binary()) -> ok.
1308rand_seed(Seed) when is_binary(Seed) ->
1309    rand_seed_nif(Seed).
1310
1311rand_seed_nif(_Seed) -> ?nif_stub.
1312
1313%%%================================================================
1314%%%
1315%%% Sign/verify
1316%%%
1317%%%================================================================
1318-type pk_sign_verify_algs() :: rsa | dss | ecdsa | eddsa .
1319
1320-type pk_sign_verify_opts() :: [ rsa_sign_verify_opt() ] .
1321
1322-type rsa_sign_verify_opt() :: {rsa_padding, rsa_sign_verify_padding()}
1323                             | {rsa_pss_saltlen, integer()}
1324                             | {rsa_mgf1_md, sha2()}.
1325
1326-type rsa_sign_verify_padding() :: rsa_pkcs1_padding | rsa_pkcs1_pss_padding
1327                                 | rsa_x931_padding | rsa_no_padding
1328                                   .
1329
1330
1331%%%----------------------------------------------------------------
1332%%% Sign
1333
1334-spec sign(Algorithm, DigestType, Msg, Key)
1335          -> Signature
1336                 when Algorithm :: pk_sign_verify_algs(),
1337                      DigestType :: rsa_digest_type()
1338                                  | dss_digest_type()
1339                                  | ecdsa_digest_type()
1340                                  | none,
1341                      Msg :: iodata() | {digest,iodata()},
1342                      Key :: rsa_private()
1343                           | dss_private()
1344                           | [ecdsa_private() | ecdsa_params()]
1345                           | [eddsa_private() | eddsa_params()]
1346                           | engine_key_ref(),
1347                      Signature :: binary() .
1348
1349sign(Algorithm, Type, Data, Key) ->
1350    sign(Algorithm, Type, Data, Key, []).
1351
1352
1353-spec sign(Algorithm, DigestType, Msg, Key, Options)
1354          -> Signature
1355                 when Algorithm :: pk_sign_verify_algs(),
1356                      DigestType :: rsa_digest_type()
1357                                  | dss_digest_type()
1358                                  | ecdsa_digest_type()
1359                                  | none,
1360                      Msg :: iodata() | {digest,iodata()},
1361                      Key :: rsa_private()
1362                           | dss_private()
1363                           | [ecdsa_private() | ecdsa_params()]
1364                           | [eddsa_private() | eddsa_params()]
1365                           | engine_key_ref(),
1366                      Options :: pk_sign_verify_opts(),
1367                      Signature :: binary() .
1368
1369sign(Algorithm0, Type0, Data, Key, Options) ->
1370    {Algorithm, Type} = sign_verify_compatibility(Algorithm0, Type0, Data),
1371    case pkey_sign_nif(Algorithm, Type, Data, format_pkey(Algorithm, Key), Options) of
1372	error -> erlang:error(badkey, [Algorithm, Type, Data, Key, Options]);
1373	notsup -> erlang:error(notsup);
1374	Signature -> Signature
1375    end.
1376
1377pkey_sign_nif(_Algorithm, _Type, _Digest, _Key, _Options) -> ?nif_stub.
1378
1379%%%----------------------------------------------------------------
1380%%% Verify
1381
1382-spec verify(Algorithm, DigestType, Msg, Signature, Key)
1383            -> Result
1384                   when Algorithm :: pk_sign_verify_algs(),
1385                        DigestType :: rsa_digest_type()
1386                                    | dss_digest_type()
1387                                    | ecdsa_digest_type()
1388                                    | none,
1389                        Msg :: iodata() | {digest,iodata()},
1390                        Signature :: binary(),
1391                        Key :: rsa_public()
1392                             | dss_public()
1393                             | [ecdsa_public() | ecdsa_params()]
1394                             | [eddsa_public() | eddsa_params()]
1395                             | engine_key_ref(),
1396                        Result :: boolean().
1397
1398verify(Algorithm, Type, Data, Signature, Key) ->
1399    verify(Algorithm, Type, Data, Signature, Key, []).
1400
1401-spec verify(Algorithm, DigestType, Msg, Signature, Key, Options)
1402            -> Result
1403                   when Algorithm :: pk_sign_verify_algs(),
1404                        DigestType :: rsa_digest_type()
1405                                    | dss_digest_type()
1406                                    | ecdsa_digest_type()
1407                                    | none,
1408                        Msg :: iodata() | {digest,iodata()},
1409                        Signature :: binary(),
1410                        Key :: rsa_public()
1411                             | dss_public()
1412                             | [ecdsa_public() | ecdsa_params()]
1413                             | [eddsa_public() | eddsa_params()]
1414                             | engine_key_ref(),
1415                        Options :: pk_sign_verify_opts(),
1416                        Result :: boolean().
1417
1418verify(Algorithm0, Type0, Data, Signature, Key, Options) ->
1419    {Algorithm, Type} = sign_verify_compatibility(Algorithm0, Type0, Data),
1420    case pkey_verify_nif(Algorithm, Type, Data, Signature, format_pkey(Algorithm, Key), Options) of
1421	notsup -> erlang:error(notsup);
1422	Boolean -> Boolean
1423    end.
1424
1425pkey_verify_nif(_Algorithm, _Type, _Data, _Signature, _Key, _Options) -> ?nif_stub.
1426
1427%% Backwards compatible:
1428sign_verify_compatibility(dss, none, Digest) ->
1429    {sha, {digest, Digest}};
1430sign_verify_compatibility(Algorithm0, Type0, _Digest) ->
1431    {Algorithm0, Type0}.
1432
1433%%%================================================================
1434%%%
1435%%% Public/private encrypt/decrypt
1436%%%
1437%%% Only rsa works so far (although ecdsa | dss should do it)
1438%%%================================================================
1439-type pk_encrypt_decrypt_algs() :: rsa .
1440
1441-type pk_encrypt_decrypt_opts() ::  [rsa_opt()] | rsa_compat_opts().
1442
1443-type rsa_compat_opts() :: [{rsa_pad, rsa_padding()}]
1444                         | rsa_padding() .
1445
1446-type rsa_padding() :: rsa_pkcs1_padding
1447                     | rsa_pkcs1_oaep_padding
1448                     | rsa_sslv23_padding
1449                     | rsa_x931_padding
1450                     | rsa_no_padding.
1451
1452-type rsa_opt() :: {rsa_padding, rsa_padding()}
1453                 | {signature_md, atom()}
1454                 | {rsa_mgf1_md, sha}
1455                 | {rsa_oaep_label, binary()}
1456                 | {rsa_oaep_md, sha} .
1457
1458%%%---- Encrypt with public key
1459
1460-spec public_encrypt(Algorithm, PlainText, PublicKey, Options) ->
1461                            CipherText when Algorithm :: pk_encrypt_decrypt_algs(),
1462                                            PlainText :: binary(),
1463                                            PublicKey :: rsa_public() | engine_key_ref(),
1464                                            Options :: pk_encrypt_decrypt_opts(),
1465                                            CipherText :: binary().
1466public_encrypt(Algorithm, PlainText, PublicKey, Options) ->
1467    pkey_crypt(Algorithm, PlainText, PublicKey, Options, false, true).
1468
1469%%%---- Decrypt with private key
1470
1471-spec private_decrypt(Algorithm, CipherText, PrivateKey, Options) ->
1472                             PlainText when Algorithm :: pk_encrypt_decrypt_algs(),
1473                                            CipherText :: binary(),
1474                                            PrivateKey :: rsa_private() | engine_key_ref(),
1475                                            Options :: pk_encrypt_decrypt_opts(),
1476                                            PlainText :: binary() .
1477private_decrypt(Algorithm, CipherText, PrivateKey, Options) ->
1478    pkey_crypt(Algorithm, CipherText,  PrivateKey, Options, true, false).
1479
1480%%%---- Encrypt with private key
1481
1482-spec private_encrypt(Algorithm, PlainText, PrivateKey, Options) ->
1483                            CipherText when Algorithm :: pk_encrypt_decrypt_algs(),
1484                                            PlainText :: binary(),
1485                                            PrivateKey :: rsa_private() | engine_key_ref(),
1486                                            Options :: pk_encrypt_decrypt_opts(),
1487                                            CipherText :: binary().
1488private_encrypt(Algorithm, PlainText, PrivateKey, Options) ->
1489    pkey_crypt(Algorithm, PlainText,  PrivateKey, Options, true, true).
1490
1491%%%---- Decrypt with public key
1492
1493-spec public_decrypt(Algorithm, CipherText, PublicKey, Options) ->
1494                             PlainText when Algorithm :: pk_encrypt_decrypt_algs(),
1495                                            CipherText :: binary(),
1496                                            PublicKey :: rsa_public() | engine_key_ref(),
1497                                            Options :: pk_encrypt_decrypt_opts(),
1498                                            PlainText :: binary() .
1499public_decrypt(Algorithm, CipherText, PublicKey, Options) ->
1500    pkey_crypt(Algorithm, CipherText, PublicKey, Options, false, false).
1501
1502%%%---- Call the nif, but fix a compatibility issue first
1503
1504%% Backwards compatible (rsa_pad -> rsa_padding is handled by the pkey_crypt_nif):
1505pkey_crypt(rsa, Text, Key, Padding, PubPriv, EncDec) when is_atom(Padding) ->
1506    pkey_crypt(rsa, Text, Key, [{rsa_padding, Padding}], PubPriv, EncDec);
1507
1508pkey_crypt(Alg, Text, Key, Options, PubPriv, EncDec) ->
1509    case pkey_crypt_nif(Alg, Text, format_pkey(Alg,Key), Options, PubPriv, EncDec) of
1510	error when EncDec==true  -> erlang:error(encrypt_failed, [Alg, Text, Key, Options]);
1511	error when EncDec==false -> erlang:error(decrypt_failed, [Alg, Text, Key, Options]);
1512	notsup -> erlang:error(notsup);
1513	Out -> Out
1514    end.
1515
1516pkey_crypt_nif(_Algorithm, _In, _Key, _Options, _IsPrivate, _IsEncrypt) -> ?nif_stub.
1517
1518%%%================================================================
1519%%%
1520%%%
1521%%%
1522%%%================================================================
1523
1524-spec generate_key(Type, Params)
1525                 -> {PublicKey, PrivKeyOut}
1526                        when Type :: dh | ecdh | eddh | eddsa | rsa | srp,
1527                             PublicKey :: dh_public() | ecdh_public() | rsa_public() | srp_public(),
1528                             PrivKeyOut :: dh_private() | ecdh_private() | rsa_private() | {srp_public(),srp_private()},
1529                             Params :: dh_params() | ecdh_params() | eddsa_params() | rsa_params() | srp_gen_params()
1530                                       .
1531generate_key(Type, Params) ->
1532    generate_key(Type, Params, undefined).
1533
1534-spec generate_key(Type, Params, PrivKeyIn)
1535                 -> {PublicKey, PrivKeyOut}
1536                        when Type :: dh | ecdh | eddh | eddsa | rsa | srp,
1537                             PublicKey :: dh_public() | ecdh_public() | rsa_public() | srp_public(),
1538                             PrivKeyIn :: undefined | dh_private() | ecdh_private() | rsa_private() | {srp_public(),srp_private()},
1539                             PrivKeyOut :: dh_private() | ecdh_private() | rsa_private() | {srp_public(),srp_private()},
1540                             Params :: dh_params() | ecdh_params() | eddsa_params() | rsa_params() | srp_comp_params()
1541                                       .
1542
1543generate_key(dh, DHParameters0, PrivateKey) ->
1544    {DHParameters, Len} =
1545        case DHParameters0 of
1546            [P,G,L] -> {[P,G], L};
1547            [P,G] -> {[P,G], 0}
1548        end,
1549    dh_generate_key_nif(ensure_int_as_bin(PrivateKey),
1550			map_ensure_int_as_bin(DHParameters),
1551                        0, Len);
1552
1553generate_key(srp, {host, [Verifier, Generator, Prime, Version]}, PrivArg)
1554  when is_binary(Verifier), is_binary(Generator), is_binary(Prime), is_atom(Version) ->
1555    Private = case PrivArg of
1556		  undefined -> strong_rand_bytes(32);
1557		  _ -> ensure_int_as_bin(PrivArg)
1558	      end,
1559    host_srp_gen_key(Private, Verifier, Generator, Prime, Version);
1560
1561generate_key(srp, {user, [Generator, Prime, Version]}, PrivateArg)
1562  when is_binary(Generator), is_binary(Prime), is_atom(Version) ->
1563    Private = case PrivateArg of
1564		  undefined -> strong_rand_bytes(32);
1565		  _ -> PrivateArg
1566	      end,
1567    user_srp_gen_key(Private, Generator, Prime);
1568
1569generate_key(rsa, {ModulusSize, PublicExponent}, undefined) ->
1570    case rsa_generate_key_nif(ModulusSize, ensure_int_as_bin(PublicExponent)) of
1571        error ->
1572            erlang:error(computation_failed,
1573                         [rsa,{ModulusSize,PublicExponent}]);
1574        Private ->
1575            {lists:sublist(Private, 2), Private}
1576    end;
1577
1578generate_key(eddh, Curve, PrivKey) when Curve == x448 ;
1579                                        Curve == x25519 ->
1580    evp_generate_key_nif(Curve, ensure_int_as_bin(PrivKey));
1581generate_key(ecdh, Curve, PrivKey) when Curve == x448 ;
1582                                        Curve == x25519 ->
1583    %% This was here before the eddh was added as an own Type
1584    evp_generate_key_nif(Curve, ensure_int_as_bin(PrivKey));
1585generate_key(ecdh, Curve, PrivKey) ->
1586    ec_key_generate(nif_curve_params(Curve), ensure_int_as_bin(PrivKey));
1587
1588generate_key(eddsa, Curve, PrivKey) when Curve == ed448 ;
1589                                         Curve == ed25519 ->
1590    evp_generate_key_nif(Curve, ensure_int_as_bin(PrivKey)).
1591
1592evp_generate_key_nif(_Curve, _PrivKey) -> ?nif_stub.
1593
1594
1595-spec compute_key(Type, OthersPublicKey, MyPrivateKey, Params)
1596                 -> SharedSecret
1597                        when Type :: dh | ecdh | eddh |  srp,
1598                             SharedSecret :: binary(),
1599                             OthersPublicKey :: dh_public() | ecdh_public() | srp_public(),
1600                             MyPrivateKey :: dh_private() | ecdh_private() | {srp_public(),srp_private()},
1601                             Params :: dh_params() | ecdh_params() | srp_comp_params()
1602                                       .
1603
1604compute_key(dh, OthersPublicKey, MyPrivateKey, DHParameters) ->
1605    case dh_compute_key_nif(ensure_int_as_bin(OthersPublicKey),
1606			    ensure_int_as_bin(MyPrivateKey),
1607			    map_ensure_int_as_bin(DHParameters)) of
1608	error -> erlang:error(computation_failed,
1609			      [dh,OthersPublicKey,MyPrivateKey,DHParameters]);
1610	Ret -> Ret
1611    end;
1612
1613compute_key(srp, HostPublic, {UserPublic, UserPrivate},
1614	    {user, [DerivedKey, Prime, Generator, Version | ScramblerArg]}) when
1615      is_binary(Prime),
1616      is_binary(Generator),
1617      is_atom(Version) ->
1618    HostPubBin = ensure_int_as_bin(HostPublic),
1619    Multiplier = srp_multiplier(Version, Generator, Prime),
1620    Scrambler = case ScramblerArg of
1621		    [] -> srp_scrambler(Version, ensure_int_as_bin(UserPublic),
1622					HostPubBin, Prime);
1623		    [S] -> S
1624		end,
1625    notsup_to_error(
1626    srp_user_secret_nif(ensure_int_as_bin(UserPrivate), Scrambler, HostPubBin,
1627                          Multiplier, Generator, DerivedKey, Prime));
1628
1629compute_key(srp, UserPublic, {HostPublic, HostPrivate},
1630	    {host,[Verifier, Prime, Version | ScramblerArg]}) when
1631      is_binary(Verifier),
1632      is_binary(Prime),
1633      is_atom(Version) ->
1634    UserPubBin = ensure_int_as_bin(UserPublic),
1635    Scrambler = case ScramblerArg of
1636		    [] -> srp_scrambler(Version, UserPubBin, ensure_int_as_bin(HostPublic), Prime);
1637		    [S] -> S
1638		end,
1639    notsup_to_error(
1640    srp_host_secret_nif(Verifier, ensure_int_as_bin(HostPrivate), Scrambler,
1641                          UserPubBin, Prime));
1642
1643compute_key(ecdh, Others, My, Curve) when Curve == x448 ;
1644                                          Curve == x25519 ->
1645    evp_compute_key_nif(Curve, ensure_int_as_bin(Others), ensure_int_as_bin(My));
1646
1647compute_key(eddh, Others, My, Curve) when Curve == x448 ;
1648                                          Curve == x25519 ->
1649    evp_compute_key_nif(Curve, ensure_int_as_bin(Others), ensure_int_as_bin(My));
1650
1651compute_key(ecdh, Others, My, Curve) ->
1652    ecdh_compute_key_nif(ensure_int_as_bin(Others),
1653			 nif_curve_params(Curve),
1654			 ensure_int_as_bin(My)).
1655
1656
1657evp_compute_key_nif(_Curve, _OthersBin, _MyBin) -> ?nif_stub.
1658
1659
1660%%%================================================================
1661%%%
1662%%% XOR - xor to iolists and return a binary
1663%%% NB doesn't check that they are the same size, just concatenates
1664%%% them and sends them to the driver
1665%%%
1666%%%================================================================
1667
1668-spec exor(iodata(), iodata()) -> binary().
1669
1670exor(Bin1, Bin2) ->
1671    Data1 = iolist_to_binary(Bin1),
1672    Data2 = iolist_to_binary(Bin2),
1673    MaxBytes = max_bytes(),
1674    exor(Data1, Data2, erlang:byte_size(Data1), MaxBytes, []).
1675
1676
1677%%%================================================================
1678%%%
1679%%% Exponentiation modulo
1680%%%
1681%%%================================================================
1682
1683-spec mod_pow(N, P, M) -> Result when N :: binary() | integer(),
1684                                      P :: binary() | integer(),
1685                                      M :: binary() | integer(),
1686                                      Result :: binary() | error .
1687mod_pow(Base, Exponent, Prime) ->
1688    case mod_exp_nif(ensure_int_as_bin(Base), ensure_int_as_bin(Exponent), ensure_int_as_bin(Prime), 0) of
1689	<<0>> -> error;
1690	R -> R
1691    end.
1692
1693%%%======================================================================
1694%%%
1695%%% Engine functions
1696%%%
1697%%%======================================================================
1698
1699%%%---- Refering to keys stored in an engine:
1700-type key_id()   :: string() | binary() .
1701-type password() :: string() | binary() .
1702
1703-type engine_key_ref() :: #{engine :=   engine_ref(),
1704                            key_id :=   key_id(),
1705                            password => password(),
1706                            term() => term()
1707                           }.
1708
1709%%%---- Commands:
1710-type engine_cmnd() :: {unicode:chardata(), unicode:chardata()}.
1711
1712%%----------------------------------------------------------------------
1713%% Function: engine_get_all_methods/0
1714%%----------------------------------------------------------------------
1715-type engine_method_type() :: engine_method_rsa | engine_method_dsa | engine_method_dh |
1716                              engine_method_rand | engine_method_ecdh | engine_method_ecdsa |
1717                              engine_method_ciphers | engine_method_digests | engine_method_store |
1718                              engine_method_pkey_meths | engine_method_pkey_asn1_meths |
1719                              engine_method_ec.
1720
1721-type engine_ref() :: term().
1722
1723-spec engine_get_all_methods() -> Result when Result :: [engine_method_type()].
1724engine_get_all_methods() ->
1725     notsup_to_error(engine_get_all_methods_nif()).
1726
1727%%----------------------------------------------------------------------
1728%% Function: engine_load/3
1729%%----------------------------------------------------------------------
1730-spec engine_load(EngineId, PreCmds, PostCmds) ->
1731                         Result when EngineId::unicode:chardata(),
1732                                     PreCmds::[engine_cmnd()],
1733                                     PostCmds::[engine_cmnd()],
1734                                     Result :: {ok, Engine::engine_ref()} | {error, Reason::term()}.
1735engine_load(EngineId, PreCmds, PostCmds) when is_list(PreCmds),
1736                                              is_list(PostCmds) ->
1737    engine_load(EngineId, PreCmds, PostCmds, engine_get_all_methods()).
1738
1739%%----------------------------------------------------------------------
1740%% Function: engine_load/4
1741%%----------------------------------------------------------------------
1742-spec engine_load(EngineId, PreCmds, PostCmds, EngineMethods) ->
1743                         Result when EngineId::unicode:chardata(),
1744                                     PreCmds::[engine_cmnd()],
1745                                     PostCmds::[engine_cmnd()],
1746                                     EngineMethods::[engine_method_type()],
1747                                     Result :: {ok, Engine::engine_ref()} | {error, Reason::term()}.
1748engine_load(EngineId, PreCmds, PostCmds, EngineMethods) when is_list(PreCmds),
1749                                                             is_list(PostCmds) ->
1750    try
1751        ok = notsup_to_error(engine_load_dynamic_nif()),
1752        case notsup_to_error(engine_by_id_nif(ensure_bin_chardata(EngineId))) of
1753            {ok, Engine} ->
1754                engine_load_1(Engine, PreCmds, PostCmds, EngineMethods);
1755            {error, Error1} ->
1756                {error, Error1}
1757        end
1758    catch
1759        throw:Error2 ->
1760            Error2
1761    end.
1762
1763engine_load_1(Engine, PreCmds, PostCmds, EngineMethods) ->
1764    try
1765        ok = engine_nif_wrapper(engine_ctrl_cmd_strings_nif(Engine, ensure_bin_cmds(PreCmds), 0)),
1766        ok = engine_nif_wrapper(engine_init_nif(Engine)),
1767        engine_load_2(Engine, PostCmds, EngineMethods),
1768        {ok, Engine}
1769    catch
1770        throw:Error ->
1771            %% The engine couldn't initialise, release the structural reference
1772            ok = engine_free_nif(Engine),
1773            throw(Error);
1774        error:badarg ->
1775            %% For example bad argument list, release the structural reference
1776            ok = engine_free_nif(Engine),
1777            error(badarg)
1778    end.
1779
1780engine_load_2(Engine, PostCmds, EngineMethods) ->
1781    try
1782        ok = engine_nif_wrapper(engine_ctrl_cmd_strings_nif(Engine, ensure_bin_cmds(PostCmds), 0)),
1783        [ok = engine_nif_wrapper(engine_register_nif(Engine, engine_method_atom_to_int(Method))) ||
1784            Method <- EngineMethods],
1785        ok
1786    catch
1787       throw:Error ->
1788          %% The engine registration failed, release the functional reference
1789          ok = engine_free_nif(Engine),
1790          throw(Error)
1791    end.
1792
1793%%----------------------------------------------------------------------
1794%% Function: engine_unload/1
1795%%----------------------------------------------------------------------
1796-spec engine_unload(Engine) -> Result when Engine :: engine_ref(),
1797                                           Result :: ok | {error, Reason::term()}.
1798engine_unload(Engine) ->
1799    engine_unload(Engine, engine_get_all_methods()).
1800
1801-spec engine_unload(Engine, EngineMethods) -> Result when Engine :: engine_ref(),
1802                                                          EngineMethods :: [engine_method_type()],
1803                                                          Result :: ok | {error, Reason::term()}.
1804engine_unload(Engine, EngineMethods) ->
1805    try
1806        [ok = engine_nif_wrapper(engine_unregister_nif(Engine, engine_method_atom_to_int(Method))) ||
1807            Method <- EngineMethods],
1808        %% Release the reference from engine_by_id_nif
1809        ok = engine_nif_wrapper(engine_free_nif(Engine))
1810    catch
1811       throw:Error ->
1812          Error
1813    end.
1814
1815%%----------------------------------------------------------------------
1816%% Function: engine_by_id/1
1817%%----------------------------------------------------------------------
1818-spec engine_by_id(EngineId) -> Result when EngineId :: unicode:chardata(),
1819                                            Result :: {ok, Engine::engine_ref()} | {error, Reason::term()} .
1820engine_by_id(EngineId) ->
1821    try
1822        notsup_to_error(engine_by_id_nif(ensure_bin_chardata(EngineId)))
1823    catch
1824       throw:Error ->
1825          Error
1826    end.
1827
1828%%----------------------------------------------------------------------
1829%% Function: engine_add/1
1830%%----------------------------------------------------------------------
1831-spec engine_add(Engine) -> Result when Engine :: engine_ref(),
1832                                        Result ::  ok | {error, Reason::term()} .
1833engine_add(Engine) ->
1834    notsup_to_error(engine_add_nif(Engine)).
1835
1836%%----------------------------------------------------------------------
1837%% Function: engine_remove/1
1838%%----------------------------------------------------------------------
1839-spec engine_remove(Engine) -> Result when Engine :: engine_ref(),
1840                                           Result ::  ok | {error, Reason::term()} .
1841engine_remove(Engine) ->
1842    notsup_to_error(engine_remove_nif(Engine)).
1843
1844%%----------------------------------------------------------------------
1845%% Function: engine_get_id/1
1846%%----------------------------------------------------------------------
1847-spec engine_get_id(Engine) -> EngineId when Engine :: engine_ref(),
1848                                             EngineId :: unicode:chardata().
1849engine_get_id(Engine) ->
1850    notsup_to_error(engine_get_id_nif(Engine)).
1851
1852%%----------------------------------------------------------------------
1853%% Function: engine_get_name/1
1854%%----------------------------------------------------------------------
1855-spec engine_get_name(Engine) -> EngineName when Engine :: engine_ref(),
1856                                                 EngineName :: unicode:chardata().
1857engine_get_name(Engine) ->
1858    notsup_to_error(engine_get_name_nif(Engine)).
1859
1860%%----------------------------------------------------------------------
1861%% Function: engine_list/0
1862%%----------------------------------------------------------------------
1863-spec engine_list() -> Result when Result :: [EngineId::unicode:chardata()].
1864engine_list() ->
1865    case notsup_to_error(engine_get_first_nif()) of
1866        {ok, <<>>} ->
1867            [];
1868        {ok, Engine} ->
1869            case notsup_to_error(engine_get_id_nif(Engine)) of
1870                <<>> ->
1871                    engine_list(Engine, []);
1872                EngineId ->
1873                    engine_list(Engine, [EngineId])
1874            end
1875    end.
1876
1877engine_list(Engine0, IdList) ->
1878    case notsup_to_error(engine_get_next_nif(Engine0)) of
1879        {ok, <<>>} ->
1880            lists:reverse(IdList);
1881        {ok, Engine1} ->
1882            case notsup_to_error(engine_get_id_nif(Engine1)) of
1883                <<>> ->
1884                    engine_list(Engine1, IdList);
1885                EngineId ->
1886                    engine_list(Engine1, [EngineId |IdList])
1887            end
1888    end.
1889
1890%%----------------------------------------------------------------------
1891%% Function: engine_ctrl_cmd_string/3
1892%%----------------------------------------------------------------------
1893-spec engine_ctrl_cmd_string(Engine, CmdName, CmdArg) ->
1894                                    Result when Engine::term(),
1895                                                CmdName::unicode:chardata(),
1896                                                CmdArg::unicode:chardata(),
1897                                                Result :: ok | {error, Reason::term()}.
1898engine_ctrl_cmd_string(Engine, CmdName, CmdArg) ->
1899    engine_ctrl_cmd_string(Engine, CmdName, CmdArg, false).
1900
1901%%----------------------------------------------------------------------
1902%% Function: engine_ctrl_cmd_string/4
1903%%----------------------------------------------------------------------
1904-spec engine_ctrl_cmd_string(Engine, CmdName, CmdArg, Optional) ->
1905                                    Result when Engine::term(),
1906                                                CmdName::unicode:chardata(),
1907                                                CmdArg::unicode:chardata(),
1908                                                Optional::boolean(),
1909                                                Result :: ok | {error, Reason::term()}.
1910engine_ctrl_cmd_string(Engine, CmdName, CmdArg, Optional) ->
1911    case engine_ctrl_cmd_strings_nif(Engine,
1912                                     ensure_bin_cmds([{CmdName, CmdArg}]),
1913                                     bool_to_int(Optional)) of
1914        ok ->
1915            ok;
1916        notsup ->
1917            erlang:error(notsup);
1918        {error, Error} ->
1919            {error, Error}
1920    end.
1921
1922%%----------------------------------------------------------------------
1923%% Function: ensure_engine_loaded/2
1924%% Special version of load that only uses dynamic engine to load
1925%%----------------------------------------------------------------------
1926-spec ensure_engine_loaded(EngineId, LibPath) ->
1927                                  Result when EngineId :: unicode:chardata(),
1928                                              LibPath :: unicode:chardata(),
1929                                              Result :: {ok, Engine::engine_ref()} | {error, Reason::term()}.
1930ensure_engine_loaded(EngineId, LibPath) ->
1931    ensure_engine_loaded(EngineId, LibPath, engine_get_all_methods()).
1932
1933%%----------------------------------------------------------------------
1934%% Function: ensure_engine_loaded/3
1935%% Special version of load that only uses dynamic engine to load
1936%%----------------------------------------------------------------------
1937-spec ensure_engine_loaded(EngineId, LibPath, EngineMethods) ->
1938                                  Result when EngineId :: unicode:chardata(),
1939                                              LibPath :: unicode:chardata(),
1940                                              EngineMethods :: [engine_method_type()],
1941                                              Result :: {ok, Engine::engine_ref()} | {error, Reason::term()}.
1942ensure_engine_loaded(EngineId, LibPath, EngineMethods) ->
1943    try
1944        List = crypto:engine_list(),
1945        case lists:member(EngineId, List) of
1946            true ->
1947                notsup_to_error(engine_by_id_nif(ensure_bin_chardata(EngineId)));
1948            false ->
1949                ok = notsup_to_error(engine_load_dynamic_nif()),
1950                case notsup_to_error(engine_by_id_nif(ensure_bin_chardata(<<"dynamic">>))) of
1951                    {ok, Engine} ->
1952                        PreCommands = [{<<"SO_PATH">>, ensure_bin_chardata(LibPath)},
1953                                       {<<"ID">>, ensure_bin_chardata(EngineId)},
1954                                       <<"LOAD">>],
1955                        ensure_engine_loaded_1(Engine, PreCommands, EngineMethods);
1956                    {error, Error1} ->
1957                        {error, Error1}
1958                end
1959        end
1960    catch
1961        throw:Error2 ->
1962            Error2
1963    end.
1964
1965ensure_engine_loaded_1(Engine, PreCmds, Methods) ->
1966    try
1967        ok = engine_nif_wrapper(engine_ctrl_cmd_strings_nif(Engine, ensure_bin_cmds(PreCmds), 0)),
1968        ok = engine_nif_wrapper(engine_add_nif(Engine)),
1969        ok = engine_nif_wrapper(engine_init_nif(Engine)),
1970        ensure_engine_loaded_2(Engine, Methods),
1971        {ok, Engine}
1972    catch
1973        throw:Error ->
1974            %% The engine couldn't initialise, release the structural reference
1975            ok = engine_free_nif(Engine),
1976            throw(Error)
1977    end.
1978
1979ensure_engine_loaded_2(Engine, Methods) ->
1980    try
1981        [ok = engine_nif_wrapper(engine_register_nif(Engine, engine_method_atom_to_int(Method))) ||
1982            Method <- Methods],
1983        ok
1984    catch
1985       throw:Error ->
1986          %% The engine registration failed, release the functional reference
1987          ok = engine_free_nif(Engine),
1988          throw(Error)
1989    end.
1990%%----------------------------------------------------------------------
1991%% Function: ensure_engine_unloaded/1
1992%%----------------------------------------------------------------------
1993-spec ensure_engine_unloaded(Engine) -> Result when Engine :: engine_ref(),
1994                                                    Result :: ok | {error, Reason::term()}.
1995ensure_engine_unloaded(Engine) ->
1996    ensure_engine_unloaded(Engine, engine_get_all_methods()).
1997
1998%%----------------------------------------------------------------------
1999%% Function: ensure_engine_unloaded/2
2000%%----------------------------------------------------------------------
2001-spec ensure_engine_unloaded(Engine, EngineMethods) ->
2002                                    Result when Engine :: engine_ref(),
2003                                                EngineMethods :: [engine_method_type()],
2004                                                Result :: ok | {error, Reason::term()}.
2005ensure_engine_unloaded(Engine, EngineMethods) ->
2006    List = crypto:engine_list(),
2007    EngineId = crypto:engine_get_id(Engine),
2008    case lists:member(EngineId, List) of
2009        true ->
2010            case engine_remove(Engine) of
2011                ok ->
2012                    engine_unload(Engine, EngineMethods);
2013                {error, Error} ->
2014                    {error, Error}
2015            end;
2016        false ->
2017            engine_unload(Engine, EngineMethods)
2018    end.
2019
2020
2021%%--------------------------------------------------------------------
2022%%% On load
2023%%--------------------------------------------------------------------
2024on_load() ->
2025    LibBaseName = "crypto",
2026    PrivDir = code:priv_dir(crypto),
2027    LibName = case erlang:system_info(build_type) of
2028		  opt ->
2029		      LibBaseName;
2030		  Type ->
2031		      LibTypeName = LibBaseName ++ "."  ++ atom_to_list(Type),
2032		      case (filelib:wildcard(
2033			      filename:join(
2034				[PrivDir,
2035				 "lib",
2036				 LibTypeName ++ "*"])) /= []) orelse
2037			  (filelib:wildcard(
2038			     filename:join(
2039			       [PrivDir,
2040				"lib",
2041				erlang:system_info(system_architecture),
2042				LibTypeName ++ "*"])) /= []) of
2043			  true -> LibTypeName;
2044			  false -> LibBaseName
2045		      end
2046	      end,
2047    Lib = filename:join([PrivDir, "lib", LibName]),
2048    LibBin   = path2bin(Lib),
2049    FipsMode = application:get_env(crypto, fips_mode, false) == true,
2050    Status = case erlang:load_nif(Lib, {?CRYPTO_NIF_VSN,LibBin,FipsMode}) of
2051		 ok -> ok;
2052		 {error, {load_failed, _}}=Error1 ->
2053		     ArchLibDir =
2054			 filename:join([PrivDir, "lib",
2055					erlang:system_info(system_architecture)]),
2056		     Candidate =
2057			 filelib:wildcard(filename:join([ArchLibDir,LibName ++ "*" ]),erl_prim_loader),
2058		     case Candidate of
2059			 [] -> Error1;
2060			 _ ->
2061			     ArchLib = filename:join([ArchLibDir, LibName]),
2062                             ArchBin = path2bin(ArchLib),
2063			     erlang:load_nif(ArchLib, {?CRYPTO_NIF_VSN,ArchBin,FipsMode})
2064		     end;
2065		 Error1 -> Error1
2066	     end,
2067    case Status of
2068	ok -> ok;
2069	{error, {E, Str}} ->
2070            Fmt = "Unable to load crypto library. Failed with error:~n\"~p, ~s\"~n~s",
2071            Extra = case E of
2072                        load_failed ->
2073                            "OpenSSL might not be installed on this system.\n";
2074                        _ -> ""
2075                    end,
2076	    error_logger:error_msg(Fmt, [E,Str,Extra]),
2077	    Status
2078    end.
2079
2080path2bin(Path) when is_list(Path) ->
2081    Encoding = file:native_name_encoding(),
2082    case unicode:characters_to_binary(Path,Encoding,Encoding) of
2083	Bin when is_binary(Bin) ->
2084	    Bin
2085    end.
2086
2087%%%================================================================
2088%%%================================================================
2089%%%
2090%%% Internal functions
2091%%%
2092%%%================================================================
2093
2094max_bytes() ->
2095    ?MAX_BYTES_TO_NIF.
2096
2097notsup_to_error(notsup) ->
2098    erlang:error(notsup);
2099notsup_to_error(Other) ->
2100    Other.
2101
2102%% HASH --------------------------------------------------------------------
2103hash(Hash, Data, Size, Max) when Size =< Max ->
2104    notsup_to_error(hash_nif(Hash, Data));
2105hash(Hash, Data, Size, Max) ->
2106    State0 = hash_init(Hash),
2107    State1 = hash_update(State0, Data, Size, Max),
2108    hash_final(State1).
2109
2110hash_update(State, Data, Size, MaxBytes)  when Size =< MaxBytes ->
2111    notsup_to_error(hash_update_nif(State, Data));
2112hash_update(State0, Data, _, MaxBytes) ->
2113    <<Increment:MaxBytes/binary, Rest/binary>> = Data,
2114    State = notsup_to_error(hash_update_nif(State0, Increment)),
2115    hash_update(State, Rest, erlang:byte_size(Rest), MaxBytes).
2116
2117hash_info_nif(_Hash) -> ?nif_stub.
2118hash_nif(_Hash, _Data) -> ?nif_stub.
2119hash_init_nif(_Hash) -> ?nif_stub.
2120hash_update_nif(_State, _Data) -> ?nif_stub.
2121hash_final_nif(_State) -> ?nif_stub.
2122
2123%%%================================================================
2124
2125%% Secure remote password  -------------------------------------------------------------------
2126
2127user_srp_gen_key(Private, Generator, Prime) ->
2128    %% Ensure the SRP algorithm is disabled in FIPS mode
2129    case info_fips() of
2130        enabled -> erlang:error(notsup);
2131        _       -> ok
2132    end,
2133    case mod_pow(Generator, Private, Prime) of
2134	error ->
2135	    error;
2136	Public ->
2137	    {Public, Private}
2138    end.
2139
2140host_srp_gen_key(Private, Verifier, Generator, Prime, Version) ->
2141 Multiplier = srp_multiplier(Version, Generator, Prime),
2142   case srp_value_B_nif(Multiplier, Verifier, Generator, Private, Prime) of
2143   error ->
2144       error;
2145   notsup ->
2146       erlang:error(notsup);
2147   Public ->
2148       {Public, Private}
2149   end.
2150
2151srp_multiplier('6a', Generator, Prime) ->
2152    %% k = SHA1(N | PAD(g)) from http://srp.stanford.edu/design.html
2153    C0 = hash_init(sha),
2154    C1 = hash_update(C0, Prime),
2155    C2 = hash_update(C1, srp_pad_to(erlang:byte_size(Prime), Generator)),
2156    hash_final(C2);
2157srp_multiplier('6', _, _) ->
2158    <<3/integer>>;
2159srp_multiplier('3', _, _) ->
2160    <<1/integer>>.
2161
2162srp_scrambler(Version, UserPublic, HostPublic, Prime) when Version == '6'; Version == '6a'->
2163    %% SHA1(PAD(A) | PAD(B)) from http://srp.stanford.edu/design.html
2164    PadLength = erlang:byte_size(Prime),
2165    C0 = hash_init(sha),
2166    C1 = hash_update(C0, srp_pad_to(PadLength, UserPublic)),
2167    C2 = hash_update(C1, srp_pad_to(PadLength, HostPublic)),
2168    hash_final(C2);
2169srp_scrambler('3', _, HostPublic, _Prime) ->
2170    %% The parameter u is a 32-bit unsigned integer which takes its value
2171    %% from the first 32 bits of the SHA1 hash of B, MSB first.
2172    <<U:32/bits, _/binary>> = hash(sha, HostPublic),
2173    U.
2174
2175srp_pad_length(Width, Length) ->
2176    (Width - Length rem Width) rem Width.
2177
2178srp_pad_to(Width, Binary) ->
2179    case srp_pad_length(Width, size(Binary)) of
2180        0 -> Binary;
2181        N -> << 0:(N*8), Binary/binary>>
2182    end.
2183
2184srp_host_secret_nif(_Verifier, _B, _U, _A, _Prime) -> ?nif_stub.
2185
2186srp_user_secret_nif(_A, _U, _B, _Multiplier, _Generator, _Exponent, _Prime) -> ?nif_stub.
2187
2188srp_value_B_nif(_Multiplier, _Verifier, _Generator, _Exponent, _Prime) -> ?nif_stub.
2189
2190
2191%% Public Keys  --------------------------------------------------------------------
2192%% RSA Rivest-Shamir-Adleman functions
2193%%
2194
2195rsa_generate_key_nif(_Bits, _Exp) -> ?nif_stub.
2196
2197%% DH Diffie-Hellman functions
2198%%
2199
2200%% DHParameters = [P (Prime)= mpint(), G(Generator) = mpint()]
2201%% PrivKey = mpint()
2202dh_generate_key_nif(_PrivateKey, _DHParameters, _Mpint, _Length) -> ?nif_stub.
2203
2204%% DHParameters = [P (Prime)= mpint(), G(Generator) = mpint()]
2205%% MyPrivKey, OthersPublicKey = mpint()
2206dh_compute_key_nif(_OthersPublicKey, _MyPrivateKey, _DHParameters) -> ?nif_stub.
2207
2208ec_key_generate(_Curve, _Key) -> ?nif_stub.
2209
2210ecdh_compute_key_nif(_Others, _Curve, _My) -> ?nif_stub.
2211
2212-spec ec_curves() -> [EllipticCurve] when EllipticCurve :: ec_named_curve()
2213                                                         | edwards_curve_dh()
2214                                                         | edwards_curve_ed() .
2215
2216ec_curves() ->
2217    crypto_ec_curves:curves().
2218
2219-spec ec_curve(CurveName) -> ExplicitCurve when CurveName :: ec_named_curve(),
2220                                                ExplicitCurve :: ec_explicit_curve() .
2221ec_curve(X) ->
2222    crypto_ec_curves:curve(X).
2223
2224
2225-spec privkey_to_pubkey(Type, EnginePrivateKeyRef) -> PublicKey when Type :: rsa | dss,
2226                                                                     EnginePrivateKeyRef :: engine_key_ref(),
2227                                                                     PublicKey ::  rsa_public() | dss_public() .
2228privkey_to_pubkey(Alg, EngineMap) when Alg == rsa; Alg == dss; Alg == ecdsa ->
2229    try privkey_to_pubkey_nif(Alg, format_pkey(Alg,EngineMap))
2230    of
2231        [_|_]=L -> map_ensure_bin_as_int(L);
2232        X -> X
2233    catch
2234        error:badarg when Alg==ecdsa ->
2235            {error, notsup};
2236        error:badarg ->
2237            {error, not_found};
2238        error:notsup ->
2239            {error, notsup}
2240    end.
2241
2242privkey_to_pubkey_nif(_Alg, _EngineMap) -> ?nif_stub.
2243
2244
2245%%
2246%% EC
2247%%
2248
2249term_to_nif_prime({prime_field, Prime}) ->
2250    {prime_field, ensure_int_as_bin(Prime)};
2251term_to_nif_prime(PrimeField) ->
2252    PrimeField.
2253
2254term_to_nif_curve({A, B, Seed}) ->
2255    {ensure_int_as_bin(A), ensure_int_as_bin(B), Seed}.
2256
2257nif_curve_params({PrimeField, Curve, BasePoint, Order, CoFactor}) ->
2258    {term_to_nif_prime(PrimeField),
2259     term_to_nif_curve(Curve),
2260     ensure_int_as_bin(BasePoint),
2261     ensure_int_as_bin(Order),
2262     ensure_int_as_bin(CoFactor)};
2263nif_curve_params(Curve) when is_atom(Curve) ->
2264    %% named curve
2265    case Curve of
2266        x448 -> {evp,Curve};
2267        x25519 -> {evp,Curve};
2268        _ -> crypto_ec_curves:curve(Curve)
2269    end.
2270
2271
2272%% MISC --------------------------------------------------------------------
2273
2274exor(Data1, Data2, Size, MaxByts, [])  when Size =< MaxByts ->
2275    do_exor(Data1, Data2);
2276exor(Data1, Data2, Size, MaxByts, Acc) when Size =< MaxByts ->
2277    Result = do_exor(Data1, Data2),
2278    list_to_binary(lists:reverse([Result | Acc]));
2279exor(Data1, Data2, _Size, MaxByts, Acc) ->
2280     <<Increment1:MaxByts/binary, Rest1/binary>> = Data1,
2281     <<Increment2:MaxByts/binary, Rest2/binary>> = Data2,
2282    Result = do_exor(Increment1, Increment2),
2283    exor(Rest1, Rest2, erlang:byte_size(Rest1), MaxByts, [Result | Acc]).
2284
2285do_exor(_A, _B) -> ?nif_stub.
2286
2287hash_algorithms() -> ?nif_stub.
2288pubkey_algorithms() -> ?nif_stub.
2289cipher_algorithms() -> ?nif_stub.
2290mac_algorithms() -> ?nif_stub.
2291curve_algorithms() -> ?nif_stub.
2292rsa_opts_algorithms() -> ?nif_stub.
2293
2294
2295int_to_bin(X) when X < 0 -> int_to_bin_neg(X, []);
2296int_to_bin(X) -> int_to_bin_pos(X, []).
2297
2298int_to_bin_pos(0,Ds=[_|_]) ->
2299    list_to_binary(Ds);
2300int_to_bin_pos(X,Ds) ->
2301    int_to_bin_pos(X bsr 8, [(X band 255)|Ds]).
2302
2303int_to_bin_neg(-1, Ds=[MSB|_]) when MSB >= 16#80 ->
2304    list_to_binary(Ds);
2305int_to_bin_neg(X,Ds) ->
2306    int_to_bin_neg(X bsr 8, [(X band 255)|Ds]).
2307
2308-spec bytes_to_integer(binary()) -> integer() .
2309bytes_to_integer(Bin) ->
2310    bin_to_int(Bin).
2311
2312bin_to_int(Bin) when is_binary(Bin) ->
2313    Bits = bit_size(Bin),
2314    <<Integer:Bits/integer>> = Bin,
2315    Integer;
2316bin_to_int(undefined) ->
2317    undefined.
2318
2319map_ensure_int_as_bin([H|_]=List) when is_integer(H) ->
2320    lists:map(fun(E) -> int_to_bin(E) end, List);
2321map_ensure_int_as_bin(List) ->
2322    List.
2323
2324ensure_int_as_bin(Int) when is_integer(Int) ->
2325    int_to_bin(Int);
2326ensure_int_as_bin(Bin) ->
2327    Bin.
2328
2329map_ensure_bin_as_int(List) when is_list(List) ->
2330    lists:map(fun ensure_bin_as_int/1, List).
2331
2332ensure_bin_as_int(Bin) when is_binary(Bin) ->
2333    bin_to_int(Bin);
2334ensure_bin_as_int(E) ->
2335    E.
2336
2337format_pkey(_Alg, #{engine:=_, key_id:=T}=M) when is_binary(T) -> format_pwd(M);
2338format_pkey(_Alg, #{engine:=_, key_id:=T}=M) when is_list(T) -> format_pwd(M#{key_id:=list_to_binary(T)});
2339format_pkey(_Alg, #{engine:=_           }=M) -> error({bad_key_id, M});
2340format_pkey(_Alg, #{}=M) -> error({bad_engine_map, M});
2341%%%
2342format_pkey(rsa, Key) ->
2343    map_ensure_int_as_bin(Key);
2344format_pkey(ecdsa, [Key, Curve]) ->
2345    {nif_curve_params(Curve), ensure_int_as_bin(Key)};
2346format_pkey(eddsa, [PubKey, Curve]) when  Curve == ed25519;
2347                                          Curve == ed448 ->
2348    [ensure_int_as_bin(PubKey), Curve];
2349format_pkey(dss, Key) ->
2350    map_ensure_int_as_bin(Key);
2351format_pkey(_, Key) ->
2352    Key.
2353
2354format_pwd(#{password := Pwd}=M) when is_list(Pwd) -> M#{password := list_to_binary(Pwd)};
2355format_pwd(M) -> M.
2356
2357%%--------------------------------------------------------------------
2358%%
2359
2360%% large integer in a binary with 32bit length
2361%% MP representaion  (SSH2)
2362mpint(X) when X < 0 -> mpint_neg(X);
2363mpint(X) -> mpint_pos(X).
2364
2365-define(UINT32(X),   X:32/unsigned-big-integer).
2366
2367
2368mpint_neg(X) ->
2369    Bin = int_to_bin_neg(X, []),
2370    Sz = byte_size(Bin),
2371    <<?UINT32(Sz), Bin/binary>>.
2372
2373mpint_pos(X) ->
2374    Bin = int_to_bin_pos(X, []),
2375    <<MSB,_/binary>> = Bin,
2376    Sz = byte_size(Bin),
2377    if MSB band 16#80 == 16#80 ->
2378	    <<?UINT32((Sz+1)), 0, Bin/binary>>;
2379       true ->
2380	    <<?UINT32(Sz), Bin/binary>>
2381    end.
2382
2383%% int from integer in a binary with 32bit length
2384erlint(<<MPIntSize:32/integer,MPIntValue/binary>>) ->
2385    Bits= MPIntSize * 8,
2386    <<Integer:Bits/integer>> = MPIntValue,
2387    Integer.
2388
2389%%
2390%% mod_exp - utility for rsa generation and SRP
2391%%
2392mod_exp_nif(_Base,_Exp,_Mod,_bin_hdr) -> ?nif_stub.
2393
2394%%%----------------------------------------------------------------
2395%% 9470495 == V(0,9,8,zh).
2396%% 268435615 == V(1,0,0,i).
2397%% 268439663 == V(1,0,1,f).
2398
2399packed_openssl_version(MAJ, MIN, FIX, P0) ->
2400    %% crypto.c
2401    P1 = atom_to_list(P0),
2402    P = lists:sum([C-$a||C<-P1]),
2403    ((((((((MAJ bsl 8) bor MIN) bsl 8 ) bor FIX) bsl 8) bor (P+1)) bsl 4) bor 16#f).
2404
2405%%--------------------------------------------------------------------
2406%% Engine nifs
2407engine_by_id_nif(_EngineId) -> ?nif_stub.
2408engine_init_nif(_Engine) -> ?nif_stub.
2409engine_free_nif(_Engine) -> ?nif_stub.
2410engine_load_dynamic_nif() -> ?nif_stub.
2411engine_ctrl_cmd_strings_nif(_Engine, _Cmds, _Optional) -> ?nif_stub.
2412engine_add_nif(_Engine)  -> ?nif_stub.
2413engine_remove_nif(_Engine)  -> ?nif_stub.
2414engine_register_nif(_Engine, _EngineMethod) -> ?nif_stub.
2415engine_unregister_nif(_Engine, _EngineMethod) -> ?nif_stub.
2416engine_get_first_nif() -> ?nif_stub.
2417engine_get_next_nif(_Engine) -> ?nif_stub.
2418engine_get_id_nif(_Engine) -> ?nif_stub.
2419engine_get_name_nif(_Engine) -> ?nif_stub.
2420engine_get_all_methods_nif() -> ?nif_stub.
2421
2422%%--------------------------------------------------------------------
2423%% Engine internals
2424engine_nif_wrapper(ok) ->
2425    ok;
2426engine_nif_wrapper(notsup) ->
2427    erlang:error(notsup);
2428engine_nif_wrapper({error, Error}) ->
2429    throw({error, Error}).
2430
2431ensure_bin_chardata(CharData) when is_binary(CharData) ->
2432    CharData;
2433ensure_bin_chardata(CharData) ->
2434    unicode:characters_to_binary(CharData).
2435
2436ensure_bin_cmds(CMDs) ->
2437    ensure_bin_cmds(CMDs, []).
2438
2439ensure_bin_cmds([], Acc) ->
2440    lists:reverse(Acc);
2441ensure_bin_cmds([{Key, Value} |CMDs], Acc) ->
2442    ensure_bin_cmds(CMDs, [{ensure_bin_chardata(Key), ensure_bin_chardata(Value)} | Acc]);
2443ensure_bin_cmds([Key | CMDs], Acc) ->
2444    ensure_bin_cmds(CMDs, [{ensure_bin_chardata(Key), <<"">>} | Acc]).
2445
2446engine_methods_convert_to_bitmask([], BitMask) ->
2447    BitMask;
2448engine_methods_convert_to_bitmask(engine_method_all, _BitMask) ->
2449    16#FFFF;
2450engine_methods_convert_to_bitmask(engine_method_none, _BitMask) ->
2451    16#0000;
2452engine_methods_convert_to_bitmask([M |Ms], BitMask) ->
2453    engine_methods_convert_to_bitmask(Ms, BitMask bor engine_method_atom_to_int(M)).
2454
2455bool_to_int(true) -> 1;
2456bool_to_int(false) -> 0.
2457
2458engine_method_atom_to_int(engine_method_rsa) -> 16#0001;
2459engine_method_atom_to_int(engine_method_dsa) -> 16#0002;
2460engine_method_atom_to_int(engine_method_dh) -> 16#0004;
2461engine_method_atom_to_int(engine_method_rand) -> 16#0008;
2462engine_method_atom_to_int(engine_method_ecdh) -> 16#0010;
2463engine_method_atom_to_int(engine_method_ecdsa) -> 16#0020;
2464engine_method_atom_to_int(engine_method_ciphers) -> 16#0040;
2465engine_method_atom_to_int(engine_method_digests) -> 16#0080;
2466engine_method_atom_to_int(engine_method_store) -> 16#0100;
2467engine_method_atom_to_int(engine_method_pkey_meths) -> 16#0200;
2468engine_method_atom_to_int(engine_method_pkey_asn1_meths) -> 16#0400;
2469engine_method_atom_to_int(engine_method_ec) -> 16#0800;
2470engine_method_atom_to_int(X) ->
2471    erlang:error(badarg, [X]).
2472
2473get_test_engine() ->
2474    Type = erlang:system_info(system_architecture),
2475    LibDir = filename:join([code:priv_dir(crypto), "lib"]),
2476    ArchDir = filename:join([LibDir, Type]),
2477    case filelib:is_dir(ArchDir) of
2478	true  -> check_otp_test_engine(ArchDir);
2479	false -> check_otp_test_engine(LibDir)
2480    end.
2481
2482check_otp_test_engine(LibDir) ->
2483    case choose_otp_test_engine(LibDir) of
2484        false ->
2485            {error, notexist};
2486        LibName ->
2487            LibPath = filename:join(LibDir,LibName),
2488            case filelib:is_file(LibPath) of
2489                true ->
2490                    {ok, unicode:characters_to_binary(LibPath)};
2491                false ->
2492                    {error, notexist}
2493            end
2494    end.
2495
2496
2497choose_otp_test_engine(LibDir) ->
2498    LibNames = filelib:wildcard("otp_test_engine.*", LibDir),
2499    Type = atom_to_list(erlang:system_info(build_type)),
2500    choose_otp_test_engine(LibNames, Type, false).
2501
2502choose_otp_test_engine([LibName | T], Type, Acc) ->
2503    case string:lexemes(LibName, ".") of
2504        [_, Type, _SO] ->
2505            LibName;  %% Choose typed if exists (valgrind,asan)
2506        [_, _SO] ->
2507            %% Fallback on typeless (opt)
2508            choose_otp_test_engine(T, Type, LibName);
2509        _ ->
2510            choose_otp_test_engine(T, Type, Acc)
2511    end;
2512choose_otp_test_engine([], _, Acc) ->
2513    Acc.
2514