diff options
Diffstat (limited to 'lib/public_key')
-rw-r--r-- | lib/public_key/src/pubkey_pbe.erl | 64 | ||||
-rw-r--r-- | lib/public_key/src/pubkey_ssh.erl | 41 | ||||
-rw-r--r-- | lib/public_key/test/pbe_SUITE.erl | 14 |
3 files changed, 74 insertions, 45 deletions
diff --git a/lib/public_key/src/pubkey_pbe.erl b/lib/public_key/src/pubkey_pbe.erl index 43f6c42f10..6f0be53db9 100644 --- a/lib/public_key/src/pubkey_pbe.erl +++ b/lib/public_key/src/pubkey_pbe.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2011-2011. All Rights Reserved. +%% Copyright Ericsson AB 2011-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -23,7 +23,7 @@ -include("public_key.hrl"). -export([encode/4, decode/4, decrypt_parameters/1]). --export([pbdkdf1/4, pbdkdf2/6]). +-export([pbdkdf1/4, pbdkdf2/7]). -define(DEFAULT_SHA_MAC_KEYLEN, 20). -define(ASN1_OCTET_STR_TAG, 4). @@ -40,16 +40,16 @@ %%-------------------------------------------------------------------- encode(Data, Password, "DES-CBC" = Cipher, KeyDevParams) -> {Key, IV} = password_to_key_and_iv(Password, Cipher, KeyDevParams), - crypto:des_cbc_encrypt(Key, IV, Data); + crypto:block_encrypt(des_cbc, Key, IV, Data); encode(Data, Password, "DES-EDE3-CBC" = Cipher, KeyDevParams) -> {Key, IV} = password_to_key_and_iv(Password, Cipher, KeyDevParams), <<Key1:8/binary, Key2:8/binary, Key3:8/binary>> = Key, - crypto:des_ede3_cbc_encrypt(Key1, Key2, Key3, IV, Data); + crypto:block_encrypt(des3_cbc, [Key1, Key2, Key3], IV, Data); encode(Data, Password, "RC2-CBC" = Cipher, KeyDevParams) -> {Key, IV} = password_to_key_and_iv(Password, Cipher, KeyDevParams), - crypto:rc2_cbc_encrypt(Key, IV, Data). + crypto:block_encrypt(rc2_cbc, Key, IV, Data). %%-------------------------------------------------------------------- -spec decode(binary(), string(), string(), term()) -> binary(). %% @@ -57,16 +57,16 @@ encode(Data, Password, "RC2-CBC" = Cipher, KeyDevParams) -> %%-------------------------------------------------------------------- decode(Data, Password,"DES-CBC"= Cipher, KeyDevParams) -> {Key, IV} = password_to_key_and_iv(Password, Cipher, KeyDevParams), - crypto:des_cbc_decrypt(Key, IV, Data); + crypto:block_decrypt(des_cbc, Key, IV, Data); decode(Data, Password,"DES-EDE3-CBC" = Cipher, KeyDevParams) -> {Key, IV} = password_to_key_and_iv(Password, Cipher, KeyDevParams), <<Key1:8/binary, Key2:8/binary, Key3:8/binary>> = Key, - crypto:des_ede3_cbc_decrypt(Key1, Key2, Key3, IV, Data); + crypto:block_decrypt(des3_cbc, [Key1, Key2, Key3], IV, Data); decode(Data, Password,"RC2-CBC"= Cipher, KeyDevParams) -> {Key, IV} = password_to_key_and_iv(Password, Cipher, KeyDevParams), - crypto:rc2_cbc_decrypt(Key, IV, Data). + crypto:block_decrypt(rc2_cbc, Key, IV, Data). %%-------------------------------------------------------------------- -spec pbdkdf1(string(), iodata(), integer(), atom()) -> binary(). @@ -77,21 +77,21 @@ decode(Data, Password,"RC2-CBC"= Cipher, KeyDevParams) -> pbdkdf1(_, _, 0, Acc) -> Acc; pbdkdf1(Password, Salt, Count, Hash) -> - Result = crypto:Hash([Password, Salt]), + Result = crypto:hash(Hash, [Password, Salt]), do_pbdkdf1(Result, Count-1, Result, Hash). %%-------------------------------------------------------------------- --spec pbdkdf2(string(), iodata(), integer(), integer(), fun(), integer()) +-spec pbdkdf2(string(), iodata(), integer(), integer(), fun(), atom(), integer()) -> binary(). %% %% Description: Implements password based decryption key derive function 2. %% Exported mainly for testing purposes. %%-------------------------------------------------------------------- -pbdkdf2(Password, Salt, Count, DerivedKeyLen, Prf, PrfOutputLen)-> +pbdkdf2(Password, Salt, Count, DerivedKeyLen, Prf, PrfHash, PrfOutputLen)-> NumBlocks = ceiling(DerivedKeyLen / PrfOutputLen), NumLastBlockOctets = DerivedKeyLen - (NumBlocks - 1) * PrfOutputLen , blocks(NumBlocks, NumLastBlockOctets, 1, Password, Salt, - Count, Prf, PrfOutputLen, <<>>). + Count, Prf, PrfHash, PrfOutputLen, <<>>). %%-------------------------------------------------------------------- -spec decrypt_parameters(#'EncryptedPrivateKeyInfo_encryptionAlgorithm'{}) -> {Cipher::string(), #'PBES2-params'{}}. @@ -106,10 +106,10 @@ decrypt_parameters(#'EncryptedPrivateKeyInfo_encryptionAlgorithm'{ %%% Internal functions %%-------------------------------------------------------------------- password_to_key_and_iv(Password, _, #'PBES2-params'{} = Params) -> - {Salt, ItrCount, KeyLen, PseudoRandomFunction, PseudoOtputLen, IV} = + {Salt, ItrCount, KeyLen, PseudoRandomFunction, PseudoHash, PseudoOtputLen, IV} = key_derivation_params(Params), <<Key:KeyLen/binary, _/binary>> = - pbdkdf2(Password, Salt, ItrCount, KeyLen, PseudoRandomFunction, PseudoOtputLen), + pbdkdf2(Password, Salt, ItrCount, KeyLen, PseudoRandomFunction, PseudoHash, PseudoOtputLen), {Key, IV}; password_to_key_and_iv(Password, Cipher, Salt) -> KeyLen = derived_key_length(Cipher, undefined), @@ -122,13 +122,13 @@ password_to_key_and_iv(Password, Cipher, Salt) -> pem_encrypt(_, _, _, 0, Acc, _) -> Acc; pem_encrypt(Prev, Password, Salt, Count, Acc, Hash) -> - Result = crypto:Hash([Prev, Password, Salt]), + Result = crypto:hash(Hash, [Prev, Password, Salt]), pem_encrypt(Result, Password, Salt, Count-1 , <<Acc/binary, Result/binary>>, Hash). do_pbdkdf1(_, 0, Acc, _) -> Acc; do_pbdkdf1(Prev, Count, Acc, Hash) -> - Result = crypto:Hash(Prev), + Result = crypto:hash(Hash, Prev), do_pbdkdf1(Result, Count-1 , <<Result/binary, Acc/binary>>, Hash). iv(#'PBES2-params_encryptionScheme'{algorithm = Algo, @@ -143,23 +143,23 @@ iv(#'PBES2-params_encryptionScheme'{algorithm = ?'rc2CBC', {ok, #'RC2-CBC-Parameter'{iv = IV}} = 'PKCS-FRAME':decode('RC2-CBC-Parameter', ASN1IV), iolist_to_binary(IV). -blocks(1, N, Index, Password, Salt, Count, Prf, PrfLen, Acc) -> - <<XorSum:N/binary, _/binary>> = xor_sum(Password, Salt, Count, Index, Prf, PrfLen), +blocks(1, N, Index, Password, Salt, Count, Prf, PrfHash, PrfLen, Acc) -> + <<XorSum:N/binary, _/binary>> = xor_sum(Password, Salt, Count, Index, Prf, PrfHash, PrfLen), <<Acc/binary, XorSum/binary>>; -blocks(NumBlocks, N, Index, Password, Salt, Count, Prf, PrfLen, Acc) -> - XorSum = xor_sum(Password, Salt, Count, Index, Prf, PrfLen), - blocks(NumBlocks -1, N, Index +1, Password, Salt, Count, Prf, +blocks(NumBlocks, N, Index, Password, Salt, Count, Prf, PrfHash, PrfLen, Acc) -> + XorSum = xor_sum(Password, Salt, Count, Index, Prf, PrfHash, PrfLen), + blocks(NumBlocks -1, N, Index +1, Password, Salt, Count, Prf, PrfHash, PrfLen, <<Acc/binary, XorSum/binary>>). -xor_sum(Password, Salt, Count, Index, Prf, PrfLen) -> - Result = Prf(Password, [Salt,<<Index:32/unsigned-big-integer>>], PrfLen), - do_xor_sum(Prf, PrfLen, Result, Password, Count-1, Result). +xor_sum(Password, Salt, Count, Index, Prf, PrfHash, PrfLen) -> + Result = Prf(PrfHash, Password, [Salt,<<Index:32/unsigned-big-integer>>], PrfLen), + do_xor_sum(Prf, PrfHash, PrfLen, Result, Password, Count-1, Result). -do_xor_sum(_, _, _, _, 0, Acc) -> +do_xor_sum(_, _, _, _, _, 0, Acc) -> Acc; -do_xor_sum(Prf, PrfLen, Prev, Password, Count, Acc)-> - Result = Prf(Password, Prev, PrfLen), - do_xor_sum(Prf, PrfLen, Result, Password, Count-1, crypto:exor(Acc, Result)). +do_xor_sum(Prf, PrfHash, PrfLen, Prev, Password, Count, Acc)-> + Result = Prf(PrfHash, Password, Prev, PrfLen), + do_xor_sum(Prf, PrfHash, PrfLen, Result, Password, Count-1, crypto:exor(Acc, Result)). decrypt_parameters(?'id-PBES2', DekParams) -> {ok, Params} = 'PKCS-FRAME':decode('PBES2-params', DekParams), @@ -174,18 +174,18 @@ key_derivation_params(#'PBES2-params'{keyDerivationFunc = KeyDerivationFunc, keyLength = Length, prf = Prf}} = KeyDerivationFunc, #'PBES2-params_encryptionScheme'{algorithm = Algo} = EncScheme, - {PseudoRandomFunction, PseudoOtputLen} = pseudo_random_function(Prf), + {PseudoRandomFunction, PseudoHash, PseudoOtputLen} = pseudo_random_function(Prf), KeyLen = derived_key_length(Algo, Length), {OctetSalt, Count, KeyLen, - PseudoRandomFunction, PseudoOtputLen, iv(EncScheme)}. + PseudoRandomFunction, PseudoHash, PseudoOtputLen, iv(EncScheme)}. %% This function currently matches a tuple that ougth to be the value %% ?'id-hmacWithSHA1, but we need some kind of ASN1-fix for this. pseudo_random_function(#'PBKDF2-params_prf'{algorithm = {_,_, _,'id-hmacWithSHA1'}}) -> - {fun crypto:sha_mac/3, pseudo_output_length(?'id-hmacWithSHA1')}; + {fun crypto:hmac/4, sha, pseudo_output_length(?'id-hmacWithSHA1')}; pseudo_random_function(#'PBKDF2-params_prf'{algorithm = ?'id-hmacWithSHA1'}) -> - {fun crypto:sha_mac/3, pseudo_output_length(?'id-hmacWithSHA1')}. + {fun crypto:hmac/4, sha, pseudo_output_length(?'id-hmacWithSHA1')}. pseudo_output_length(?'id-hmacWithSHA1') -> ?DEFAULT_SHA_MAC_KEYLEN. diff --git a/lib/public_key/src/pubkey_ssh.erl b/lib/public_key/src/pubkey_ssh.erl index 008ea96dd3..aed1f57bbc 100644 --- a/lib/public_key/src/pubkey_ssh.erl +++ b/lib/public_key/src/pubkey_ssh.erl @@ -362,18 +362,18 @@ comma_list_encode([Option | Rest], Acc) -> ssh2_pubkey_encode(#'RSAPublicKey'{modulus = N, publicExponent = E}) -> TypeStr = <<"ssh-rsa">>, StrLen = size(TypeStr), - EBin = crypto:mpint(E), - NBin = crypto:mpint(N), + EBin = mpint(E), + NBin = mpint(N), <<?UINT32(StrLen), TypeStr:StrLen/binary, EBin/binary, NBin/binary>>; ssh2_pubkey_encode({Y, #'Dss-Parms'{p = P, q = Q, g = G}}) -> TypeStr = <<"ssh-dss">>, StrLen = size(TypeStr), - PBin = crypto:mpint(P), - QBin = crypto:mpint(Q), - GBin = crypto:mpint(G), - YBin = crypto:mpint(Y), + PBin = mpint(P), + QBin = mpint(Q), + GBin = mpint(G), + YBin = mpint(Y), <<?UINT32(StrLen), TypeStr:StrLen/binary, PBin/binary, QBin/binary, @@ -476,3 +476,32 @@ split_n(N, Bin, Acc) -> [Last] -> split_n(0, <<>>, [Last | Acc]) end. +%% large integer in a binary with 32bit length +%% MP representaion (SSH2) +mpint(X) when X < 0 -> mpint_neg(X); +mpint(X) -> mpint_pos(X). + +mpint_neg(X) -> + Bin = int_to_bin_neg(X, []), + Sz = byte_size(Bin), + <<?UINT32(Sz), Bin/binary>>. + +mpint_pos(X) -> + Bin = int_to_bin_pos(X, []), + <<MSB,_/binary>> = Bin, + Sz = byte_size(Bin), + if MSB band 16#80 == 16#80 -> + <<?UINT32((Sz+1)), 0, Bin/binary>>; + true -> + <<?UINT32(Sz), Bin/binary>> + end. + +int_to_bin_pos(0,Ds=[_|_]) -> + list_to_binary(Ds); +int_to_bin_pos(X,Ds) -> + int_to_bin_pos(X bsr 8, [(X band 255)|Ds]). + +int_to_bin_neg(-1, Ds=[MSB|_]) when MSB >= 16#80 -> + list_to_binary(Ds); +int_to_bin_neg(X,Ds) -> + int_to_bin_neg(X bsr 8, [(X band 255)|Ds]). diff --git a/lib/public_key/test/pbe_SUITE.erl b/lib/public_key/test/pbe_SUITE.erl index 8fba1e8cd3..254601b107 100644 --- a/lib/public_key/test/pbe_SUITE.erl +++ b/lib/public_key/test/pbe_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2011-2012. All Rights Reserved. +%% Copyright Ericsson AB 2011-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -109,7 +109,7 @@ pbdkdf2(Config) when is_list(Config) -> <<16#0c, 16#60, 16#c8, 16#0f, 16#96, 16#1f, 16#0e, 16#71, 16#f3, 16#a9, 16#b5, 16#24, 16#af, 16#60, 16#12, 16#06, - 16#2f, 16#e0, 16#37, 16#a6>> = pubkey_pbe:pbdkdf2("password", "salt", 1, 20, fun crypto:sha_mac/3, 20), + 16#2f, 16#e0, 16#37, 16#a6>> = pubkey_pbe:pbdkdf2("password", "salt", 1, 20, fun crypto:hmac/4, sha, 20), %% Input: %% P = "password" (8 octets) @@ -125,7 +125,7 @@ pbdkdf2(Config) when is_list(Config) -> <<16#ea, 16#6c, 16#01, 16#4d, 16#c7, 16#2d, 16#6f, 16#8c, 16#cd, 16#1e, 16#d9, 16#2a, 16#ce, 16#1d, 16#41, 16#f0, 16#d8, 16#de, 16#89, 16#57>> = - pubkey_pbe:pbdkdf2("password", "salt", 2, 20, fun crypto:sha_mac/3, 20), + pubkey_pbe:pbdkdf2("password", "salt", 2, 20, fun crypto:hmac/4, sha, 20), %% Input: %% P = "password" (8 octets) @@ -140,7 +140,7 @@ pbdkdf2(Config) when is_list(Config) -> <<16#4b, 16#00, 16#79, 16#01, 16#b7, 16#65, 16#48, 16#9a, 16#be, 16#ad, 16#49, 16#d9, 16#26, 16#f7, 16#21, 16#d0, - 16#65, 16#a4, 16#29, 16#c1>> = pubkey_pbe:pbdkdf2("password", "salt", 4096, 20, fun crypto:sha_mac/3, 20), + 16#65, 16#a4, 16#29, 16#c1>> = pubkey_pbe:pbdkdf2("password", "salt", 4096, 20, fun crypto:hmac/4, sha, 20), %% Input: %% P = "password" (8 octets) @@ -156,7 +156,7 @@ pbdkdf2(Config) when is_list(Config) -> <<16#ee, 16#fe, 16#3d, 16#61, 16#cd, 16#4d, 16#a4, 16#e4, 16#e9, 16#94, 16#5b, 16#3d, 16#6b, 16#a2, 16#15, 16#8c, - 16#26, 16#34, 16#e9, 16#84>> = pubkey_pbe:pbdkdf2("password", "salt", 16777216, 20, fun crypto:sha_mac/3, 20), + 16#26, 16#34, 16#e9, 16#84>> = pubkey_pbe:pbdkdf2("password", "salt", 16777216, 20, fun crypto:hmac/4, sha, 20), %% Input: %% P = "passwordPASSWORDpassword" (24 octets) @@ -175,7 +175,7 @@ pbdkdf2(Config) when is_list(Config) -> 16#8b, 16#29, 16#1a, 16#96, 16#4c, 16#f2, 16#f0, 16#70, 16#38>> = pubkey_pbe:pbdkdf2("passwordPASSWORDpassword", - "saltSALTsaltSALTsaltSALTsaltSALTsalt", 4096, 25, fun crypto:sha_mac/3, 20), + "saltSALTsaltSALTsaltSALTsaltSALTsalt", 4096, 25, fun crypto:hmac/4, sha, 20), %% Input: %% P = "pass\0word" (9 octets) @@ -190,7 +190,7 @@ pbdkdf2(Config) when is_list(Config) -> <<16#56, 16#fa, 16#6a, 16#a7, 16#55, 16#48, 16#09, 16#9d, 16#cc, 16#37, 16#d7, 16#f0, 16#34, 16#25, 16#e0, 16#c3>> = pubkey_pbe:pbdkdf2("pass\0word", - "sa\0lt", 4096, 16, fun crypto:sha_mac/3, 20). + "sa\0lt", 4096, 16, fun crypto:hmac/4, sha, 20). encrypted_private_key_info() -> [{doc,"Tests reading a EncryptedPrivateKeyInfo file encrypted with different ciphers"}]. |