1 // SPDX-License-Identifier: BSD-2-Clause
2 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
3  *
4  * LibTomCrypt is a library that provides various cryptographic
5  * algorithms in a highly modular and flexible manner.
6  *
7  * The library is free for all purposes without any express
8  * guarantee it works.
9  */
10 
11 /******************************************************************************
12  * This Rabbit C source code was morphed fm the EU eSTREAM ECRYPT submission
13  * and should run on any conforming C implementation (C90 or later).
14  *
15  * This implementation supports any key length up to 128 bits (16 bytes) and
16  * works in increments of 8-bit bytes.  Keys must be submitted as whole bytes
17  * and shorter keys will be right-null-padded to 16 bytes.  Likewise, an iv
18  * may be any length up to 8 bytes and will be padded out to 8 bytes.
19  *
20  * The eSTREAM submission was rather picky about the calling sequence of
21  * ECRYPT_process_blocks() and ECRYPT_process_bytes().  That version allowed
22  * calling ECRYPT_process_blocks() multiple times for a multiple of whole
23  * 16-byte blocks, but once ECRYPT_process_bytes() was called. no more calls
24  * were supported correctly.  This implementation handles the keystream
25  * differently and rabbit_crypt() may be called as many times as desired,
26  * crypting any number of bytes each time.
27  *
28  *   http://www.ecrypt.eu.org/stream/e2-rabbit.html
29  *
30  * NB: One of the test vectors distributed by the eSTREAM site in the file
31  *     "rabbit_p3source.zip" is in error.  Referring to "test-vectors.txt"
32  *     in that ZIP file, the 3rd line in "out1" should be
33  *     "96 D6 73 16 88 D1 68 DA 51 D4 0C 70 C3 A1 16 F4".
34  *
35  * Here is the original legal notice accompanying the Rabbit submission
36  * to the EU eSTREAM competition.
37  *---------------------------------------------------------------------------
38  * Copyright (C) Cryptico A/S. All rights reserved.
39  *
40  * YOU SHOULD CAREFULLY READ THIS LEGAL NOTICE BEFORE USING THIS SOFTWARE.
41  *
42  * This software is developed by Cryptico A/S and/or its suppliers.
43  * All title and intellectual property rights in and to the software,
44  * including but not limited to patent rights and copyrights, are owned
45  * by Cryptico A/S and/or its suppliers.
46  *
47  * The software may be used solely for non-commercial purposes
48  * without the prior written consent of Cryptico A/S. For further
49  * information on licensing terms and conditions please contact
50  * Cryptico A/S at info@cryptico.com
51  *
52  * Cryptico, CryptiCore, the Cryptico logo and "Re-thinking encryption"
53  * are either trademarks or registered trademarks of Cryptico A/S.
54  *
55  * Cryptico A/S shall not in any way be liable for any use of this
56  * software. The software is provided "as is" without any express or
57  * implied warranty.
58  *---------------------------------------------------------------------------
59  * On October 6, 2008, Rabbit was "released into the public domain and
60  * may be used freely for any purpose."
61  *   http://www.ecrypt.eu.org/stream/rabbitpf.html
62  *   https://web.archive.org/web/20090630021733/http://www.ecrypt.eu.org/stream/phorum/read.php?1,1244
63  ******************************************************************************/
64 
65 
66 #include "tomcrypt_private.h"
67 
68 #ifdef LTC_RABBIT
69 
70 /* local/private prototypes  (NB: rabbit_ctx and rabbit_state are different)  */
71 static LTC_INLINE ulong32 _rabbit_g_func(ulong32 x);
72 static LTC_INLINE void _rabbit_next_state(rabbit_ctx *p_instance);
73 static LTC_INLINE void _rabbit_gen_1_block(rabbit_state* st, unsigned char *out);
74 
75 /* -------------------------------------------------------------------------- */
76 
77 /* Square a 32-bit unsigned integer to obtain the 64-bit result and return */
78 /* the upper 32 bits XOR the lower 32 bits */
_rabbit_g_func(ulong32 x)79 static LTC_INLINE ulong32 _rabbit_g_func(ulong32 x)
80 {
81    ulong32 a, b, h, l;
82 
83    /* Construct high and low argument for squaring */
84    a = x &  0xFFFF;
85    b = x >> 16;
86 
87    /* Calculate high and low result of squaring */
88    h = ((((ulong32)(a*a)>>17) + (ulong32)(a*b))>>15) + b*b;
89    l = x * x;
90 
91    /* Return high XOR low */
92    return (ulong32)(h^l);
93 }
94 
95 /* -------------------------------------------------------------------------- */
96 
97 /* Calculate the next internal state */
_rabbit_next_state(rabbit_ctx * p_instance)98 static LTC_INLINE void _rabbit_next_state(rabbit_ctx *p_instance)
99 {
100    ulong32 g[8], c_old[8], i;
101 
102    /* Save old counter values */
103    for (i=0; i<8; i++) {
104       c_old[i] = p_instance->c[i];
105    }
106 
107    /* Calculate new counter values */
108    p_instance->c[0] = (ulong32)(p_instance->c[0] + 0x4D34D34D + p_instance->carry);
109    p_instance->c[1] = (ulong32)(p_instance->c[1] + 0xD34D34D3 + (p_instance->c[0] < c_old[0]));
110    p_instance->c[2] = (ulong32)(p_instance->c[2] + 0x34D34D34 + (p_instance->c[1] < c_old[1]));
111    p_instance->c[3] = (ulong32)(p_instance->c[3] + 0x4D34D34D + (p_instance->c[2] < c_old[2]));
112    p_instance->c[4] = (ulong32)(p_instance->c[4] + 0xD34D34D3 + (p_instance->c[3] < c_old[3]));
113    p_instance->c[5] = (ulong32)(p_instance->c[5] + 0x34D34D34 + (p_instance->c[4] < c_old[4]));
114    p_instance->c[6] = (ulong32)(p_instance->c[6] + 0x4D34D34D + (p_instance->c[5] < c_old[5]));
115    p_instance->c[7] = (ulong32)(p_instance->c[7] + 0xD34D34D3 + (p_instance->c[6] < c_old[6]));
116    p_instance->carry = (p_instance->c[7] < c_old[7]);
117 
118    /* Calculate the g-values */
119    for (i=0;i<8;i++) {
120       g[i] = _rabbit_g_func((ulong32)(p_instance->x[i] + p_instance->c[i]));
121    }
122 
123    /* Calculate new state values */
124    p_instance->x[0] = (ulong32)(g[0] + ROLc(g[7],16) + ROLc(g[6], 16));
125    p_instance->x[1] = (ulong32)(g[1] + ROLc(g[0], 8) + g[7]);
126    p_instance->x[2] = (ulong32)(g[2] + ROLc(g[1],16) + ROLc(g[0], 16));
127    p_instance->x[3] = (ulong32)(g[3] + ROLc(g[2], 8) + g[1]);
128    p_instance->x[4] = (ulong32)(g[4] + ROLc(g[3],16) + ROLc(g[2], 16));
129    p_instance->x[5] = (ulong32)(g[5] + ROLc(g[4], 8) + g[3]);
130    p_instance->x[6] = (ulong32)(g[6] + ROLc(g[5],16) + ROLc(g[4], 16));
131    p_instance->x[7] = (ulong32)(g[7] + ROLc(g[6], 8) + g[5]);
132 }
133 
134 /* ------------------------------------------------------------------------- */
135 
_rabbit_gen_1_block(rabbit_state * st,unsigned char * out)136 static LTC_INLINE void _rabbit_gen_1_block(rabbit_state* st, unsigned char *out)
137 {
138     ulong32 *ptr;
139 
140     /* Iterate the work context once */
141     _rabbit_next_state(&(st->work_ctx));
142 
143     /* Generate 16 bytes of pseudo-random data */
144     ptr = (ulong32*)&(st->work_ctx.x);
145     STORE32L((ptr[0] ^ (ptr[5]>>16) ^ (ulong32)(ptr[3]<<16)), out+ 0);
146     STORE32L((ptr[2] ^ (ptr[7]>>16) ^ (ulong32)(ptr[5]<<16)), out+ 4);
147     STORE32L((ptr[4] ^ (ptr[1]>>16) ^ (ulong32)(ptr[7]<<16)), out+ 8);
148     STORE32L((ptr[6] ^ (ptr[3]>>16) ^ (ulong32)(ptr[1]<<16)), out+12);
149 }
150 
151 /* -------------------------------------------------------------------------- */
152 
153 /* Key setup */
rabbit_setup(rabbit_state * st,const unsigned char * key,unsigned long keylen)154 int rabbit_setup(rabbit_state* st, const unsigned char *key, unsigned long keylen)
155 {
156    ulong32 k0, k1, k2, k3, i;
157    unsigned char  tmpkey[16] = {0};
158 
159    LTC_ARGCHK(st != NULL);
160    LTC_ARGCHK(key != NULL);
161    LTC_ARGCHK(keylen <= 16);
162 
163    /* init state */
164    XMEMSET(st, 0, sizeof(rabbit_state));
165 
166    /* pad key in tmpkey */
167    XMEMCPY(tmpkey, key, keylen);
168 
169    /* Generate four subkeys */
170    LOAD32L(k0, tmpkey+ 0);
171    LOAD32L(k1, tmpkey+ 4);
172    LOAD32L(k2, tmpkey+ 8);
173    LOAD32L(k3, tmpkey+12);
174 
175 #ifdef LTC_CLEAN_STACK
176    /* done with tmpkey, wipe it */
177    zeromem(tmpkey, sizeof(tmpkey));
178 #endif
179 
180    /* Generate initial state variables */
181    st->master_ctx.x[0] = k0;
182    st->master_ctx.x[2] = k1;
183    st->master_ctx.x[4] = k2;
184    st->master_ctx.x[6] = k3;
185    st->master_ctx.x[1] = (ulong32)(k3<<16) | (k2>>16);
186    st->master_ctx.x[3] = (ulong32)(k0<<16) | (k3>>16);
187    st->master_ctx.x[5] = (ulong32)(k1<<16) | (k0>>16);
188    st->master_ctx.x[7] = (ulong32)(k2<<16) | (k1>>16);
189 
190    /* Generate initial counter values */
191    st->master_ctx.c[0] = ROLc(k2, 16);
192    st->master_ctx.c[2] = ROLc(k3, 16);
193    st->master_ctx.c[4] = ROLc(k0, 16);
194    st->master_ctx.c[6] = ROLc(k1, 16);
195    st->master_ctx.c[1] = (k0&0xFFFF0000) | (k1&0xFFFF);
196    st->master_ctx.c[3] = (k1&0xFFFF0000) | (k2&0xFFFF);
197    st->master_ctx.c[5] = (k2&0xFFFF0000) | (k3&0xFFFF);
198    st->master_ctx.c[7] = (k3&0xFFFF0000) | (k0&0xFFFF);
199 
200    /* Clear carry bit */
201    st->master_ctx.carry = 0;
202 
203    /* Iterate the master context four times */
204    for (i=0; i<4; i++) {
205       _rabbit_next_state(&(st->master_ctx));
206    }
207 
208    /* Modify the counters */
209    for (i=0; i<8; i++) {
210       st->master_ctx.c[i] ^= st->master_ctx.x[(i+4)&0x7];
211    }
212 
213    /* Copy master instance to work instance */
214    for (i=0; i<8; i++) {
215       st->work_ctx.x[i] = st->master_ctx.x[i];
216       st->work_ctx.c[i] = st->master_ctx.c[i];
217    }
218    st->work_ctx.carry = st->master_ctx.carry;
219    /* ...and prepare block for crypt() */
220    XMEMSET(&(st->block), 0, sizeof(st->block));
221    st->unused = 0;
222 
223    return CRYPT_OK;
224 }
225 
226 /* -------------------------------------------------------------------------- */
227 
228 /* IV setup */
rabbit_setiv(rabbit_state * st,const unsigned char * iv,unsigned long ivlen)229 int rabbit_setiv(rabbit_state* st, const unsigned char *iv, unsigned long ivlen)
230 {
231    ulong32 i0, i1, i2, i3, i;
232    unsigned char  tmpiv[8] = {0};
233 
234    LTC_ARGCHK(st != NULL);
235    LTC_ARGCHK(iv != NULL || ivlen == 0);
236    LTC_ARGCHK(ivlen <= 8);
237 
238    /* pad iv in tmpiv */
239    if (iv && ivlen > 0) XMEMCPY(tmpiv, iv, ivlen);
240 
241    /* Generate four subvectors */
242    LOAD32L(i0, tmpiv+0);
243    LOAD32L(i2, tmpiv+4);
244    i1 = (i0>>16) | (i2&0xFFFF0000);
245    i3 = (i2<<16) | (i0&0x0000FFFF);
246 
247    /* Modify counter values */
248    st->work_ctx.c[0] = st->master_ctx.c[0] ^ i0;
249    st->work_ctx.c[1] = st->master_ctx.c[1] ^ i1;
250    st->work_ctx.c[2] = st->master_ctx.c[2] ^ i2;
251    st->work_ctx.c[3] = st->master_ctx.c[3] ^ i3;
252    st->work_ctx.c[4] = st->master_ctx.c[4] ^ i0;
253    st->work_ctx.c[5] = st->master_ctx.c[5] ^ i1;
254    st->work_ctx.c[6] = st->master_ctx.c[6] ^ i2;
255    st->work_ctx.c[7] = st->master_ctx.c[7] ^ i3;
256 
257    /* Copy state variables */
258    for (i=0; i<8; i++) {
259       st->work_ctx.x[i] = st->master_ctx.x[i];
260    }
261    st->work_ctx.carry = st->master_ctx.carry;
262 
263    /* Iterate the work context four times */
264    for (i=0; i<4; i++) {
265       _rabbit_next_state(&(st->work_ctx));
266    }
267 
268    /* reset keystream buffer and unused count */
269    XMEMSET(&(st->block), 0, sizeof(st->block));
270    st->unused = 0;
271 
272    return CRYPT_OK;
273 }
274 
275 /* ------------------------------------------------------------------------- */
276 
277 /* Crypt a chunk of any size (encrypt/decrypt) */
rabbit_crypt(rabbit_state * st,const unsigned char * in,unsigned long inlen,unsigned char * out)278 int rabbit_crypt(rabbit_state* st, const unsigned char *in, unsigned long inlen, unsigned char *out)
279 {
280    unsigned char buf[16];
281    unsigned long i, j;
282 
283    if (inlen == 0) return CRYPT_OK; /* nothing to do */
284 
285    LTC_ARGCHK(st        != NULL);
286    LTC_ARGCHK(in        != NULL);
287    LTC_ARGCHK(out       != NULL);
288 
289    if (st->unused > 0) {
290       j = MIN(st->unused, inlen);
291       for (i = 0; i < j; ++i, st->unused--) out[i] = in[i] ^ st->block[16 - st->unused];
292       inlen -= j;
293       if (inlen == 0) return CRYPT_OK;
294       out += j;
295       in  += j;
296    }
297    for (;;) {
298      /* gen a block for buf */
299      _rabbit_gen_1_block(st, buf);
300      if (inlen <= 16) {
301        /* XOR and send to out */
302        for (i = 0; i < inlen; ++i) out[i] = in[i] ^ buf[i];
303        st->unused = 16 - inlen;
304        /* copy remainder to block */
305        for (i = inlen; i < 16; ++i) st->block[i] = buf[i];
306        return CRYPT_OK;
307      }
308      /* XOR entire buf and send to out */
309      for (i = 0; i < 16; ++i) out[i] = in[i] ^ buf[i];
310      inlen -= 16;
311      out += 16;
312      in  += 16;
313    }
314 }
315 
316 /* ------------------------------------------------------------------------- */
317 
rabbit_keystream(rabbit_state * st,unsigned char * out,unsigned long outlen)318 int rabbit_keystream(rabbit_state *st, unsigned char *out, unsigned long outlen)
319 {
320    if (outlen == 0) return CRYPT_OK; /* nothing to do */
321 
322    LTC_ARGCHK(out != NULL);
323 
324    XMEMSET(out, 0, outlen);
325    return rabbit_crypt(st, out, outlen, out);
326 }
327 
328 /* -------------------------------------------------------------------------- */
329 
rabbit_done(rabbit_state * st)330 int rabbit_done(rabbit_state *st)
331 {
332    LTC_ARGCHK(st != NULL);
333 
334    zeromem(st, sizeof(rabbit_state));
335    return CRYPT_OK;
336 }
337 
338 /* -------------------------------------------------------------------------- */
339 
rabbit_test(void)340 int rabbit_test(void)
341 {
342 #ifndef LTC_TEST
343    return CRYPT_NOP;
344 #else
345    rabbit_state st;
346    int err;
347    unsigned char out[1000] = { 0 };
348    {
349       /* all 3 tests use key and iv fm set 6, vector 3, the last vector in:
350          http://www.ecrypt.eu.org/stream/svn/viewcvs.cgi/ecrypt/trunk/submissions/rabbit/verified.test-vectors?rev=210&view=log
351       */
352 
353       /* --- Test 1 (generate whole blocks) --------------------------------- */
354 
355       {
356          unsigned char k[]  = { 0x0F, 0x62, 0xB5, 0x08, 0x5B, 0xAE, 0x01, 0x54,
357                                 0xA7, 0xFA, 0x4D, 0xA0, 0xF3, 0x46, 0x99, 0xEC };
358          unsigned char iv[] = { 0x28, 0x8F, 0xF6, 0x5D, 0xC4, 0x2B, 0x92, 0xF9 };
359          char pt[64]        = { 0 };
360          unsigned char ct[] = { 0x61, 0x3C, 0xB0, 0xBA, 0x96, 0xAF, 0xF6, 0xCA,
361                                 0xCF, 0x2A, 0x45, 0x9A, 0x10, 0x2A, 0x7F, 0x78,
362                                 0xCA, 0x98, 0x5C, 0xF8, 0xFD, 0xD1, 0x47, 0x40,
363                                 0x18, 0x75, 0x8E, 0x36, 0xAE, 0x99, 0x23, 0xF5,
364                                 0x19, 0xD1, 0x3D, 0x71, 0x8D, 0xAF, 0x8D, 0x7C,
365                                 0x0C, 0x10, 0x9B, 0x79, 0xD5, 0x74, 0x94, 0x39,
366                                 0xB7, 0xEF, 0xA4, 0xC4, 0xC9, 0xC8, 0xD2, 0x9D,
367                                 0xC5, 0xB3, 0x88, 0x83, 0x14, 0xA6, 0x81, 0x6F };
368          unsigned long ptlen = sizeof(pt);
369 
370          /* crypt 64 nulls */
371          if ((err = rabbit_setup(&st, k, sizeof(k)))                   != CRYPT_OK) return err;
372          if ((err = rabbit_setiv(&st, iv, sizeof(iv)))                 != CRYPT_OK) return err;
373          if ((err = rabbit_crypt(&st, (unsigned char*)pt, ptlen, out)) != CRYPT_OK) return err;
374          if (compare_testvector(out, ptlen, ct, ptlen, "RABBIT-TV1", 1))   return CRYPT_FAIL_TESTVECTOR;
375       }
376 
377       /* --- Test 2 (generate unusual number of bytes each time) ------------ */
378 
379       {
380          unsigned char k[]  = { 0x0F, 0x62, 0xB5, 0x08, 0x5B, 0xAE, 0x01, 0x54,
381                                 0xA7, 0xFA, 0x4D, 0xA0, 0xF3, 0x46, 0x99, 0xEC };
382          unsigned char iv[] = { 0x28, 0x8F, 0xF6, 0x5D, 0xC4, 0x2B, 0x92, 0xF9 };
383          char          pt[39] = { 0 };
384          unsigned char ct[] = { 0x61, 0x3C, 0xB0, 0xBA,   0x96, 0xAF, 0xF6, 0xCA,
385                                 0xCF, 0x2A, 0x45, 0x9A,   0x10, 0x2A, 0x7F, 0x78,
386                                 0xCA, 0x98, 0x5C, 0xF8,   0xFD, 0xD1, 0x47, 0x40,
387                                 0x18, 0x75, 0x8E, 0x36,   0xAE, 0x99, 0x23, 0xF5,
388                                 0x19, 0xD1, 0x3D, 0x71,   0x8D, 0xAF, 0x8D };
389          unsigned long ptlen = sizeof(pt);
390 
391          /* crypt piece by piece (hit at least one 16-byte boundary) */
392          if ((err = rabbit_setup(&st, k, sizeof(k)))                          != CRYPT_OK) return err;
393          if ((err = rabbit_setiv(&st, iv, sizeof(iv)))                        != CRYPT_OK) return err;
394          if ((err = rabbit_crypt(&st, (unsigned char*)pt,       5, out))      != CRYPT_OK) return err;
395          if ((err = rabbit_crypt(&st, (unsigned char*)pt +  5, 11, out +  5)) != CRYPT_OK) return err;
396          if ((err = rabbit_crypt(&st, (unsigned char*)pt + 16, 14, out + 16)) != CRYPT_OK) return err;
397          if ((err = rabbit_crypt(&st, (unsigned char*)pt + 30,  2, out + 30)) != CRYPT_OK) return err;
398          if ((err = rabbit_crypt(&st, (unsigned char*)pt + 32,  7, out + 32)) != CRYPT_OK) return err;
399          if (compare_testvector(out, ptlen, ct, ptlen, "RABBIT-TV2", 1))   return CRYPT_FAIL_TESTVECTOR;
400       }
401 
402       /* --- Test 3 (use non-null data) ------------------------------------- */
403 
404       {
405          unsigned char k[]  = { 0x0F, 0x62, 0xB5, 0x08, 0x5B, 0xAE, 0x01, 0x54,
406                                 0xA7, 0xFA, 0x4D, 0xA0, 0xF3, 0x46, 0x99, 0xEC };
407          unsigned char iv[] = { 0x28, 0x8F, 0xF6, 0x5D, 0xC4, 0x2B, 0x92, 0xF9 };
408          char          pt[] = "Kilroy was here, there, and everywhere!";
409          unsigned char ct[] = { 0x2a, 0x55, 0xdc, 0xc8,   0xf9, 0xd6, 0xd6, 0xbd,
410                                 0xae, 0x59, 0x65, 0xf2,   0x75, 0x58, 0x1a, 0x54,
411                                 0xea, 0xec, 0x34, 0x9d,   0x8f, 0xb4, 0x6b, 0x60,
412                                 0x79, 0x1b, 0xea, 0x16,   0xcb, 0xef, 0x46, 0x87,
413                                 0x60, 0xa6, 0x55, 0x14,   0xff, 0xca, 0xac };
414          unsigned long ptlen = strlen(pt);
415          unsigned char out2[1000] = { 0 };
416          unsigned char nulls[1000] = { 0 };
417 
418          /* crypt piece by piece */
419          if ((err = rabbit_setup(&st, k, sizeof(k)))                          != CRYPT_OK) return err;
420          if ((err = rabbit_setiv(&st, iv, sizeof(iv)))                        != CRYPT_OK) return err;
421          if ((err = rabbit_crypt(&st, (unsigned char*)pt,       5, out))      != CRYPT_OK) return err;
422          if ((err = rabbit_crypt(&st, (unsigned char*)pt +  5, 29, out +  5)) != CRYPT_OK) return err;
423          if ((err = rabbit_crypt(&st, (unsigned char*)pt + 34,  5, out + 34)) != CRYPT_OK) return err;
424          if (compare_testvector(out, ptlen, ct, ptlen, "RABBIT-TV3", 1))   return CRYPT_FAIL_TESTVECTOR;
425 
426       /* --- Test 4 (crypt in a single call) ------------------------------------ */
427 
428          if ((err = rabbit_memory(k, sizeof(k), iv, sizeof(iv),
429                                    (unsigned char*)pt, sizeof(pt), out))      != CRYPT_OK) return err;
430          if (compare_testvector(out, ptlen, ct, ptlen, "RABBIT-TV4", 1))   return CRYPT_FAIL_TESTVECTOR;
431          /* use 'out' (ciphertext) in the next decryption test */
432 
433       /* --- Test 5 (decrypt ciphertext) ------------------------------------ */
434 
435          /* decrypt ct (out) and compare with pt (start with only setiv() to reset) */
436          if ((err = rabbit_setiv(&st, iv, sizeof(iv)))                        != CRYPT_OK) return err;
437          if ((err = rabbit_crypt(&st, out, ptlen, out2))                      != CRYPT_OK) return err;
438          if (compare_testvector(out2, ptlen, pt, ptlen, "RABBIT-TV5", 1))  return CRYPT_FAIL_TESTVECTOR;
439 
440       /* --- Test 6 (wipe state, incl key) ---------------------------------- */
441 
442          if ((err = rabbit_done(&st))                      != CRYPT_OK) return err;
443          if (compare_testvector(&st, sizeof(st), nulls, sizeof(st), "RABBIT-TV6", 1))  return CRYPT_FAIL_TESTVECTOR;
444 
445       }
446 
447       return CRYPT_OK;
448    }
449 #endif
450 }
451 
452 /* -------------------------------------------------------------------------- */
453 
454 #endif
455 
456 /* ref:         $Format:%D$ */
457 /* git commit:  $Format:%H$ */
458 /* commit time: $Format:%ai$ */
459