siv-rb 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|