pq_crypto-seal 0.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 +7 -0
- data/.github/workflows/ci.yml +66 -0
- data/CHANGELOG.md +44 -0
- data/FORMAT.md +139 -0
- data/GET_STARTED.md +30 -0
- data/Gemfile +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +215 -0
- data/RELEASING.md +34 -0
- data/Rakefile +19 -0
- data/SECURITY.md +85 -0
- data/VENDORING.md +14 -0
- data/ext/pq_crypto_seal/aegis_unused_stubs.c +20 -0
- data/ext/pq_crypto_seal/extconf.rb +296 -0
- data/ext/pq_crypto_seal/pq_crypto_seal.c +390 -0
- data/ext/pq_crypto_seal/vendor/libaegis/LICENSE +21 -0
- data/ext/pq_crypto_seal/vendor/libaegis/TREE_SHA256 +1 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l.c +246 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_aesni.c +73 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_aesni.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_altivec.c +70 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_altivec.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_common.h +691 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_neon_aes.c +77 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_neon_aes.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_neon_sha3.c +86 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_neon_sha3.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_soft.c +63 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_soft.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/implementations.h +40 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2.c +247 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_aesni.c +108 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_aesni.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_altivec.c +103 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_altivec.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_avx2.c +79 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_avx2.h +11 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_common.h +795 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_neon_aes.c +111 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_neon_aes.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_soft.c +96 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_soft.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/implementations.h +40 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4.c +252 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_aesni.c +117 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_aesni.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_altivec.c +111 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_altivec.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_avx2.c +112 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_avx2.h +11 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_avx512.c +85 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_avx512.h +11 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_common.h +808 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_neon_aes.c +119 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_neon_aes.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_soft.c +104 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_soft.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/implementations.h +41 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256/aegis256.c +240 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256/aegis256_aesni.c +68 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256/aegis256_aesni.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256/aegis256_altivec.c +68 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256/aegis256_altivec.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256/aegis256_common.h +673 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256/aegis256_neon_aes.c +75 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256/aegis256_neon_aes.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256/aegis256_soft.c +58 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256/aegis256_soft.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256/implementations.h +39 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2.c +247 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_aesni.c +103 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_aesni.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_altivec.c +101 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_altivec.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_avx2.c +74 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_avx2.h +11 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_common.h +790 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_neon_aes.c +109 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_neon_aes.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_soft.c +91 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_soft.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/implementations.h +41 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4.c +252 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_aesni.c +112 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_aesni.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_altivec.c +109 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_altivec.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_avx2.c +107 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_avx2.h +11 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_avx512.c +79 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_avx512.h +11 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_common.h +805 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_neon_aes.c +117 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_neon_aes.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_soft.c +99 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_soft.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/implementations.h +42 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/common/common.c +81 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/common/common.h +144 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/common/cpu.c +378 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/common/cpu.h +34 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/common/keccak.c +187 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/common/keccak.h +13 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/common/softaes.c +338 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/common/softaes.h +69 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/include/aegis.h +77 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/include/aegis128l.h +311 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/include/aegis128x2.h +313 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/include/aegis128x4.h +313 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/include/aegis256.h +311 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/include/aegis256x2.h +313 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/include/aegis256x4.h +313 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/include/aegis_raf.h +580 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/raf/raf.c +87 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/raf/raf_aegis128l.c +20 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/raf/raf_aegis128x2.c +20 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/raf/raf_aegis128x4.c +20 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/raf/raf_aegis256.c +20 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/raf/raf_aegis256x2.c +20 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/raf/raf_aegis256x4.c +20 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/raf/raf_internal.h +152 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/raf/raf_merkle.c +268 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/raf/raf_merkle.h +165 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/raf/raf_variant.h +1119 -0
- data/fuzz/decrypt_fuzz.rb +119 -0
- data/lib/pq_crypto/seal/binary.rb +62 -0
- data/lib/pq_crypto/seal/core.rb +398 -0
- data/lib/pq_crypto/seal/errors.rb +15 -0
- data/lib/pq_crypto/seal/format.rb +275 -0
- data/lib/pq_crypto/seal/io.rb +336 -0
- data/lib/pq_crypto/seal/native.rb +13 -0
- data/lib/pq_crypto/seal/padding.rb +47 -0
- data/lib/pq_crypto/seal/version.rb +6 -0
- data/lib/pq_crypto/seal.rb +32 -0
- data/pq_crypto-seal.gemspec +37 -0
- data/script/vendor_libs.rb +79 -0
- data/test/aegis_vectors_test.rb +54 -0
- data/test/golden_vectors_test.rb +183 -0
- data/test/io_test.rb +125 -0
- data/test/native_test.rb +36 -0
- data/test/seal_test.rb +238 -0
- data/test/test_helper.rb +6 -0
- metadata +244 -0
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
#include "ruby.h"
|
|
2
|
+
#include "ruby/thread.h"
|
|
3
|
+
#include <limits.h>
|
|
4
|
+
#include <stdint.h>
|
|
5
|
+
#include <string.h>
|
|
6
|
+
#include <openssl/crypto.h>
|
|
7
|
+
#include <openssl/evp.h>
|
|
8
|
+
#include <openssl/hmac.h>
|
|
9
|
+
#include <openssl/rand.h>
|
|
10
|
+
#include "aegis.h"
|
|
11
|
+
#include "aegis256.h"
|
|
12
|
+
|
|
13
|
+
#define KEY_BYTES 32
|
|
14
|
+
#define NONCE_BYTES 32
|
|
15
|
+
#define TAG_BYTES 32
|
|
16
|
+
#define NOGVL_THRESHOLD 32768
|
|
17
|
+
|
|
18
|
+
typedef struct {
|
|
19
|
+
aegis256_state state;
|
|
20
|
+
int mode;
|
|
21
|
+
int finalized;
|
|
22
|
+
} seal_state;
|
|
23
|
+
|
|
24
|
+
static VALUE mPQCrypto, mSeal, mNative, cEncryptor, cDecryptor, eAuth;
|
|
25
|
+
|
|
26
|
+
static void secure_free(void *ptr) {
|
|
27
|
+
seal_state *st = (seal_state *)ptr;
|
|
28
|
+
if (st != NULL) {
|
|
29
|
+
OPENSSL_cleanse(st, sizeof(*st));
|
|
30
|
+
xfree(st);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
static size_t state_memsize(const void *ptr) {
|
|
35
|
+
return ptr ? sizeof(seal_state) : 0;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
static const rb_data_type_t state_type = {"PQCrypto::Seal::NativeState",
|
|
39
|
+
{0, secure_free, state_memsize, 0, {0}},
|
|
40
|
+
0,
|
|
41
|
+
0,
|
|
42
|
+
RUBY_TYPED_FREE_IMMEDIATELY};
|
|
43
|
+
|
|
44
|
+
static VALUE state_alloc(VALUE klass) {
|
|
45
|
+
seal_state *st;
|
|
46
|
+
VALUE obj = TypedData_Make_Struct(klass, seal_state, &state_type, st);
|
|
47
|
+
memset(st, 0, sizeof(*st));
|
|
48
|
+
return obj;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
static void require_length(VALUE str, long expected, const char *name) {
|
|
52
|
+
StringValue(str);
|
|
53
|
+
if (RSTRING_LEN(str) != expected)
|
|
54
|
+
rb_raise(rb_eArgError, "%s must be %ld bytes", name, expected);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
static VALUE native_random_bytes(VALUE self, VALUE length_value) {
|
|
58
|
+
(void)self;
|
|
59
|
+
long length = NUM2LONG(length_value);
|
|
60
|
+
if (length < 0)
|
|
61
|
+
rb_raise(rb_eArgError, "length must be non-negative");
|
|
62
|
+
VALUE out = rb_str_new(NULL, length);
|
|
63
|
+
long offset = 0;
|
|
64
|
+
while (offset < length) {
|
|
65
|
+
int chunk = (int)((length - offset) > INT_MAX ? INT_MAX : (length - offset));
|
|
66
|
+
if (RAND_bytes((unsigned char *)RSTRING_PTR(out) + offset, chunk) != 1) {
|
|
67
|
+
rb_raise(rb_eRuntimeError, "OpenSSL RAND_bytes failed");
|
|
68
|
+
}
|
|
69
|
+
offset += chunk;
|
|
70
|
+
}
|
|
71
|
+
return out;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
static VALUE native_sha256(VALUE self, VALUE input) {
|
|
75
|
+
(void)self;
|
|
76
|
+
StringValue(input);
|
|
77
|
+
unsigned char digest[EVP_MAX_MD_SIZE];
|
|
78
|
+
unsigned int length = 0;
|
|
79
|
+
if (EVP_Digest(RSTRING_PTR(input), (size_t)RSTRING_LEN(input), digest, &length, EVP_sha256(),
|
|
80
|
+
NULL) != 1 ||
|
|
81
|
+
length != 32) {
|
|
82
|
+
rb_raise(rb_eRuntimeError, "OpenSSL SHA-256 failed");
|
|
83
|
+
}
|
|
84
|
+
return rb_str_new((const char *)digest, 32);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
static VALUE native_hkdf_sha256(VALUE self, VALUE ikm, VALUE info, VALUE length_value) {
|
|
88
|
+
(void)self;
|
|
89
|
+
StringValue(ikm);
|
|
90
|
+
StringValue(info);
|
|
91
|
+
|
|
92
|
+
long requested = NUM2LONG(length_value);
|
|
93
|
+
if (requested <= 0 || requested > 8160) {
|
|
94
|
+
rb_raise(rb_eArgError, "invalid HKDF output length");
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const long ikm_len_long = RSTRING_LEN(ikm);
|
|
98
|
+
const long info_len_long = RSTRING_LEN(info);
|
|
99
|
+
if (ikm_len_long < 0 || ikm_len_long > INT_MAX) {
|
|
100
|
+
rb_raise(rb_eArgError, "HKDF input key material is too large");
|
|
101
|
+
}
|
|
102
|
+
if (info_len_long < 0) {
|
|
103
|
+
rb_raise(rb_eArgError, "HKDF info length is invalid");
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const size_t ikm_len = (size_t)ikm_len_long;
|
|
107
|
+
const size_t info_len = (size_t)info_len_long;
|
|
108
|
+
if (info_len > SIZE_MAX - 33U) {
|
|
109
|
+
rb_raise(rb_eArgError, "HKDF info is too large");
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
VALUE out = rb_str_new(NULL, requested);
|
|
113
|
+
const size_t expand_capacity = 32U + info_len + 1U;
|
|
114
|
+
unsigned char *expand_input = ALLOC_N(unsigned char, expand_capacity);
|
|
115
|
+
unsigned char salt[32] = {0};
|
|
116
|
+
unsigned char prk[32] = {0};
|
|
117
|
+
unsigned char t[32] = {0};
|
|
118
|
+
unsigned int digest_len = 0;
|
|
119
|
+
size_t t_len = 0;
|
|
120
|
+
size_t produced = 0;
|
|
121
|
+
unsigned int block = 1;
|
|
122
|
+
|
|
123
|
+
if (HMAC(EVP_sha256(), salt, (int)sizeof(salt), (const unsigned char *)RSTRING_PTR(ikm),
|
|
124
|
+
ikm_len, prk, &digest_len) == NULL ||
|
|
125
|
+
digest_len != sizeof(prk)) {
|
|
126
|
+
OPENSSL_cleanse(expand_input, expand_capacity);
|
|
127
|
+
xfree(expand_input);
|
|
128
|
+
OPENSSL_cleanse(prk, sizeof(prk));
|
|
129
|
+
OPENSSL_cleanse(t, sizeof(t));
|
|
130
|
+
rb_raise(rb_eRuntimeError, "OpenSSL HMAC-SHA256 extract failed");
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
while (produced < (size_t)requested) {
|
|
134
|
+
size_t input_len = 0;
|
|
135
|
+
if (t_len != 0) {
|
|
136
|
+
memcpy(expand_input, t, t_len);
|
|
137
|
+
input_len += t_len;
|
|
138
|
+
}
|
|
139
|
+
if (info_len != 0) {
|
|
140
|
+
memcpy(expand_input + input_len, RSTRING_PTR(info), info_len);
|
|
141
|
+
input_len += info_len;
|
|
142
|
+
}
|
|
143
|
+
expand_input[input_len++] = (unsigned char)block;
|
|
144
|
+
|
|
145
|
+
digest_len = 0;
|
|
146
|
+
if (HMAC(EVP_sha256(), prk, (int)sizeof(prk), expand_input, input_len, t, &digest_len) ==
|
|
147
|
+
NULL ||
|
|
148
|
+
digest_len != sizeof(t)) {
|
|
149
|
+
OPENSSL_cleanse(expand_input, expand_capacity);
|
|
150
|
+
xfree(expand_input);
|
|
151
|
+
OPENSSL_cleanse(prk, sizeof(prk));
|
|
152
|
+
OPENSSL_cleanse(t, sizeof(t));
|
|
153
|
+
rb_raise(rb_eRuntimeError, "OpenSSL HMAC-SHA256 expand failed");
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
t_len = sizeof(t);
|
|
157
|
+
size_t remaining = (size_t)requested - produced;
|
|
158
|
+
size_t copy_len = remaining < t_len ? remaining : t_len;
|
|
159
|
+
memcpy((unsigned char *)RSTRING_PTR(out) + produced, t, copy_len);
|
|
160
|
+
produced += copy_len;
|
|
161
|
+
block++;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
OPENSSL_cleanse(expand_input, expand_capacity);
|
|
165
|
+
xfree(expand_input);
|
|
166
|
+
OPENSSL_cleanse(prk, sizeof(prk));
|
|
167
|
+
OPENSSL_cleanse(t, sizeof(t));
|
|
168
|
+
RB_GC_GUARD(ikm);
|
|
169
|
+
RB_GC_GUARD(info);
|
|
170
|
+
return out;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
static VALUE native_hkdf_backend(VALUE self) {
|
|
174
|
+
(void)self;
|
|
175
|
+
return rb_str_new_cstr("rfc5869-hmac-sha256-v1");
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
typedef struct {
|
|
179
|
+
const uint8_t *key, *nonce, *ad, *input, *tag;
|
|
180
|
+
uint8_t *output, *out_tag;
|
|
181
|
+
size_t adlen, input_len;
|
|
182
|
+
int result;
|
|
183
|
+
} one_shot_args;
|
|
184
|
+
|
|
185
|
+
static void *encrypt_without_gvl(void *ptr) {
|
|
186
|
+
one_shot_args *a = (one_shot_args *)ptr;
|
|
187
|
+
a->result = aegis256_encrypt_detached(a->output, a->out_tag, TAG_BYTES, a->input, a->input_len,
|
|
188
|
+
a->ad, a->adlen, a->nonce, a->key);
|
|
189
|
+
return NULL;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
static void *decrypt_without_gvl(void *ptr) {
|
|
193
|
+
one_shot_args *a = (one_shot_args *)ptr;
|
|
194
|
+
a->result = aegis256_decrypt_detached(a->output, a->input, a->input_len, a->tag, TAG_BYTES,
|
|
195
|
+
a->ad, a->adlen, a->nonce, a->key);
|
|
196
|
+
return NULL;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
static VALUE native_encrypt(VALUE self, VALUE key, VALUE nonce, VALUE ad, VALUE plaintext) {
|
|
200
|
+
(void)self;
|
|
201
|
+
require_length(key, KEY_BYTES, "key");
|
|
202
|
+
require_length(nonce, NONCE_BYTES, "nonce");
|
|
203
|
+
StringValue(ad);
|
|
204
|
+
StringValue(plaintext);
|
|
205
|
+
VALUE ciphertext = rb_str_new(NULL, RSTRING_LEN(plaintext));
|
|
206
|
+
VALUE tag = rb_str_new(NULL, TAG_BYTES);
|
|
207
|
+
one_shot_args args = {(uint8_t *)RSTRING_PTR(key),
|
|
208
|
+
(uint8_t *)RSTRING_PTR(nonce),
|
|
209
|
+
(uint8_t *)RSTRING_PTR(ad),
|
|
210
|
+
(uint8_t *)RSTRING_PTR(plaintext),
|
|
211
|
+
NULL,
|
|
212
|
+
(uint8_t *)RSTRING_PTR(ciphertext),
|
|
213
|
+
(uint8_t *)RSTRING_PTR(tag),
|
|
214
|
+
(size_t)RSTRING_LEN(ad),
|
|
215
|
+
(size_t)RSTRING_LEN(plaintext),
|
|
216
|
+
-1};
|
|
217
|
+
if (args.input_len >= NOGVL_THRESHOLD)
|
|
218
|
+
rb_thread_call_without_gvl(encrypt_without_gvl, &args, RUBY_UBF_IO, NULL);
|
|
219
|
+
else
|
|
220
|
+
encrypt_without_gvl(&args);
|
|
221
|
+
RB_GC_GUARD(key);
|
|
222
|
+
RB_GC_GUARD(nonce);
|
|
223
|
+
RB_GC_GUARD(ad);
|
|
224
|
+
RB_GC_GUARD(plaintext);
|
|
225
|
+
if (args.result != 0)
|
|
226
|
+
rb_raise(rb_eRuntimeError, "AEGIS-256 encryption failed");
|
|
227
|
+
return rb_ary_new_from_args(2, ciphertext, tag);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
static VALUE native_decrypt(VALUE self, VALUE key, VALUE nonce, VALUE ad, VALUE ciphertext,
|
|
231
|
+
VALUE tag) {
|
|
232
|
+
(void)self;
|
|
233
|
+
require_length(key, KEY_BYTES, "key");
|
|
234
|
+
require_length(nonce, NONCE_BYTES, "nonce");
|
|
235
|
+
require_length(tag, TAG_BYTES, "tag");
|
|
236
|
+
StringValue(ad);
|
|
237
|
+
StringValue(ciphertext);
|
|
238
|
+
VALUE plaintext = rb_str_new(NULL, RSTRING_LEN(ciphertext));
|
|
239
|
+
one_shot_args args = {(uint8_t *)RSTRING_PTR(key),
|
|
240
|
+
(uint8_t *)RSTRING_PTR(nonce),
|
|
241
|
+
(uint8_t *)RSTRING_PTR(ad),
|
|
242
|
+
(uint8_t *)RSTRING_PTR(ciphertext),
|
|
243
|
+
(uint8_t *)RSTRING_PTR(tag),
|
|
244
|
+
(uint8_t *)RSTRING_PTR(plaintext),
|
|
245
|
+
NULL,
|
|
246
|
+
(size_t)RSTRING_LEN(ad),
|
|
247
|
+
(size_t)RSTRING_LEN(ciphertext),
|
|
248
|
+
-1};
|
|
249
|
+
if (args.input_len >= NOGVL_THRESHOLD)
|
|
250
|
+
rb_thread_call_without_gvl(decrypt_without_gvl, &args, RUBY_UBF_IO, NULL);
|
|
251
|
+
else
|
|
252
|
+
decrypt_without_gvl(&args);
|
|
253
|
+
RB_GC_GUARD(key);
|
|
254
|
+
RB_GC_GUARD(nonce);
|
|
255
|
+
RB_GC_GUARD(ad);
|
|
256
|
+
RB_GC_GUARD(ciphertext);
|
|
257
|
+
RB_GC_GUARD(tag);
|
|
258
|
+
if (args.result != 0) {
|
|
259
|
+
OPENSSL_cleanse(RSTRING_PTR(plaintext), (size_t)RSTRING_LEN(plaintext));
|
|
260
|
+
rb_raise(eAuth, "AEGIS-256 authentication failed");
|
|
261
|
+
}
|
|
262
|
+
return plaintext;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
static VALUE native_secure_equal(VALUE self, VALUE a, VALUE b) {
|
|
266
|
+
(void)self;
|
|
267
|
+
StringValue(a);
|
|
268
|
+
StringValue(b);
|
|
269
|
+
if (RSTRING_LEN(a) != RSTRING_LEN(b))
|
|
270
|
+
return Qfalse;
|
|
271
|
+
return CRYPTO_memcmp(RSTRING_PTR(a), RSTRING_PTR(b), (size_t)RSTRING_LEN(a)) == 0 ? Qtrue
|
|
272
|
+
: Qfalse;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
static VALUE state_initialize(VALUE self, VALUE key, VALUE nonce, VALUE ad) {
|
|
276
|
+
seal_state *st;
|
|
277
|
+
TypedData_Get_Struct(self, seal_state, &state_type, st);
|
|
278
|
+
require_length(key, KEY_BYTES, "key");
|
|
279
|
+
require_length(nonce, NONCE_BYTES, "nonce");
|
|
280
|
+
StringValue(ad);
|
|
281
|
+
aegis256_state_init(&st->state, (uint8_t *)RSTRING_PTR(ad), (size_t)RSTRING_LEN(ad),
|
|
282
|
+
(uint8_t *)RSTRING_PTR(nonce), (uint8_t *)RSTRING_PTR(key));
|
|
283
|
+
st->finalized = 0;
|
|
284
|
+
st->mode = rb_obj_is_kind_of(self, cEncryptor) ? 1 : 2;
|
|
285
|
+
return self;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
typedef struct {
|
|
289
|
+
seal_state *st;
|
|
290
|
+
const uint8_t *in;
|
|
291
|
+
uint8_t *out;
|
|
292
|
+
size_t len;
|
|
293
|
+
int result;
|
|
294
|
+
} update_args;
|
|
295
|
+
static void *update_encrypt_nogvl(void *ptr) {
|
|
296
|
+
update_args *a = ptr;
|
|
297
|
+
a->result = aegis256_state_encrypt_update(&a->st->state, a->out, a->in, a->len);
|
|
298
|
+
return NULL;
|
|
299
|
+
}
|
|
300
|
+
static void *update_decrypt_nogvl(void *ptr) {
|
|
301
|
+
update_args *a = ptr;
|
|
302
|
+
a->result = aegis256_state_decrypt_update(&a->st->state, a->out, a->in, a->len);
|
|
303
|
+
return NULL;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
static VALUE state_update(VALUE self, VALUE input) {
|
|
307
|
+
seal_state *st;
|
|
308
|
+
TypedData_Get_Struct(self, seal_state, &state_type, st);
|
|
309
|
+
if (st->mode != 1 && st->mode != 2)
|
|
310
|
+
rb_raise(rb_eRuntimeError, "AEGIS state is not initialized");
|
|
311
|
+
if (st->finalized)
|
|
312
|
+
rb_raise(rb_eRuntimeError, "AEGIS state is finalized");
|
|
313
|
+
StringValue(input);
|
|
314
|
+
VALUE out = rb_str_new(NULL, RSTRING_LEN(input));
|
|
315
|
+
update_args args = {st, (uint8_t *)RSTRING_PTR(input), (uint8_t *)RSTRING_PTR(out),
|
|
316
|
+
(size_t)RSTRING_LEN(input), -1};
|
|
317
|
+
void *(*fn)(void *) = st->mode == 1 ? update_encrypt_nogvl : update_decrypt_nogvl;
|
|
318
|
+
if (args.len >= NOGVL_THRESHOLD)
|
|
319
|
+
rb_thread_call_without_gvl(fn, &args, RUBY_UBF_IO, NULL);
|
|
320
|
+
else
|
|
321
|
+
fn(&args);
|
|
322
|
+
RB_GC_GUARD(input);
|
|
323
|
+
if (args.result != 0)
|
|
324
|
+
rb_raise(rb_eRuntimeError, "AEGIS-256 update failed");
|
|
325
|
+
return out;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
static VALUE encrypt_final(VALUE self) {
|
|
329
|
+
seal_state *st;
|
|
330
|
+
TypedData_Get_Struct(self, seal_state, &state_type, st);
|
|
331
|
+
if (st->mode != 1)
|
|
332
|
+
rb_raise(rb_eRuntimeError, "AEGIS encrypt state is not initialized");
|
|
333
|
+
if (st->finalized)
|
|
334
|
+
rb_raise(rb_eRuntimeError, "AEGIS state is finalized");
|
|
335
|
+
VALUE tag = rb_str_new(NULL, TAG_BYTES);
|
|
336
|
+
int result = aegis256_state_encrypt_final(&st->state, (uint8_t *)RSTRING_PTR(tag), TAG_BYTES);
|
|
337
|
+
st->finalized = 1;
|
|
338
|
+
OPENSSL_cleanse(&st->state, sizeof(st->state));
|
|
339
|
+
if (result != 0)
|
|
340
|
+
rb_raise(rb_eRuntimeError, "AEGIS-256 finalization failed");
|
|
341
|
+
return tag;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
static VALUE decrypt_final(VALUE self, VALUE tag) {
|
|
345
|
+
seal_state *st;
|
|
346
|
+
TypedData_Get_Struct(self, seal_state, &state_type, st);
|
|
347
|
+
if (st->mode != 2)
|
|
348
|
+
rb_raise(rb_eRuntimeError, "AEGIS decrypt state is not initialized");
|
|
349
|
+
if (st->finalized)
|
|
350
|
+
rb_raise(rb_eRuntimeError, "AEGIS state is finalized");
|
|
351
|
+
require_length(tag, TAG_BYTES, "tag");
|
|
352
|
+
int result = aegis256_state_decrypt_final(&st->state, (uint8_t *)RSTRING_PTR(tag), TAG_BYTES);
|
|
353
|
+
st->finalized = 1;
|
|
354
|
+
OPENSSL_cleanse(&st->state, sizeof(st->state));
|
|
355
|
+
if (result != 0)
|
|
356
|
+
rb_raise(eAuth, "AEGIS-256 authentication failed");
|
|
357
|
+
return Qtrue;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
void Init_pq_crypto_seal(void) {
|
|
361
|
+
if (OpenSSL_version_num() < 0x30000000L) {
|
|
362
|
+
rb_raise(rb_eRuntimeError, "pq_crypto-seal requires OpenSSL 3.0 or newer at runtime");
|
|
363
|
+
}
|
|
364
|
+
if (aegis_init() != 0)
|
|
365
|
+
rb_raise(rb_eRuntimeError, "libaegis initialization failed");
|
|
366
|
+
mPQCrypto = rb_define_module("PQCrypto");
|
|
367
|
+
mSeal = rb_define_module_under(mPQCrypto, "Seal");
|
|
368
|
+
mNative = rb_define_module_under(mSeal, "Native");
|
|
369
|
+
eAuth = rb_path2class("PQCrypto::Seal::AuthenticationError");
|
|
370
|
+
|
|
371
|
+
rb_define_singleton_method(mNative, "random_bytes", native_random_bytes, 1);
|
|
372
|
+
rb_define_singleton_method(mNative, "sha256", native_sha256, 1);
|
|
373
|
+
rb_define_singleton_method(mNative, "hkdf_sha256", native_hkdf_sha256, 3);
|
|
374
|
+
rb_define_singleton_method(mNative, "hkdf_backend", native_hkdf_backend, 0);
|
|
375
|
+
rb_define_singleton_method(mNative, "aegis256_encrypt", native_encrypt, 4);
|
|
376
|
+
rb_define_singleton_method(mNative, "aegis256_decrypt", native_decrypt, 5);
|
|
377
|
+
rb_define_singleton_method(mNative, "secure_equal", native_secure_equal, 2);
|
|
378
|
+
|
|
379
|
+
cEncryptor = rb_define_class_under(mNative, "Encryptor", rb_cObject);
|
|
380
|
+
rb_define_alloc_func(cEncryptor, state_alloc);
|
|
381
|
+
rb_define_method(cEncryptor, "initialize", state_initialize, 3);
|
|
382
|
+
rb_define_method(cEncryptor, "update", state_update, 1);
|
|
383
|
+
rb_define_method(cEncryptor, "final", encrypt_final, 0);
|
|
384
|
+
|
|
385
|
+
cDecryptor = rb_define_class_under(mNative, "Decryptor", rb_cObject);
|
|
386
|
+
rb_define_alloc_func(cDecryptor, state_alloc);
|
|
387
|
+
rb_define_method(cDecryptor, "initialize", state_initialize, 3);
|
|
388
|
+
rb_define_method(cDecryptor, "update", state_update, 1);
|
|
389
|
+
rb_define_method(cDecryptor, "final", decrypt_final, 1);
|
|
390
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025-2026 Frank Denis
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
c2f4594acaf51785960fb1dda1cb80d663d54e671c6e465197f7924b338b8ef7
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
#include <stddef.h>
|
|
2
|
+
#include <stdint.h>
|
|
3
|
+
|
|
4
|
+
#include "../common/common.h"
|
|
5
|
+
#include "../common/cpu.h"
|
|
6
|
+
#include "aegis128l.h"
|
|
7
|
+
#include "aegis128l_aesni.h"
|
|
8
|
+
#include "aegis128l_altivec.h"
|
|
9
|
+
#include "aegis128l_neon_aes.h"
|
|
10
|
+
#include "aegis128l_neon_sha3.h"
|
|
11
|
+
|
|
12
|
+
#ifndef HAS_HW_AES
|
|
13
|
+
# include "aegis128l_soft.h"
|
|
14
|
+
static const aegis128l_implementation *implementation = &aegis128l_soft_implementation;
|
|
15
|
+
#else
|
|
16
|
+
# if defined(__aarch64__) || defined(_M_ARM64)
|
|
17
|
+
static const aegis128l_implementation *implementation = &aegis128l_neon_aes_implementation;
|
|
18
|
+
# elif defined(__x86_64__) || defined(__i386__)
|
|
19
|
+
static const aegis128l_implementation *implementation = &aegis128l_aesni_implementation;
|
|
20
|
+
# elif defined(__ALTIVEC__) && defined(__CRYPTO__)
|
|
21
|
+
static const aegis128l_implementation *implementation = &aegis128l_altivec_implementation;
|
|
22
|
+
# else
|
|
23
|
+
# error "Unsupported architecture"
|
|
24
|
+
# endif
|
|
25
|
+
#endif
|
|
26
|
+
|
|
27
|
+
size_t
|
|
28
|
+
aegis128l_keybytes(void)
|
|
29
|
+
{
|
|
30
|
+
return aegis128l_KEYBYTES;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
size_t
|
|
34
|
+
aegis128l_npubbytes(void)
|
|
35
|
+
{
|
|
36
|
+
return aegis128l_NPUBBYTES;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
size_t
|
|
40
|
+
aegis128l_abytes_min(void)
|
|
41
|
+
{
|
|
42
|
+
return aegis128l_ABYTES_MIN;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
size_t
|
|
46
|
+
aegis128l_abytes_max(void)
|
|
47
|
+
{
|
|
48
|
+
return aegis128l_ABYTES_MAX;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
size_t
|
|
52
|
+
aegis128l_tailbytes_max(void)
|
|
53
|
+
{
|
|
54
|
+
return aegis128l_TAILBYTES_MAX;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
int
|
|
58
|
+
aegis128l_encrypt_detached(uint8_t *c, uint8_t *mac, size_t maclen, const uint8_t *m, size_t mlen,
|
|
59
|
+
const uint8_t *ad, size_t adlen, const uint8_t *npub, const uint8_t *k)
|
|
60
|
+
{
|
|
61
|
+
if (maclen != 16 && maclen != 32) {
|
|
62
|
+
errno = EINVAL;
|
|
63
|
+
return -1;
|
|
64
|
+
}
|
|
65
|
+
return implementation->encrypt_detached(c, mac, maclen, m, mlen, ad, adlen, npub, k);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
int
|
|
69
|
+
aegis128l_decrypt_detached(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *mac,
|
|
70
|
+
size_t maclen, const uint8_t *ad, size_t adlen, const uint8_t *npub,
|
|
71
|
+
const uint8_t *k)
|
|
72
|
+
{
|
|
73
|
+
if (maclen != 16 && maclen != 32) {
|
|
74
|
+
errno = EINVAL;
|
|
75
|
+
return -1;
|
|
76
|
+
}
|
|
77
|
+
return implementation->decrypt_detached(m, c, clen, mac, maclen, ad, adlen, npub, k);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
int
|
|
81
|
+
aegis128l_encrypt(uint8_t *c, size_t maclen, const uint8_t *m, size_t mlen, const uint8_t *ad,
|
|
82
|
+
size_t adlen, const uint8_t *npub, const uint8_t *k)
|
|
83
|
+
{
|
|
84
|
+
return aegis128l_encrypt_detached(c, c + mlen, maclen, m, mlen, ad, adlen, npub, k);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
int
|
|
88
|
+
aegis128l_decrypt(uint8_t *m, const uint8_t *c, size_t clen, size_t maclen, const uint8_t *ad,
|
|
89
|
+
size_t adlen, const uint8_t *npub, const uint8_t *k)
|
|
90
|
+
{
|
|
91
|
+
int ret = -1;
|
|
92
|
+
|
|
93
|
+
if (clen >= maclen) {
|
|
94
|
+
ret = aegis128l_decrypt_detached(m, c, clen - maclen, c + clen - maclen, maclen, ad, adlen,
|
|
95
|
+
npub, k);
|
|
96
|
+
}
|
|
97
|
+
return ret;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
void
|
|
101
|
+
aegis128l_state_init(aegis128l_state *st_, const uint8_t *ad, size_t adlen, const uint8_t *npub,
|
|
102
|
+
const uint8_t *k)
|
|
103
|
+
{
|
|
104
|
+
memset(st_, 0, sizeof *st_);
|
|
105
|
+
implementation->state_init(st_, ad, adlen, npub, k);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
int
|
|
109
|
+
aegis128l_state_encrypt_update(aegis128l_state *st_, uint8_t *c, const uint8_t *m, size_t mlen)
|
|
110
|
+
{
|
|
111
|
+
return implementation->state_encrypt_update(st_, c, m, mlen);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
int
|
|
115
|
+
aegis128l_state_encrypt_final(aegis128l_state *st_, uint8_t *mac, size_t maclen)
|
|
116
|
+
{
|
|
117
|
+
if (maclen != 16 && maclen != 32) {
|
|
118
|
+
errno = EINVAL;
|
|
119
|
+
return -1;
|
|
120
|
+
}
|
|
121
|
+
return implementation->state_encrypt_final(st_, mac, maclen);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
int
|
|
125
|
+
aegis128l_state_decrypt_update(aegis128l_state *st_, uint8_t *m, const uint8_t *c, size_t clen)
|
|
126
|
+
{
|
|
127
|
+
return implementation->state_decrypt_update(st_, m, c, clen);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
int
|
|
131
|
+
aegis128l_state_decrypt_final(aegis128l_state *st_, const uint8_t *mac, size_t maclen)
|
|
132
|
+
{
|
|
133
|
+
if (maclen != 16 && maclen != 32) {
|
|
134
|
+
errno = EINVAL;
|
|
135
|
+
return -1;
|
|
136
|
+
}
|
|
137
|
+
return implementation->state_decrypt_final(st_, mac, maclen);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
void
|
|
141
|
+
aegis128l_stream(uint8_t *out, size_t len, const uint8_t *npub, const uint8_t *k)
|
|
142
|
+
{
|
|
143
|
+
implementation->stream(out, len, npub, k);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
void
|
|
147
|
+
aegis128l_encrypt_unauthenticated(uint8_t *c, const uint8_t *m, size_t mlen, const uint8_t *npub,
|
|
148
|
+
const uint8_t *k)
|
|
149
|
+
{
|
|
150
|
+
implementation->encrypt_unauthenticated(c, m, mlen, npub, k);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
void
|
|
154
|
+
aegis128l_decrypt_unauthenticated(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *npub,
|
|
155
|
+
const uint8_t *k)
|
|
156
|
+
{
|
|
157
|
+
implementation->decrypt_unauthenticated(m, c, clen, npub, k);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
void
|
|
161
|
+
aegis128l_mac_init(aegis128l_mac_state *st_, const uint8_t *k, const uint8_t *npub)
|
|
162
|
+
{
|
|
163
|
+
memset(st_, 0, sizeof *st_);
|
|
164
|
+
implementation->state_mac_init(st_, npub, k);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
int
|
|
168
|
+
aegis128l_mac_update(aegis128l_mac_state *st_, const uint8_t *m, size_t mlen)
|
|
169
|
+
{
|
|
170
|
+
return implementation->state_mac_update(st_, m, mlen);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
int
|
|
174
|
+
aegis128l_mac_final(aegis128l_mac_state *st_, uint8_t *mac, size_t maclen)
|
|
175
|
+
{
|
|
176
|
+
if (maclen != 16 && maclen != 32) {
|
|
177
|
+
errno = EINVAL;
|
|
178
|
+
return -1;
|
|
179
|
+
}
|
|
180
|
+
return implementation->state_mac_final(st_, mac, maclen);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
int
|
|
184
|
+
aegis128l_mac_verify(aegis128l_mac_state *st_, const uint8_t *mac, size_t maclen)
|
|
185
|
+
{
|
|
186
|
+
uint8_t expected_mac[32];
|
|
187
|
+
|
|
188
|
+
switch (maclen) {
|
|
189
|
+
case 16:
|
|
190
|
+
implementation->state_mac_final(st_, expected_mac, maclen);
|
|
191
|
+
return aegis_verify_16(expected_mac, mac);
|
|
192
|
+
case 32:
|
|
193
|
+
implementation->state_mac_final(st_, expected_mac, maclen);
|
|
194
|
+
return aegis_verify_32(expected_mac, mac);
|
|
195
|
+
default:
|
|
196
|
+
errno = EINVAL;
|
|
197
|
+
return -1;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
void
|
|
202
|
+
aegis128l_mac_reset(aegis128l_mac_state *st_)
|
|
203
|
+
{
|
|
204
|
+
implementation->state_mac_reset(st_);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
void
|
|
208
|
+
aegis128l_mac_state_clone(aegis128l_mac_state *dst, const aegis128l_mac_state *src)
|
|
209
|
+
{
|
|
210
|
+
implementation->state_mac_clone(dst, src);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
int
|
|
214
|
+
aegis128l_pick_best_implementation(void)
|
|
215
|
+
{
|
|
216
|
+
#ifndef HAS_HW_AES
|
|
217
|
+
implementation = &aegis128l_soft_implementation;
|
|
218
|
+
#endif
|
|
219
|
+
|
|
220
|
+
#if defined(__aarch64__) || defined(_M_ARM64)
|
|
221
|
+
if (aegis_runtime_has_neon_sha3()) {
|
|
222
|
+
implementation = &aegis128l_neon_sha3_implementation;
|
|
223
|
+
return 0;
|
|
224
|
+
}
|
|
225
|
+
if (aegis_runtime_has_neon_aes()) {
|
|
226
|
+
implementation = &aegis128l_neon_aes_implementation;
|
|
227
|
+
return 0;
|
|
228
|
+
}
|
|
229
|
+
#endif
|
|
230
|
+
|
|
231
|
+
#if defined(__x86_64__) || defined(_M_AMD64) || defined(__i386__) || defined(_M_IX86)
|
|
232
|
+
if (aegis_runtime_has_aesni() && aegis_runtime_has_avx()) {
|
|
233
|
+
implementation = &aegis128l_aesni_implementation;
|
|
234
|
+
return 0;
|
|
235
|
+
}
|
|
236
|
+
#endif
|
|
237
|
+
|
|
238
|
+
#if defined(__ALTIVEC__) && defined(__CRYPTO__)
|
|
239
|
+
if (aegis_runtime_has_altivec()) {
|
|
240
|
+
implementation = &aegis128l_altivec_implementation;
|
|
241
|
+
return 0;
|
|
242
|
+
}
|
|
243
|
+
#endif
|
|
244
|
+
|
|
245
|
+
return 0; /* LCOV_EXCL_LINE */
|
|
246
|
+
}
|