gmssl 1.0.5 → 1.1.0
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 +4 -4
- data/lib/gmssl/ghash.rb +29 -0
- data/lib/gmssl/random.rb +19 -0
- data/lib/gmssl/sm3.rb +90 -0
- data/lib/gmssl/sm4.rb +172 -0
- data/lib/gmssl/version.rb +4 -0
- data/lib/gmssl/zuc.rb +72 -0
- data/lib/gmssl.rb +2 -0
- data/test/helper.rb +17 -0
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 91be02f2afeab55a32d5baa453111c80def28f5d1abfbf6be95b137f216103dd
|
4
|
+
data.tar.gz: 8b6c27ee63aac9a32249f6050fe146211f14ba0cb50c021791e4b6886a011a79
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 00c9c994e7a478215afa4705a4ac03d8b08e5e651d4cc8b1ddd1a7a9b6224fe62e2c3804ae4dca950c6b4ddc44a7b68d75fcce8f7098a99782ff9cf73ae22095
|
7
|
+
data.tar.gz: 42770e67af88dcde97433e3a70064bcef5dececf5700ff232752385f41cca461adc3b781ee7548aa0346aaf1d88a6edc84296fa19857b0c1223d3ce381aa8056
|
data/lib/gmssl/ghash.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ffi'
|
4
|
+
|
5
|
+
module GmSSL
|
6
|
+
module Ghash
|
7
|
+
extend FFI::Library
|
8
|
+
file = File.join GmSSL.lib, LIB_FILE
|
9
|
+
ffi_lib file
|
10
|
+
|
11
|
+
class GF128 < FFI::Struct
|
12
|
+
layout :data, [:uint64, 2]
|
13
|
+
end
|
14
|
+
|
15
|
+
class GHASH_CTX < FFI::Struct
|
16
|
+
layout :H, GF128,
|
17
|
+
:X, GF128,
|
18
|
+
:aadlen, :size_t,
|
19
|
+
:clen, :size_t,
|
20
|
+
:block, [:uint8, 16],
|
21
|
+
:num, :size_t
|
22
|
+
end
|
23
|
+
|
24
|
+
attach_function :ghash, [:pointer, :pointer, :size_t, :pointer, :size_t, :pointer], :void
|
25
|
+
attach_function :ghash_init, [GHASH_CTX.by_ref, :pointer, :pointer, :size_t], :void
|
26
|
+
attach_function :ghash_update, [GHASH_CTX.by_ref, :pointer, :size_t], :void
|
27
|
+
attach_function :ghash_finish, [GHASH_CTX.by_ref, :pointer], :void
|
28
|
+
end
|
29
|
+
end
|
data/lib/gmssl/random.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ffi'
|
4
|
+
|
5
|
+
module GmSSL
|
6
|
+
module Random
|
7
|
+
extend FFI::Library
|
8
|
+
file = File.join GmSSL.lib, LIB_FILE
|
9
|
+
ffi_lib file
|
10
|
+
|
11
|
+
attach_function :rand_bytes, [:pointer, :size_t], :int
|
12
|
+
|
13
|
+
def self.bytes(n = 256)
|
14
|
+
buf = FFI::MemoryPointer.new(:uint8, n)
|
15
|
+
Random.rand_bytes(buf, n)
|
16
|
+
buf.read_bytes(n).unpack('H*').first
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/gmssl/sm3.rb
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ffi'
|
4
|
+
require 'helper'
|
5
|
+
|
6
|
+
module GmSSL
|
7
|
+
module SM3
|
8
|
+
extend FFI::Library
|
9
|
+
file = File.join GmSSL.lib, LIB_FILE
|
10
|
+
ffi_lib file
|
11
|
+
|
12
|
+
SM3_DIGEST_SIZE = 32
|
13
|
+
SM3_BLOCK_SIZE = 64
|
14
|
+
SM3_STATE_WORDS = 8
|
15
|
+
SM3_HMAC_SIZE = SM3_DIGEST_SIZE
|
16
|
+
SM3_PBKDF2_MIN_ITER = 10000
|
17
|
+
SM3_PBKDF2_MAX_ITER = 16777215
|
18
|
+
SM3_PBKDF2_MAX_SALT_SIZE = 64
|
19
|
+
SM3_PBKDF2_DEFAULT_SALT_SIZE = 8
|
20
|
+
|
21
|
+
class SM3_CTX < FFI::Struct
|
22
|
+
layout :digest, [:uint32, SM3_STATE_WORDS],
|
23
|
+
:nblocks, :uint64,
|
24
|
+
:block, [:uint8, SM3_BLOCK_SIZE],
|
25
|
+
:num, :size_t
|
26
|
+
end
|
27
|
+
|
28
|
+
class SM3_HMAC_CTX < FFI::Struct
|
29
|
+
layout :sm3_ctx, SM3_CTX,
|
30
|
+
:key, [:uint8, SM3_BLOCK_SIZE]
|
31
|
+
end
|
32
|
+
|
33
|
+
class SM3_KDF_CTX < FFI::Struct
|
34
|
+
layout :sm3_ctx, SM3_CTX,
|
35
|
+
:outlen, :size_t
|
36
|
+
end
|
37
|
+
|
38
|
+
class SM3_DIGEST_CTX < FFI::Union
|
39
|
+
layout :sm3_ctx, SM3_CTX,
|
40
|
+
:hmac_ctx, SM3_HMAC_CTX
|
41
|
+
end
|
42
|
+
|
43
|
+
attach_function :sm3_compress_blocks, [:pointer, :pointer, :size_t], :void
|
44
|
+
attach_function :sm3_init, [SM3_CTX.by_ref], :void
|
45
|
+
attach_function :sm3_update, [SM3_CTX.by_ref, :pointer, :size_t], :void
|
46
|
+
attach_function :sm3_finish, [SM3_CTX.by_ref, :pointer], :void
|
47
|
+
|
48
|
+
attach_function :sm3_hmac_init, [SM3_HMAC_CTX.by_ref, :pointer, :size_t], :void
|
49
|
+
attach_function :sm3_hmac_update, [SM3_HMAC_CTX.by_ref, :pointer, :size_t], :void
|
50
|
+
attach_function :sm3_hmac_finish, [SM3_HMAC_CTX.by_ref, :pointer], :void
|
51
|
+
|
52
|
+
attach_function :sm3_kdf_init, [SM3_KDF_CTX.by_ref, :size_t], :void
|
53
|
+
attach_function :sm3_kdf_update, [SM3_KDF_CTX.by_ref, :pointer, :size_t], :void
|
54
|
+
attach_function :sm3_kdf_finish, [SM3_KDF_CTX.by_ref, :pointer], :void
|
55
|
+
attach_function :sm3_pbkdf2, [:string, :size_t, :pointer, :size_t, :size_t, :size_t, :pointer], :int
|
56
|
+
|
57
|
+
attach_function :sm3_digest_init, [SM3_DIGEST_CTX.by_ref, :pointer, :size_t], :int
|
58
|
+
attach_function :sm3_digest_update, [SM3_DIGEST_CTX.by_ref, :pointer, :size_t], :int
|
59
|
+
attach_function :sm3_digest_finish, [SM3_DIGEST_CTX.by_ref, :pointer], :int
|
60
|
+
|
61
|
+
def self.digest(data)
|
62
|
+
# Initialize SM3
|
63
|
+
sm3_ctx = SM3_CTX.new
|
64
|
+
sm3_init(sm3_ctx)
|
65
|
+
# Update SM3 context with data
|
66
|
+
sm3_update(sm3_ctx, data, data.bytesize)
|
67
|
+
# Finalize the hash
|
68
|
+
digest = FFI::MemoryPointer.new(:uint8, SM3_DIGEST_SIZE)
|
69
|
+
sm3_finish(sm3_ctx, digest)
|
70
|
+
digest.read_bytes(SM3_DIGEST_SIZE).unpack1('H*')
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.hmac(hex_key, data)
|
74
|
+
key = hex_string_to_packed_bytes(hex_key)
|
75
|
+
ctx = SM3_HMAC_CTX.new
|
76
|
+
sm3_hmac_init(ctx, key, key.bytesize)
|
77
|
+
sm3_hmac_update(ctx, data, data.bytesize)
|
78
|
+
mac = FFI::MemoryPointer.new(:uint8, SM3_HMAC_SIZE)
|
79
|
+
sm3_hmac_finish(ctx, mac)
|
80
|
+
mac.read_string(SM3_HMAC_SIZE).unpack1('H*')
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.pbkdf2(psswd, hex_salt, iterations, outlen)
|
84
|
+
salt = hex_string_to_packed_bytes(hex_salt)
|
85
|
+
out = FFI::MemoryPointer.new(:uint8, outlen)
|
86
|
+
sm3_pbkdf2(psswd, psswd.bytesize, salt, salt.bytesize, iterations, outlen, out)
|
87
|
+
out.read_string(outlen).unpack1('H*')
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
data/lib/gmssl/sm4.rb
ADDED
@@ -0,0 +1,172 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ffi'
|
4
|
+
|
5
|
+
require 'gmssl/ghash'
|
6
|
+
|
7
|
+
module GmSSL
|
8
|
+
module SM4
|
9
|
+
extend FFI::Library
|
10
|
+
file = File.join GmSSL.lib, LIB_FILE
|
11
|
+
ffi_lib file
|
12
|
+
|
13
|
+
SM4_KEY_SIZE = 16
|
14
|
+
SM4_BLOCK_SIZE = 16
|
15
|
+
SM4_NUM_ROUNDS = 32
|
16
|
+
SM4_GCM_MAX_TAG_SIZE = 16
|
17
|
+
|
18
|
+
class SM4_KEY < FFI::Struct
|
19
|
+
layout :rk, [:uint32, SM4_NUM_ROUNDS]
|
20
|
+
end
|
21
|
+
|
22
|
+
class SM4_CBC_CTX < FFI::Struct
|
23
|
+
layout :sm4_key, SM4_KEY,
|
24
|
+
:iv, [:uint8, SM4_BLOCK_SIZE],
|
25
|
+
:block, [:uint8, SM4_BLOCK_SIZE],
|
26
|
+
:block_nbytes, :size_t
|
27
|
+
end
|
28
|
+
|
29
|
+
class SM4_CTR_CTX < FFI::Struct
|
30
|
+
layout :sm4_key, SM4_KEY,
|
31
|
+
:ctr, [:uint8, SM4_BLOCK_SIZE],
|
32
|
+
:block, [:uint8, SM4_BLOCK_SIZE],
|
33
|
+
:block_nbytes, :size_t
|
34
|
+
end
|
35
|
+
|
36
|
+
class SM4_GCM_CTX < FFI::Struct
|
37
|
+
layout :enc_ctx, SM4_CTR_CTX,
|
38
|
+
:mac_ctx, GmSSL::Ghash::GHASH_CTX, # GHASH_CTX defined in ghash.rb
|
39
|
+
:Y, [:uint8, 16],
|
40
|
+
:taglen, :size_t,
|
41
|
+
:mac, [:uint8, 16],
|
42
|
+
:maclen, :size_t,
|
43
|
+
:encedlen, :uint64
|
44
|
+
end
|
45
|
+
|
46
|
+
attach_function :sm4_set_encrypt_key, [SM4_KEY.by_ref, :pointer], :void
|
47
|
+
attach_function :sm4_set_decrypt_key, [SM4_KEY.by_ref, :pointer], :void
|
48
|
+
attach_function :sm4_encrypt, [SM4_KEY.by_ref, :pointer, :pointer], :void
|
49
|
+
|
50
|
+
attach_function :sm4_encrypt_blocks, [SM4_KEY.by_ref, :pointer, :size_t, :pointer], :void
|
51
|
+
attach_function :sm4_cbc_encrypt_blocks, [SM4_KEY.by_ref, :pointer, :pointer, :size_t, :pointer], :void
|
52
|
+
attach_function :sm4_cbc_decrypt_blocks, [SM4_KEY.by_ref, :pointer, :pointer, :size_t, :pointer], :void
|
53
|
+
attach_function :sm4_ctr_encrypt_blocks, [SM4_KEY.by_ref, :pointer, :pointer, :size_t, :pointer], :void
|
54
|
+
attach_function :sm4_ctr32_encrypt_blocks, [SM4_KEY.by_ref, :pointer, :pointer, :size_t, :pointer], :void
|
55
|
+
|
56
|
+
attach_function :sm4_cbc_padding_encrypt, [SM4_KEY.by_ref, :pointer, :pointer, :size_t, :pointer, :pointer], :int
|
57
|
+
attach_function :sm4_cbc_padding_decrypt, [SM4_KEY.by_ref, :pointer, :pointer, :size_t, :pointer, :pointer], :int
|
58
|
+
attach_function :sm4_ctr_encrypt, [SM4_KEY.by_ref, :pointer, :pointer, :size_t, :pointer], :void
|
59
|
+
attach_function :sm4_ctr32_encrypt, [SM4_KEY.by_ref, :pointer, :pointer, :size_t, :pointer], :void
|
60
|
+
|
61
|
+
attach_function :sm4_cbc_encrypt_init, [SM4_CBC_CTX.by_ref, :pointer, :pointer], :int
|
62
|
+
attach_function :sm4_cbc_encrypt_update, [SM4_CBC_CTX.by_ref, :pointer, :size_t, :pointer, :pointer], :int
|
63
|
+
attach_function :sm4_cbc_encrypt_finish, [SM4_CBC_CTX.by_ref, :pointer, :pointer], :int
|
64
|
+
attach_function :sm4_cbc_decrypt_init, [SM4_CBC_CTX.by_ref, :pointer, :pointer], :int
|
65
|
+
attach_function :sm4_cbc_decrypt_update, [SM4_CBC_CTX.by_ref, :pointer, :size_t, :pointer, :pointer], :int
|
66
|
+
attach_function :sm4_cbc_decrypt_finish, [SM4_CBC_CTX.by_ref, :pointer, :pointer], :int
|
67
|
+
|
68
|
+
attach_function :sm4_ctr_encrypt_init, [SM4_CTR_CTX.by_ref, :pointer, :pointer], :int
|
69
|
+
attach_function :sm4_ctr_encrypt_update, [SM4_CTR_CTX.by_ref, :pointer, :size_t, :pointer, :pointer], :int
|
70
|
+
attach_function :sm4_ctr_encrypt_finish, [SM4_CTR_CTX.by_ref, :pointer, :pointer], :int
|
71
|
+
attach_function :sm4_ctr32_encrypt_init, [SM4_CTR_CTX.by_ref, :pointer, :pointer], :int
|
72
|
+
attach_function :sm4_ctr32_encrypt_update, [SM4_CTR_CTX.by_ref, :pointer, :size_t, :pointer, :pointer], :int
|
73
|
+
attach_function :sm4_ctr32_encrypt_finish, [SM4_CTR_CTX.by_ref, :pointer, :pointer], :int
|
74
|
+
|
75
|
+
attach_function :sm4_gcm_encrypt, [SM4_KEY.by_ref, :pointer, :size_t, :pointer, :size_t, :pointer, :size_t, :pointer, :size_t, :pointer], :int
|
76
|
+
attach_function :sm4_gcm_decrypt, [SM4_KEY.by_ref, :pointer, :size_t, :pointer, :size_t, :pointer, :size_t, :pointer, :size_t, :pointer], :int
|
77
|
+
|
78
|
+
attach_function :sm4_gcm_encrypt_init, [SM4_GCM_CTX.by_ref, :pointer, :size_t, :pointer, :size_t, :pointer, :size_t, :size_t], :int
|
79
|
+
attach_function :sm4_gcm_encrypt_update, [SM4_GCM_CTX.by_ref, :pointer, :size_t, :pointer, :pointer], :int
|
80
|
+
attach_function :sm4_gcm_encrypt_finish, [SM4_GCM_CTX.by_ref, :pointer, :pointer], :int
|
81
|
+
attach_function :sm4_gcm_decrypt_init, [SM4_GCM_CTX.by_ref, :pointer, :size_t, :pointer, :size_t, :pointer, :size_t, :size_t], :int
|
82
|
+
attach_function :sm4_gcm_decrypt_update, [SM4_GCM_CTX.by_ref, :pointer, :size_t, :pointer, :pointer], :int
|
83
|
+
attach_function :sm4_gcm_decrypt_finish, [SM4_GCM_CTX.by_ref, :pointer, :pointer], :int
|
84
|
+
|
85
|
+
def self.cbc_encrypt(key, iv, plaintext)
|
86
|
+
ctx = SM4::SM4_CBC_CTX.new
|
87
|
+
SM4.sm4_cbc_encrypt_init(ctx, key, iv)
|
88
|
+
ciphertext = FFI::MemoryPointer.new(:uint8, plaintext.bytesize + SM4::SM4_BLOCK_SIZE)
|
89
|
+
outlen = FFI::MemoryPointer.new(:size_t)
|
90
|
+
SM4.sm4_cbc_encrypt_update(ctx, plaintext, plaintext.bytesize, ciphertext, outlen)
|
91
|
+
ciphertext_len = outlen.read(:size_t)
|
92
|
+
SM4.sm4_cbc_encrypt_finish(ctx, ciphertext + ciphertext_len, outlen)
|
93
|
+
ciphertext_len += outlen.read(:size_t)
|
94
|
+
bytes_to_hex_string ciphertext.read_bytes(ciphertext_len)
|
95
|
+
end
|
96
|
+
|
97
|
+
def self.cbc_decrypt(key, iv, ciphertext)
|
98
|
+
ciphertext = hex_string_to_packed_bytes ciphertext
|
99
|
+
ctx = SM4::SM4_CBC_CTX.new
|
100
|
+
SM4.sm4_cbc_decrypt_init(ctx, key, iv)
|
101
|
+
decrypted = FFI::MemoryPointer.new(:uint8, ciphertext.bytesize + SM4::SM4_BLOCK_SIZE)
|
102
|
+
outlen = FFI::MemoryPointer.new(:size_t)
|
103
|
+
SM4.sm4_cbc_decrypt_update(ctx, ciphertext, ciphertext.bytesize, decrypted, outlen)
|
104
|
+
decrypted_len = outlen.read(:size_t)
|
105
|
+
SM4.sm4_cbc_decrypt_finish(ctx, decrypted + decrypted_len, outlen)
|
106
|
+
decrypted_len += outlen.read(:size_t)
|
107
|
+
decrypted.read_bytes(decrypted_len)
|
108
|
+
end
|
109
|
+
|
110
|
+
def self.ctr_encrypt(input_string, key_hex, ctr_hex)
|
111
|
+
key = hex_string_to_packed_bytes(key_hex)
|
112
|
+
ctr = hex_string_to_packed_bytes(ctr_hex)
|
113
|
+
input_data = input_string.bytes.pack("C*")
|
114
|
+
output_data = FFI::MemoryPointer.new(:uint8, input_data.bytesize)
|
115
|
+
output_length = FFI::MemoryPointer.new(:size_t)
|
116
|
+
key_ptr = FFI::MemoryPointer.new(:uint8, SM4::SM4_KEY_SIZE)
|
117
|
+
ctr_ptr = FFI::MemoryPointer.new(:uint8, SM4::SM4_BLOCK_SIZE)
|
118
|
+
key_ptr.put_array_of_uint8(0, key.bytes)
|
119
|
+
ctr_ptr.put_array_of_uint8(0, ctr.bytes)
|
120
|
+
ctx = SM4::SM4_CTR_CTX.new
|
121
|
+
SM4.sm4_ctr_encrypt_init(ctx, key_ptr, ctr_ptr)
|
122
|
+
SM4.sm4_ctr_encrypt_update(ctx, input_data, input_data.bytesize, output_data, output_length)
|
123
|
+
SM4.sm4_ctr_encrypt_finish(ctx, output_data, output_length)
|
124
|
+
encrypted_data = output_data.read_string(output_length.read(:size_t))
|
125
|
+
encrypted_data.unpack("H*")[0]
|
126
|
+
end
|
127
|
+
|
128
|
+
def self.gcm_encrypt(key, iv, aad, input)
|
129
|
+
key = hex_string_to_packed_bytes key
|
130
|
+
iv = hex_string_to_packed_bytes iv
|
131
|
+
key_struct = SM4::SM4_KEY.new
|
132
|
+
key_ptr = FFI::MemoryPointer.new(:uint8, SM4::SM4_KEY_SIZE)
|
133
|
+
key_ptr.put_array_of_uint8(0, key.bytes)
|
134
|
+
SM4::sm4_set_encrypt_key(key_struct, key_ptr)
|
135
|
+
iv_ptr = FFI::MemoryPointer.new(:uint8, SM4::SM4_BLOCK_SIZE)
|
136
|
+
iv_ptr.put_array_of_uint8(0, iv.bytes)
|
137
|
+
aad_ptr = FFI::MemoryPointer.new(:uint8, aad.bytesize)
|
138
|
+
aad_ptr.put_array_of_uint8(0, aad.bytes)
|
139
|
+
input_ptr = FFI::MemoryPointer.new(:uint8, input.bytesize)
|
140
|
+
input_ptr.put_array_of_uint8(0, input.bytes)
|
141
|
+
output_ptr = FFI::MemoryPointer.new(:uint8, input.bytesize)
|
142
|
+
tag_ptr = FFI::MemoryPointer.new(:uint8, SM4::SM4_GCM_MAX_TAG_SIZE)
|
143
|
+
SM4::sm4_gcm_encrypt(key_struct, iv_ptr, iv.bytesize, aad_ptr, aad.bytesize, input_ptr, input.bytesize, output_ptr, SM4::SM4_GCM_MAX_TAG_SIZE, tag_ptr)
|
144
|
+
encrypted_output = encrypted_output = output_ptr.read_string(input.bytesize).unpack1("H*")
|
145
|
+
tag = tag_ptr.read_string(SM4::SM4_GCM_MAX_TAG_SIZE).unpack1("H*")
|
146
|
+
return encrypted_output, tag
|
147
|
+
end
|
148
|
+
|
149
|
+
def self.gcm_decrypt(key, iv, aad, encrypted_output, tag)
|
150
|
+
encrypted_output = hex_string_to_packed_bytes encrypted_output
|
151
|
+
tag = hex_string_to_packed_bytes tag
|
152
|
+
key = hex_string_to_packed_bytes key
|
153
|
+
iv = hex_string_to_packed_bytes iv
|
154
|
+
key_struct = SM4::SM4_KEY.new
|
155
|
+
key_ptr = FFI::MemoryPointer.new(:uint8, SM4::SM4_KEY_SIZE)
|
156
|
+
key_ptr.put_array_of_uint8(0, key.bytes)
|
157
|
+
SM4::sm4_set_encrypt_key(key_struct, key_ptr)
|
158
|
+
iv_ptr = FFI::MemoryPointer.new(:uint8, SM4::SM4_BLOCK_SIZE)
|
159
|
+
iv_ptr.put_array_of_uint8(0, iv.bytes)
|
160
|
+
aad_ptr = FFI::MemoryPointer.new(:uint8, aad.bytesize)
|
161
|
+
aad_ptr.put_array_of_uint8(0, aad.bytes)
|
162
|
+
encrypted_ptr = FFI::MemoryPointer.new(:uint8, encrypted_output.bytesize)
|
163
|
+
encrypted_ptr.put_array_of_uint8(0, encrypted_output.bytes)
|
164
|
+
tag_ptr = FFI::MemoryPointer.new(:uint8, SM4::SM4_GCM_MAX_TAG_SIZE)
|
165
|
+
tag_ptr.put_array_of_uint8(0, tag.bytes)
|
166
|
+
decrypted_output_ptr = FFI::MemoryPointer.new(:uint8, encrypted_output.bytesize)
|
167
|
+
SM4::sm4_gcm_decrypt(key_struct, iv_ptr, iv.bytesize, aad_ptr, aad.bytesize, encrypted_ptr, encrypted_output.bytesize, tag_ptr, SM4::SM4_GCM_MAX_TAG_SIZE, decrypted_output_ptr)
|
168
|
+
decrypted_output = decrypted_output_ptr.read_string(encrypted_output.bytesize)
|
169
|
+
return decrypted_output
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
data/lib/gmssl/version.rb
CHANGED
data/lib/gmssl/zuc.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ffi'
|
4
|
+
require 'helper'
|
5
|
+
|
6
|
+
module GmSSL
|
7
|
+
module ZUC
|
8
|
+
extend FFI::Library
|
9
|
+
file = File.join GmSSL.lib, LIB_FILE
|
10
|
+
ffi_lib file
|
11
|
+
|
12
|
+
ZUC_KEY_SIZE = 16
|
13
|
+
ZUC_IV_SIZE = 16
|
14
|
+
|
15
|
+
class ZUC_STATE < FFI::Struct
|
16
|
+
layout :LFSR, [:uint32, 16],
|
17
|
+
:R1, :uint32,
|
18
|
+
:R2, :uint32
|
19
|
+
end
|
20
|
+
|
21
|
+
class ZUC_CTX < FFI::Struct
|
22
|
+
layout :zuc_state, ZUC_STATE,
|
23
|
+
:block, [:uint8, 4],
|
24
|
+
:block_nbytes, :size_t
|
25
|
+
end
|
26
|
+
|
27
|
+
attach_function :zuc_init, [ZUC_STATE.by_ref, :pointer, :pointer], :void
|
28
|
+
attach_function :zuc_encrypt, [ZUC_STATE.by_ref, :pointer, :size_t, :pointer], :void
|
29
|
+
attach_function :zuc_encrypt_init, [ZUC_CTX.by_ref, :pointer, :pointer], :int
|
30
|
+
attach_function :zuc_encrypt_update, [ZUC_CTX.by_ref, :pointer, :size_t, :pointer, :pointer], :int
|
31
|
+
attach_function :zuc_encrypt_finish, [ZUC_CTX.by_ref, :pointer, :pointer], :int
|
32
|
+
|
33
|
+
def self.encrypt(key, iv, input)
|
34
|
+
key = hex_string_to_packed_bytes key
|
35
|
+
iv = hex_string_to_packed_bytes iv
|
36
|
+
key_ptr = FFI::MemoryPointer.new(:uint8, ZUC::ZUC_KEY_SIZE)
|
37
|
+
key_ptr.put_array_of_uint8(0, key.bytes)
|
38
|
+
iv_ptr = FFI::MemoryPointer.new(:uint8, ZUC::ZUC_IV_SIZE)
|
39
|
+
iv_ptr.put_array_of_uint8(0, iv.bytes)
|
40
|
+
ctx = ZUC::ZUC_CTX.new
|
41
|
+
ZUC::zuc_encrypt_init(ctx, key_ptr, iv_ptr)
|
42
|
+
input_ptr = FFI::MemoryPointer.new(:uint8, input.bytesize)
|
43
|
+
input_ptr.put_array_of_uint8(0, input.bytes)
|
44
|
+
output_ptr = FFI::MemoryPointer.new(:uint8, input.bytesize)
|
45
|
+
outlen_ptr = FFI::MemoryPointer.new(:size_t)
|
46
|
+
ZUC::zuc_encrypt_update(ctx, input_ptr, input.bytesize, output_ptr, outlen_ptr)
|
47
|
+
ZUC::zuc_encrypt_finish(ctx, output_ptr, outlen_ptr)
|
48
|
+
encrypted_output = output_ptr.get_array_of_uint8(0, input.bytesize)
|
49
|
+
bytes_to_hex_string encrypted_output.pack('C*')
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.decrypt(key, iv, encrypted_output)
|
53
|
+
encrypted_output = hex_string_to_packed_bytes encrypted_output
|
54
|
+
key = hex_string_to_packed_bytes key
|
55
|
+
iv = hex_string_to_packed_bytes iv
|
56
|
+
key_ptr = FFI::MemoryPointer.new(:uint8, ZUC::ZUC_KEY_SIZE)
|
57
|
+
key_ptr.put_array_of_uint8(0, key.bytes)
|
58
|
+
iv_ptr = FFI::MemoryPointer.new(:uint8, ZUC::ZUC_IV_SIZE)
|
59
|
+
iv_ptr.put_array_of_uint8(0, iv.bytes)
|
60
|
+
ctx = ZUC::ZUC_CTX.new
|
61
|
+
ZUC::zuc_encrypt_init(ctx, key_ptr, iv_ptr)
|
62
|
+
encrypted_input_ptr = FFI::MemoryPointer.new(:uint8, encrypted_output.bytesize)
|
63
|
+
encrypted_input_ptr.put_array_of_uint8(0, encrypted_output.bytes)
|
64
|
+
decrypted_output_ptr = FFI::MemoryPointer.new(:uint8, encrypted_output.bytesize)
|
65
|
+
outlen_ptr = FFI::MemoryPointer.new(:size_t)
|
66
|
+
ZUC::zuc_encrypt_update(ctx, encrypted_input_ptr, encrypted_output.bytesize, decrypted_output_ptr, outlen_ptr)
|
67
|
+
ZUC::zuc_encrypt_finish(ctx, decrypted_output_ptr, outlen_ptr)
|
68
|
+
decrypted_output = decrypted_output_ptr.get_array_of_uint8(0, encrypted_output.bytesize)
|
69
|
+
decrypted_output.pack('C*')
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
data/lib/gmssl.rb
CHANGED
data/test/helper.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Example usage
|
4
|
+
# hex_string = "54A38E3B599E48C4F581FEC14B62EA29"
|
5
|
+
# packed_bytes = hex_string_to_packed_bytes(hex_string)
|
6
|
+
# puts packed_bytes
|
7
|
+
def hex_string_to_packed_bytes(hex_string)
|
8
|
+
hex_string.scan(/../).map { |byte| byte.hex }.pack("C*")
|
9
|
+
end
|
10
|
+
|
11
|
+
# Example usage
|
12
|
+
# bytes = [0x54, 0xA3, 0x8E, 0x3B, 0x59, 0x9E, 0x48, 0xC4]
|
13
|
+
# hex_string = bytes_to_hex_string(bytes.pack('C*'))
|
14
|
+
# puts hex_string
|
15
|
+
def bytes_to_hex_string(bytes)
|
16
|
+
bytes.unpack1('H*')
|
17
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gmssl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- memorycancel
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-01-
|
10
|
+
date: 2025-01-22 00:00:00.000000000 Z
|
11
11
|
dependencies: []
|
12
12
|
description: GmSSL c to ruby FFI
|
13
13
|
email: memorycancel@gmail.com
|
@@ -67,7 +67,13 @@ files:
|
|
67
67
|
- GmSSL/build/bin/x509test
|
68
68
|
- GmSSL/build/bin/zuctest
|
69
69
|
- lib/gmssl.rb
|
70
|
+
- lib/gmssl/ghash.rb
|
71
|
+
- lib/gmssl/random.rb
|
72
|
+
- lib/gmssl/sm3.rb
|
73
|
+
- lib/gmssl/sm4.rb
|
70
74
|
- lib/gmssl/version.rb
|
75
|
+
- lib/gmssl/zuc.rb
|
76
|
+
- test/helper.rb
|
71
77
|
homepage: https://rubygems.org/gems/gmssl
|
72
78
|
licenses:
|
73
79
|
- MIT
|