Skip to content

Commit cac4b64

Browse files
committed
kdf: add a shorthand method for Argon2id
1 parent dce970b commit cac4b64

File tree

3 files changed

+57
-0
lines changed

3 files changed

+57
-0
lines changed

lib/openssl.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
require_relative 'openssl/cipher'
1818
require_relative 'openssl/digest'
1919
require_relative 'openssl/hmac'
20+
require_relative 'openssl/kdf'
2021
require_relative 'openssl/pkcs5'
2122
require_relative 'openssl/pkey'
2223
require_relative 'openssl/ssl'

lib/openssl/kdf.rb

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# frozen_string_literal: true
2+
3+
module OpenSSL
4+
module KDF
5+
if respond_to?(:derive)
6+
# Argon2id, a variant of Argon2, is a password hashing function
7+
# described in {RFC 9106}[https://www.rfc-editor.org/rfc/rfc9106].
8+
#
9+
# This methods requires \OpenSSL 3.2 or later.
10+
#
11+
# === Parameters
12+
# pass:: Passowrd to be hashed. Message string +P+ in RFC 9106.
13+
# salt:: Salt. Nonce +S+ in RFC 9106.
14+
# lanes:: Degree of parallelism. +p+ in RFC 9106.
15+
# length:: Desired output length in bytes. Tag length +T+ in RFC 9106.
16+
# memcost:: Memory size in the number of kibibytes. +m+ in RFC 9106.
17+
# iter:: Number of passes. +t+ in RFC 9106.
18+
# secret:: Secret value. Optional. +K+ in RFC 9106.
19+
# ad:: Associated data. Optional. +X+ in RFC 9106.
20+
#
21+
# === Example
22+
# password = "\x01" * 32
23+
# salt = "\x02" * 16
24+
# secret = "\x03" * 8
25+
# ad = "\x04" * 12
26+
# ret = OpenSSL::KDF.argon2id(
27+
# password, salt: salt, lanes: 4, length: 32,
28+
# memcost: 32, iter: 3, secret: secret, ad: ad,
29+
# )
30+
# p ret.unpack1("H*")
31+
# #=> "0d640df58d78766c08c037a34a8b53c9d01ef0452d75b65eb52520e96b01e659"
32+
def self.argon2id(pass, salt:, lanes:, length:, memcost:, iter:,
33+
secret: "", ad: "")
34+
params = {
35+
pass: pass, salt: salt, lanes: lanes, memcost: memcost, iter: iter,
36+
secret: secret, ad: ad,
37+
}
38+
derive("ARGON2ID", length, params)
39+
end
40+
end
41+
end
42+
end

test/openssl/test_kdf.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,20 @@ def test_derive
201201
}
202202
end if openssl?(3, 0, 0) || OpenSSL::KDF.respond_to?(:derive)
203203

204+
def test_argon2id_rfc9106
205+
# https://www.rfc-editor.org/rfc/rfc9106.html#section-5.3
206+
# 5.3. Argon2id Test Vectors
207+
password = B("01" * 32)
208+
salt = B("02" * 16)
209+
secret = B("03" * 8)
210+
ad = B("04" * 12)
211+
tag = B("0d640df58d78766c08c037a34a8b53c9d0" \
212+
"1ef0452d75b65eb52520e96b01e659")
213+
ret = OpenSSL::KDF.argon2id(password, salt: salt, lanes: 4, length: 32,
214+
memcost: 32, iter: 3, secret: secret, ad: ad)
215+
assert_equal(tag, ret)
216+
end if openssl?(3, 2, 0)
217+
204218
private
205219

206220
def B(ary)

0 commit comments

Comments
 (0)