diff --git a/src/prolog/lib/crypto.pl b/src/prolog/lib/crypto.pl index b93a9cff..909127d4 100644 --- a/src/prolog/lib/crypto.pl +++ b/src/prolog/lib/crypto.pl @@ -184,8 +184,7 @@ crypto_random_byte(B) :- '$crypto_random_byte'(B). crypto_data_hash(Data0, Hash, Options0) :- must_be(list, Options0), - option(encoding(Encoding), Options0, utf8), - encoding_bytes(Encoding, Data0, Data), + options_data_bytes(Options0, Data0, Data), functor_hash_options(algorithm, A, Options0, _), ( hash_algorithm(A) -> true ; domain_error(hash_algorithm, A, crypto_data_hash/3) @@ -193,6 +192,10 @@ crypto_data_hash(Data0, Hash, Options0) :- '$crypto_data_hash'(Data, HashBytes, A), hex_bytes(Hash, HashBytes). +options_data_bytes(Options, Data, Bytes) :- + option(encoding(Encoding), Options, utf8), + must_be(atom, Encoding), + encoding_bytes(Encoding, Data, Bytes). default_hash(sha256). @@ -250,8 +253,9 @@ hash_algorithm(sha512_256). crypto_data_hkdf(Data0, L, Bytes, Options0) :- functor_hash_options(algorithm, Algorithm, Options0, Options), - option(encoding(Encoding), Options, utf8), - encoding_bytes(Encoding, Data0, Data), + must_be(integer, L), + L >= 0, + options_data_bytes(Options, Data0, Data), option(salt(SaltBytes), Options, []), must_be_bytes(SaltBytes, crypto_data_hkdf/4), option(info(Info0), Options, []), @@ -259,6 +263,10 @@ crypto_data_hkdf(Data0, L, Bytes, Options0) :- '$crypto_data_hkdf'(Data, SaltBytes, Info, Algorithm, L, Bytes). option(What, Options, Default) :- + ( member(V, Options), var(V) -> + instantiation_error(option/3) + ; true + ), ( member(What, Options) -> true ; What =.. [_,Default] ). @@ -379,7 +387,7 @@ crypto_password_hash(Password0, Hash, Options) :- Algorithm = 'pbkdf2-sha512', % current default and only option option(algorithm(Algorithm), Options, Algorithm), ( member(salt(SaltBytes), Options) -> - true + must_be_bytes(SaltBytes, crypto_password_hash/2) ; crypto_n_random_bytes(16, SaltBytes) ), '$crypto_password_hash'(Password, SaltBytes, Iterations, HashBytes), @@ -531,8 +539,7 @@ bytes_base64_([A,B,C|Ls]) --> [W,X,Y,Z], - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ crypto_data_encrypt(PlainText0, Algorithm, Key, IV, CipherText, Options) :- - option(encoding(Encoding), Options, utf8), - encoding_bytes(Encoding, PlainText0, PlainText), + options_data_bytes(Options, PlainText0, PlainText), option(tag(Tag), Options, _), ( nonvar(Tag) -> must_be_bytes(Tag, crypto_data_encrypt/6) @@ -580,7 +587,7 @@ crypto_data_decrypt(CipherText0, Algorithm, Key, IV, PlainText, Options) :- must_be_bytes(Key, crypto_data_decrypt/6), must_be_bytes(IV, crypto_data_decrypt/6), must_be(atom, Algorithm), - option(encoding(Encoding), Options, utf8), + encoding_options(Encoding, Options), must_be(list, CipherText0), encoding_bytes(octet, CipherText0, CipherText1), append(CipherText1, Tag, CipherText), @@ -590,19 +597,19 @@ crypto_data_decrypt(CipherText0, Algorithm, Key, IV, PlainText, Options) :- '$crypto_data_decrypt'(CipherText, Key, IV, Encoding, PlainText). encoding_bytes(octet, Bs0, Bs) :- + must_be(list, Bs0), ( maplist(integer, Bs0) -> Bs0 = Bs ; maplist(char_code, Bs0, Bs) ), must_be_bytes(Bs, crypto_encoding). encoding_bytes(utf8, Cs, Bs) :- + must_be(list, Cs), ( maplist(atom, Cs) -> chars_bytes_(Cs, Bs, crypto_encoding) ; domain_error(encryption_encoding, Cs, crypto) ). -char_code(Char, Code) :- atom_codes(Char, [Code]). - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Modular multiplicative inverse. diff --git a/src/prolog/machine/system_calls.rs b/src/prolog/machine/system_calls.rs index 8281259e..9554badb 100644 --- a/src/prolog/machine/system_calls.rs +++ b/src/prolog/machine/system_calls.rs @@ -5275,7 +5275,10 @@ impl MachineState { let salt = hkdf::Salt::new(digest_alg, &salt); let mut bytes : Vec = Vec::new(); bytes.resize(length, 0); - salt.extract(&data).expand(&[&info[..]], MyKey(length)).unwrap().fill(&mut bytes).unwrap(); + match salt.extract(&data).expand(&[&info[..]], MyKey(length)) { + Ok(r) => { r.fill(&mut bytes).unwrap(); } + _ => { self.fail = true; return Ok(()); } + } Addr::HeapCell(self.heap.to_list(bytes.iter().map(|b| HeapCellValue::Integer(Rc::new(Integer::from(*b)))))) }; @@ -5294,7 +5297,10 @@ impl MachineState { u64::try_from(n).unwrap() } Ok(Number::Integer(n)) => { - n.to_u64().unwrap() + match n.to_u64() { + Some(i) => { i } + None => { self.fail = true; return Ok(()); } + } } _ => { unreachable!()