siv-rb 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.
- data/ext/siv/aes_locl.h +89 -0
- data/ext/siv/extconf.rb +6 -0
- data/ext/siv/siv.c +364 -0
- data/ext/siv/siv.h +79 -0
- data/ext/siv/wrapper.c +302 -0
- data/lib/siv-rb.rb +18 -0
- data/lib/siv-rb/version.rb +3 -0
- metadata +86 -0
data/ext/siv/aes_locl.h
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
/* crypto/aes/aes.h -*- mode:C; c-file-style: "eay" -*- */
|
2
|
+
/* ====================================================================
|
3
|
+
* Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
|
4
|
+
*
|
5
|
+
* Redistribution and use in source and binary forms, with or without
|
6
|
+
* modification, are permitted provided that the following conditions
|
7
|
+
* are met:
|
8
|
+
*
|
9
|
+
* 1. Redistributions of source code must retain the above copyright
|
10
|
+
* notice, this list of conditions and the following disclaimer.
|
11
|
+
*
|
12
|
+
* 2. Redistributions in binary form must reproduce the above copyright
|
13
|
+
* notice, this list of conditions and the following disclaimer in
|
14
|
+
* the documentation and/or other materials provided with the
|
15
|
+
* distribution.
|
16
|
+
*
|
17
|
+
* 3. All advertising materials mentioning features or use of this
|
18
|
+
* software must display the following acknowledgment:
|
19
|
+
* "This product includes software developed by the OpenSSL Project
|
20
|
+
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
21
|
+
*
|
22
|
+
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
23
|
+
* endorse or promote products derived from this software without
|
24
|
+
* prior written permission. For written permission, please contact
|
25
|
+
* openssl-core@openssl.org.
|
26
|
+
*
|
27
|
+
* 5. Products derived from this software may not be called "OpenSSL"
|
28
|
+
* nor may "OpenSSL" appear in their names without prior written
|
29
|
+
* permission of the OpenSSL Project.
|
30
|
+
*
|
31
|
+
* 6. Redistributions of any form whatsoever must retain the following
|
32
|
+
* acknowledgment:
|
33
|
+
* "This product includes software developed by the OpenSSL Project
|
34
|
+
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
35
|
+
*
|
36
|
+
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
37
|
+
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
38
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
39
|
+
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
40
|
+
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
41
|
+
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
42
|
+
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
43
|
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
44
|
+
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
45
|
+
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
46
|
+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
47
|
+
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
48
|
+
* ====================================================================
|
49
|
+
*
|
50
|
+
*/
|
51
|
+
|
52
|
+
#ifndef HEADER_AES_LOCL_H
|
53
|
+
#define HEADER_AES_LOCL_H
|
54
|
+
|
55
|
+
#include <openssl/e_os2.h>
|
56
|
+
|
57
|
+
#ifdef OPENSSL_NO_AES
|
58
|
+
#error AES is disabled.
|
59
|
+
#endif
|
60
|
+
|
61
|
+
#include <stdio.h>
|
62
|
+
#include <stdlib.h>
|
63
|
+
#include <string.h>
|
64
|
+
|
65
|
+
#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64))
|
66
|
+
# define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
|
67
|
+
# define GETU32(p) SWAP(*((u32 *)(p)))
|
68
|
+
# define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); }
|
69
|
+
#else
|
70
|
+
# define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3]))
|
71
|
+
# define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); }
|
72
|
+
#endif
|
73
|
+
|
74
|
+
#ifdef AES_LONG
|
75
|
+
typedef unsigned long u32;
|
76
|
+
#else
|
77
|
+
typedef unsigned int u32;
|
78
|
+
#endif
|
79
|
+
typedef unsigned short u16;
|
80
|
+
typedef unsigned char u8;
|
81
|
+
|
82
|
+
#define MAXKC (256/32)
|
83
|
+
#define MAXKB (256/8)
|
84
|
+
#define MAXNR 14
|
85
|
+
|
86
|
+
/* This controls loop-unrolling in aes_core.c */
|
87
|
+
#undef FULL_UNROLL
|
88
|
+
|
89
|
+
#endif /* !HEADER_AES_LOCL_H */
|
data/ext/siv/extconf.rb
ADDED
data/ext/siv/siv.c
ADDED
@@ -0,0 +1,364 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (c) The Industrial Lounge, 2007
|
3
|
+
*
|
4
|
+
* Copyright holder grants permission for redistribution and use in source
|
5
|
+
* and binary forms, with or without modification, provided that the
|
6
|
+
* following conditions are met:
|
7
|
+
* 1. Redistribution of source code must retain the above copyright
|
8
|
+
* notice, this list of conditions, and the following disclaimer
|
9
|
+
* in all source files.
|
10
|
+
* 2. Redistribution in binary form must retain the above copyright
|
11
|
+
* notice, this list of conditions, and the following disclaimer
|
12
|
+
* in the documentation and/or other materials provided with the
|
13
|
+
* distribution.
|
14
|
+
* 3. All advertising materials and documentation mentioning features
|
15
|
+
* or use of this software must display the following acknowledgement:
|
16
|
+
*
|
17
|
+
* "This product includes software written by
|
18
|
+
* Dan Harkins (dharkins at lounge dot org)"
|
19
|
+
*
|
20
|
+
* "DISCLAIMER OF LIABILITY
|
21
|
+
*
|
22
|
+
* THIS SOFTWARE IS PROVIDED BY THE INDUSTRIAL LOUNGE ``AS IS''
|
23
|
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
24
|
+
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
25
|
+
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INDUSTRIAL LOUNGE BE LIABLE
|
26
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
27
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
28
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
29
|
+
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
30
|
+
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
31
|
+
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
32
|
+
* SUCH DAMAGE."
|
33
|
+
*
|
34
|
+
* This license and distribution terms cannot be changed. In other words,
|
35
|
+
* this code cannot simply be copied and put under another distribution
|
36
|
+
* license (including the GNU public license).
|
37
|
+
*/
|
38
|
+
#include <stdio.h>
|
39
|
+
#include <string.h>
|
40
|
+
#include <openssl/crypto.h>
|
41
|
+
#include <openssl/evp.h>
|
42
|
+
#include <openssl/aes.h>
|
43
|
+
#include "siv.h"
|
44
|
+
#include "aes_locl.h"
|
45
|
+
|
46
|
+
#define Rb 0x87
|
47
|
+
|
48
|
+
static void
|
49
|
+
xor (unsigned char *output, const unsigned char *input)
|
50
|
+
{
|
51
|
+
int i;
|
52
|
+
|
53
|
+
i = AES_BLOCK_SIZE - 1;
|
54
|
+
do {
|
55
|
+
output[i] ^= input[i];
|
56
|
+
i--;
|
57
|
+
} while (i >= 0);
|
58
|
+
return;
|
59
|
+
}
|
60
|
+
|
61
|
+
static void
|
62
|
+
times_two (unsigned char *output, unsigned char *input)
|
63
|
+
{
|
64
|
+
int i;
|
65
|
+
unsigned char *out = output, *in = input;
|
66
|
+
unsigned char carry = 0;
|
67
|
+
|
68
|
+
out = output + AES_BLOCK_SIZE - 1;
|
69
|
+
in = input + AES_BLOCK_SIZE - 1;
|
70
|
+
for (i = 0; i < AES_BLOCK_SIZE; i++) {
|
71
|
+
*(out--) = (*in << 1) | carry;
|
72
|
+
carry = (*(in--) & 0x80) ? 1 : 0;
|
73
|
+
}
|
74
|
+
|
75
|
+
if (carry) {
|
76
|
+
output[AES_BLOCK_SIZE-1] ^= Rb;
|
77
|
+
}
|
78
|
+
return;
|
79
|
+
}
|
80
|
+
|
81
|
+
static void
|
82
|
+
pad (unsigned char *buf, int len)
|
83
|
+
{
|
84
|
+
int i;
|
85
|
+
|
86
|
+
i = len;
|
87
|
+
buf[i++] = 0x80;
|
88
|
+
if (i < AES_BLOCK_SIZE) {
|
89
|
+
memset(buf + i, 0, AES_BLOCK_SIZE - i);
|
90
|
+
}
|
91
|
+
}
|
92
|
+
|
93
|
+
void
|
94
|
+
aes_cmac (siv_ctx *ctx, const unsigned char *msg, int mlen, unsigned char *C)
|
95
|
+
{
|
96
|
+
int n, i, slop;
|
97
|
+
unsigned char Mn[AES_BLOCK_SIZE], *ptr;
|
98
|
+
|
99
|
+
// NOTE(jacobsa): For some reason, weird things happen when when `zero` is
|
100
|
+
// a global, as in the original program.
|
101
|
+
unsigned char zero[AES_BLOCK_SIZE] = {
|
102
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
103
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
104
|
+
};
|
105
|
+
|
106
|
+
memcpy(C, zero, AES_BLOCK_SIZE);
|
107
|
+
|
108
|
+
n = (mlen+(AES_BLOCK_SIZE-1))/AES_BLOCK_SIZE;
|
109
|
+
|
110
|
+
ptr = (unsigned char *)msg;
|
111
|
+
for (i = 0; i < (n-1); i++) {
|
112
|
+
xor(C, ptr);
|
113
|
+
AES_ecb_encrypt(C, C, &ctx->s2v_sched, AES_ENCRYPT);
|
114
|
+
ptr += AES_BLOCK_SIZE;
|
115
|
+
}
|
116
|
+
|
117
|
+
memset(Mn, 0, AES_BLOCK_SIZE);
|
118
|
+
if ((slop = (mlen % AES_BLOCK_SIZE)) != 0) {
|
119
|
+
memcpy(Mn, ptr, slop);
|
120
|
+
pad(Mn, slop);
|
121
|
+
xor(Mn, ctx->K2);
|
122
|
+
} else {
|
123
|
+
if (msg != NULL && mlen != 0) {
|
124
|
+
memcpy(Mn, ptr, AES_BLOCK_SIZE);
|
125
|
+
xor(Mn, ctx->K1);
|
126
|
+
} else {
|
127
|
+
pad(Mn, 0);
|
128
|
+
xor(Mn, ctx->K2);
|
129
|
+
}
|
130
|
+
}
|
131
|
+
xor(C, Mn);
|
132
|
+
AES_ecb_encrypt(C, C, &ctx->s2v_sched, AES_ENCRYPT);
|
133
|
+
return;
|
134
|
+
}
|
135
|
+
|
136
|
+
int
|
137
|
+
s2v_final (siv_ctx *ctx, const unsigned char *X, int xlen, unsigned char *digest)
|
138
|
+
{
|
139
|
+
unsigned char T[AES_BLOCK_SIZE], C[AES_BLOCK_SIZE];
|
140
|
+
unsigned char padX[AES_BLOCK_SIZE], *ptr;
|
141
|
+
int blocks, i, slop;
|
142
|
+
|
143
|
+
// NOTE(jacobsa): For some reason, weird things happen when when `zero` is
|
144
|
+
// a global, as in the original program.
|
145
|
+
unsigned char zero[AES_BLOCK_SIZE] = {
|
146
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
147
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
148
|
+
};
|
149
|
+
|
150
|
+
if (xlen < AES_BLOCK_SIZE) {
|
151
|
+
memcpy(padX, X, xlen);
|
152
|
+
pad(padX, xlen);
|
153
|
+
|
154
|
+
times_two(T, ctx->T);
|
155
|
+
xor(T, padX);
|
156
|
+
aes_cmac(ctx, T, AES_BLOCK_SIZE, digest);
|
157
|
+
} else {
|
158
|
+
if (xlen == AES_BLOCK_SIZE) {
|
159
|
+
memcpy(T, X, AES_BLOCK_SIZE);
|
160
|
+
xor(T, ctx->T);
|
161
|
+
aes_cmac(ctx, T, AES_BLOCK_SIZE, digest);
|
162
|
+
} else {
|
163
|
+
blocks = (xlen+(AES_BLOCK_SIZE-1))/AES_BLOCK_SIZE - 1;
|
164
|
+
ptr = (unsigned char *)X;
|
165
|
+
memcpy(C, zero, AES_BLOCK_SIZE);
|
166
|
+
if (blocks > 1) {
|
167
|
+
for (i = 0; i < (blocks-1); i++) {
|
168
|
+
xor(C, ptr);
|
169
|
+
AES_ecb_encrypt(C, C, &ctx->s2v_sched, AES_ENCRYPT);
|
170
|
+
ptr += AES_BLOCK_SIZE;
|
171
|
+
}
|
172
|
+
}
|
173
|
+
memcpy(T, ptr, AES_BLOCK_SIZE);
|
174
|
+
slop = xlen % AES_BLOCK_SIZE;
|
175
|
+
if (slop) {
|
176
|
+
for (i = 0; i < AES_BLOCK_SIZE - slop; i++) {
|
177
|
+
T[i + slop] ^= ctx->T[i];
|
178
|
+
}
|
179
|
+
xor(C, T);
|
180
|
+
AES_ecb_encrypt(C, C, &ctx->s2v_sched, AES_ENCRYPT);
|
181
|
+
ptr += AES_BLOCK_SIZE;
|
182
|
+
memset(T, 0, AES_BLOCK_SIZE);
|
183
|
+
memcpy(T, ptr, slop);
|
184
|
+
for (i = 0; i < slop; i++) {
|
185
|
+
T[i] ^= ctx->T[(AES_BLOCK_SIZE-slop)+i];
|
186
|
+
}
|
187
|
+
pad(T, slop);
|
188
|
+
xor(T, ctx->K2);
|
189
|
+
} else {
|
190
|
+
xor(C, ptr);
|
191
|
+
AES_ecb_encrypt(C, C, &ctx->s2v_sched, AES_ENCRYPT);
|
192
|
+
ptr += AES_BLOCK_SIZE;
|
193
|
+
memcpy(T, ptr, AES_BLOCK_SIZE);
|
194
|
+
xor(T, ctx->T);
|
195
|
+
xor(T, ctx->K1);
|
196
|
+
}
|
197
|
+
xor(C, T);
|
198
|
+
AES_ecb_encrypt(C, digest, &ctx->s2v_sched, AES_ENCRYPT);
|
199
|
+
}
|
200
|
+
|
201
|
+
}
|
202
|
+
return 0;
|
203
|
+
}
|
204
|
+
|
205
|
+
void
|
206
|
+
s2v_add (siv_ctx *ctx, const unsigned char *Y)
|
207
|
+
{
|
208
|
+
unsigned char T[AES_BLOCK_SIZE];
|
209
|
+
|
210
|
+
memcpy(T, ctx->T, AES_BLOCK_SIZE);
|
211
|
+
times_two(ctx->T, T);
|
212
|
+
xor(ctx->T, Y);
|
213
|
+
}
|
214
|
+
|
215
|
+
void
|
216
|
+
s2v_update (siv_ctx *ctx, const unsigned char *X, int xlen)
|
217
|
+
{
|
218
|
+
unsigned char Y[AES_BLOCK_SIZE];
|
219
|
+
|
220
|
+
aes_cmac(ctx, X, xlen, Y);
|
221
|
+
s2v_add(ctx, Y);
|
222
|
+
}
|
223
|
+
|
224
|
+
int
|
225
|
+
siv_init (siv_ctx *ctx, const unsigned char *key, int keylen)
|
226
|
+
{
|
227
|
+
unsigned char L[AES_BLOCK_SIZE];
|
228
|
+
|
229
|
+
// NOTE(jacobsa): For some reason, weird things happen when when `zero` is
|
230
|
+
// a global, as in the original program.
|
231
|
+
unsigned char zero[AES_BLOCK_SIZE] = {
|
232
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
233
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
234
|
+
};
|
235
|
+
|
236
|
+
memset((char *)ctx, 0, sizeof(siv_ctx));
|
237
|
+
switch (keylen) {
|
238
|
+
case SIV_512:
|
239
|
+
AES_set_encrypt_key(key, 256, &ctx->s2v_sched);
|
240
|
+
AES_set_encrypt_key(key+AES_256_BYTES, 256, &ctx->ctr_sched);
|
241
|
+
break;
|
242
|
+
case SIV_384:
|
243
|
+
AES_set_encrypt_key(key, 192, &ctx->s2v_sched);
|
244
|
+
AES_set_encrypt_key(key+AES_192_BYTES, 192, &ctx->ctr_sched);
|
245
|
+
break;
|
246
|
+
case SIV_256:
|
247
|
+
AES_set_encrypt_key(key, 128, &ctx->s2v_sched);
|
248
|
+
AES_set_encrypt_key(key+AES_128_BYTES, 128, &ctx->ctr_sched);
|
249
|
+
break;
|
250
|
+
default:
|
251
|
+
return -1;
|
252
|
+
}
|
253
|
+
|
254
|
+
AES_ecb_encrypt(zero, L, &ctx->s2v_sched, AES_ENCRYPT);
|
255
|
+
times_two(ctx->K1, L);
|
256
|
+
times_two(ctx->K2, ctx->K1);
|
257
|
+
|
258
|
+
memset(ctx->benchmark, 0, AES_BLOCK_SIZE);
|
259
|
+
aes_cmac(ctx, zero, AES_BLOCK_SIZE, ctx->T);
|
260
|
+
return 1;
|
261
|
+
}
|
262
|
+
|
263
|
+
void
|
264
|
+
siv_restart (siv_ctx *ctx)
|
265
|
+
{
|
266
|
+
// NOTE(jacobsa): For some reason, weird things happen when when `zero` is
|
267
|
+
// a global, as in the original program.
|
268
|
+
unsigned char zero[AES_BLOCK_SIZE] = {
|
269
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
270
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
271
|
+
};
|
272
|
+
|
273
|
+
memset(ctx->benchmark, 0, AES_BLOCK_SIZE);
|
274
|
+
memset(ctx->T, 0, AES_BLOCK_SIZE);
|
275
|
+
aes_cmac(ctx, zero, AES_BLOCK_SIZE, ctx->T);
|
276
|
+
}
|
277
|
+
|
278
|
+
void
|
279
|
+
s2v_benchmark (siv_ctx *ctx)
|
280
|
+
{
|
281
|
+
memcpy(ctx->benchmark, ctx->T, AES_BLOCK_SIZE);
|
282
|
+
}
|
283
|
+
|
284
|
+
void
|
285
|
+
s2v_reset (siv_ctx *ctx)
|
286
|
+
{
|
287
|
+
memcpy(ctx->T, ctx->benchmark, AES_BLOCK_SIZE);
|
288
|
+
}
|
289
|
+
|
290
|
+
void
|
291
|
+
siv_aes_ctr (siv_ctx *ctx, const unsigned char *p, const int lenp,
|
292
|
+
unsigned char *c, const unsigned char *iv)
|
293
|
+
{
|
294
|
+
int i, j;
|
295
|
+
unsigned char ctr[AES_BLOCK_SIZE], ecr[AES_BLOCK_SIZE];
|
296
|
+
unsigned long inc;
|
297
|
+
|
298
|
+
memcpy(ctr, iv, AES_BLOCK_SIZE);
|
299
|
+
ctr[12] &= 0x7f; ctr[8] &= 0x7f;
|
300
|
+
inc = GETU32(ctr + 12);
|
301
|
+
for (i = 0; i < lenp; i+=AES_BLOCK_SIZE) {
|
302
|
+
AES_ecb_encrypt(ctr, ecr, &ctx->ctr_sched, AES_ENCRYPT);
|
303
|
+
for (j = 0; j < AES_BLOCK_SIZE; j++) {
|
304
|
+
if ((i + j) == lenp) {
|
305
|
+
return;
|
306
|
+
}
|
307
|
+
c[i+j] = p[i+j] ^ ecr[j];
|
308
|
+
}
|
309
|
+
inc++; inc &= 0xffffffff;
|
310
|
+
PUTU32(ctr + 12, inc);
|
311
|
+
}
|
312
|
+
}
|
313
|
+
|
314
|
+
int
|
315
|
+
siv_encrypt (siv_ctx *ctx, const unsigned char *p, unsigned char *c,
|
316
|
+
const int len, unsigned char *counter,
|
317
|
+
const int nad, const int* adlens, const unsigned char** ads)
|
318
|
+
{
|
319
|
+
const unsigned char *ad;
|
320
|
+
int adlen;
|
321
|
+
int i;
|
322
|
+
unsigned char ctr[AES_BLOCK_SIZE];
|
323
|
+
|
324
|
+
for (i = 0; i < nad; ++i) {
|
325
|
+
ad = ads[i];
|
326
|
+
adlen = adlens[i];
|
327
|
+
s2v_update(ctx, ad, adlen);
|
328
|
+
}
|
329
|
+
|
330
|
+
s2v_final(ctx, p, len, ctr);
|
331
|
+
memcpy(counter, ctr, AES_BLOCK_SIZE);
|
332
|
+
siv_aes_ctr(ctx, p, len, c, ctr);
|
333
|
+
siv_restart(ctx);
|
334
|
+
return 1;
|
335
|
+
}
|
336
|
+
|
337
|
+
int
|
338
|
+
siv_decrypt (siv_ctx *ctx, const unsigned char *c, unsigned char *p,
|
339
|
+
const int len, unsigned char *counter,
|
340
|
+
const int nad, const int* adlens, const unsigned char** ads)
|
341
|
+
{
|
342
|
+
va_list ap;
|
343
|
+
const unsigned char *ad;
|
344
|
+
int adlen;
|
345
|
+
int i;
|
346
|
+
unsigned char ctr[AES_BLOCK_SIZE];
|
347
|
+
|
348
|
+
memcpy(ctr, counter, AES_BLOCK_SIZE);
|
349
|
+
siv_aes_ctr(ctx, c, len, p, ctr);
|
350
|
+
for (i = 0; i < nad; ++i) {
|
351
|
+
ad = ads[i];
|
352
|
+
adlen = adlens[i];
|
353
|
+
s2v_update(ctx, ad, adlen);
|
354
|
+
}
|
355
|
+
s2v_final(ctx, p, len, ctr);
|
356
|
+
|
357
|
+
siv_restart(ctx);
|
358
|
+
if (memcmp(ctr, counter, AES_BLOCK_SIZE)) {
|
359
|
+
memset(p, 0, len);
|
360
|
+
return -1;
|
361
|
+
} else {
|
362
|
+
return 1;
|
363
|
+
}
|
364
|
+
}
|
data/ext/siv/siv.h
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (c) The Industrial Lounge, 2007
|
3
|
+
*
|
4
|
+
* Copyright holder grants permission for redistribution and use in source
|
5
|
+
* and binary forms, with or without modification, provided that the
|
6
|
+
* following conditions are met:
|
7
|
+
* 1. Redistribution of source code must retain the above copyright
|
8
|
+
* notice, this list of conditions, and the following disclaimer
|
9
|
+
* in all source files.
|
10
|
+
* 2. Redistribution in binary form must retain the above copyright
|
11
|
+
* notice, this list of conditions, and the following disclaimer
|
12
|
+
* in the documentation and/or other materials provided with the
|
13
|
+
* distribution.
|
14
|
+
* 3. All advertising materials and documentation mentioning features
|
15
|
+
* or use of this software must display the following acknowledgement:
|
16
|
+
*
|
17
|
+
* "This product includes software written by
|
18
|
+
* Dan Harkins (dharkins at lounge dot org)"
|
19
|
+
*
|
20
|
+
* "DISCLAIMER OF LIABILITY
|
21
|
+
*
|
22
|
+
* THIS SOFTWARE IS PROVIDED BY THE INDUSTRIAL LOUNGE ``AS IS''
|
23
|
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
24
|
+
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
25
|
+
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INDUSTRIAL LOUNGE BE LIABLE
|
26
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
27
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
28
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
29
|
+
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
30
|
+
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
31
|
+
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
32
|
+
* SUCH DAMAGE."
|
33
|
+
*
|
34
|
+
* This license and distribution terms cannot be changed. In other words,
|
35
|
+
* this code cannot simply be copied and put under another distribution
|
36
|
+
* license (including the GNU public license).
|
37
|
+
*/
|
38
|
+
#ifndef _SIV_H_
|
39
|
+
#define _SIV_H_
|
40
|
+
|
41
|
+
#include <openssl/aes.h>
|
42
|
+
|
43
|
+
#define AES_128_BYTES 16
|
44
|
+
#define AES_192_BYTES 24
|
45
|
+
#define AES_256_BYTES 32
|
46
|
+
#define SIV_256 256
|
47
|
+
#define SIV_384 384
|
48
|
+
#define SIV_512 512
|
49
|
+
|
50
|
+
typedef struct _siv_ctx {
|
51
|
+
unsigned char K1[AES_BLOCK_SIZE];
|
52
|
+
unsigned char K2[AES_BLOCK_SIZE];
|
53
|
+
unsigned char T[AES_BLOCK_SIZE];
|
54
|
+
unsigned char benchmark[AES_BLOCK_SIZE];
|
55
|
+
AES_KEY ctr_sched;
|
56
|
+
AES_KEY s2v_sched;
|
57
|
+
} siv_ctx;
|
58
|
+
|
59
|
+
/*
|
60
|
+
* exported APIs
|
61
|
+
*/
|
62
|
+
void aes_cmac (siv_ctx *, const unsigned char *, int, unsigned char *);
|
63
|
+
int siv_init(siv_ctx *, const unsigned char *, int);
|
64
|
+
void siv_reset(siv_ctx *);
|
65
|
+
void s2v_benchmark(siv_ctx *);
|
66
|
+
void s2v_add(siv_ctx *, const unsigned char *);
|
67
|
+
void s2v_update(siv_ctx *, const unsigned char *, int);
|
68
|
+
int s2v_final(siv_ctx *, const unsigned char *, int, unsigned char *);
|
69
|
+
void siv_restart(siv_ctx *);
|
70
|
+
void siv_aes_ctr(siv_ctx *, const unsigned char *, const int, unsigned char *,
|
71
|
+
const unsigned char *);
|
72
|
+
int siv_encrypt (siv_ctx *ctx, const unsigned char *p, unsigned char *c,
|
73
|
+
const int len, unsigned char *counter,
|
74
|
+
const int nad, const int* adlens, const unsigned char** ads);
|
75
|
+
int siv_decrypt(siv_ctx *, const unsigned char *, unsigned char *,
|
76
|
+
const int, unsigned char *,
|
77
|
+
const int nad, const int* adlens, const unsigned char** ads);
|
78
|
+
|
79
|
+
#endif /* _SIV_H_ */
|
data/ext/siv/wrapper.c
ADDED
@@ -0,0 +1,302 @@
|
|
1
|
+
#include <ruby.h>
|
2
|
+
#include "siv.h"
|
3
|
+
|
4
|
+
// Convenience constant for unsigned char size
|
5
|
+
const int SIV_UCHAR_SIZE = sizeof(unsigned char);
|
6
|
+
|
7
|
+
// Top-level objects for the native extension
|
8
|
+
static VALUE siv_rb;
|
9
|
+
static VALUE siv_rb_cipher;
|
10
|
+
|
11
|
+
/*
|
12
|
+
* Initialize an SIV::Cipher object with a key.
|
13
|
+
* Performs basic length validation on the key.
|
14
|
+
*/
|
15
|
+
static VALUE siv_rb_initialize(VALUE self, VALUE key) {
|
16
|
+
|
17
|
+
int keyLen;
|
18
|
+
|
19
|
+
// Replace key value with key.to_str
|
20
|
+
StringValue(key);
|
21
|
+
|
22
|
+
// Get the key length as an int.
|
23
|
+
keyLen = RSTRING_LEN(key);
|
24
|
+
|
25
|
+
// Make sure key is not empty
|
26
|
+
if (keyLen == 0) {
|
27
|
+
rb_raise(rb_eArgError, "Key must be non-empty.");
|
28
|
+
}
|
29
|
+
|
30
|
+
// Make sure key is acceptable size
|
31
|
+
if (keyLen * 8 != SIV_256 &&
|
32
|
+
keyLen * 8 != SIV_384 &&
|
33
|
+
keyLen * 8 != SIV_512) {
|
34
|
+
rb_raise(rb_eArgError, "Supported key sizes are 256, 384 and 512 bits.");
|
35
|
+
}
|
36
|
+
|
37
|
+
// Set key as instance variable
|
38
|
+
rb_iv_set(self, "@key", key);
|
39
|
+
|
40
|
+
return self;
|
41
|
+
|
42
|
+
}
|
43
|
+
|
44
|
+
/*
|
45
|
+
* Get an siv_ctx object for the current instance
|
46
|
+
* by fetching the @key instance variable, converting
|
47
|
+
* it to a byte array and feeding it into siv_init.
|
48
|
+
* Called by siv_rb_encrypt and siv_rb_decrypt.
|
49
|
+
*
|
50
|
+
* Returns 1 upon success, 0 upon failure.
|
51
|
+
*/
|
52
|
+
static int siv_rb_get_ctx(VALUE self, siv_ctx* ctx) {
|
53
|
+
|
54
|
+
VALUE key; unsigned char* cKey; int cKeyLen;
|
55
|
+
|
56
|
+
// Get the key instance variable
|
57
|
+
key = rb_iv_get(self, "@key");
|
58
|
+
|
59
|
+
// Convert the key to a byte array
|
60
|
+
cKey = (unsigned char*) RSTRING_PTR(key);
|
61
|
+
cKeyLen = RSTRING_LEN(key);
|
62
|
+
|
63
|
+
// Initialize the context with the key
|
64
|
+
if (siv_init(ctx, cKey, cKeyLen * 8) < 0) {
|
65
|
+
return 0;
|
66
|
+
}
|
67
|
+
|
68
|
+
// Return 1 upon successful initialization
|
69
|
+
return 1;
|
70
|
+
|
71
|
+
}
|
72
|
+
|
73
|
+
/*
|
74
|
+
* Get the associated data as an array of integer lengths
|
75
|
+
* and an array of unsigned char arrays representing data.
|
76
|
+
*/
|
77
|
+
static int siv_rb_get_associated(VALUE associated, int* cAdLensIn, unsigned char** cAdsIn) {
|
78
|
+
|
79
|
+
// Reference to arguments
|
80
|
+
int cAdNum; int* cAdLens;
|
81
|
+
unsigned char** cAds;
|
82
|
+
|
83
|
+
// Values for iterator
|
84
|
+
int i; VALUE adElement;
|
85
|
+
unsigned char* cAdElement;
|
86
|
+
int cAdElementLen;
|
87
|
+
|
88
|
+
// Set the references to arguments.
|
89
|
+
cAdLens = cAdLensIn; cAds = cAdsIn;
|
90
|
+
|
91
|
+
// Get the number of associated data items
|
92
|
+
cAdNum = (int) RARRAY_LEN(associated);
|
93
|
+
|
94
|
+
// Iterate over each associated data
|
95
|
+
for (i = 0; i < cAdNum; i++) {
|
96
|
+
|
97
|
+
// Get an element in the Ruby array
|
98
|
+
adElement = rb_ary_entry(associated, (long) i);
|
99
|
+
|
100
|
+
// Convert the Ruby string to bytes
|
101
|
+
StringValue(adElement);
|
102
|
+
cAdElement = (unsigned char*) RSTRING_PTR(adElement);
|
103
|
+
cAdElementLen = RSTRING_LEN(adElement);
|
104
|
+
|
105
|
+
// Set the element length
|
106
|
+
cAdLens[i] = cAdElementLen;
|
107
|
+
|
108
|
+
// Set the element data
|
109
|
+
if (cAdElementLen > 0) {
|
110
|
+
|
111
|
+
cAds[i] = (unsigned char*) malloc(SIV_UCHAR_SIZE * cAdElementLen);
|
112
|
+
cAds[i] = cAdElement;
|
113
|
+
|
114
|
+
}
|
115
|
+
|
116
|
+
}
|
117
|
+
|
118
|
+
// Return 1 to indicate success;
|
119
|
+
return 1;
|
120
|
+
|
121
|
+
}
|
122
|
+
|
123
|
+
/*
|
124
|
+
* Encrypt a plaintext and some associated data
|
125
|
+
*/
|
126
|
+
static VALUE siv_rb_encrypt(VALUE self, VALUE plaintext, VALUE associated) {
|
127
|
+
|
128
|
+
// Holds the SIV context object.
|
129
|
+
siv_ctx ctx;
|
130
|
+
|
131
|
+
// Input plaintext as byte array.
|
132
|
+
const unsigned char* cPlaintext;
|
133
|
+
|
134
|
+
// Length of the input plaintext.
|
135
|
+
int cPlaintextLen;
|
136
|
+
|
137
|
+
// Holds the SIV counter object.
|
138
|
+
unsigned char cCounter[AES_BLOCK_SIZE];
|
139
|
+
|
140
|
+
// Holds the SIV ciphertext object.
|
141
|
+
unsigned char* cCiphertext;
|
142
|
+
|
143
|
+
// Hold the parsed associated data.
|
144
|
+
int cAdNum; int* cAdLens; unsigned char** cAds;
|
145
|
+
|
146
|
+
// For concatenation of IV with data.
|
147
|
+
unsigned char* cOutput;
|
148
|
+
int cOutputLen; int outputInd;
|
149
|
+
|
150
|
+
// Get the SIV context based on the instance's key.
|
151
|
+
if (!siv_rb_get_ctx(self, &ctx)) {
|
152
|
+
rb_raise(rb_eRuntimeError, "Could not get SIV context");
|
153
|
+
}
|
154
|
+
|
155
|
+
// Replace the plaintext with plaintext.to_str
|
156
|
+
StringValue(plaintext);
|
157
|
+
|
158
|
+
// Convert the plaintext to a byte array.
|
159
|
+
cPlaintext = (const unsigned char*) RSTRING_PTR(plaintext);
|
160
|
+
|
161
|
+
// Get the length of the plaintext as an int.
|
162
|
+
cPlaintextLen = RSTRING_LEN(plaintext);
|
163
|
+
|
164
|
+
cAdNum = (int) RARRAY_LEN(associated);
|
165
|
+
cAdLens = (int *) malloc(sizeof(int) * cAdNum);
|
166
|
+
cAds = (unsigned char **) malloc(sizeof(unsigned char*) * cAdNum);
|
167
|
+
|
168
|
+
// Get the parsed associated data values.
|
169
|
+
if (!siv_rb_get_associated(associated, cAdLens, cAds)) {
|
170
|
+
rb_raise(rb_eRuntimeError, "Could not get associated data");
|
171
|
+
}
|
172
|
+
|
173
|
+
// Allocate space for the ciphertext.
|
174
|
+
cCiphertext = (unsigned char*) malloc(SIV_UCHAR_SIZE * cPlaintextLen);
|
175
|
+
|
176
|
+
// Call siv_encrypt with all parameters.
|
177
|
+
if (siv_encrypt( &ctx, cPlaintext, cCiphertext,
|
178
|
+
(const int) cPlaintextLen, cCounter,
|
179
|
+
(const int) cAdNum, cAdLens, cAds) < 0) {
|
180
|
+
rb_raise(rb_eRuntimeError, "SIV encryption failed");
|
181
|
+
}
|
182
|
+
|
183
|
+
// Prepend the IV (counter) to the ciphertext.
|
184
|
+
cOutputLen = cPlaintextLen + AES_BLOCK_SIZE;
|
185
|
+
cOutput = (unsigned char*) malloc(SIV_UCHAR_SIZE * cOutputLen);
|
186
|
+
|
187
|
+
// Iterate through the output to prepend the iv.
|
188
|
+
for (outputInd = 0; outputInd < cOutputLen; ++outputInd) {
|
189
|
+
cOutput[outputInd] = (outputInd < AES_BLOCK_SIZE) ?
|
190
|
+
cCounter[outputInd] : cCiphertext[outputInd - AES_BLOCK_SIZE];
|
191
|
+
}
|
192
|
+
|
193
|
+
// Free up dynamically allocated memory.
|
194
|
+
free(cAdLens); free(cAds); free(cCiphertext);
|
195
|
+
|
196
|
+
// Return a new Ruby string with the resulting value.
|
197
|
+
return rb_str_new((const char*) cOutput, cOutputLen);
|
198
|
+
|
199
|
+
}
|
200
|
+
|
201
|
+
static VALUE siv_rb_decrypt(VALUE self, VALUE ciphertext, VALUE associated) {
|
202
|
+
|
203
|
+
siv_ctx ctx;
|
204
|
+
|
205
|
+
// Holds the counter object bytes
|
206
|
+
unsigned char cCounter[AES_BLOCK_SIZE];
|
207
|
+
|
208
|
+
// Holds the iv + ciphertext bytes
|
209
|
+
const unsigned char* cCiphertext;
|
210
|
+
int cCiphertextLen;
|
211
|
+
|
212
|
+
// Holds the ciphertext-only bytes
|
213
|
+
unsigned char* cCiphertextTrunc;
|
214
|
+
int j; int cCiphertextTruncLen;
|
215
|
+
|
216
|
+
// Receives the plaintext bytes
|
217
|
+
const unsigned char* cPlaintext;
|
218
|
+
|
219
|
+
// Holds associated-data
|
220
|
+
int cAdNum; int* cAdLens;
|
221
|
+
unsigned char** cAds;
|
222
|
+
|
223
|
+
// Get the SIV context with the key
|
224
|
+
if (!siv_rb_get_ctx(self, &ctx)) {
|
225
|
+
rb_raise(rb_eRuntimeError, "Could not get SIV context");
|
226
|
+
}
|
227
|
+
|
228
|
+
// Get the ciphertext bytes and length
|
229
|
+
StringValue(ciphertext);
|
230
|
+
cCiphertext = (unsigned char*) RSTRING_PTR(ciphertext);
|
231
|
+
cCiphertextLen = RSTRING_LEN(ciphertext);
|
232
|
+
|
233
|
+
// Truncate the IV (counter) off the ciphertext
|
234
|
+
cCiphertextTrunc = (unsigned char*) malloc(
|
235
|
+
SIV_UCHAR_SIZE * (cCiphertextLen - AES_BLOCK_SIZE));
|
236
|
+
cCiphertextTruncLen = cCiphertextLen - AES_BLOCK_SIZE;
|
237
|
+
|
238
|
+
// Iterate through the ciphertext to truncate
|
239
|
+
for (j = 0; j < cCiphertextLen; j++) {
|
240
|
+
if (j < AES_BLOCK_SIZE) cCounter[j] = cCiphertext[j];
|
241
|
+
else cCiphertextTrunc[j - AES_BLOCK_SIZE] = cCiphertext[j];
|
242
|
+
}
|
243
|
+
|
244
|
+
// Get the number of associated data items in the array.
|
245
|
+
cAdNum = (int) RARRAY_LEN(associated);
|
246
|
+
cAdLens = (int *) malloc(sizeof(int) * cAdNum);
|
247
|
+
cAds = (unsigned char **) malloc(sizeof(unsigned char*) * cAdNum);
|
248
|
+
|
249
|
+
// Get the associated data lengths and data arrays
|
250
|
+
if (!siv_rb_get_associated(associated, cAdLens, cAds)) {
|
251
|
+
rb_raise(rb_eRuntimeError, "Could not get associated data");
|
252
|
+
}
|
253
|
+
|
254
|
+
// Allocate space to receive the plaintext.
|
255
|
+
cPlaintext = (unsigned char*) malloc(SIV_UCHAR_SIZE * cCiphertextTruncLen);
|
256
|
+
|
257
|
+
// Decrypt the ciphertext using SIV.
|
258
|
+
if (siv_decrypt(&ctx, cCiphertextTrunc, cPlaintext,
|
259
|
+
(const int) cCiphertextTruncLen, cCounter,
|
260
|
+
(const int) cAdNum, cAdLens, cAds) < 0) {
|
261
|
+
rb_raise(rb_eRuntimeError, "SIV decryption failed");
|
262
|
+
}
|
263
|
+
|
264
|
+
// Free up dynamically allocated memory.
|
265
|
+
free(cAdLens); free(cAds); free(cCiphertextTrunc);
|
266
|
+
|
267
|
+
// Build and return a Ruby string object with the plaintext
|
268
|
+
return rb_str_new((const char*) cPlaintext, cCiphertextTruncLen);
|
269
|
+
|
270
|
+
}
|
271
|
+
|
272
|
+
/*
|
273
|
+
* Main wrapper for the SIV Ruby native extension.
|
274
|
+
*/
|
275
|
+
void Init_wrapper(void) {
|
276
|
+
|
277
|
+
// Define the top-level module
|
278
|
+
siv_rb = rb_define_module("SIV");
|
279
|
+
|
280
|
+
// Define the cipher class
|
281
|
+
siv_rb_cipher = rb_define_class_under(siv_rb, "Cipher", rb_cObject);
|
282
|
+
|
283
|
+
// Define the implemented methods.
|
284
|
+
rb_define_method(siv_rb_cipher, "initialize", siv_rb_initialize, 1);
|
285
|
+
rb_define_method(siv_rb_cipher, "encrypt_native", siv_rb_encrypt, 2);
|
286
|
+
rb_define_method(siv_rb_cipher, "decrypt_native", siv_rb_decrypt, 2);
|
287
|
+
|
288
|
+
return;
|
289
|
+
|
290
|
+
}
|
291
|
+
|
292
|
+
/*
|
293
|
+
Debug helper method to print byte arrays in hex format.
|
294
|
+
|
295
|
+
void print_hex(const char* header, const unsigned char *bytes, int len) {
|
296
|
+
|
297
|
+
int i = 0; printf("\n%s (%d): ", header, len);
|
298
|
+
for (i = 0; i < len; ++i) printf("%x", bytes[i]);
|
299
|
+
printf("\n");
|
300
|
+
|
301
|
+
}
|
302
|
+
*/
|
data/lib/siv-rb.rb
ADDED
metadata
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: siv-rb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Louis Mullie
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2014-04-29 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 2.12.0
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 2.12.0
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
description: ! ' Ruby C extension for the AES-SIV deterministic authenticated encryption
|
47
|
+
mode. '
|
48
|
+
email:
|
49
|
+
- louis.mullie@gmail.com
|
50
|
+
executables: []
|
51
|
+
extensions:
|
52
|
+
- ext/siv/extconf.rb
|
53
|
+
extra_rdoc_files: []
|
54
|
+
files:
|
55
|
+
- lib/siv-rb/version.rb
|
56
|
+
- lib/siv-rb.rb
|
57
|
+
- ext/siv/siv.c
|
58
|
+
- ext/siv/wrapper.c
|
59
|
+
- ext/siv/aes_locl.h
|
60
|
+
- ext/siv/siv.h
|
61
|
+
- ext/siv/extconf.rb
|
62
|
+
homepage: https://github.com/cryodex/siv-rb
|
63
|
+
licenses: []
|
64
|
+
post_install_message:
|
65
|
+
rdoc_options: []
|
66
|
+
require_paths:
|
67
|
+
- lib
|
68
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
69
|
+
none: false
|
70
|
+
requirements:
|
71
|
+
- - ! '>='
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0'
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - ! '>='
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '0'
|
80
|
+
requirements: []
|
81
|
+
rubyforge_project:
|
82
|
+
rubygems_version: 1.8.25
|
83
|
+
signing_key:
|
84
|
+
specification_version: 3
|
85
|
+
summary: Ruby C extension for the AES-SIV deterministic authenticated encryption mode.
|
86
|
+
test_files: []
|