ffi-libsodium 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +191 -0
- data/README.md +21 -0
- data/lib/crypto/aead/chacha20_poly1305.rb +75 -0
- data/lib/crypto/auth.rb +54 -0
- data/lib/crypto/box.rb +150 -0
- data/lib/crypto/generic_hash.rb +123 -0
- data/lib/crypto/one_time_auth.rb +87 -0
- data/lib/crypto/pw_hash/scrypt_salsa208_sha256.rb +101 -0
- data/lib/crypto/scalar_mult.rb +55 -0
- data/lib/crypto/secret_box.rb +101 -0
- data/lib/crypto/short_hash.rb +41 -0
- data/lib/crypto/sign.rb +102 -0
- data/lib/libsodium.rb +21 -0
- data/lib/random_bytes.rb +21 -0
- data/lib/sodium.rb +69 -0
- data/lib/sodium/buffer.rb +11 -0
- data/lib/sodium/secret_buffer.rb +58 -0
- data/lib/sodium/utils.rb +71 -0
- data/lib/sodium/version.rb +3 -0
- metadata +90 -0
@@ -0,0 +1,123 @@
|
|
1
|
+
require_relative '../sodium'
|
2
|
+
require_relative '../sodium/utils'
|
3
|
+
require_relative '../sodium/buffer'
|
4
|
+
require_relative '../sodium/secret_buffer'
|
5
|
+
|
6
|
+
module Crypto
|
7
|
+
module GenericHash
|
8
|
+
extend FFI::Library
|
9
|
+
extend Sodium::Utils
|
10
|
+
|
11
|
+
ffi_lib :libsodium
|
12
|
+
|
13
|
+
attach_function :primitive, :crypto_generichash_primitive, [], :string
|
14
|
+
attach_function :bytes_min, :crypto_generichash_bytes_min, [], :size_t
|
15
|
+
attach_function :bytes_max, :crypto_generichash_bytes_max, [], :size_t
|
16
|
+
attach_function :bytes, :crypto_generichash_bytes, [], :size_t
|
17
|
+
attach_function :keybytes_min, :crypto_generichash_keybytes_min, [], :size_t
|
18
|
+
attach_function :keybytes_max, :crypto_generichash_keybytes_max, [], :size_t
|
19
|
+
attach_function :keybytes, :crypto_generichash_keybytes, [], :size_t
|
20
|
+
|
21
|
+
PRIMITIVE = primitive.freeze
|
22
|
+
BYTES_MIN = bytes_min.freeze
|
23
|
+
BYTES_MAX = bytes_max.freeze
|
24
|
+
BYTES = bytes.freeze
|
25
|
+
KEYBYTES_MIN = keybytes_min.freeze
|
26
|
+
KEYBYTES_MAX = keybytes_max.freeze
|
27
|
+
KEYBYTES = keybytes.freeze
|
28
|
+
|
29
|
+
attach_function :crypto_generichash, [:buffer_out, :size_t, :buffer_in, :ulong_long, :buffer_in, :size_t], :int, blocking: true
|
30
|
+
|
31
|
+
class State < FFI::Struct
|
32
|
+
pack 64
|
33
|
+
layout :h, [:uint64, 8],
|
34
|
+
:t, [:uint64, 2],
|
35
|
+
:f, [:uint64, 2],
|
36
|
+
:buf, [:uint8, 2 * 128],
|
37
|
+
:buflen, :size_t,
|
38
|
+
:last_node, :uint8
|
39
|
+
end
|
40
|
+
|
41
|
+
attach_function :crypto_generichash_init, [State.ptr, :buffer_in, :size_t, :size_t], :int, blocking: true
|
42
|
+
attach_function :crypto_generichash_update, [State.ptr, :buffer_in, :ulong_long], :int, blocking: true
|
43
|
+
attach_function :crypto_generichash_final, [State.ptr, :buffer_out, :ulong_long], :int, blocking: true
|
44
|
+
|
45
|
+
module_function
|
46
|
+
|
47
|
+
def generichash(message, hash_size = BYTES, key = nil)
|
48
|
+
message_len = get_size(message)
|
49
|
+
if hash_size > BYTES_MAX ||hash_size < BYTES_MIN
|
50
|
+
fail Sodium::LengthError, "Hash size must be between #{BYTES_MIN} and #{BYTES_MAX} bytes, got size=#{hash_size.to_int} bytes", caller
|
51
|
+
end
|
52
|
+
|
53
|
+
if key
|
54
|
+
key_len = get_size(key)
|
55
|
+
|
56
|
+
if key_len > KEYBYTES_MAX ||key_len < KEYBYTES_MIN
|
57
|
+
fail Sodium::LengthError, "Key length must be between #{KEYBYTES_MIN} and #{KEYBYTES_MAX} bytes, got length=#{key_len} bytes", caller
|
58
|
+
end
|
59
|
+
else
|
60
|
+
key_len = 0
|
61
|
+
end
|
62
|
+
|
63
|
+
blake2b = Sodium::Buffer.new(:uchar, hash_size)
|
64
|
+
key.readonly if key.is_a?(Sodium::SecretBuffer)
|
65
|
+
rc = crypto_generichash(blake2b, hash_size, message, message_len, key, key_len)
|
66
|
+
key.noaccess if key.is_a?(Sodium::SecretBuffer)
|
67
|
+
if rc == -1
|
68
|
+
raise Sodium::CryptoError
|
69
|
+
end
|
70
|
+
|
71
|
+
blake2b
|
72
|
+
end
|
73
|
+
|
74
|
+
def init(key = nil, hash_size = BYTES)
|
75
|
+
if key
|
76
|
+
key_len = get_size(key)
|
77
|
+
|
78
|
+
if key_len > KEYBYTES_MAX ||key_len < KEYBYTES_MIN
|
79
|
+
fail Sodium::LengthError, "Key length must be between #{KEYBYTES_MIN} and #{KEYBYTES_MAX} bytes, got length=#{key_len} bytes", caller
|
80
|
+
end
|
81
|
+
else
|
82
|
+
key_len = 0
|
83
|
+
end
|
84
|
+
|
85
|
+
if hash_size > BYTES_MAX ||hash_size < BYTES_MIN
|
86
|
+
fail Sodium::LengthError, "Hash size must be between #{BYTES_MIN} and #{BYTES_MAX} bytes, got size=#{hash_size.to_int} bytes", caller
|
87
|
+
end
|
88
|
+
|
89
|
+
state = State.new
|
90
|
+
blake2b = Sodium::Buffer.new(:uchar, hash_size)
|
91
|
+
key.readonly if key.is_a?(Sodium::SecretBuffer)
|
92
|
+
rc = crypto_generichash_init(state, key, key_len, hash_size)
|
93
|
+
key.noaccess if key.is_a?(Sodium::SecretBuffer)
|
94
|
+
if rc == -1
|
95
|
+
raise Sodium::CryptoError
|
96
|
+
end
|
97
|
+
|
98
|
+
[state, blake2b]
|
99
|
+
end
|
100
|
+
|
101
|
+
def update(state, message)
|
102
|
+
message_len = get_size(message)
|
103
|
+
|
104
|
+
if crypto_generichash_update(state, message, message_len) == -1
|
105
|
+
raise Sodium::CryptoError
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def final(state, blake2b)
|
110
|
+
get_pointer(blake2b)
|
111
|
+
|
112
|
+
if crypto_generichash_final(state, blake2b, blake2b.size) == -1
|
113
|
+
raise Sodium::CryptoError
|
114
|
+
end
|
115
|
+
|
116
|
+
blake2b
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def self.generichash(*args)
|
121
|
+
GenericHash.generichash(*args)
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require_relative '../sodium'
|
2
|
+
require_relative '../sodium/utils'
|
3
|
+
require_relative '../sodium/buffer'
|
4
|
+
require_relative '../sodium/secret_buffer'
|
5
|
+
|
6
|
+
module Crypto
|
7
|
+
module OneTimeAuth
|
8
|
+
extend FFI::Library
|
9
|
+
extend Sodium::Utils
|
10
|
+
|
11
|
+
ffi_lib :libsodium
|
12
|
+
|
13
|
+
attach_function :primitive, :crypto_onetimeauth_primitive, [], :string
|
14
|
+
attach_function :bytes, :crypto_onetimeauth_bytes, [], :size_t
|
15
|
+
attach_function :keybytes, :crypto_onetimeauth_keybytes, [], :size_t
|
16
|
+
|
17
|
+
PRIMITIVE = primitive.freeze
|
18
|
+
BYTES = bytes.freeze
|
19
|
+
KEYBYTES = keybytes.freeze
|
20
|
+
|
21
|
+
attach_function :crypto_onetimeauth, [:buffer_out, :buffer_in, :ulong_long, :buffer_in], :int
|
22
|
+
attach_function :crypto_onetimeauth_verify, [:buffer_in, :buffer_in, :ulong_long, :buffer_in], :int
|
23
|
+
|
24
|
+
class State < FFI::Struct
|
25
|
+
layout :aligner, :ulong_long,
|
26
|
+
:opaque, [:uchar, 136]
|
27
|
+
end
|
28
|
+
|
29
|
+
attach_function :crypto_onetimeauth_init, [State.ptr, :buffer_in], :int
|
30
|
+
attach_function :crypto_onetimeauth_update, [State.ptr, :buffer_in, :ulong_long], :int
|
31
|
+
attach_function :crypto_onetimeauth_final, [State.ptr, :buffer_out], :int
|
32
|
+
|
33
|
+
module_function
|
34
|
+
|
35
|
+
def onetimeauth(message, key)
|
36
|
+
message_len = get_size(message)
|
37
|
+
check_length(key, KEYBYTES, :SecretKey)
|
38
|
+
|
39
|
+
out = Sodium::Buffer.new(:uchar, BYTES)
|
40
|
+
key.readonly if key.is_a?(Sodium::SecretBuffer)
|
41
|
+
crypto_onetimeauth(out, message, message_len, key)
|
42
|
+
key.noaccess if key.is_a?(Sodium::SecretBuffer)
|
43
|
+
|
44
|
+
out
|
45
|
+
end
|
46
|
+
|
47
|
+
def verify(out, message, key)
|
48
|
+
check_length(out, BYTES, :Authenticator)
|
49
|
+
message_len = get_size(message)
|
50
|
+
check_length(key, KEYBYTES, :SecretKey)
|
51
|
+
|
52
|
+
key.readonly if key.is_a?(Sodium::SecretBuffer)
|
53
|
+
rc = crypto_onetimeauth_verify(out, message, message_len, key)
|
54
|
+
key.noaccess if key.is_a?(Sodium::SecretBuffer)
|
55
|
+
|
56
|
+
rc == 0
|
57
|
+
end
|
58
|
+
|
59
|
+
def init(key)
|
60
|
+
check_length(key, KEYBYTES, :SecretKey)
|
61
|
+
|
62
|
+
state = State.new
|
63
|
+
key.readonly if key.is_a?(Sodium::SecretBuffer)
|
64
|
+
crypto_onetimeauth_init(state, key)
|
65
|
+
key.noaccess if key.is_a?(Sodium::SecretBuffer)
|
66
|
+
|
67
|
+
state
|
68
|
+
end
|
69
|
+
|
70
|
+
def update(state, message)
|
71
|
+
message_len = get_size(message)
|
72
|
+
|
73
|
+
crypto_onetimeauth_update(state, message, message_len)
|
74
|
+
end
|
75
|
+
|
76
|
+
def final(state)
|
77
|
+
out = Sodium::Buffer.new(:uchar, BYTES)
|
78
|
+
crypto_onetimeauth_final(state, out)
|
79
|
+
|
80
|
+
out
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.onetimeauth(*args)
|
85
|
+
OneTimeAuth.onetimeauth(*args)
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require_relative '../../sodium'
|
2
|
+
require_relative '../../sodium/utils'
|
3
|
+
require_relative '../../sodium/buffer'
|
4
|
+
require_relative '../../sodium/secret_buffer'
|
5
|
+
require_relative '../../random_bytes'
|
6
|
+
|
7
|
+
module Crypto
|
8
|
+
module PwHash
|
9
|
+
module ScryptSalsa208SHA256
|
10
|
+
PACK_C = 'c*'.freeze
|
11
|
+
PRIMITIVE = 'scryptsalsa208sha256'.freeze
|
12
|
+
|
13
|
+
extend FFI::Library
|
14
|
+
extend Sodium::Utils
|
15
|
+
|
16
|
+
ffi_lib :libsodium
|
17
|
+
|
18
|
+
class << self
|
19
|
+
def crypto_pwhash_scryptsalsa208sha256_primitive
|
20
|
+
PRIMITIVE
|
21
|
+
end
|
22
|
+
|
23
|
+
alias_method :primitive, :crypto_pwhash_scryptsalsa208sha256_primitive
|
24
|
+
end
|
25
|
+
|
26
|
+
attach_function :saltbytes, :crypto_pwhash_scryptsalsa208sha256_saltbytes, [], :size_t
|
27
|
+
attach_function :strbytes, :crypto_pwhash_scryptsalsa208sha256_strbytes, [], :size_t
|
28
|
+
attach_function :strprefix, :crypto_pwhash_scryptsalsa208sha256_strprefix, [], :string
|
29
|
+
attach_function :opslimit_interactive, :crypto_pwhash_scryptsalsa208sha256_opslimit_interactive, [], :size_t
|
30
|
+
attach_function :memlimit_interactive, :crypto_pwhash_scryptsalsa208sha256_memlimit_interactive, [], :size_t
|
31
|
+
attach_function :opslimit_sensitive, :crypto_pwhash_scryptsalsa208sha256_opslimit_sensitive, [], :size_t
|
32
|
+
attach_function :memlimit_sensitive, :crypto_pwhash_scryptsalsa208sha256_memlimit_sensitive, [], :size_t
|
33
|
+
|
34
|
+
SALTBYTES = saltbytes.freeze
|
35
|
+
STRBYTES = strbytes.freeze
|
36
|
+
STRPREFIX = strprefix.freeze
|
37
|
+
OPSLIMIT_INTERACTIVE = opslimit_interactive.freeze
|
38
|
+
MEMLIMIT_INTERACTIVE = memlimit_interactive.freeze
|
39
|
+
OPSLIMIT_SENSITIVE = opslimit_sensitive.freeze
|
40
|
+
MEMLIMIT_SENSITIVE = memlimit_sensitive.freeze
|
41
|
+
|
42
|
+
attach_function :crypto_pwhash_scryptsalsa208sha256, [:buffer_out, :ulong_long, :buffer_in, :ulong_long, :buffer_in, :ulong_long, :size_t], :int, blocking: true
|
43
|
+
attach_function :crypto_pwhash_scryptsalsa208sha256_str, [:buffer_out, :buffer_in, :ulong_long, :ulong_long, :size_t], :int, blocking: true
|
44
|
+
attach_function :crypto_pwhash_scryptsalsa208sha256_str_verify, [:buffer_in, :buffer_in, :ulong_long], :int, blocking: true
|
45
|
+
|
46
|
+
module_function
|
47
|
+
|
48
|
+
def salt
|
49
|
+
RandomBytes.buf(SALTBYTES)
|
50
|
+
end
|
51
|
+
|
52
|
+
def scryptsalsa208sha256(passwd, outlen, salt, opslimit = OPSLIMIT_INTERACTIVE, memlimit = MEMLIMIT_INTERACTIVE)
|
53
|
+
passwd_len = get_size(passwd)
|
54
|
+
check_length(salt, SALTBYTES, :Salt)
|
55
|
+
if opslimit < OPSLIMIT_INTERACTIVE
|
56
|
+
fail Sodium::LengthError, "Opslimit must be at least #{OPSLIMIT_INTERACTIVE}, got #{opslimit.to_int}", caller
|
57
|
+
end
|
58
|
+
if memlimit < MEMLIMIT_INTERACTIVE
|
59
|
+
fail Sodium::LengthError, "Memlimit must be at least #{MEMLIMIT_INTERACTIVE}, got #{memlimit.to_int}", caller
|
60
|
+
end
|
61
|
+
|
62
|
+
out = Sodium::SecretBuffer.new(outlen)
|
63
|
+
rc = crypto_pwhash_scryptsalsa208sha256(out, outlen, passwd, passwd_len, salt, opslimit, memlimit)
|
64
|
+
out.noaccess
|
65
|
+
if rc == -1
|
66
|
+
raise NoMemoryError, "Failed to allocate memory max size=#{memlimit.to_int} bytes", caller
|
67
|
+
end
|
68
|
+
|
69
|
+
out
|
70
|
+
end
|
71
|
+
|
72
|
+
def str(passwd, opslimit = OPSLIMIT_INTERACTIVE, memlimit = MEMLIMIT_INTERACTIVE)
|
73
|
+
passwd_len = get_size(passwd)
|
74
|
+
if opslimit < OPSLIMIT_INTERACTIVE
|
75
|
+
fail Sodium::LengthError, "Opslimit must be at least #{OPSLIMIT_INTERACTIVE}, got #{opslimit.to_int}", caller
|
76
|
+
end
|
77
|
+
if memlimit < MEMLIMIT_INTERACTIVE
|
78
|
+
fail Sodium::LengthError, "Memlimit must be at least #{MEMLIMIT_INTERACTIVE}, got #{memlimit.to_int}", caller
|
79
|
+
end
|
80
|
+
|
81
|
+
hashed_password = FFI::MemoryPointer.new(:char, STRBYTES)
|
82
|
+
if crypto_pwhash_scryptsalsa208sha256_str(hashed_password, passwd, passwd_len, opslimit, memlimit) == -1
|
83
|
+
raise NoMemoryError, "Failed to allocate memory max size=#{memlimit.to_int} bytes", caller
|
84
|
+
end
|
85
|
+
|
86
|
+
hashed_password.read_array_of_char(STRBYTES).pack(PACK_C)
|
87
|
+
end
|
88
|
+
|
89
|
+
def str_verify(str, passwd)
|
90
|
+
check_length(str, STRBYTES, :Str)
|
91
|
+
passwd_len = get_size(passwd)
|
92
|
+
|
93
|
+
crypto_pwhash_scryptsalsa208sha256_str_verify(str, passwd, passwd_len) == 0
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def self.scryptsalsa208sha256(*args)
|
98
|
+
ScryptSalsa208SHA256.scryptsalsa208sha256(*args)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require_relative '../sodium'
|
2
|
+
require_relative '../sodium/utils'
|
3
|
+
require_relative '../sodium/buffer'
|
4
|
+
require_relative '../sodium/secret_buffer'
|
5
|
+
require_relative '../random_bytes'
|
6
|
+
|
7
|
+
module Crypto
|
8
|
+
module ScalarMult
|
9
|
+
extend FFI::Library
|
10
|
+
extend Sodium::Utils
|
11
|
+
|
12
|
+
ffi_lib :libsodium
|
13
|
+
|
14
|
+
attach_function :primitive, :crypto_scalarmult_primitive, [], :string
|
15
|
+
attach_function :bytes, :crypto_scalarmult_bytes, [], :size_t
|
16
|
+
attach_function :scalarbytes, :crypto_scalarmult_scalarbytes, [], :size_t
|
17
|
+
|
18
|
+
PRIMITIVE = primitive.freeze
|
19
|
+
BYTES = bytes.freeze
|
20
|
+
SCALARBYTES = scalarbytes.freeze
|
21
|
+
|
22
|
+
attach_function :crypto_scalarmult_base, [:buffer_out, :buffer_in], :int
|
23
|
+
attach_function :crypto_scalarmult, [:buffer_out, :buffer_in, :buffer_in], :int
|
24
|
+
|
25
|
+
module_function
|
26
|
+
|
27
|
+
def base(secret_key)
|
28
|
+
check_length(secret_key, SCALARBYTES, :SecretKey)
|
29
|
+
|
30
|
+
public_key = Sodium::Buffer.new(:uchar, BYTES)
|
31
|
+
secret_key.readonly if secret_key.is_a?(Sodium::SecretBuffer)
|
32
|
+
crypto_scalarmult_base(public_key, secret_key)
|
33
|
+
secret_key.noaccess if secret_key.is_a?(Sodium::SecretBuffer)
|
34
|
+
|
35
|
+
public_key
|
36
|
+
end
|
37
|
+
|
38
|
+
def scalarmut(secret_key, public_key)
|
39
|
+
check_length(secret_key, SCALARBYTES, :SecretKey)
|
40
|
+
check_length(public_key, SCALARBYTES, :PublicKey)
|
41
|
+
|
42
|
+
shared_secret = Sodium::SecretBuffer.new(BYTES)
|
43
|
+
secret_key.readonly if secret_key.is_a?(Sodium::SecretBuffer)
|
44
|
+
crypto_scalarmult(shared_secret, secret_key, public_key)
|
45
|
+
secret_key.noaccess if secret_key.is_a?(Sodium::SecretBuffer)
|
46
|
+
shared_secret.noaccess
|
47
|
+
|
48
|
+
shared_secret
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.scalarmut(*args)
|
53
|
+
ScalarMult.scalarmut(*args)
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require_relative '../sodium'
|
2
|
+
require_relative '../sodium/utils'
|
3
|
+
require_relative '../sodium/buffer'
|
4
|
+
require_relative '../sodium/secret_buffer'
|
5
|
+
require_relative '../random_bytes'
|
6
|
+
|
7
|
+
module Crypto
|
8
|
+
module SecretBox
|
9
|
+
extend FFI::Library
|
10
|
+
extend Sodium::Utils
|
11
|
+
|
12
|
+
ffi_lib :libsodium
|
13
|
+
|
14
|
+
attach_function :primitive, :crypto_secretbox_primitive, [], :string
|
15
|
+
attach_function :keybytes, :crypto_secretbox_keybytes, [], :size_t
|
16
|
+
attach_function :noncebytes, :crypto_secretbox_noncebytes, [], :size_t
|
17
|
+
attach_function :macbytes, :crypto_secretbox_macbytes, [], :size_t
|
18
|
+
|
19
|
+
PRIMITIVE = primitive.freeze
|
20
|
+
KEYBYTES = keybytes.freeze
|
21
|
+
NONCEBYTES = noncebytes.freeze
|
22
|
+
MACBYTES = macbytes.freeze
|
23
|
+
|
24
|
+
attach_function :crypto_secretbox_easy, [:buffer_out, :buffer_in, :ulong_long, :buffer_in, :buffer_in], :int, blocking: true
|
25
|
+
attach_function :crypto_secretbox_open_easy, [:buffer_out, :buffer_in, :ulong_long, :buffer_in, :buffer_in], :int, blocking: true
|
26
|
+
|
27
|
+
module_function
|
28
|
+
|
29
|
+
def nonce
|
30
|
+
RandomBytes.buf(NONCEBYTES)
|
31
|
+
end
|
32
|
+
|
33
|
+
def easy(message, nonce, key)
|
34
|
+
message_len = get_size(message)
|
35
|
+
check_length(nonce, NONCEBYTES, :Nonce)
|
36
|
+
check_length(key, KEYBYTES, :SecretKey)
|
37
|
+
|
38
|
+
ciphertext = Sodium::Buffer.new(:uchar, MACBYTES + message_len)
|
39
|
+
key.readonly if key.is_a?(Sodium::SecretBuffer)
|
40
|
+
crypto_secretbox_easy(ciphertext, message, message_len, nonce, key)
|
41
|
+
key.noaccess if key.is_a?(Sodium::SecretBuffer)
|
42
|
+
|
43
|
+
ciphertext
|
44
|
+
end
|
45
|
+
|
46
|
+
def open_easy(ciphertext, nonce, key)
|
47
|
+
ciphertext_len = get_size(ciphertext)
|
48
|
+
check_length(nonce, NONCEBYTES, :Nonce)
|
49
|
+
check_length(key, KEYBYTES, :SecretKey)
|
50
|
+
|
51
|
+
decrypted = Sodium::Buffer.new(:uchar, ciphertext_len - MACBYTES)
|
52
|
+
key.readonly if key.is_a?(Sodium::SecretBuffer)
|
53
|
+
rc = crypto_secretbox_open_easy(decrypted, ciphertext, ciphertext_len, nonce, key)
|
54
|
+
key.noaccess if key.is_a?(Sodium::SecretBuffer)
|
55
|
+
if rc == -1
|
56
|
+
raise Sodium::CryptoError, "Message forged", caller
|
57
|
+
end
|
58
|
+
|
59
|
+
decrypted
|
60
|
+
end
|
61
|
+
|
62
|
+
def easy_in_place(data, nonce, key)
|
63
|
+
message = get_string(data)
|
64
|
+
check_length(nonce, NONCEBYTES, :Nonce)
|
65
|
+
check_length(key, KEYBYTES, :SecretKey)
|
66
|
+
|
67
|
+
message_len = message.bytesize
|
68
|
+
message << zeros(MACBYTES)
|
69
|
+
key.readonly if key.is_a?(Sodium::SecretBuffer)
|
70
|
+
crypto_secretbox_easy(message, message, message_len, nonce, key)
|
71
|
+
key.noaccess if key.is_a?(Sodium::SecretBuffer)
|
72
|
+
|
73
|
+
message
|
74
|
+
end
|
75
|
+
|
76
|
+
def open_easy_in_place(data, nonce, key, utf8 = false)
|
77
|
+
ciphertext = get_string(data)
|
78
|
+
unless (message_len = ciphertext.bytesize - MACBYTES) > 0
|
79
|
+
fail Sodium::LengthError, "Ciphertext is too short", caller
|
80
|
+
end
|
81
|
+
|
82
|
+
check_length(nonce, NONCEBYTES, :Nonce)
|
83
|
+
check_length(key, KEYBYTES, :SecretKey)
|
84
|
+
|
85
|
+
key.readonly if key.is_a?(Sodium::SecretBuffer)
|
86
|
+
rc = crypto_secretbox_open_easy(ciphertext, ciphertext, ciphertext.bytesize, nonce, key)
|
87
|
+
key.noaccess if key.is_a?(Sodium::SecretBuffer)
|
88
|
+
if rc == -1
|
89
|
+
raise Sodium::CryptoError, "Message forged", caller
|
90
|
+
end
|
91
|
+
|
92
|
+
if utf8
|
93
|
+
ciphertext.slice!(message_len..-1).force_encoding(Encoding::UTF_8)
|
94
|
+
else
|
95
|
+
ciphertext.slice!(message_len..-1)
|
96
|
+
end
|
97
|
+
|
98
|
+
ciphertext
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|