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