1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 1999-2018. 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_lib/0, info_fips/0, supports/0, enable_fips_mode/1, 26 version/0, bytes_to_integer/1]). 27-export([equal_const_time/2]). 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([hmac/3, hmac/4, hmac_init/2, hmac_update/2, hmac_final/1, hmac_final_n/2]). 32-export([cmac/3, cmac/4]). 33-export([poly1305/2]). 34-export([exor/2, strong_rand_bytes/1, mod_pow/3]). 35-export([rand_seed/0, rand_seed_alg/1]). 36-export([rand_seed_s/0, rand_seed_alg_s/1]). 37-export([rand_plugin_next/1]). 38-export([rand_plugin_uniform/1]). 39-export([rand_plugin_uniform/2]). 40-export([rand_cache_plugin_next/1]). 41-export([rand_uniform/2]). 42-export([block_encrypt/3, block_decrypt/3, block_encrypt/4, block_decrypt/4]). 43-export([next_iv/2, next_iv/3]). 44-export([stream_init/2, stream_init/3, stream_encrypt/2, stream_decrypt/2]). 45-export([public_encrypt/4, private_decrypt/4]). 46-export([private_encrypt/4, public_decrypt/4]). 47-export([privkey_to_pubkey/2]). 48-export([ec_curve/1, ec_curves/0]). 49-export([rand_seed/1]). 50%% Engine 51-export([ 52 engine_get_all_methods/0, 53 engine_load/3, 54 engine_load/4, 55 engine_unload/1, 56 engine_by_id/1, 57 engine_list/0, 58 engine_ctrl_cmd_string/3, 59 engine_ctrl_cmd_string/4, 60 engine_add/1, 61 engine_remove/1, 62 engine_get_id/1, 63 engine_get_name/1, 64 ensure_engine_loaded/2, 65 ensure_engine_loaded/3, 66 ensure_engine_unloaded/1, 67 ensure_engine_unloaded/2 68 ]). 69 70-export_type([ %% A minimum exported: only what public_key needs. 71 dh_private/0, 72 dh_public/0, 73 dss_digest_type/0, 74 ec_named_curve/0, 75 ecdsa_digest_type/0, 76 pk_encrypt_decrypt_opts/0, 77 pk_sign_verify_opts/0, 78 rsa_digest_type/0, 79 sha1/0, 80 sha2/0 81 ]). 82 83-export_type([engine_ref/0, 84 key_id/0, 85 password/0 86 ]). 87 88%%% Opaque types must be exported :( 89-export_type([ 90 stream_state/0, 91 hmac_state/0, 92 hash_state/0 93 ]). 94 95%% Private. For tests. 96-export([packed_openssl_version/4, engine_methods_convert_to_bitmask/2, get_test_engine/0]). 97 98-deprecated({rand_uniform, 2, next_major_release}). 99 100%% This should correspond to the similar macro in crypto.c 101-define(MAX_BYTES_TO_NIF, 20000). %% Current value is: erlang:system_info(context_reductions) * 10 102 103%% Used by strong_rand_float/0 104-define(HALF_DBL_EPSILON, 1.1102230246251565e-16). % math:pow(2, -53) 105 106 107%%% ===== BEGIN NEW TYPING ==== 108 109%%% Basic 110-type key_integer() :: integer() | binary(). % Always binary() when used as return value 111 112%%% Keys 113-type rsa_public() :: [key_integer()] . % [E, N] 114-type rsa_private() :: [key_integer()] . % [E, N, D] | [E, N, D, P1, P2, E1, E2, C] 115-type rsa_params() :: {ModulusSizeInBits::integer(), PublicExponent::key_integer()} . 116 117-type dss_public() :: [key_integer()] . % [P, Q, G, Y] 118-type dss_private() :: [key_integer()] . % [P, Q, G, X] 119 120-type ecdsa_public() :: key_integer() . 121-type ecdsa_private() :: key_integer() . 122-type ecdsa_params() :: ec_named_curve() | ec_explicit_curve() . 123 124-type eddsa_public() :: key_integer() . 125-type eddsa_private() :: key_integer() . 126-type eddsa_params() :: edwards_curve_ed() . 127 128-type srp_public() :: key_integer() . 129-type srp_private() :: key_integer() . 130-type srp_gen_params() :: {user,srp_user_gen_params()} | {host,srp_host_gen_params()}. 131-type srp_comp_params() :: {user,srp_user_comp_params()} | {host,srp_host_comp_params()}. 132-type srp_user_gen_params() :: list(binary() | atom() | list()) . 133-type srp_host_gen_params() :: list(binary() | atom() | list()) . 134-type srp_user_comp_params() :: list(binary() | atom()) . 135-type srp_host_comp_params() :: list(binary() | atom()) . 136 137-type dh_public() :: key_integer() . 138-type dh_private() :: key_integer() . 139-type dh_params() :: [key_integer()] . % [P, G] | [P, G, PrivateKeyBitLength] 140 141-type ecdh_public() :: key_integer() . 142-type ecdh_private() :: key_integer() . 143-type ecdh_params() :: ec_named_curve() | edwards_curve_dh() | ec_explicit_curve() . 144 145 146%%% Curves 147 148-type ec_explicit_curve() :: {Field :: ec_field(), 149 Curve :: ec_curve(), 150 BasePoint :: binary(), 151 Order :: binary(), 152 CoFactor :: none | % FIXME: Really? 153 binary() 154 } . 155 156-type ec_curve() :: {A :: binary(), 157 B :: binary(), 158 Seed :: none | binary() 159 } . 160 161-type ec_field() :: ec_prime_field() | ec_characteristic_two_field() . 162 163-type ec_prime_field() :: {prime_field, Prime :: integer()} . 164-type ec_characteristic_two_field() :: {characteristic_two_field, M :: integer(), Basis :: ec_basis()} . 165 166-type ec_basis() :: {tpbasis, K :: non_neg_integer()} 167 | {ppbasis, K1 :: non_neg_integer(), K2 :: non_neg_integer(), K3 :: non_neg_integer()} 168 | onbasis . 169 170-type ec_named_curve() :: brainpoolP160r1 171 | brainpoolP160t1 172 | brainpoolP192r1 173 | brainpoolP192t1 174 | brainpoolP224r1 175 | brainpoolP224t1 176 | brainpoolP256r1 177 | brainpoolP256t1 178 | brainpoolP320r1 179 | brainpoolP320t1 180 | brainpoolP384r1 181 | brainpoolP384t1 182 | brainpoolP512r1 183 | brainpoolP512t1 184 | c2pnb163v1 185 | c2pnb163v2 186 | c2pnb163v3 187 | c2pnb176v1 188 | c2pnb208w1 189 | c2pnb272w1 190 | c2pnb304w1 191 | c2pnb368w1 192 | c2tnb191v1 193 | c2tnb191v2 194 | c2tnb191v3 195 | c2tnb239v1 196 | c2tnb239v2 197 | c2tnb239v3 198 | c2tnb359v1 199 | c2tnb431r1 200 | ipsec3 201 | ipsec4 202 | prime192v1 203 | prime192v2 204 | prime192v3 205 | prime239v1 206 | prime239v2 207 | prime239v3 208 | prime256v1 209 | secp112r1 210 | secp112r2 211 | secp128r1 212 | secp128r2 213 | secp160k1 214 | secp160r1 215 | secp160r2 216 | secp192k1 217 | secp192r1 218 | secp224k1 219 | secp224r1 220 | secp256k1 221 | secp256r1 222 | secp384r1 223 | secp521r1 224 | sect113r1 225 | sect113r2 226 | sect131r1 227 | sect131r2 228 | sect163k1 229 | sect163r1 230 | sect163r2 231 | sect193r1 232 | sect193r2 233 | sect233k1 234 | sect233r1 235 | sect239k1 236 | sect283k1 237 | sect283r1 238 | sect409k1 239 | sect409r1 240 | sect571k1 241 | sect571r1 242 | wtls1 243 | wtls10 244 | wtls11 245 | wtls12 246 | wtls3 247 | wtls4 248 | wtls5 249 | wtls6 250 | wtls7 251 | wtls8 252 | wtls9 253 . 254 255-type edwards_curve_dh() :: x25519 | x448 . 256 257-type edwards_curve_ed() :: ed25519 | ed448 . 258 259%%% 260-type block_cipher_with_iv() :: cbc_cipher() 261 | cfb_cipher() 262 | aes_cbc128 263 | aes_cbc256 264 | aes_ige256 265 | blowfish_ofb64 266 | des3_cbf % cfb misspelled 267 | des_ede3 268 | rc2_cbc . 269 270-type cbc_cipher() :: des_cbc | des3_cbc | aes_cbc | blowfish_cbc . 271-type aead_cipher() :: aes_gcm | aes_ccm | chacha20_poly1305 . 272-type cfb_cipher() :: aes_cfb128 | aes_cfb8 | blowfish_cfb64 | des3_cfb | des_cfb . 273 274-type block_cipher_without_iv() :: ecb_cipher() . 275-type ecb_cipher() :: des_ecb | blowfish_ecb | aes_ecb . 276 277-type key() :: iodata(). 278-type des3_key() :: [key()]. 279 280%%% 281-type rsa_digest_type() :: sha1() | sha2() | md5 | ripemd160 . 282-type dss_digest_type() :: sha1() | sha2() . 283-type ecdsa_digest_type() :: sha1() | sha2() . 284 285-type sha1() :: sha . 286-type sha2() :: sha224 | sha256 | sha384 | sha512 . 287-type sha3() :: sha3_224 | sha3_256 | sha3_384 | sha3_512 . 288 289-type compatibility_only_hash() :: md5 | md4 . 290 291-type crypto_integer() :: binary() | integer(). 292 293-compile(no_native). 294-on_load(on_load/0). 295-define(CRYPTO_NIF_VSN,302). 296 297-define(nif_stub,nif_stub_error(?LINE)). 298nif_stub_error(Line) -> 299 erlang:nif_error({nif_not_loaded,module,?MODULE,line,Line}). 300 301%%-------------------------------------------------------------------- 302%%% API 303%%-------------------------------------------------------------------- 304%% Crypto app version history: 305%% (no version): Driver implementation 306%% 2.0 : NIF implementation, requires OTP R14 307 308%% When generating documentation from crypto.erl, the macro ?CRYPTO_VSN is not defined. 309%% That causes the doc generation to stop... 310-ifndef(CRYPTO_VSN). 311-define(CRYPTO_VSN, "??"). 312-endif. 313version() -> ?CRYPTO_VSN. 314 315-spec start() -> ok | {error, Reason::term()}. 316start() -> 317 application:start(crypto). 318 319-spec stop() -> ok | {error, Reason::term()}. 320stop() -> 321 application:stop(crypto). 322 323-spec supports() -> [Support] 324 when Support :: {hashs, Hashs} 325 | {ciphers, Ciphers} 326 | {public_keys, PKs} 327 | {macs, Macs} 328 | {curves, Curves} 329 | {rsa_opts, RSAopts}, 330 Hashs :: [sha1() | sha2() | sha3() | ripemd160 | compatibility_only_hash()], 331 Ciphers :: [stream_cipher() 332 | block_cipher_with_iv() | block_cipher_without_iv() 333 | aead_cipher() 334 ], 335 PKs :: [rsa | dss | ecdsa | dh | ecdh | ec_gf2m], 336 Macs :: [hmac | cmac | poly1305], 337 Curves :: [ec_named_curve() | edwards_curve_dh() | edwards_curve_ed()], 338 RSAopts :: [rsa_sign_verify_opt() | rsa_opt()] . 339supports()-> 340 {Hashs, PubKeys, Ciphers, Macs, Curves, RsaOpts} = algorithms(), 341 [{hashs, Hashs}, 342 {ciphers, Ciphers}, 343 {public_keys, PubKeys}, 344 {macs, Macs}, 345 {curves, Curves}, 346 {rsa_opts, RsaOpts} 347 ]. 348 349-spec info_lib() -> [{Name,VerNum,VerStr}] when Name :: binary(), 350 VerNum :: integer(), 351 VerStr :: binary() . 352info_lib() -> ?nif_stub. 353 354-spec info_fips() -> not_supported | not_enabled | enabled. 355 356info_fips() -> ?nif_stub. 357 358-spec enable_fips_mode(Enable) -> Result when Enable :: boolean(), 359 Result :: boolean(). 360enable_fips_mode(_) -> ?nif_stub. 361 362%%%================================================================ 363%%% 364%%% Compare in constant time 365%%% 366%%%================================================================ 367 368%%% Candidate for a NIF 369 370equal_const_time(X1, X2) -> 371 equal_const_time(X1, X2, true). 372 373 374equal_const_time(<<B1,R1/binary>>, <<B2,R2/binary>>, Truth) -> 375 equal_const_time(R1, R2, Truth and (B1 == B2)); 376equal_const_time(<<_,R1/binary>>, <<>>, Truth) -> 377 equal_const_time(R1, <<>>, Truth and false); 378equal_const_time(<<>>, <<>>, Truth) -> 379 Truth; 380 381equal_const_time([H1|T1], [H2|T2], Truth) -> 382 equal_const_time(T1, T2, Truth and (H1 == H2)); 383equal_const_time([_|T1], [], Truth) -> 384 equal_const_time(T1, [], Truth and false); 385equal_const_time([], [], Truth) -> 386 Truth; 387 388equal_const_time(_, _, _) -> 389 false. 390 391%%%================================================================ 392%%% 393%%% Hashing 394%%% 395%%%================================================================ 396 397-define(HASH_HASH_ALGORITHM, sha1() | sha2() | sha3() | ripemd160 | compatibility_only_hash() ). 398 399-spec hash(Type, Data) -> Digest when Type :: ?HASH_HASH_ALGORITHM, 400 Data :: iodata(), 401 Digest :: binary(). 402hash(Type, Data) -> 403 Data1 = iolist_to_binary(Data), 404 MaxBytes = max_bytes(), 405 hash(Type, Data1, erlang:byte_size(Data1), MaxBytes). 406 407-opaque hash_state() :: reference(). 408 409-spec hash_init(Type) -> State when Type :: ?HASH_HASH_ALGORITHM, 410 State :: hash_state(). 411hash_init(Type) -> 412 notsup_to_error(hash_init_nif(Type)). 413 414-spec hash_update(State, Data) -> NewState when State :: hash_state(), 415 NewState :: hash_state(), 416 Data :: iodata() . 417hash_update(Context, Data) -> 418 Data1 = iolist_to_binary(Data), 419 MaxBytes = max_bytes(), 420 hash_update(Context, Data1, erlang:byte_size(Data1), MaxBytes). 421 422-spec hash_final(State) -> Digest when State :: hash_state(), 423 Digest :: binary(). 424hash_final(Context) -> 425 notsup_to_error(hash_final_nif(Context)). 426 427%%%================================================================ 428%%% 429%%% MACs (Message Authentication Codes) 430%%% 431%%%================================================================ 432 433%%%---- HMAC 434 435-define(HMAC_HASH_ALGORITHM, sha1() | sha2() | sha3() | compatibility_only_hash()). 436 437%%%---- hmac/3,4 438 439-spec hmac(Type, Key, Data) -> 440 Mac when Type :: ?HMAC_HASH_ALGORITHM, 441 Key :: iodata(), 442 Data :: iodata(), 443 Mac :: binary() . 444hmac(Type, Key, Data) -> 445 Data1 = iolist_to_binary(Data), 446 hmac(Type, Key, Data1, undefined, erlang:byte_size(Data1), max_bytes()). 447 448-spec hmac(Type, Key, Data, MacLength) -> 449 Mac when Type :: ?HMAC_HASH_ALGORITHM, 450 Key :: iodata(), 451 Data :: iodata(), 452 MacLength :: integer(), 453 Mac :: binary() . 454 455hmac(Type, Key, Data, MacLength) -> 456 Data1 = iolist_to_binary(Data), 457 hmac(Type, Key, Data1, MacLength, erlang:byte_size(Data1), max_bytes()). 458 459%%%---- hmac_init, hamc_update, hmac_final 460 461-opaque hmac_state() :: binary(). 462 463-spec hmac_init(Type, Key) -> 464 State when Type :: ?HMAC_HASH_ALGORITHM, 465 Key :: iodata(), 466 State :: hmac_state() . 467hmac_init(Type, Key) -> 468 notsup_to_error(hmac_init_nif(Type, Key)). 469 470%%%---- hmac_update 471 472-spec hmac_update(State, Data) -> NewState when Data :: iodata(), 473 State :: hmac_state(), 474 NewState :: hmac_state(). 475hmac_update(State, Data0) -> 476 Data = iolist_to_binary(Data0), 477 hmac_update(State, Data, erlang:byte_size(Data), max_bytes()). 478 479%%%---- hmac_final 480 481-spec hmac_final(State) -> Mac when State :: hmac_state(), 482 Mac :: binary(). 483hmac_final(Context) -> 484 notsup_to_error(hmac_final_nif(Context)). 485 486-spec hmac_final_n(State, HashLen) -> Mac when State :: hmac_state(), 487 HashLen :: integer(), 488 Mac :: binary(). 489hmac_final_n(Context, HashLen) -> 490 notsup_to_error(hmac_final_nif(Context, HashLen)). 491 492%%%---- CMAC 493 494-define(CMAC_CIPHER_ALGORITHM, cbc_cipher() | cfb_cipher() | blowfish_cbc | des_ede3 | rc2_cbc ). 495 496-spec cmac(Type, Key, Data) -> 497 Mac when Type :: ?CMAC_CIPHER_ALGORITHM, 498 Key :: iodata(), 499 Data :: iodata(), 500 Mac :: binary(). 501cmac(Type, Key, Data) -> 502 notsup_to_error(cmac_nif(Type, Key, Data)). 503 504-spec cmac(Type, Key, Data, MacLength) -> 505 Mac when Type :: ?CMAC_CIPHER_ALGORITHM, 506 Key :: iodata(), 507 Data :: iodata(), 508 MacLength :: integer(), 509 Mac :: binary(). 510cmac(Type, Key, Data, MacLength) -> 511 erlang:binary_part(cmac(Type, Key, Data), 0, MacLength). 512 513%%%---- POLY1305 514 515-spec poly1305(iodata(), iodata()) -> Mac when Mac :: binary(). 516 517poly1305(Key, Data) -> 518 poly1305_nif(Key, Data). 519 520%%%================================================================ 521%%% 522%%% Encrypt/decrypt 523%%% 524%%%================================================================ 525 526%%%---- Block ciphers 527 528-spec block_encrypt(Type::block_cipher_with_iv(), Key::key()|des3_key(), Ivec::binary(), PlainText::iodata()) -> binary(); 529 (Type::aead_cipher(), Key::iodata(), Ivec::binary(), {AAD::binary(), PlainText::iodata()}) -> 530 {binary(), binary()}; 531 (aes_gcm | aes_ccm, Key::iodata(), Ivec::binary(), {AAD::binary(), PlainText::iodata(), TagLength::1..16}) -> 532 {binary(), binary()}. 533 534block_encrypt(Type, Key, Ivec, PlainText) when Type =:= des_cbc; 535 Type =:= des_cfb; 536 Type =:= blowfish_cbc; 537 Type =:= blowfish_cfb64; 538 Type =:= blowfish_ofb64; 539 Type =:= aes_cbc128; 540 Type =:= aes_cfb8; 541 Type =:= aes_cfb128; 542 Type =:= aes_cbc256; 543 Type =:= aes_cbc; 544 Type =:= rc2_cbc -> 545 notsup_to_error(block_crypt_nif(Type, Key, Ivec, PlainText, true)); 546block_encrypt(Type, Key0, Ivec, PlainText) when Type =:= des3_cbc; 547 Type =:= des_ede3 -> 548 Key = check_des3_key(Key0), 549 notsup_to_error(block_crypt_nif(des_ede3_cbc, Key, Ivec, PlainText, true)); 550block_encrypt(des3_cbf, Key0, Ivec, PlainText) -> % cfb misspelled 551 Key = check_des3_key(Key0), 552 notsup_to_error(block_crypt_nif(des_ede3_cbf, Key, Ivec, PlainText, true)); 553block_encrypt(des3_cfb, Key0, Ivec, PlainText) -> 554 Key = check_des3_key(Key0), 555 notsup_to_error(block_crypt_nif(des_ede3_cfb, Key, Ivec, PlainText, true)); 556block_encrypt(aes_ige256, Key, Ivec, PlainText) -> 557 notsup_to_error(aes_ige_crypt_nif(Key, Ivec, PlainText, true)); 558block_encrypt(Type, Key, Ivec, {AAD, PlainText}) when Type =:= aes_gcm; 559 Type =:= aes_ccm -> 560 aead_encrypt(Type, Key, Ivec, AAD, PlainText); 561block_encrypt(Type, Key, Ivec, {AAD, PlainText, TagLength}) when Type =:= aes_gcm; 562 Type =:= aes_ccm -> 563 aead_encrypt(Type, Key, Ivec, AAD, PlainText, TagLength); 564block_encrypt(chacha20_poly1305=Type, Key, Ivec, {AAD, PlainText}) -> 565 aead_encrypt(Type, Key, Ivec, AAD, PlainText, 16). 566 567 568-spec block_decrypt(Type::block_cipher_with_iv(), Key::key()|des3_key(), Ivec::binary(), Data::iodata()) -> binary(); 569 (Type::aead_cipher(), Key::iodata(), Ivec::binary(), 570 {AAD::binary(), Data::iodata(), Tag::binary()}) -> binary() | error. 571block_decrypt(Type, Key, Ivec, Data) when Type =:= des_cbc; 572 Type =:= des_cfb; 573 Type =:= blowfish_cbc; 574 Type =:= blowfish_cfb64; 575 Type =:= blowfish_ofb64; 576 Type =:= aes_cbc; 577 Type =:= aes_cbc128; 578 Type =:= aes_cfb8; 579 Type =:= aes_cfb128; 580 Type =:= aes_cbc256; 581 Type =:= rc2_cbc -> 582 notsup_to_error(block_crypt_nif(Type, Key, Ivec, Data, false)); 583block_decrypt(Type, Key0, Ivec, Data) when Type =:= des3_cbc; 584 Type =:= des_ede3 -> 585 Key = check_des3_key(Key0), 586 notsup_to_error(block_crypt_nif(des_ede3_cbc, Key, Ivec, Data, false)); 587block_decrypt(des3_cbf, Key0, Ivec, Data) -> % cfb misspelled 588 Key = check_des3_key(Key0), 589 notsup_to_error(block_crypt_nif(des_ede3_cbf, Key, Ivec, Data, false)); 590block_decrypt(des3_cfb, Key0, Ivec, Data) -> 591 Key = check_des3_key(Key0), 592 notsup_to_error(block_crypt_nif(des_ede3_cfb, Key, Ivec, Data, false)); 593block_decrypt(aes_ige256, Key, Ivec, Data) -> 594 notsup_to_error(aes_ige_crypt_nif(Key, Ivec, Data, false)); 595block_decrypt(Type, Key, Ivec, {AAD, Data, Tag}) when Type =:= aes_gcm; 596 Type =:= aes_ccm; 597 Type =:= chacha20_poly1305 -> 598 aead_decrypt(Type, Key, Ivec, AAD, Data, Tag). 599 600 601-spec block_encrypt(Type::block_cipher_without_iv(), Key::key(), PlainText::iodata()) -> binary(). 602 603block_encrypt(Type, Key, PlainText) -> 604 notsup_to_error(block_crypt_nif(Type, Key, PlainText, true)). 605 606 607-spec block_decrypt(Type::block_cipher_without_iv(), Key::key(), Data::iodata()) -> binary(). 608 609block_decrypt(Type, Key, Data) -> 610 notsup_to_error(block_crypt_nif(Type, Key, Data, false)). 611 612 613-spec next_iv(Type:: cbc_cipher(), Data) -> NextIVec when % Type :: cbc_cipher(), %des_cbc | des3_cbc | aes_cbc | aes_ige, 614 Data :: iodata(), 615 NextIVec :: binary(). 616next_iv(Type, Data) when is_binary(Data) -> 617 IVecSize = case Type of 618 des_cbc -> 8; 619 des3_cbc -> 8; 620 aes_cbc -> 16; 621 aes_ige -> 32 622 end, 623 {_, IVec} = split_binary(Data, size(Data) - IVecSize), 624 IVec; 625next_iv(Type, Data) when is_list(Data) -> 626 next_iv(Type, list_to_binary(Data)). 627 628-spec next_iv(des_cfb, Data, IVec) -> NextIVec when Data :: iodata(), 629 IVec :: binary(), 630 NextIVec :: binary(). 631 632next_iv(des_cfb, Data, IVec) -> 633 IVecAndData = list_to_binary([IVec, Data]), 634 {_, NewIVec} = split_binary(IVecAndData, byte_size(IVecAndData) - 8), 635 NewIVec; 636next_iv(Type, Data, _Ivec) -> 637 next_iv(Type, Data). 638 639%%%---- Stream ciphers 640 641-opaque stream_state() :: {stream_cipher(), reference()}. 642 643-type stream_cipher() :: rc4 | aes_ctr | chacha20 . 644 645-spec stream_init(Type, Key, IVec) -> State when Type :: aes_ctr | chacha20, 646 Key :: iodata(), 647 IVec :: binary(), 648 State :: stream_state() . 649stream_init(aes_ctr, Key, Ivec) -> 650 {aes_ctr, aes_ctr_stream_init(Key, Ivec)}; 651stream_init(chacha20, Key, Ivec) -> 652 {chacha20, chacha20_stream_init(Key,Ivec)}. 653 654-spec stream_init(Type, Key) -> State when Type :: rc4, 655 Key :: iodata(), 656 State :: stream_state() . 657stream_init(rc4, Key) -> 658 {rc4, notsup_to_error(rc4_set_key(Key))}. 659 660-spec stream_encrypt(State, PlainText) -> {NewState, CipherText} 661 when State :: stream_state(), 662 PlainText :: iodata(), 663 NewState :: stream_state(), 664 CipherText :: iodata() . 665stream_encrypt(State, Data0) -> 666 Data = iolist_to_binary(Data0), 667 MaxByts = max_bytes(), 668 stream_crypt(fun do_stream_encrypt/2, State, Data, erlang:byte_size(Data), MaxByts, []). 669 670-spec stream_decrypt(State, CipherText) -> {NewState, PlainText} 671 when State :: stream_state(), 672 CipherText :: iodata(), 673 NewState :: stream_state(), 674 PlainText :: iodata() . 675stream_decrypt(State, Data0) -> 676 Data = iolist_to_binary(Data0), 677 MaxByts = max_bytes(), 678 stream_crypt(fun do_stream_decrypt/2, State, Data, erlang:byte_size(Data), MaxByts, []). 679 680 681%%%================================================================ 682%%% 683%%% RAND - pseudo random numbers using RN_ and BN_ functions in crypto lib 684%%% 685%%%================================================================ 686-type rand_cache_seed() :: 687 nonempty_improper_list(non_neg_integer(), binary()). 688 689-spec strong_rand_bytes(N::non_neg_integer()) -> binary(). 690strong_rand_bytes(Bytes) -> 691 case strong_rand_bytes_nif(Bytes) of 692 false -> erlang:error(low_entropy); 693 Bin -> Bin 694 end. 695strong_rand_bytes_nif(_Bytes) -> ?nif_stub. 696 697 698-spec rand_seed() -> rand:state(). 699rand_seed() -> 700 rand:seed(rand_seed_s()). 701 702-spec rand_seed_s() -> rand:state(). 703rand_seed_s() -> 704 rand_seed_alg_s(?MODULE). 705 706-spec rand_seed_alg(Alg :: atom()) -> 707 {rand:alg_handler(), 708 atom() | rand_cache_seed()}. 709rand_seed_alg(Alg) -> 710 rand:seed(rand_seed_alg_s(Alg)). 711 712-define(CRYPTO_CACHE_BITS, 56). 713-spec rand_seed_alg_s(Alg :: atom()) -> 714 {rand:alg_handler(), 715 atom() | rand_cache_seed()}. 716rand_seed_alg_s(?MODULE) -> 717 {#{ type => ?MODULE, 718 bits => 64, 719 next => fun ?MODULE:rand_plugin_next/1, 720 uniform => fun ?MODULE:rand_plugin_uniform/1, 721 uniform_n => fun ?MODULE:rand_plugin_uniform/2}, 722 no_seed}; 723rand_seed_alg_s(crypto_cache) -> 724 CacheBits = ?CRYPTO_CACHE_BITS, 725 EnvCacheSize = 726 application:get_env( 727 crypto, rand_cache_size, CacheBits * 16), % Cache 16 * 8 words 728 Bytes = (CacheBits + 7) div 8, 729 CacheSize = 730 case ((EnvCacheSize + (Bytes - 1)) div Bytes) * Bytes of 731 Sz when is_integer(Sz), Bytes =< Sz -> 732 Sz; 733 _ -> 734 Bytes 735 end, 736 {#{ type => crypto_cache, 737 bits => CacheBits, 738 next => fun ?MODULE:rand_cache_plugin_next/1}, 739 {CacheBits, CacheSize, <<>>}}. 740 741rand_plugin_next(Seed) -> 742 {bytes_to_integer(strong_rand_range(1 bsl 64)), Seed}. 743 744rand_plugin_uniform(State) -> 745 {strong_rand_float(), State}. 746 747rand_plugin_uniform(Max, State) -> 748 {bytes_to_integer(strong_rand_range(Max)) + 1, State}. 749 750rand_cache_plugin_next({CacheBits, CacheSize, <<>>}) -> 751 rand_cache_plugin_next( 752 {CacheBits, CacheSize, strong_rand_bytes(CacheSize)}); 753rand_cache_plugin_next({CacheBits, CacheSize, Cache}) -> 754 <<I:CacheBits, NewCache/binary>> = Cache, 755 {I, {CacheBits, CacheSize, NewCache}}. 756 757strong_rand_range(Range) when is_integer(Range), Range > 0 -> 758 BinRange = int_to_bin(Range), 759 strong_rand_range(BinRange); 760strong_rand_range(BinRange) when is_binary(BinRange) -> 761 case strong_rand_range_nif(BinRange) of 762 false -> 763 erlang:error(low_entropy); 764 <<BinResult/binary>> -> 765 BinResult 766 end. 767strong_rand_range_nif(_BinRange) -> ?nif_stub. 768 769strong_rand_float() -> 770 WholeRange = strong_rand_range(1 bsl 53), 771 ?HALF_DBL_EPSILON * bytes_to_integer(WholeRange). 772 773-spec rand_uniform(crypto_integer(), crypto_integer()) -> 774 crypto_integer(). 775rand_uniform(From, To) when is_binary(From), is_binary(To) -> 776 case rand_uniform_nif(From,To) of 777 <<Len:32/integer, MSB, Rest/binary>> when MSB > 127 -> 778 <<(Len + 1):32/integer, 0, MSB, Rest/binary>>; 779 Whatever -> 780 Whatever 781 end; 782rand_uniform(From,To) when is_integer(From),is_integer(To) -> 783 if From < 0 -> 784 rand_uniform_pos(0, To - From) + From; 785 true -> 786 rand_uniform_pos(From, To) 787 end. 788 789rand_uniform_pos(From,To) when From < To -> 790 BinFrom = mpint(From), 791 BinTo = mpint(To), 792 case rand_uniform(BinFrom, BinTo) of 793 Result when is_binary(Result) -> 794 erlint(Result); 795 Other -> 796 Other 797 end; 798rand_uniform_pos(_,_) -> 799 error(badarg). 800 801rand_uniform_nif(_From,_To) -> ?nif_stub. 802 803 804-spec rand_seed(binary()) -> ok. 805rand_seed(Seed) when is_binary(Seed) -> 806 rand_seed_nif(Seed). 807 808rand_seed_nif(_Seed) -> ?nif_stub. 809 810%%%================================================================ 811%%% 812%%% Sign/verify 813%%% 814%%%================================================================ 815-type pk_sign_verify_algs() :: rsa | dss | ecdsa | eddsa . 816 817-type pk_sign_verify_opts() :: [ rsa_sign_verify_opt() ] . 818 819-type rsa_sign_verify_opt() :: {rsa_padding, rsa_sign_verify_padding()} 820 | {rsa_pss_saltlen, integer()} . 821 822-type rsa_sign_verify_padding() :: rsa_pkcs1_padding | rsa_pkcs1_pss_padding 823 | rsa_x931_padding | rsa_no_padding 824 . 825 826 827%%%---------------------------------------------------------------- 828%%% Sign 829 830-spec sign(Algorithm, DigestType, Msg, Key) 831 -> Signature 832 when Algorithm :: pk_sign_verify_algs(), 833 DigestType :: rsa_digest_type() 834 | dss_digest_type() 835 | ecdsa_digest_type(), 836 Msg :: binary() | {digest,binary()}, 837 Key :: rsa_private() 838 | dss_private() 839 | [ecdsa_private() | ecdsa_params()] 840 | [eddsa_private() | eddsa_params()] 841 | engine_key_ref(), 842 Signature :: binary() . 843 844sign(Algorithm, Type, Data, Key) -> 845 sign(Algorithm, Type, Data, Key, []). 846 847 848-spec sign(Algorithm, DigestType, Msg, Key, Options) 849 -> Signature 850 when Algorithm :: pk_sign_verify_algs(), 851 DigestType :: rsa_digest_type() 852 | dss_digest_type() 853 | ecdsa_digest_type() 854 | none, 855 Msg :: binary() | {digest,binary()}, 856 Key :: rsa_private() 857 | dss_private() 858 | [ecdsa_private() | ecdsa_params()] 859 | [eddsa_private() | eddsa_params()] 860 | engine_key_ref(), 861 Options :: pk_sign_verify_opts(), 862 Signature :: binary() . 863 864sign(Algorithm0, Type0, Data, Key, Options) -> 865 {Algorithm, Type} = sign_verify_compatibility(Algorithm0, Type0, Data), 866 case pkey_sign_nif(Algorithm, Type, Data, format_pkey(Algorithm, Key), Options) of 867 error -> erlang:error(badkey, [Algorithm, Type, Data, Key, Options]); 868 notsup -> erlang:error(notsup); 869 Signature -> Signature 870 end. 871 872pkey_sign_nif(_Algorithm, _Type, _Digest, _Key, _Options) -> ?nif_stub. 873 874%%%---------------------------------------------------------------- 875%%% Verify 876 877-spec verify(Algorithm, DigestType, Msg, Signature, Key) 878 -> Result 879 when Algorithm :: pk_sign_verify_algs(), 880 DigestType :: rsa_digest_type() 881 | dss_digest_type() 882 | ecdsa_digest_type() 883 | none, 884 Msg :: binary() | {digest,binary()}, 885 Signature :: binary(), 886 Key :: rsa_public() 887 | dss_public() 888 | [ecdsa_public() | ecdsa_params()] 889 | [eddsa_public() | eddsa_params()] 890 | engine_key_ref(), 891 Result :: boolean(). 892 893verify(Algorithm, Type, Data, Signature, Key) -> 894 verify(Algorithm, Type, Data, Signature, Key, []). 895 896-spec verify(Algorithm, DigestType, Msg, Signature, Key, Options) 897 -> Result 898 when Algorithm :: pk_sign_verify_algs(), 899 DigestType :: rsa_digest_type() 900 | dss_digest_type() 901 | ecdsa_digest_type(), 902 Msg :: binary() | {digest,binary()}, 903 Signature :: binary(), 904 Key :: rsa_public() 905 | dss_public() 906 | [ecdsa_public() | ecdsa_params()] 907 | [eddsa_public() | eddsa_params()] 908 | engine_key_ref(), 909 Options :: pk_sign_verify_opts(), 910 Result :: boolean(). 911 912verify(Algorithm0, Type0, Data, Signature, Key, Options) -> 913 {Algorithm, Type} = sign_verify_compatibility(Algorithm0, Type0, Data), 914 case pkey_verify_nif(Algorithm, Type, Data, Signature, format_pkey(Algorithm, Key), Options) of 915 notsup -> erlang:error(notsup); 916 Boolean -> Boolean 917 end. 918 919pkey_verify_nif(_Algorithm, _Type, _Data, _Signature, _Key, _Options) -> ?nif_stub. 920 921%% Backwards compatible: 922sign_verify_compatibility(dss, none, Digest) -> 923 {sha, {digest, Digest}}; 924sign_verify_compatibility(Algorithm0, Type0, _Digest) -> 925 {Algorithm0, Type0}. 926 927%%%================================================================ 928%%% 929%%% Public/private encrypt/decrypt 930%%% 931%%% Only rsa works so far (although ecdsa | dss should do it) 932%%%================================================================ 933-type pk_encrypt_decrypt_algs() :: rsa . 934 935-type pk_encrypt_decrypt_opts() :: [rsa_opt()] | rsa_compat_opts(). 936 937-type rsa_compat_opts() :: [{rsa_pad, rsa_padding()}] 938 | rsa_padding() . 939 940-type rsa_padding() :: rsa_pkcs1_padding 941 | rsa_pkcs1_oaep_padding 942 | rsa_sslv23_padding 943 | rsa_x931_padding 944 | rsa_no_padding. 945 946-type rsa_opt() :: {rsa_padding, rsa_padding()} 947 | {signature_md, atom()} 948 | {rsa_mgf1_md, sha} 949 | {rsa_oaep_label, binary()} 950 | {rsa_oaep_md, sha} . 951 952%%%---- Encrypt with public key 953 954-spec public_encrypt(Algorithm, PlainText, PublicKey, Options) -> 955 CipherText when Algorithm :: pk_encrypt_decrypt_algs(), 956 PlainText :: binary(), 957 PublicKey :: rsa_public() | engine_key_ref(), 958 Options :: pk_encrypt_decrypt_opts(), 959 CipherText :: binary(). 960public_encrypt(Algorithm, PlainText, PublicKey, Options) -> 961 pkey_crypt(Algorithm, PlainText, PublicKey, Options, false, true). 962 963%%%---- Decrypt with private key 964 965-spec private_decrypt(Algorithm, CipherText, PrivateKey, Options) -> 966 PlainText when Algorithm :: pk_encrypt_decrypt_algs(), 967 CipherText :: binary(), 968 PrivateKey :: rsa_private() | engine_key_ref(), 969 Options :: pk_encrypt_decrypt_opts(), 970 PlainText :: binary() . 971private_decrypt(Algorithm, CipherText, PrivateKey, Options) -> 972 pkey_crypt(Algorithm, CipherText, PrivateKey, Options, true, false). 973 974%%%---- Encrypt with private key 975 976-spec private_encrypt(Algorithm, PlainText, PrivateKey, Options) -> 977 CipherText when Algorithm :: pk_encrypt_decrypt_algs(), 978 PlainText :: binary(), 979 PrivateKey :: rsa_private() | engine_key_ref(), 980 Options :: pk_encrypt_decrypt_opts(), 981 CipherText :: binary(). 982private_encrypt(Algorithm, PlainText, PrivateKey, Options) -> 983 pkey_crypt(Algorithm, PlainText, PrivateKey, Options, true, true). 984 985%%%---- Decrypt with public key 986 987-spec public_decrypt(Algorithm, CipherText, PublicKey, Options) -> 988 PlainText when Algorithm :: pk_encrypt_decrypt_algs(), 989 CipherText :: binary(), 990 PublicKey :: rsa_public() | engine_key_ref(), 991 Options :: pk_encrypt_decrypt_opts(), 992 PlainText :: binary() . 993public_decrypt(Algorithm, CipherText, PublicKey, Options) -> 994 pkey_crypt(Algorithm, CipherText, PublicKey, Options, false, false). 995 996%%%---- Call the nif, but fix a compatibility issue first 997 998%% Backwards compatible (rsa_pad -> rsa_padding is handled by the pkey_crypt_nif): 999pkey_crypt(rsa, Text, Key, Padding, PubPriv, EncDec) when is_atom(Padding) -> 1000 pkey_crypt(rsa, Text, Key, [{rsa_padding, Padding}], PubPriv, EncDec); 1001 1002pkey_crypt(Alg, Text, Key, Options, PubPriv, EncDec) -> 1003 case pkey_crypt_nif(Alg, Text, format_pkey(Alg,Key), Options, PubPriv, EncDec) of 1004 error when EncDec==true -> erlang:error(encrypt_failed, [Alg, Text, Key, Options]); 1005 error when EncDec==false -> erlang:error(decrypt_failed, [Alg, Text, Key, Options]); 1006 notsup -> erlang:error(notsup); 1007 Out -> Out 1008 end. 1009 1010pkey_crypt_nif(_Algorithm, _In, _Key, _Options, _IsPrivate, _IsEncrypt) -> ?nif_stub. 1011 1012%%%================================================================ 1013%%% 1014%%% 1015%%% 1016%%%================================================================ 1017 1018-spec generate_key(Type, Params) 1019 -> {PublicKey, PrivKeyOut} 1020 when Type :: dh | ecdh | rsa | srp, 1021 PublicKey :: dh_public() | ecdh_public() | rsa_public() | srp_public(), 1022 PrivKeyOut :: dh_private() | ecdh_private() | rsa_private() | {srp_public(),srp_private()}, 1023 Params :: dh_params() | ecdh_params() | rsa_params() | srp_gen_params() 1024 . 1025generate_key(Type, Params) -> 1026 generate_key(Type, Params, undefined). 1027 1028-spec generate_key(Type, Params, PrivKeyIn) 1029 -> {PublicKey, PrivKeyOut} 1030 when Type :: dh | ecdh | rsa | srp, 1031 PublicKey :: dh_public() | ecdh_public() | rsa_public() | srp_public(), 1032 PrivKeyIn :: undefined | dh_private() | ecdh_private() | rsa_private() | {srp_public(),srp_private()}, 1033 PrivKeyOut :: dh_private() | ecdh_private() | rsa_private() | {srp_public(),srp_private()}, 1034 Params :: dh_params() | ecdh_params() | rsa_params() | srp_comp_params() 1035 . 1036 1037generate_key(dh, DHParameters0, PrivateKey) -> 1038 {DHParameters, Len} = 1039 case DHParameters0 of 1040 [P,G,L] -> {[P,G], L}; 1041 [P,G] -> {[P,G], 0} 1042 end, 1043 dh_generate_key_nif(ensure_int_as_bin(PrivateKey), 1044 map_ensure_int_as_bin(DHParameters), 1045 0, Len); 1046 1047generate_key(srp, {host, [Verifier, Generator, Prime, Version]}, PrivArg) 1048 when is_binary(Verifier), is_binary(Generator), is_binary(Prime), is_atom(Version) -> 1049 Private = case PrivArg of 1050 undefined -> strong_rand_bytes(32); 1051 _ -> ensure_int_as_bin(PrivArg) 1052 end, 1053 host_srp_gen_key(Private, Verifier, Generator, Prime, Version); 1054 1055generate_key(srp, {user, [Generator, Prime, Version]}, PrivateArg) 1056 when is_binary(Generator), is_binary(Prime), is_atom(Version) -> 1057 Private = case PrivateArg of 1058 undefined -> strong_rand_bytes(32); 1059 _ -> PrivateArg 1060 end, 1061 user_srp_gen_key(Private, Generator, Prime); 1062 1063generate_key(rsa, {ModulusSize, PublicExponent}, undefined) -> 1064 case rsa_generate_key_nif(ModulusSize, ensure_int_as_bin(PublicExponent)) of 1065 error -> 1066 erlang:error(computation_failed, 1067 [rsa,{ModulusSize,PublicExponent}]); 1068 Private -> 1069 {lists:sublist(Private, 2), Private} 1070 end; 1071 1072 1073generate_key(ecdh, Curve, undefined) when Curve == x448 ; 1074 Curve == x25519 -> 1075 evp_generate_key_nif(Curve); 1076generate_key(ecdh, Curve, PrivKey) -> 1077 ec_key_generate(nif_curve_params(Curve), ensure_int_as_bin(PrivKey)). 1078 1079 1080evp_generate_key_nif(_Curve) -> ?nif_stub. 1081 1082 1083-spec compute_key(Type, OthersPublicKey, MyPrivateKey, Params) 1084 -> SharedSecret 1085 when Type :: dh | ecdh | srp, 1086 SharedSecret :: binary(), 1087 OthersPublicKey :: dh_public() | ecdh_public() | srp_public(), 1088 MyPrivateKey :: dh_private() | ecdh_private() | {srp_public(),srp_private()}, 1089 Params :: dh_params() | ecdh_params() | srp_comp_params() 1090 . 1091 1092compute_key(dh, OthersPublicKey, MyPrivateKey, DHParameters) -> 1093 case dh_compute_key_nif(ensure_int_as_bin(OthersPublicKey), 1094 ensure_int_as_bin(MyPrivateKey), 1095 map_ensure_int_as_bin(DHParameters)) of 1096 error -> erlang:error(computation_failed, 1097 [dh,OthersPublicKey,MyPrivateKey,DHParameters]); 1098 Ret -> Ret 1099 end; 1100 1101compute_key(srp, HostPublic, {UserPublic, UserPrivate}, 1102 {user, [DerivedKey, Prime, Generator, Version | ScramblerArg]}) when 1103 is_binary(Prime), 1104 is_binary(Generator), 1105 is_atom(Version) -> 1106 HostPubBin = ensure_int_as_bin(HostPublic), 1107 Multiplier = srp_multiplier(Version, Generator, Prime), 1108 Scrambler = case ScramblerArg of 1109 [] -> srp_scrambler(Version, ensure_int_as_bin(UserPublic), 1110 HostPubBin, Prime); 1111 [S] -> S 1112 end, 1113 notsup_to_error( 1114 srp_user_secret_nif(ensure_int_as_bin(UserPrivate), Scrambler, HostPubBin, 1115 Multiplier, Generator, DerivedKey, Prime)); 1116 1117compute_key(srp, UserPublic, {HostPublic, HostPrivate}, 1118 {host,[Verifier, Prime, Version | ScramblerArg]}) when 1119 is_binary(Verifier), 1120 is_binary(Prime), 1121 is_atom(Version) -> 1122 UserPubBin = ensure_int_as_bin(UserPublic), 1123 Scrambler = case ScramblerArg of 1124 [] -> srp_scrambler(Version, UserPubBin, ensure_int_as_bin(HostPublic), Prime); 1125 [S] -> S 1126 end, 1127 notsup_to_error( 1128 srp_host_secret_nif(Verifier, ensure_int_as_bin(HostPrivate), Scrambler, 1129 UserPubBin, Prime)); 1130 1131compute_key(ecdh, Others, My, Curve) when Curve == x448 ; 1132 Curve == x25519 -> 1133 evp_compute_key_nif(Curve, ensure_int_as_bin(Others), ensure_int_as_bin(My)); 1134 1135compute_key(ecdh, Others, My, Curve) -> 1136 ecdh_compute_key_nif(ensure_int_as_bin(Others), 1137 nif_curve_params(Curve), 1138 ensure_int_as_bin(My)). 1139 1140 1141evp_compute_key_nif(_Curve, _OthersBin, _MyBin) -> ?nif_stub. 1142 1143 1144%%%================================================================ 1145%%% 1146%%% XOR - xor to iolists and return a binary 1147%%% NB doesn't check that they are the same size, just concatenates 1148%%% them and sends them to the driver 1149%%% 1150%%%================================================================ 1151 1152-spec exor(iodata(), iodata()) -> binary(). 1153 1154exor(Bin1, Bin2) -> 1155 Data1 = iolist_to_binary(Bin1), 1156 Data2 = iolist_to_binary(Bin2), 1157 MaxBytes = max_bytes(), 1158 exor(Data1, Data2, erlang:byte_size(Data1), MaxBytes, []). 1159 1160 1161%%%================================================================ 1162%%% 1163%%% Exponentiation modulo 1164%%% 1165%%%================================================================ 1166 1167-spec mod_pow(N, P, M) -> Result when N :: binary() | integer(), 1168 P :: binary() | integer(), 1169 M :: binary() | integer(), 1170 Result :: binary() | error . 1171mod_pow(Base, Exponent, Prime) -> 1172 case mod_exp_nif(ensure_int_as_bin(Base), ensure_int_as_bin(Exponent), ensure_int_as_bin(Prime), 0) of 1173 <<0>> -> error; 1174 R -> R 1175 end. 1176 1177%%%====================================================================== 1178%%% 1179%%% Engine functions 1180%%% 1181%%%====================================================================== 1182 1183%%%---- Refering to keys stored in an engine: 1184-type key_id() :: string() | binary() . 1185-type password() :: string() | binary() . 1186 1187-type engine_key_ref() :: #{engine := engine_ref(), 1188 key_id := key_id(), 1189 password => password(), 1190 term() => term() 1191 }. 1192 1193%%%---- Commands: 1194-type engine_cmnd() :: {unicode:chardata(), unicode:chardata()}. 1195 1196%%---------------------------------------------------------------------- 1197%% Function: engine_get_all_methods/0 1198%%---------------------------------------------------------------------- 1199-type engine_method_type() :: engine_method_rsa | engine_method_dsa | engine_method_dh | 1200 engine_method_rand | engine_method_ecdh | engine_method_ecdsa | 1201 engine_method_ciphers | engine_method_digests | engine_method_store | 1202 engine_method_pkey_meths | engine_method_pkey_asn1_meths | 1203 engine_method_ec. 1204 1205-type engine_ref() :: term(). 1206 1207-spec engine_get_all_methods() -> Result when Result :: [engine_method_type()]. 1208engine_get_all_methods() -> 1209 notsup_to_error(engine_get_all_methods_nif()). 1210 1211%%---------------------------------------------------------------------- 1212%% Function: engine_load/3 1213%%---------------------------------------------------------------------- 1214-spec engine_load(EngineId, PreCmds, PostCmds) -> 1215 Result when EngineId::unicode:chardata(), 1216 PreCmds::[engine_cmnd()], 1217 PostCmds::[engine_cmnd()], 1218 Result :: {ok, Engine::engine_ref()} | {error, Reason::term()}. 1219engine_load(EngineId, PreCmds, PostCmds) when is_list(PreCmds), 1220 is_list(PostCmds) -> 1221 engine_load(EngineId, PreCmds, PostCmds, engine_get_all_methods()). 1222 1223%%---------------------------------------------------------------------- 1224%% Function: engine_load/4 1225%%---------------------------------------------------------------------- 1226-spec engine_load(EngineId, PreCmds, PostCmds, EngineMethods) -> 1227 Result when EngineId::unicode:chardata(), 1228 PreCmds::[engine_cmnd()], 1229 PostCmds::[engine_cmnd()], 1230 EngineMethods::[engine_method_type()], 1231 Result :: {ok, Engine::engine_ref()} | {error, Reason::term()}. 1232engine_load(EngineId, PreCmds, PostCmds, EngineMethods) when is_list(PreCmds), 1233 is_list(PostCmds) -> 1234 try 1235 ok = notsup_to_error(engine_load_dynamic_nif()), 1236 case notsup_to_error(engine_by_id_nif(ensure_bin_chardata(EngineId))) of 1237 {ok, Engine} -> 1238 engine_load_1(Engine, PreCmds, PostCmds, EngineMethods); 1239 {error, Error1} -> 1240 {error, Error1} 1241 end 1242 catch 1243 throw:Error2 -> 1244 Error2 1245 end. 1246 1247engine_load_1(Engine, PreCmds, PostCmds, EngineMethods) -> 1248 try 1249 ok = engine_nif_wrapper(engine_ctrl_cmd_strings_nif(Engine, ensure_bin_cmds(PreCmds), 0)), 1250 ok = engine_nif_wrapper(engine_init_nif(Engine)), 1251 engine_load_2(Engine, PostCmds, EngineMethods), 1252 {ok, Engine} 1253 catch 1254 throw:Error -> 1255 %% The engine couldn't initialise, release the structural reference 1256 ok = engine_free_nif(Engine), 1257 throw(Error); 1258 error:badarg -> 1259 %% For example bad argument list, release the structural reference 1260 ok = engine_free_nif(Engine), 1261 error(badarg) 1262 end. 1263 1264engine_load_2(Engine, PostCmds, EngineMethods) -> 1265 try 1266 ok = engine_nif_wrapper(engine_ctrl_cmd_strings_nif(Engine, ensure_bin_cmds(PostCmds), 0)), 1267 [ok = engine_nif_wrapper(engine_register_nif(Engine, engine_method_atom_to_int(Method))) || 1268 Method <- EngineMethods], 1269 ok 1270 catch 1271 throw:Error -> 1272 %% The engine registration failed, release the functional reference 1273 ok = engine_finish_nif(Engine), 1274 throw(Error) 1275 end. 1276 1277%%---------------------------------------------------------------------- 1278%% Function: engine_unload/1 1279%%---------------------------------------------------------------------- 1280-spec engine_unload(Engine) -> Result when Engine :: engine_ref(), 1281 Result :: ok | {error, Reason::term()}. 1282engine_unload(Engine) -> 1283 engine_unload(Engine, engine_get_all_methods()). 1284 1285-spec engine_unload(Engine, EngineMethods) -> Result when Engine :: engine_ref(), 1286 EngineMethods :: [engine_method_type()], 1287 Result :: ok | {error, Reason::term()}. 1288engine_unload(Engine, EngineMethods) -> 1289 try 1290 [ok = engine_nif_wrapper(engine_unregister_nif(Engine, engine_method_atom_to_int(Method))) || 1291 Method <- EngineMethods], 1292 %% Release the functional reference from engine_init_nif 1293 ok = engine_nif_wrapper(engine_finish_nif(Engine)), 1294 %% Release the structural reference from engine_by_id_nif 1295 ok = engine_nif_wrapper(engine_free_nif(Engine)) 1296 catch 1297 throw:Error -> 1298 Error 1299 end. 1300 1301%%---------------------------------------------------------------------- 1302%% Function: engine_by_id/1 1303%%---------------------------------------------------------------------- 1304-spec engine_by_id(EngineId) -> Result when EngineId :: unicode:chardata(), 1305 Result :: {ok, Engine::engine_ref()} | {error, Reason::term()} . 1306engine_by_id(EngineId) -> 1307 try 1308 notsup_to_error(engine_by_id_nif(ensure_bin_chardata(EngineId))) 1309 catch 1310 throw:Error -> 1311 Error 1312 end. 1313 1314%%---------------------------------------------------------------------- 1315%% Function: engine_add/1 1316%%---------------------------------------------------------------------- 1317-spec engine_add(Engine) -> Result when Engine :: engine_ref(), 1318 Result :: ok | {error, Reason::term()} . 1319engine_add(Engine) -> 1320 notsup_to_error(engine_add_nif(Engine)). 1321 1322%%---------------------------------------------------------------------- 1323%% Function: engine_remove/1 1324%%---------------------------------------------------------------------- 1325-spec engine_remove(Engine) -> Result when Engine :: engine_ref(), 1326 Result :: ok | {error, Reason::term()} . 1327engine_remove(Engine) -> 1328 notsup_to_error(engine_remove_nif(Engine)). 1329 1330%%---------------------------------------------------------------------- 1331%% Function: engine_get_id/1 1332%%---------------------------------------------------------------------- 1333-spec engine_get_id(Engine) -> EngineId when Engine :: engine_ref(), 1334 EngineId :: unicode:chardata(). 1335engine_get_id(Engine) -> 1336 notsup_to_error(engine_get_id_nif(Engine)). 1337 1338%%---------------------------------------------------------------------- 1339%% Function: engine_get_name/1 1340%%---------------------------------------------------------------------- 1341-spec engine_get_name(Engine) -> EngineName when Engine :: engine_ref(), 1342 EngineName :: unicode:chardata(). 1343engine_get_name(Engine) -> 1344 notsup_to_error(engine_get_name_nif(Engine)). 1345 1346%%---------------------------------------------------------------------- 1347%% Function: engine_list/0 1348%%---------------------------------------------------------------------- 1349-spec engine_list() -> Result when Result :: [EngineId::unicode:chardata()]. 1350engine_list() -> 1351 case notsup_to_error(engine_get_first_nif()) of 1352 {ok, <<>>} -> 1353 []; 1354 {ok, Engine} -> 1355 case notsup_to_error(engine_get_id_nif(Engine)) of 1356 <<>> -> 1357 engine_list(Engine, []); 1358 EngineId -> 1359 engine_list(Engine, [EngineId]) 1360 end 1361 end. 1362 1363engine_list(Engine0, IdList) -> 1364 case notsup_to_error(engine_get_next_nif(Engine0)) of 1365 {ok, <<>>} -> 1366 lists:reverse(IdList); 1367 {ok, Engine1} -> 1368 case notsup_to_error(engine_get_id_nif(Engine1)) of 1369 <<>> -> 1370 engine_list(Engine1, IdList); 1371 EngineId -> 1372 engine_list(Engine1, [EngineId |IdList]) 1373 end 1374 end. 1375 1376%%---------------------------------------------------------------------- 1377%% Function: engine_ctrl_cmd_string/3 1378%%---------------------------------------------------------------------- 1379-spec engine_ctrl_cmd_string(Engine, CmdName, CmdArg) -> 1380 Result when Engine::term(), 1381 CmdName::unicode:chardata(), 1382 CmdArg::unicode:chardata(), 1383 Result :: ok | {error, Reason::term()}. 1384engine_ctrl_cmd_string(Engine, CmdName, CmdArg) -> 1385 engine_ctrl_cmd_string(Engine, CmdName, CmdArg, false). 1386 1387%%---------------------------------------------------------------------- 1388%% Function: engine_ctrl_cmd_string/4 1389%%---------------------------------------------------------------------- 1390-spec engine_ctrl_cmd_string(Engine, CmdName, CmdArg, Optional) -> 1391 Result when Engine::term(), 1392 CmdName::unicode:chardata(), 1393 CmdArg::unicode:chardata(), 1394 Optional::boolean(), 1395 Result :: ok | {error, Reason::term()}. 1396engine_ctrl_cmd_string(Engine, CmdName, CmdArg, Optional) -> 1397 case engine_ctrl_cmd_strings_nif(Engine, 1398 ensure_bin_cmds([{CmdName, CmdArg}]), 1399 bool_to_int(Optional)) of 1400 ok -> 1401 ok; 1402 notsup -> 1403 erlang:error(notsup); 1404 {error, Error} -> 1405 {error, Error} 1406 end. 1407 1408%%---------------------------------------------------------------------- 1409%% Function: ensure_engine_loaded/2 1410%% Special version of load that only uses dynamic engine to load 1411%%---------------------------------------------------------------------- 1412-spec ensure_engine_loaded(EngineId, LibPath) -> 1413 Result when EngineId :: unicode:chardata(), 1414 LibPath :: unicode:chardata(), 1415 Result :: {ok, Engine::engine_ref()} | {error, Reason::term()}. 1416ensure_engine_loaded(EngineId, LibPath) -> 1417 ensure_engine_loaded(EngineId, LibPath, engine_get_all_methods()). 1418 1419%%---------------------------------------------------------------------- 1420%% Function: ensure_engine_loaded/3 1421%% Special version of load that only uses dynamic engine to load 1422%%---------------------------------------------------------------------- 1423-spec ensure_engine_loaded(EngineId, LibPath, EngineMethods) -> 1424 Result when EngineId :: unicode:chardata(), 1425 LibPath :: unicode:chardata(), 1426 EngineMethods :: [engine_method_type()], 1427 Result :: {ok, Engine::engine_ref()} | {error, Reason::term()}. 1428ensure_engine_loaded(EngineId, LibPath, EngineMethods) -> 1429 try 1430 List = crypto:engine_list(), 1431 case lists:member(EngineId, List) of 1432 true -> 1433 notsup_to_error(engine_by_id_nif(ensure_bin_chardata(EngineId))); 1434 false -> 1435 ok = notsup_to_error(engine_load_dynamic_nif()), 1436 case notsup_to_error(engine_by_id_nif(ensure_bin_chardata(<<"dynamic">>))) of 1437 {ok, Engine} -> 1438 PreCommands = [{<<"SO_PATH">>, ensure_bin_chardata(LibPath)}, 1439 {<<"ID">>, ensure_bin_chardata(EngineId)}, 1440 <<"LOAD">>], 1441 ensure_engine_loaded_1(Engine, PreCommands, EngineMethods); 1442 {error, Error1} -> 1443 {error, Error1} 1444 end 1445 end 1446 catch 1447 throw:Error2 -> 1448 Error2 1449 end. 1450 1451ensure_engine_loaded_1(Engine, PreCmds, Methods) -> 1452 try 1453 ok = engine_nif_wrapper(engine_ctrl_cmd_strings_nif(Engine, ensure_bin_cmds(PreCmds), 0)), 1454 ok = engine_nif_wrapper(engine_add_nif(Engine)), 1455 ok = engine_nif_wrapper(engine_init_nif(Engine)), 1456 ensure_engine_loaded_2(Engine, Methods), 1457 {ok, Engine} 1458 catch 1459 throw:Error -> 1460 %% The engine couldn't initialise, release the structural reference 1461 ok = engine_free_nif(Engine), 1462 throw(Error) 1463 end. 1464 1465ensure_engine_loaded_2(Engine, Methods) -> 1466 try 1467 [ok = engine_nif_wrapper(engine_register_nif(Engine, engine_method_atom_to_int(Method))) || 1468 Method <- Methods], 1469 ok 1470 catch 1471 throw:Error -> 1472 %% The engine registration failed, release the functional reference 1473 ok = engine_finish_nif(Engine), 1474 throw(Error) 1475 end. 1476%%---------------------------------------------------------------------- 1477%% Function: ensure_engine_unloaded/1 1478%%---------------------------------------------------------------------- 1479-spec ensure_engine_unloaded(Engine) -> Result when Engine :: engine_ref(), 1480 Result :: ok | {error, Reason::term()}. 1481ensure_engine_unloaded(Engine) -> 1482 ensure_engine_unloaded(Engine, engine_get_all_methods()). 1483 1484%%---------------------------------------------------------------------- 1485%% Function: ensure_engine_unloaded/2 1486%%---------------------------------------------------------------------- 1487-spec ensure_engine_unloaded(Engine, EngineMethods) -> 1488 Result when Engine :: engine_ref(), 1489 EngineMethods :: [engine_method_type()], 1490 Result :: ok | {error, Reason::term()}. 1491ensure_engine_unloaded(Engine, EngineMethods) -> 1492 case engine_remove(Engine) of 1493 ok -> 1494 engine_unload(Engine, EngineMethods); 1495 {error, E} -> 1496 {error, E} 1497 end. 1498 1499%%-------------------------------------------------------------------- 1500%%% On load 1501%%-------------------------------------------------------------------- 1502on_load() -> 1503 LibBaseName = "crypto", 1504 PrivDir = code:priv_dir(crypto), 1505 LibName = case erlang:system_info(build_type) of 1506 opt -> 1507 LibBaseName; 1508 Type -> 1509 LibTypeName = LibBaseName ++ "." ++ atom_to_list(Type), 1510 case (filelib:wildcard( 1511 filename:join( 1512 [PrivDir, 1513 "lib", 1514 LibTypeName ++ "*"])) /= []) orelse 1515 (filelib:wildcard( 1516 filename:join( 1517 [PrivDir, 1518 "lib", 1519 erlang:system_info(system_architecture), 1520 LibTypeName ++ "*"])) /= []) of 1521 true -> LibTypeName; 1522 false -> LibBaseName 1523 end 1524 end, 1525 Lib = filename:join([PrivDir, "lib", LibName]), 1526 LibBin = path2bin(Lib), 1527 FipsMode = application:get_env(crypto, fips_mode, false) == true, 1528 Status = case erlang:load_nif(Lib, {?CRYPTO_NIF_VSN,LibBin,FipsMode}) of 1529 ok -> ok; 1530 {error, {load_failed, _}}=Error1 -> 1531 ArchLibDir = 1532 filename:join([PrivDir, "lib", 1533 erlang:system_info(system_architecture)]), 1534 Candidate = 1535 filelib:wildcard(filename:join([ArchLibDir,LibName ++ "*" ])), 1536 case Candidate of 1537 [] -> Error1; 1538 _ -> 1539 ArchLib = filename:join([ArchLibDir, LibName]), 1540 ArchBin = path2bin(ArchLib), 1541 erlang:load_nif(ArchLib, {?CRYPTO_NIF_VSN,ArchBin,FipsMode}) 1542 end; 1543 Error1 -> Error1 1544 end, 1545 case Status of 1546 ok -> ok; 1547 {error, {E, Str}} -> 1548 Fmt = "Unable to load crypto library. Failed with error:~n\"~p, ~s\"~n~s", 1549 Extra = case E of 1550 load_failed -> 1551 "OpenSSL might not be installed on this system.\n"; 1552 _ -> "" 1553 end, 1554 error_logger:error_msg(Fmt, [E,Str,Extra]), 1555 Status 1556 end. 1557 1558path2bin(Path) when is_list(Path) -> 1559 Encoding = file:native_name_encoding(), 1560 case unicode:characters_to_binary(Path,Encoding,Encoding) of 1561 Bin when is_binary(Bin) -> 1562 Bin 1563 end. 1564 1565%%%================================================================ 1566%%%================================================================ 1567%%% 1568%%% Internal functions 1569%%% 1570%%%================================================================ 1571 1572max_bytes() -> 1573 ?MAX_BYTES_TO_NIF. 1574 1575notsup_to_error(notsup) -> 1576 erlang:error(notsup); 1577notsup_to_error(Other) -> 1578 Other. 1579 1580%% HASH -------------------------------------------------------------------- 1581hash(Hash, Data, Size, Max) when Size =< Max -> 1582 notsup_to_error(hash_nif(Hash, Data)); 1583hash(Hash, Data, Size, Max) -> 1584 State0 = hash_init(Hash), 1585 State1 = hash_update(State0, Data, Size, Max), 1586 hash_final(State1). 1587 1588hash_update(State, Data, Size, MaxBytes) when Size =< MaxBytes -> 1589 notsup_to_error(hash_update_nif(State, Data)); 1590hash_update(State0, Data, _, MaxBytes) -> 1591 <<Increment:MaxBytes/binary, Rest/binary>> = Data, 1592 State = notsup_to_error(hash_update_nif(State0, Increment)), 1593 hash_update(State, Rest, erlang:byte_size(Rest), MaxBytes). 1594 1595hash_nif(_Hash, _Data) -> ?nif_stub. 1596hash_init_nif(_Hash) -> ?nif_stub. 1597hash_update_nif(_State, _Data) -> ?nif_stub. 1598hash_final_nif(_State) -> ?nif_stub. 1599 1600%% HMAC -------------------------------------------------------------------- 1601 1602hmac(Type, Key, Data, MacSize, Size, MaxBytes) when Size =< MaxBytes -> 1603 notsup_to_error( 1604 case MacSize of 1605 undefined -> hmac_nif(Type, Key, Data); 1606 _ -> hmac_nif(Type, Key, Data, MacSize) 1607 end); 1608hmac(Type, Key, Data, MacSize, Size, MaxBytes) -> 1609 State0 = hmac_init(Type, Key), 1610 State1 = hmac_update(State0, Data, Size, MaxBytes), 1611 case MacSize of 1612 undefined -> hmac_final(State1); 1613 _ -> hmac_final_n(State1, MacSize) 1614 end. 1615 1616hmac_update(State, Data, Size, MaxBytes) when Size =< MaxBytes -> 1617 notsup_to_error(hmac_update_nif(State, Data)); 1618hmac_update(State0, Data, _, MaxBytes) -> 1619 <<Increment:MaxBytes/binary, Rest/binary>> = Data, 1620 State = notsup_to_error(hmac_update_nif(State0, Increment)), 1621 hmac_update(State, Rest, erlang:byte_size(Rest), MaxBytes). 1622 1623hmac_nif(_Type, _Key, _Data) -> ?nif_stub. 1624hmac_nif(_Type, _Key, _Data, _MacSize) -> ?nif_stub. 1625hmac_init_nif(_Type, _Key) -> ?nif_stub. 1626hmac_update_nif(_Context, _Data) -> ?nif_stub. 1627hmac_final_nif(_Context) -> ?nif_stub. 1628hmac_final_nif(_Context, _MacSize) -> ?nif_stub. 1629 1630%% CMAC 1631cmac_nif(_Type, _Key, _Data) -> ?nif_stub. 1632 1633%% POLY1305 1634poly1305_nif(_Key, _Data) -> ?nif_stub. 1635 1636 1637%% CIPHERS -------------------------------------------------------------------- 1638 1639block_crypt_nif(_Type, _Key, _Ivec, _Text, _IsEncrypt) -> ?nif_stub. 1640block_crypt_nif(_Type, _Key, _Text, _IsEncrypt) -> ?nif_stub. 1641 1642check_des3_key(Key) -> 1643 case lists:map(fun erlang:iolist_to_binary/1, Key) of 1644 ValidKey = [B1, B2, B3] when byte_size(B1) =:= 8, 1645 byte_size(B2) =:= 8, 1646 byte_size(B3) =:= 8 -> 1647 ValidKey; 1648 _ -> 1649 error(badarg) 1650 end. 1651 1652%% 1653%% AES - in Galois/Counter Mode (GCM) 1654%% 1655%% The default tag length is EVP_GCM_TLS_TAG_LEN(16), 1656aead_encrypt(Type=aes_ccm, Key, Ivec, AAD, In) -> aead_encrypt(Type, Key, Ivec, AAD, In, 12); 1657aead_encrypt(Type=aes_gcm, Key, Ivec, AAD, In) -> aead_encrypt(Type, Key, Ivec, AAD, In, 16). 1658 1659aead_encrypt(_Type, _Key, _Ivec, _AAD, _In, _TagLength) -> ?nif_stub. 1660aead_decrypt(_Type, _Key, _Ivec, _AAD, _In, _Tag) -> ?nif_stub. 1661 1662%% 1663%% AES - with 256 bit key in infinite garble extension mode (IGE) 1664%% 1665 1666aes_ige_crypt_nif(_Key, _IVec, _Data, _IsEncrypt) -> ?nif_stub. 1667 1668 1669%% Stream ciphers -------------------------------------------------------------------- 1670 1671stream_crypt(Fun, State, Data, Size, MaxByts, []) when Size =< MaxByts -> 1672 Fun(State, Data); 1673stream_crypt(Fun, State0, Data, Size, MaxByts, Acc) when Size =< MaxByts -> 1674 {State, Cipher} = Fun(State0, Data), 1675 {State, list_to_binary(lists:reverse([Cipher | Acc]))}; 1676stream_crypt(Fun, State0, Data, _, MaxByts, Acc) -> 1677 <<Increment:MaxByts/binary, Rest/binary>> = Data, 1678 {State, CipherText} = Fun(State0, Increment), 1679 stream_crypt(Fun, State, Rest, erlang:byte_size(Rest), MaxByts, [CipherText | Acc]). 1680 1681do_stream_encrypt({aes_ctr, State0}, Data) -> 1682 {State, Cipher} = aes_ctr_stream_encrypt(State0, Data), 1683 {{aes_ctr, State}, Cipher}; 1684do_stream_encrypt({rc4, State0}, Data) -> 1685 {State, Cipher} = rc4_encrypt_with_state(State0, Data), 1686 {{rc4, State}, Cipher}; 1687do_stream_encrypt({chacha20, State0}, Data) -> 1688 {State, Cipher} = chacha20_stream_encrypt(State0, Data), 1689 {{chacha20, State}, Cipher}. 1690 1691do_stream_decrypt({aes_ctr, State0}, Data) -> 1692 {State, Text} = aes_ctr_stream_decrypt(State0, Data), 1693 {{aes_ctr, State}, Text}; 1694do_stream_decrypt({rc4, State0}, Data) -> 1695 {State, Text} = rc4_encrypt_with_state(State0, Data), 1696 {{rc4, State}, Text}; 1697do_stream_decrypt({chacha20, State0}, Data) -> 1698 {State, Cipher} = chacha20_stream_decrypt(State0, Data), 1699 {{chacha20, State}, Cipher}. 1700 1701 1702%% 1703%% AES - in counter mode (CTR) with state maintained for multi-call streaming 1704%% 1705aes_ctr_stream_init(_Key, _IVec) -> ?nif_stub. 1706aes_ctr_stream_encrypt(_State, _Data) -> ?nif_stub. 1707aes_ctr_stream_decrypt(_State, _Cipher) -> ?nif_stub. 1708 1709%% 1710%% RC4 - symmetric stream cipher 1711%% 1712rc4_set_key(_Key) -> ?nif_stub. 1713rc4_encrypt_with_state(_State, _Data) -> ?nif_stub. 1714 1715%% 1716%% CHACHA20 - stream cipher 1717%% 1718chacha20_stream_init(_Key, _IVec) -> ?nif_stub. 1719chacha20_stream_encrypt(_State, _Data) -> ?nif_stub. 1720chacha20_stream_decrypt(_State, _Data) -> ?nif_stub. 1721 1722%% Secure remote password ------------------------------------------------------------------- 1723 1724user_srp_gen_key(Private, Generator, Prime) -> 1725 %% Ensure the SRP algorithm is disabled in FIPS mode 1726 case info_fips() of 1727 enabled -> erlang:error(notsup); 1728 _ -> ok 1729 end, 1730 case mod_pow(Generator, Private, Prime) of 1731 error -> 1732 error; 1733 Public -> 1734 {Public, Private} 1735 end. 1736 1737host_srp_gen_key(Private, Verifier, Generator, Prime, Version) -> 1738 Multiplier = srp_multiplier(Version, Generator, Prime), 1739 case srp_value_B_nif(Multiplier, Verifier, Generator, Private, Prime) of 1740 error -> 1741 error; 1742 notsup -> 1743 erlang:error(notsup); 1744 Public -> 1745 {Public, Private} 1746 end. 1747 1748srp_multiplier('6a', Generator, Prime) -> 1749 %% k = SHA1(N | PAD(g)) from http://srp.stanford.edu/design.html 1750 C0 = hash_init(sha), 1751 C1 = hash_update(C0, Prime), 1752 C2 = hash_update(C1, srp_pad_to(erlang:byte_size(Prime), Generator)), 1753 hash_final(C2); 1754srp_multiplier('6', _, _) -> 1755 <<3/integer>>; 1756srp_multiplier('3', _, _) -> 1757 <<1/integer>>. 1758 1759srp_scrambler(Version, UserPublic, HostPublic, Prime) when Version == '6'; Version == '6a'-> 1760 %% SHA1(PAD(A) | PAD(B)) from http://srp.stanford.edu/design.html 1761 PadLength = erlang:byte_size(Prime), 1762 C0 = hash_init(sha), 1763 C1 = hash_update(C0, srp_pad_to(PadLength, UserPublic)), 1764 C2 = hash_update(C1, srp_pad_to(PadLength, HostPublic)), 1765 hash_final(C2); 1766srp_scrambler('3', _, HostPublic, _Prime) -> 1767 %% The parameter u is a 32-bit unsigned integer which takes its value 1768 %% from the first 32 bits of the SHA1 hash of B, MSB first. 1769 <<U:32/bits, _/binary>> = hash(sha, HostPublic), 1770 U. 1771 1772srp_pad_length(Width, Length) -> 1773 (Width - Length rem Width) rem Width. 1774 1775srp_pad_to(Width, Binary) -> 1776 case srp_pad_length(Width, size(Binary)) of 1777 0 -> Binary; 1778 N -> << 0:(N*8), Binary/binary>> 1779 end. 1780 1781srp_host_secret_nif(_Verifier, _B, _U, _A, _Prime) -> ?nif_stub. 1782 1783srp_user_secret_nif(_A, _U, _B, _Multiplier, _Generator, _Exponent, _Prime) -> ?nif_stub. 1784 1785srp_value_B_nif(_Multiplier, _Verifier, _Generator, _Exponent, _Prime) -> ?nif_stub. 1786 1787 1788%% Public Keys -------------------------------------------------------------------- 1789%% RSA Rivest-Shamir-Adleman functions 1790%% 1791 1792rsa_generate_key_nif(_Bits, _Exp) -> ?nif_stub. 1793 1794%% DH Diffie-Hellman functions 1795%% 1796 1797%% DHParameters = [P (Prime)= mpint(), G(Generator) = mpint()] 1798%% PrivKey = mpint() 1799dh_generate_key_nif(_PrivateKey, _DHParameters, _Mpint, _Length) -> ?nif_stub. 1800 1801%% DHParameters = [P (Prime)= mpint(), G(Generator) = mpint()] 1802%% MyPrivKey, OthersPublicKey = mpint() 1803dh_compute_key_nif(_OthersPublicKey, _MyPrivateKey, _DHParameters) -> ?nif_stub. 1804 1805ec_key_generate(_Curve, _Key) -> ?nif_stub. 1806 1807ecdh_compute_key_nif(_Others, _Curve, _My) -> ?nif_stub. 1808 1809-spec ec_curves() -> [EllipticCurve] when EllipticCurve :: ec_named_curve() 1810 | edwards_curve_dh() 1811 | edwards_curve_ed() . 1812 1813ec_curves() -> 1814 crypto_ec_curves:curves(). 1815 1816-spec ec_curve(CurveName) -> ExplicitCurve when CurveName :: ec_named_curve(), 1817 ExplicitCurve :: ec_explicit_curve() . 1818ec_curve(X) -> 1819 crypto_ec_curves:curve(X). 1820 1821 1822-spec privkey_to_pubkey(Type, EnginePrivateKeyRef) -> PublicKey when Type :: rsa | dss, 1823 EnginePrivateKeyRef :: engine_key_ref(), 1824 PublicKey :: rsa_public() | dss_public() . 1825privkey_to_pubkey(Alg, EngineMap) when Alg == rsa; Alg == dss; Alg == ecdsa -> 1826 try privkey_to_pubkey_nif(Alg, format_pkey(Alg,EngineMap)) 1827 of 1828 [_|_]=L -> map_ensure_bin_as_int(L); 1829 X -> X 1830 catch 1831 error:badarg when Alg==ecdsa -> 1832 {error, notsup}; 1833 error:badarg -> 1834 {error, not_found}; 1835 error:notsup -> 1836 {error, notsup} 1837 end. 1838 1839privkey_to_pubkey_nif(_Alg, _EngineMap) -> ?nif_stub. 1840 1841 1842%% 1843%% EC 1844%% 1845 1846term_to_nif_prime({prime_field, Prime}) -> 1847 {prime_field, ensure_int_as_bin(Prime)}; 1848term_to_nif_prime(PrimeField) -> 1849 PrimeField. 1850 1851term_to_nif_curve({A, B, Seed}) -> 1852 {ensure_int_as_bin(A), ensure_int_as_bin(B), Seed}. 1853 1854nif_curve_params({PrimeField, Curve, BasePoint, Order, CoFactor}) -> 1855 {term_to_nif_prime(PrimeField), 1856 term_to_nif_curve(Curve), 1857 ensure_int_as_bin(BasePoint), 1858 ensure_int_as_bin(Order), 1859 ensure_int_as_bin(CoFactor)}; 1860nif_curve_params(Curve) when is_atom(Curve) -> 1861 %% named curve 1862 case Curve of 1863 x448 -> {evp,Curve}; 1864 x25519 -> {evp,Curve}; 1865 _ -> crypto_ec_curves:curve(Curve) 1866 end. 1867 1868 1869%% MISC -------------------------------------------------------------------- 1870 1871exor(Data1, Data2, Size, MaxByts, []) when Size =< MaxByts -> 1872 do_exor(Data1, Data2); 1873exor(Data1, Data2, Size, MaxByts, Acc) when Size =< MaxByts -> 1874 Result = do_exor(Data1, Data2), 1875 list_to_binary(lists:reverse([Result | Acc])); 1876exor(Data1, Data2, _Size, MaxByts, Acc) -> 1877 <<Increment1:MaxByts/binary, Rest1/binary>> = Data1, 1878 <<Increment2:MaxByts/binary, Rest2/binary>> = Data2, 1879 Result = do_exor(Increment1, Increment2), 1880 exor(Rest1, Rest2, erlang:byte_size(Rest1), MaxByts, [Result | Acc]). 1881 1882do_exor(_A, _B) -> ?nif_stub. 1883 1884algorithms() -> ?nif_stub. 1885 1886int_to_bin(X) when X < 0 -> int_to_bin_neg(X, []); 1887int_to_bin(X) -> int_to_bin_pos(X, []). 1888 1889int_to_bin_pos(0,Ds=[_|_]) -> 1890 list_to_binary(Ds); 1891int_to_bin_pos(X,Ds) -> 1892 int_to_bin_pos(X bsr 8, [(X band 255)|Ds]). 1893 1894int_to_bin_neg(-1, Ds=[MSB|_]) when MSB >= 16#80 -> 1895 list_to_binary(Ds); 1896int_to_bin_neg(X,Ds) -> 1897 int_to_bin_neg(X bsr 8, [(X band 255)|Ds]). 1898 1899-spec bytes_to_integer(binary()) -> integer() . 1900bytes_to_integer(Bin) -> 1901 bin_to_int(Bin). 1902 1903bin_to_int(Bin) when is_binary(Bin) -> 1904 Bits = bit_size(Bin), 1905 <<Integer:Bits/integer>> = Bin, 1906 Integer; 1907bin_to_int(undefined) -> 1908 undefined. 1909 1910map_ensure_int_as_bin([H|_]=List) when is_integer(H) -> 1911 lists:map(fun(E) -> int_to_bin(E) end, List); 1912map_ensure_int_as_bin(List) -> 1913 List. 1914 1915ensure_int_as_bin(Int) when is_integer(Int) -> 1916 int_to_bin(Int); 1917ensure_int_as_bin(Bin) -> 1918 Bin. 1919 1920map_ensure_bin_as_int(List) when is_list(List) -> 1921 lists:map(fun ensure_bin_as_int/1, List). 1922 1923ensure_bin_as_int(Bin) when is_binary(Bin) -> 1924 bin_to_int(Bin); 1925ensure_bin_as_int(E) -> 1926 E. 1927 1928format_pkey(_Alg, #{engine:=_, key_id:=T}=M) when is_binary(T) -> format_pwd(M); 1929format_pkey(_Alg, #{engine:=_, key_id:=T}=M) when is_list(T) -> format_pwd(M#{key_id:=list_to_binary(T)}); 1930format_pkey(_Alg, #{engine:=_ }=M) -> error({bad_key_id, M}); 1931format_pkey(_Alg, #{}=M) -> error({bad_engine_map, M}); 1932%%% 1933format_pkey(rsa, Key) -> 1934 map_ensure_int_as_bin(Key); 1935format_pkey(ecdsa, [Key, Curve]) -> 1936 {nif_curve_params(Curve), ensure_int_as_bin(Key)}; 1937format_pkey(dss, Key) -> 1938 map_ensure_int_as_bin(Key); 1939format_pkey(_, Key) -> 1940 Key. 1941 1942format_pwd(#{password := Pwd}=M) when is_list(Pwd) -> M#{password := list_to_binary(Pwd)}; 1943format_pwd(M) -> M. 1944 1945%%-------------------------------------------------------------------- 1946%% 1947 1948%% large integer in a binary with 32bit length 1949%% MP representaion (SSH2) 1950mpint(X) when X < 0 -> mpint_neg(X); 1951mpint(X) -> mpint_pos(X). 1952 1953-define(UINT32(X), X:32/unsigned-big-integer). 1954 1955 1956mpint_neg(X) -> 1957 Bin = int_to_bin_neg(X, []), 1958 Sz = byte_size(Bin), 1959 <<?UINT32(Sz), Bin/binary>>. 1960 1961mpint_pos(X) -> 1962 Bin = int_to_bin_pos(X, []), 1963 <<MSB,_/binary>> = Bin, 1964 Sz = byte_size(Bin), 1965 if MSB band 16#80 == 16#80 -> 1966 <<?UINT32((Sz+1)), 0, Bin/binary>>; 1967 true -> 1968 <<?UINT32(Sz), Bin/binary>> 1969 end. 1970 1971%% int from integer in a binary with 32bit length 1972erlint(<<MPIntSize:32/integer,MPIntValue/binary>>) -> 1973 Bits= MPIntSize * 8, 1974 <<Integer:Bits/integer>> = MPIntValue, 1975 Integer. 1976 1977%% 1978%% mod_exp - utility for rsa generation and SRP 1979%% 1980mod_exp_nif(_Base,_Exp,_Mod,_bin_hdr) -> ?nif_stub. 1981 1982%%%---------------------------------------------------------------- 1983%% 9470495 == V(0,9,8,zh). 1984%% 268435615 == V(1,0,0,i). 1985%% 268439663 == V(1,0,1,f). 1986 1987packed_openssl_version(MAJ, MIN, FIX, P0) -> 1988 %% crypto.c 1989 P1 = atom_to_list(P0), 1990 P = lists:sum([C-$a||C<-P1]), 1991 ((((((((MAJ bsl 8) bor MIN) bsl 8 ) bor FIX) bsl 8) bor (P+1)) bsl 4) bor 16#f). 1992 1993%%-------------------------------------------------------------------- 1994%% Engine nifs 1995engine_by_id_nif(_EngineId) -> ?nif_stub. 1996engine_init_nif(_Engine) -> ?nif_stub. 1997engine_finish_nif(_Engine) -> ?nif_stub. 1998engine_free_nif(_Engine) -> ?nif_stub. 1999engine_load_dynamic_nif() -> ?nif_stub. 2000engine_ctrl_cmd_strings_nif(_Engine, _Cmds, _Optional) -> ?nif_stub. 2001engine_add_nif(_Engine) -> ?nif_stub. 2002engine_remove_nif(_Engine) -> ?nif_stub. 2003engine_register_nif(_Engine, _EngineMethod) -> ?nif_stub. 2004engine_unregister_nif(_Engine, _EngineMethod) -> ?nif_stub. 2005engine_get_first_nif() -> ?nif_stub. 2006engine_get_next_nif(_Engine) -> ?nif_stub. 2007engine_get_id_nif(_Engine) -> ?nif_stub. 2008engine_get_name_nif(_Engine) -> ?nif_stub. 2009engine_get_all_methods_nif() -> ?nif_stub. 2010 2011%%-------------------------------------------------------------------- 2012%% Engine internals 2013engine_nif_wrapper(ok) -> 2014 ok; 2015engine_nif_wrapper(notsup) -> 2016 erlang:error(notsup); 2017engine_nif_wrapper({error, Error}) -> 2018 throw({error, Error}). 2019 2020ensure_bin_chardata(CharData) when is_binary(CharData) -> 2021 CharData; 2022ensure_bin_chardata(CharData) -> 2023 unicode:characters_to_binary(CharData). 2024 2025ensure_bin_cmds(CMDs) -> 2026 ensure_bin_cmds(CMDs, []). 2027 2028ensure_bin_cmds([], Acc) -> 2029 lists:reverse(Acc); 2030ensure_bin_cmds([{Key, Value} |CMDs], Acc) -> 2031 ensure_bin_cmds(CMDs, [{ensure_bin_chardata(Key), ensure_bin_chardata(Value)} | Acc]); 2032ensure_bin_cmds([Key | CMDs], Acc) -> 2033 ensure_bin_cmds(CMDs, [{ensure_bin_chardata(Key), <<"">>} | Acc]). 2034 2035engine_methods_convert_to_bitmask([], BitMask) -> 2036 BitMask; 2037engine_methods_convert_to_bitmask(engine_method_all, _BitMask) -> 2038 16#FFFF; 2039engine_methods_convert_to_bitmask(engine_method_none, _BitMask) -> 2040 16#0000; 2041engine_methods_convert_to_bitmask([M |Ms], BitMask) -> 2042 engine_methods_convert_to_bitmask(Ms, BitMask bor engine_method_atom_to_int(M)). 2043 2044bool_to_int(true) -> 1; 2045bool_to_int(false) -> 0. 2046 2047engine_method_atom_to_int(engine_method_rsa) -> 16#0001; 2048engine_method_atom_to_int(engine_method_dsa) -> 16#0002; 2049engine_method_atom_to_int(engine_method_dh) -> 16#0004; 2050engine_method_atom_to_int(engine_method_rand) -> 16#0008; 2051engine_method_atom_to_int(engine_method_ecdh) -> 16#0010; 2052engine_method_atom_to_int(engine_method_ecdsa) -> 16#0020; 2053engine_method_atom_to_int(engine_method_ciphers) -> 16#0040; 2054engine_method_atom_to_int(engine_method_digests) -> 16#0080; 2055engine_method_atom_to_int(engine_method_store) -> 16#0100; 2056engine_method_atom_to_int(engine_method_pkey_meths) -> 16#0200; 2057engine_method_atom_to_int(engine_method_pkey_asn1_meths) -> 16#0400; 2058engine_method_atom_to_int(engine_method_ec) -> 16#0800; 2059engine_method_atom_to_int(X) -> 2060 erlang:error(badarg, [X]). 2061 2062get_test_engine() -> 2063 Type = erlang:system_info(system_architecture), 2064 LibDir = filename:join([code:priv_dir(crypto), "lib"]), 2065 ArchDir = filename:join([LibDir, Type]), 2066 case filelib:is_dir(ArchDir) of 2067 true -> check_otp_test_engine(ArchDir); 2068 false -> check_otp_test_engine(LibDir) 2069 end. 2070 2071check_otp_test_engine(LibDir) -> 2072 case filelib:wildcard("otp_test_engine*", LibDir) of 2073 [] -> 2074 {error, notexist}; 2075 [LibName|_] -> % In case of Valgrind there could be more than one 2076 LibPath = filename:join(LibDir,LibName), 2077 case filelib:is_file(LibPath) of 2078 true -> 2079 {ok, unicode:characters_to_binary(LibPath)}; 2080 false -> 2081 {error, notexist} 2082 end 2083 end. 2084