Import ciphers from libgcrypt 1.4.4.
This commit is contained in:
parent
af2f93ac47
commit
bfaae3cdd4
37 changed files with 36346 additions and 0 deletions
3900
lib/libgcrypt/cipher/ChangeLog
Normal file
3900
lib/libgcrypt/cipher/ChangeLog
Normal file
File diff suppressed because it is too large
Load diff
3301
lib/libgcrypt/cipher/ac.c
Normal file
3301
lib/libgcrypt/cipher/ac.c
Normal file
File diff suppressed because it is too large
Load diff
156
lib/libgcrypt/cipher/arcfour.c
Normal file
156
lib/libgcrypt/cipher/arcfour.c
Normal file
|
@ -0,0 +1,156 @@
|
|||
/* arcfour.c - The arcfour stream cipher
|
||||
* Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of Libgcrypt.
|
||||
*
|
||||
* Libgcrypt is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser general Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Libgcrypt is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*
|
||||
* For a description of the algorithm, see:
|
||||
* Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996.
|
||||
* ISBN 0-471-11709-9. Pages 397 ff.
|
||||
*/
|
||||
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "types.h"
|
||||
#include "g10lib.h"
|
||||
#include "cipher.h"
|
||||
|
||||
static const char *selftest(void);
|
||||
|
||||
typedef struct {
|
||||
int idx_i, idx_j;
|
||||
byte sbox[256];
|
||||
} ARCFOUR_context;
|
||||
|
||||
static void
|
||||
do_encrypt_stream( ARCFOUR_context *ctx,
|
||||
byte *outbuf, const byte *inbuf, unsigned int length )
|
||||
{
|
||||
register int i = ctx->idx_i;
|
||||
register int j = ctx->idx_j;
|
||||
register byte *sbox = ctx->sbox;
|
||||
register int t;
|
||||
|
||||
while ( length-- )
|
||||
{
|
||||
i++;
|
||||
i = i & 255; /* The and-op seems to be faster than the mod-op. */
|
||||
j += sbox[i];
|
||||
j &= 255;
|
||||
t = sbox[i]; sbox[i] = sbox[j]; sbox[j] = t;
|
||||
*outbuf++ = *inbuf++ ^ sbox[(sbox[i] + sbox[j]) & 255];
|
||||
}
|
||||
|
||||
ctx->idx_i = i;
|
||||
ctx->idx_j = j;
|
||||
}
|
||||
|
||||
static void
|
||||
encrypt_stream (void *context,
|
||||
byte *outbuf, const byte *inbuf, unsigned int length)
|
||||
{
|
||||
ARCFOUR_context *ctx = (ARCFOUR_context *) context;
|
||||
do_encrypt_stream (ctx, outbuf, inbuf, length );
|
||||
_gcry_burn_stack (64);
|
||||
}
|
||||
|
||||
|
||||
static gcry_err_code_t
|
||||
do_arcfour_setkey (void *context, const byte *key, unsigned int keylen)
|
||||
{
|
||||
static int initialized;
|
||||
static const char* selftest_failed;
|
||||
int i, j;
|
||||
byte karr[256];
|
||||
ARCFOUR_context *ctx = (ARCFOUR_context *) context;
|
||||
|
||||
if (!initialized )
|
||||
{
|
||||
initialized = 1;
|
||||
selftest_failed = selftest();
|
||||
if( selftest_failed )
|
||||
log_error ("ARCFOUR selftest failed (%s)\n", selftest_failed );
|
||||
}
|
||||
if( selftest_failed )
|
||||
return GPG_ERR_SELFTEST_FAILED;
|
||||
|
||||
if( keylen < 40/8 ) /* we want at least 40 bits */
|
||||
return GPG_ERR_INV_KEYLEN;
|
||||
|
||||
ctx->idx_i = ctx->idx_j = 0;
|
||||
for (i=0; i < 256; i++ )
|
||||
ctx->sbox[i] = i;
|
||||
for (i=0; i < 256; i++ )
|
||||
karr[i] = key[i%keylen];
|
||||
for (i=j=0; i < 256; i++ )
|
||||
{
|
||||
int t;
|
||||
j = (j + ctx->sbox[i] + karr[i]) % 256;
|
||||
t = ctx->sbox[i];
|
||||
ctx->sbox[i] = ctx->sbox[j];
|
||||
ctx->sbox[j] = t;
|
||||
}
|
||||
memset( karr, 0, 256 );
|
||||
|
||||
return GPG_ERR_NO_ERROR;
|
||||
}
|
||||
|
||||
static gcry_err_code_t
|
||||
arcfour_setkey ( void *context, const byte *key, unsigned int keylen )
|
||||
{
|
||||
ARCFOUR_context *ctx = (ARCFOUR_context *) context;
|
||||
gcry_err_code_t rc = do_arcfour_setkey (ctx, key, keylen );
|
||||
_gcry_burn_stack (300);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static const char*
|
||||
selftest(void)
|
||||
{
|
||||
ARCFOUR_context ctx;
|
||||
byte scratch[16];
|
||||
|
||||
/* Test vector from Cryptlib labeled there: "from the
|
||||
State/Commerce Department". */
|
||||
static byte key_1[] =
|
||||
{ 0x61, 0x8A, 0x63, 0xD2, 0xFB };
|
||||
static byte plaintext_1[] =
|
||||
{ 0xDC, 0xEE, 0x4C, 0xF9, 0x2C };
|
||||
static const byte ciphertext_1[] =
|
||||
{ 0xF1, 0x38, 0x29, 0xC9, 0xDE };
|
||||
|
||||
arcfour_setkey( &ctx, key_1, sizeof(key_1));
|
||||
encrypt_stream( &ctx, scratch, plaintext_1, sizeof(plaintext_1));
|
||||
if ( memcmp (scratch, ciphertext_1, sizeof (ciphertext_1)))
|
||||
return "Arcfour encryption test 1 failed.";
|
||||
arcfour_setkey( &ctx, key_1, sizeof(key_1));
|
||||
encrypt_stream(&ctx, scratch, scratch, sizeof(plaintext_1)); /* decrypt */
|
||||
if ( memcmp (scratch, plaintext_1, sizeof (plaintext_1)))
|
||||
return "Arcfour decryption test 1 failed.";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
gcry_cipher_spec_t _gcry_cipher_spec_arcfour =
|
||||
{
|
||||
"ARCFOUR", NULL, NULL, 1, 128, sizeof (ARCFOUR_context),
|
||||
arcfour_setkey, NULL, NULL, encrypt_stream, encrypt_stream,
|
||||
};
|
||||
|
54
lib/libgcrypt/cipher/bithelp.h
Normal file
54
lib/libgcrypt/cipher/bithelp.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
/* bithelp.h - Some bit manipulation helpers
|
||||
* Copyright (C) 1999, 2002 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of Libgcrypt.
|
||||
*
|
||||
* Libgcrypt is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser general Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Libgcrypt is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifndef G10_BITHELP_H
|
||||
#define G10_BITHELP_H
|
||||
|
||||
|
||||
/****************
|
||||
* Rotate the 32 bit unsigned integer X by N bits left/right
|
||||
*/
|
||||
#if defined(__GNUC__) && defined(__i386__)
|
||||
static inline u32
|
||||
rol( u32 x, int n)
|
||||
{
|
||||
__asm__("roll %%cl,%0"
|
||||
:"=r" (x)
|
||||
:"0" (x),"c" (n));
|
||||
return x;
|
||||
}
|
||||
#else
|
||||
#define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) )
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && defined(__i386__)
|
||||
static inline u32
|
||||
ror(u32 x, int n)
|
||||
{
|
||||
__asm__("rorl %%cl,%0"
|
||||
:"=r" (x)
|
||||
:"0" (x),"c" (n));
|
||||
return x;
|
||||
}
|
||||
#else
|
||||
#define ror(x,n) ( ((x) >> (n)) | ((x) << (32-(n))) )
|
||||
#endif
|
||||
|
||||
|
||||
#endif /*G10_BITHELP_H*/
|
605
lib/libgcrypt/cipher/blowfish.c
Normal file
605
lib/libgcrypt/cipher/blowfish.c
Normal file
|
@ -0,0 +1,605 @@
|
|||
/* blowfish.c - Blowfish encryption
|
||||
* Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of Libgcrypt.
|
||||
*
|
||||
* Libgcrypt is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser general Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Libgcrypt is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*
|
||||
* For a description of the algorithm, see:
|
||||
* Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996.
|
||||
* ISBN 0-471-11709-9. Pages 336 ff.
|
||||
*/
|
||||
|
||||
/* Test values:
|
||||
* key "abcdefghijklmnopqrstuvwxyz";
|
||||
* plain "BLOWFISH"
|
||||
* cipher 32 4E D0 FE F4 13 A2 03
|
||||
*
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "types.h"
|
||||
#include "g10lib.h"
|
||||
#include "cipher.h"
|
||||
|
||||
#define BLOWFISH_BLOCKSIZE 8
|
||||
#define BLOWFISH_ROUNDS 16
|
||||
|
||||
typedef struct {
|
||||
u32 s0[256];
|
||||
u32 s1[256];
|
||||
u32 s2[256];
|
||||
u32 s3[256];
|
||||
u32 p[BLOWFISH_ROUNDS+2];
|
||||
} BLOWFISH_context;
|
||||
|
||||
static gcry_err_code_t bf_setkey (void *c, const byte *key, unsigned keylen);
|
||||
static void encrypt_block (void *bc, byte *outbuf, const byte *inbuf);
|
||||
static void decrypt_block (void *bc, byte *outbuf, const byte *inbuf);
|
||||
|
||||
|
||||
/* precomputed S boxes */
|
||||
static const u32 ks0[256] = {
|
||||
0xD1310BA6,0x98DFB5AC,0x2FFD72DB,0xD01ADFB7,0xB8E1AFED,0x6A267E96,
|
||||
0xBA7C9045,0xF12C7F99,0x24A19947,0xB3916CF7,0x0801F2E2,0x858EFC16,
|
||||
0x636920D8,0x71574E69,0xA458FEA3,0xF4933D7E,0x0D95748F,0x728EB658,
|
||||
0x718BCD58,0x82154AEE,0x7B54A41D,0xC25A59B5,0x9C30D539,0x2AF26013,
|
||||
0xC5D1B023,0x286085F0,0xCA417918,0xB8DB38EF,0x8E79DCB0,0x603A180E,
|
||||
0x6C9E0E8B,0xB01E8A3E,0xD71577C1,0xBD314B27,0x78AF2FDA,0x55605C60,
|
||||
0xE65525F3,0xAA55AB94,0x57489862,0x63E81440,0x55CA396A,0x2AAB10B6,
|
||||
0xB4CC5C34,0x1141E8CE,0xA15486AF,0x7C72E993,0xB3EE1411,0x636FBC2A,
|
||||
0x2BA9C55D,0x741831F6,0xCE5C3E16,0x9B87931E,0xAFD6BA33,0x6C24CF5C,
|
||||
0x7A325381,0x28958677,0x3B8F4898,0x6B4BB9AF,0xC4BFE81B,0x66282193,
|
||||
0x61D809CC,0xFB21A991,0x487CAC60,0x5DEC8032,0xEF845D5D,0xE98575B1,
|
||||
0xDC262302,0xEB651B88,0x23893E81,0xD396ACC5,0x0F6D6FF3,0x83F44239,
|
||||
0x2E0B4482,0xA4842004,0x69C8F04A,0x9E1F9B5E,0x21C66842,0xF6E96C9A,
|
||||
0x670C9C61,0xABD388F0,0x6A51A0D2,0xD8542F68,0x960FA728,0xAB5133A3,
|
||||
0x6EEF0B6C,0x137A3BE4,0xBA3BF050,0x7EFB2A98,0xA1F1651D,0x39AF0176,
|
||||
0x66CA593E,0x82430E88,0x8CEE8619,0x456F9FB4,0x7D84A5C3,0x3B8B5EBE,
|
||||
0xE06F75D8,0x85C12073,0x401A449F,0x56C16AA6,0x4ED3AA62,0x363F7706,
|
||||
0x1BFEDF72,0x429B023D,0x37D0D724,0xD00A1248,0xDB0FEAD3,0x49F1C09B,
|
||||
0x075372C9,0x80991B7B,0x25D479D8,0xF6E8DEF7,0xE3FE501A,0xB6794C3B,
|
||||
0x976CE0BD,0x04C006BA,0xC1A94FB6,0x409F60C4,0x5E5C9EC2,0x196A2463,
|
||||
0x68FB6FAF,0x3E6C53B5,0x1339B2EB,0x3B52EC6F,0x6DFC511F,0x9B30952C,
|
||||
0xCC814544,0xAF5EBD09,0xBEE3D004,0xDE334AFD,0x660F2807,0x192E4BB3,
|
||||
0xC0CBA857,0x45C8740F,0xD20B5F39,0xB9D3FBDB,0x5579C0BD,0x1A60320A,
|
||||
0xD6A100C6,0x402C7279,0x679F25FE,0xFB1FA3CC,0x8EA5E9F8,0xDB3222F8,
|
||||
0x3C7516DF,0xFD616B15,0x2F501EC8,0xAD0552AB,0x323DB5FA,0xFD238760,
|
||||
0x53317B48,0x3E00DF82,0x9E5C57BB,0xCA6F8CA0,0x1A87562E,0xDF1769DB,
|
||||
0xD542A8F6,0x287EFFC3,0xAC6732C6,0x8C4F5573,0x695B27B0,0xBBCA58C8,
|
||||
0xE1FFA35D,0xB8F011A0,0x10FA3D98,0xFD2183B8,0x4AFCB56C,0x2DD1D35B,
|
||||
0x9A53E479,0xB6F84565,0xD28E49BC,0x4BFB9790,0xE1DDF2DA,0xA4CB7E33,
|
||||
0x62FB1341,0xCEE4C6E8,0xEF20CADA,0x36774C01,0xD07E9EFE,0x2BF11FB4,
|
||||
0x95DBDA4D,0xAE909198,0xEAAD8E71,0x6B93D5A0,0xD08ED1D0,0xAFC725E0,
|
||||
0x8E3C5B2F,0x8E7594B7,0x8FF6E2FB,0xF2122B64,0x8888B812,0x900DF01C,
|
||||
0x4FAD5EA0,0x688FC31C,0xD1CFF191,0xB3A8C1AD,0x2F2F2218,0xBE0E1777,
|
||||
0xEA752DFE,0x8B021FA1,0xE5A0CC0F,0xB56F74E8,0x18ACF3D6,0xCE89E299,
|
||||
0xB4A84FE0,0xFD13E0B7,0x7CC43B81,0xD2ADA8D9,0x165FA266,0x80957705,
|
||||
0x93CC7314,0x211A1477,0xE6AD2065,0x77B5FA86,0xC75442F5,0xFB9D35CF,
|
||||
0xEBCDAF0C,0x7B3E89A0,0xD6411BD3,0xAE1E7E49,0x00250E2D,0x2071B35E,
|
||||
0x226800BB,0x57B8E0AF,0x2464369B,0xF009B91E,0x5563911D,0x59DFA6AA,
|
||||
0x78C14389,0xD95A537F,0x207D5BA2,0x02E5B9C5,0x83260376,0x6295CFA9,
|
||||
0x11C81968,0x4E734A41,0xB3472DCA,0x7B14A94A,0x1B510052,0x9A532915,
|
||||
0xD60F573F,0xBC9BC6E4,0x2B60A476,0x81E67400,0x08BA6FB5,0x571BE91F,
|
||||
0xF296EC6B,0x2A0DD915,0xB6636521,0xE7B9F9B6,0xFF34052E,0xC5855664,
|
||||
0x53B02D5D,0xA99F8FA1,0x08BA4799,0x6E85076A };
|
||||
|
||||
static const u32 ks1[256] = {
|
||||
0x4B7A70E9,0xB5B32944,0xDB75092E,0xC4192623,0xAD6EA6B0,0x49A7DF7D,
|
||||
0x9CEE60B8,0x8FEDB266,0xECAA8C71,0x699A17FF,0x5664526C,0xC2B19EE1,
|
||||
0x193602A5,0x75094C29,0xA0591340,0xE4183A3E,0x3F54989A,0x5B429D65,
|
||||
0x6B8FE4D6,0x99F73FD6,0xA1D29C07,0xEFE830F5,0x4D2D38E6,0xF0255DC1,
|
||||
0x4CDD2086,0x8470EB26,0x6382E9C6,0x021ECC5E,0x09686B3F,0x3EBAEFC9,
|
||||
0x3C971814,0x6B6A70A1,0x687F3584,0x52A0E286,0xB79C5305,0xAA500737,
|
||||
0x3E07841C,0x7FDEAE5C,0x8E7D44EC,0x5716F2B8,0xB03ADA37,0xF0500C0D,
|
||||
0xF01C1F04,0x0200B3FF,0xAE0CF51A,0x3CB574B2,0x25837A58,0xDC0921BD,
|
||||
0xD19113F9,0x7CA92FF6,0x94324773,0x22F54701,0x3AE5E581,0x37C2DADC,
|
||||
0xC8B57634,0x9AF3DDA7,0xA9446146,0x0FD0030E,0xECC8C73E,0xA4751E41,
|
||||
0xE238CD99,0x3BEA0E2F,0x3280BBA1,0x183EB331,0x4E548B38,0x4F6DB908,
|
||||
0x6F420D03,0xF60A04BF,0x2CB81290,0x24977C79,0x5679B072,0xBCAF89AF,
|
||||
0xDE9A771F,0xD9930810,0xB38BAE12,0xDCCF3F2E,0x5512721F,0x2E6B7124,
|
||||
0x501ADDE6,0x9F84CD87,0x7A584718,0x7408DA17,0xBC9F9ABC,0xE94B7D8C,
|
||||
0xEC7AEC3A,0xDB851DFA,0x63094366,0xC464C3D2,0xEF1C1847,0x3215D908,
|
||||
0xDD433B37,0x24C2BA16,0x12A14D43,0x2A65C451,0x50940002,0x133AE4DD,
|
||||
0x71DFF89E,0x10314E55,0x81AC77D6,0x5F11199B,0x043556F1,0xD7A3C76B,
|
||||
0x3C11183B,0x5924A509,0xF28FE6ED,0x97F1FBFA,0x9EBABF2C,0x1E153C6E,
|
||||
0x86E34570,0xEAE96FB1,0x860E5E0A,0x5A3E2AB3,0x771FE71C,0x4E3D06FA,
|
||||
0x2965DCB9,0x99E71D0F,0x803E89D6,0x5266C825,0x2E4CC978,0x9C10B36A,
|
||||
0xC6150EBA,0x94E2EA78,0xA5FC3C53,0x1E0A2DF4,0xF2F74EA7,0x361D2B3D,
|
||||
0x1939260F,0x19C27960,0x5223A708,0xF71312B6,0xEBADFE6E,0xEAC31F66,
|
||||
0xE3BC4595,0xA67BC883,0xB17F37D1,0x018CFF28,0xC332DDEF,0xBE6C5AA5,
|
||||
0x65582185,0x68AB9802,0xEECEA50F,0xDB2F953B,0x2AEF7DAD,0x5B6E2F84,
|
||||
0x1521B628,0x29076170,0xECDD4775,0x619F1510,0x13CCA830,0xEB61BD96,
|
||||
0x0334FE1E,0xAA0363CF,0xB5735C90,0x4C70A239,0xD59E9E0B,0xCBAADE14,
|
||||
0xEECC86BC,0x60622CA7,0x9CAB5CAB,0xB2F3846E,0x648B1EAF,0x19BDF0CA,
|
||||
0xA02369B9,0x655ABB50,0x40685A32,0x3C2AB4B3,0x319EE9D5,0xC021B8F7,
|
||||
0x9B540B19,0x875FA099,0x95F7997E,0x623D7DA8,0xF837889A,0x97E32D77,
|
||||
0x11ED935F,0x16681281,0x0E358829,0xC7E61FD6,0x96DEDFA1,0x7858BA99,
|
||||
0x57F584A5,0x1B227263,0x9B83C3FF,0x1AC24696,0xCDB30AEB,0x532E3054,
|
||||
0x8FD948E4,0x6DBC3128,0x58EBF2EF,0x34C6FFEA,0xFE28ED61,0xEE7C3C73,
|
||||
0x5D4A14D9,0xE864B7E3,0x42105D14,0x203E13E0,0x45EEE2B6,0xA3AAABEA,
|
||||
0xDB6C4F15,0xFACB4FD0,0xC742F442,0xEF6ABBB5,0x654F3B1D,0x41CD2105,
|
||||
0xD81E799E,0x86854DC7,0xE44B476A,0x3D816250,0xCF62A1F2,0x5B8D2646,
|
||||
0xFC8883A0,0xC1C7B6A3,0x7F1524C3,0x69CB7492,0x47848A0B,0x5692B285,
|
||||
0x095BBF00,0xAD19489D,0x1462B174,0x23820E00,0x58428D2A,0x0C55F5EA,
|
||||
0x1DADF43E,0x233F7061,0x3372F092,0x8D937E41,0xD65FECF1,0x6C223BDB,
|
||||
0x7CDE3759,0xCBEE7460,0x4085F2A7,0xCE77326E,0xA6078084,0x19F8509E,
|
||||
0xE8EFD855,0x61D99735,0xA969A7AA,0xC50C06C2,0x5A04ABFC,0x800BCADC,
|
||||
0x9E447A2E,0xC3453484,0xFDD56705,0x0E1E9EC9,0xDB73DBD3,0x105588CD,
|
||||
0x675FDA79,0xE3674340,0xC5C43465,0x713E38D8,0x3D28F89E,0xF16DFF20,
|
||||
0x153E21E7,0x8FB03D4A,0xE6E39F2B,0xDB83ADF7 };
|
||||
|
||||
static const u32 ks2[256] = {
|
||||
0xE93D5A68,0x948140F7,0xF64C261C,0x94692934,0x411520F7,0x7602D4F7,
|
||||
0xBCF46B2E,0xD4A20068,0xD4082471,0x3320F46A,0x43B7D4B7,0x500061AF,
|
||||
0x1E39F62E,0x97244546,0x14214F74,0xBF8B8840,0x4D95FC1D,0x96B591AF,
|
||||
0x70F4DDD3,0x66A02F45,0xBFBC09EC,0x03BD9785,0x7FAC6DD0,0x31CB8504,
|
||||
0x96EB27B3,0x55FD3941,0xDA2547E6,0xABCA0A9A,0x28507825,0x530429F4,
|
||||
0x0A2C86DA,0xE9B66DFB,0x68DC1462,0xD7486900,0x680EC0A4,0x27A18DEE,
|
||||
0x4F3FFEA2,0xE887AD8C,0xB58CE006,0x7AF4D6B6,0xAACE1E7C,0xD3375FEC,
|
||||
0xCE78A399,0x406B2A42,0x20FE9E35,0xD9F385B9,0xEE39D7AB,0x3B124E8B,
|
||||
0x1DC9FAF7,0x4B6D1856,0x26A36631,0xEAE397B2,0x3A6EFA74,0xDD5B4332,
|
||||
0x6841E7F7,0xCA7820FB,0xFB0AF54E,0xD8FEB397,0x454056AC,0xBA489527,
|
||||
0x55533A3A,0x20838D87,0xFE6BA9B7,0xD096954B,0x55A867BC,0xA1159A58,
|
||||
0xCCA92963,0x99E1DB33,0xA62A4A56,0x3F3125F9,0x5EF47E1C,0x9029317C,
|
||||
0xFDF8E802,0x04272F70,0x80BB155C,0x05282CE3,0x95C11548,0xE4C66D22,
|
||||
0x48C1133F,0xC70F86DC,0x07F9C9EE,0x41041F0F,0x404779A4,0x5D886E17,
|
||||
0x325F51EB,0xD59BC0D1,0xF2BCC18F,0x41113564,0x257B7834,0x602A9C60,
|
||||
0xDFF8E8A3,0x1F636C1B,0x0E12B4C2,0x02E1329E,0xAF664FD1,0xCAD18115,
|
||||
0x6B2395E0,0x333E92E1,0x3B240B62,0xEEBEB922,0x85B2A20E,0xE6BA0D99,
|
||||
0xDE720C8C,0x2DA2F728,0xD0127845,0x95B794FD,0x647D0862,0xE7CCF5F0,
|
||||
0x5449A36F,0x877D48FA,0xC39DFD27,0xF33E8D1E,0x0A476341,0x992EFF74,
|
||||
0x3A6F6EAB,0xF4F8FD37,0xA812DC60,0xA1EBDDF8,0x991BE14C,0xDB6E6B0D,
|
||||
0xC67B5510,0x6D672C37,0x2765D43B,0xDCD0E804,0xF1290DC7,0xCC00FFA3,
|
||||
0xB5390F92,0x690FED0B,0x667B9FFB,0xCEDB7D9C,0xA091CF0B,0xD9155EA3,
|
||||
0xBB132F88,0x515BAD24,0x7B9479BF,0x763BD6EB,0x37392EB3,0xCC115979,
|
||||
0x8026E297,0xF42E312D,0x6842ADA7,0xC66A2B3B,0x12754CCC,0x782EF11C,
|
||||
0x6A124237,0xB79251E7,0x06A1BBE6,0x4BFB6350,0x1A6B1018,0x11CAEDFA,
|
||||
0x3D25BDD8,0xE2E1C3C9,0x44421659,0x0A121386,0xD90CEC6E,0xD5ABEA2A,
|
||||
0x64AF674E,0xDA86A85F,0xBEBFE988,0x64E4C3FE,0x9DBC8057,0xF0F7C086,
|
||||
0x60787BF8,0x6003604D,0xD1FD8346,0xF6381FB0,0x7745AE04,0xD736FCCC,
|
||||
0x83426B33,0xF01EAB71,0xB0804187,0x3C005E5F,0x77A057BE,0xBDE8AE24,
|
||||
0x55464299,0xBF582E61,0x4E58F48F,0xF2DDFDA2,0xF474EF38,0x8789BDC2,
|
||||
0x5366F9C3,0xC8B38E74,0xB475F255,0x46FCD9B9,0x7AEB2661,0x8B1DDF84,
|
||||
0x846A0E79,0x915F95E2,0x466E598E,0x20B45770,0x8CD55591,0xC902DE4C,
|
||||
0xB90BACE1,0xBB8205D0,0x11A86248,0x7574A99E,0xB77F19B6,0xE0A9DC09,
|
||||
0x662D09A1,0xC4324633,0xE85A1F02,0x09F0BE8C,0x4A99A025,0x1D6EFE10,
|
||||
0x1AB93D1D,0x0BA5A4DF,0xA186F20F,0x2868F169,0xDCB7DA83,0x573906FE,
|
||||
0xA1E2CE9B,0x4FCD7F52,0x50115E01,0xA70683FA,0xA002B5C4,0x0DE6D027,
|
||||
0x9AF88C27,0x773F8641,0xC3604C06,0x61A806B5,0xF0177A28,0xC0F586E0,
|
||||
0x006058AA,0x30DC7D62,0x11E69ED7,0x2338EA63,0x53C2DD94,0xC2C21634,
|
||||
0xBBCBEE56,0x90BCB6DE,0xEBFC7DA1,0xCE591D76,0x6F05E409,0x4B7C0188,
|
||||
0x39720A3D,0x7C927C24,0x86E3725F,0x724D9DB9,0x1AC15BB4,0xD39EB8FC,
|
||||
0xED545578,0x08FCA5B5,0xD83D7CD3,0x4DAD0FC4,0x1E50EF5E,0xB161E6F8,
|
||||
0xA28514D9,0x6C51133C,0x6FD5C7E7,0x56E14EC4,0x362ABFCE,0xDDC6C837,
|
||||
0xD79A3234,0x92638212,0x670EFA8E,0x406000E0 };
|
||||
|
||||
static const u32 ks3[256] = {
|
||||
0x3A39CE37,0xD3FAF5CF,0xABC27737,0x5AC52D1B,0x5CB0679E,0x4FA33742,
|
||||
0xD3822740,0x99BC9BBE,0xD5118E9D,0xBF0F7315,0xD62D1C7E,0xC700C47B,
|
||||
0xB78C1B6B,0x21A19045,0xB26EB1BE,0x6A366EB4,0x5748AB2F,0xBC946E79,
|
||||
0xC6A376D2,0x6549C2C8,0x530FF8EE,0x468DDE7D,0xD5730A1D,0x4CD04DC6,
|
||||
0x2939BBDB,0xA9BA4650,0xAC9526E8,0xBE5EE304,0xA1FAD5F0,0x6A2D519A,
|
||||
0x63EF8CE2,0x9A86EE22,0xC089C2B8,0x43242EF6,0xA51E03AA,0x9CF2D0A4,
|
||||
0x83C061BA,0x9BE96A4D,0x8FE51550,0xBA645BD6,0x2826A2F9,0xA73A3AE1,
|
||||
0x4BA99586,0xEF5562E9,0xC72FEFD3,0xF752F7DA,0x3F046F69,0x77FA0A59,
|
||||
0x80E4A915,0x87B08601,0x9B09E6AD,0x3B3EE593,0xE990FD5A,0x9E34D797,
|
||||
0x2CF0B7D9,0x022B8B51,0x96D5AC3A,0x017DA67D,0xD1CF3ED6,0x7C7D2D28,
|
||||
0x1F9F25CF,0xADF2B89B,0x5AD6B472,0x5A88F54C,0xE029AC71,0xE019A5E6,
|
||||
0x47B0ACFD,0xED93FA9B,0xE8D3C48D,0x283B57CC,0xF8D56629,0x79132E28,
|
||||
0x785F0191,0xED756055,0xF7960E44,0xE3D35E8C,0x15056DD4,0x88F46DBA,
|
||||
0x03A16125,0x0564F0BD,0xC3EB9E15,0x3C9057A2,0x97271AEC,0xA93A072A,
|
||||
0x1B3F6D9B,0x1E6321F5,0xF59C66FB,0x26DCF319,0x7533D928,0xB155FDF5,
|
||||
0x03563482,0x8ABA3CBB,0x28517711,0xC20AD9F8,0xABCC5167,0xCCAD925F,
|
||||
0x4DE81751,0x3830DC8E,0x379D5862,0x9320F991,0xEA7A90C2,0xFB3E7BCE,
|
||||
0x5121CE64,0x774FBE32,0xA8B6E37E,0xC3293D46,0x48DE5369,0x6413E680,
|
||||
0xA2AE0810,0xDD6DB224,0x69852DFD,0x09072166,0xB39A460A,0x6445C0DD,
|
||||
0x586CDECF,0x1C20C8AE,0x5BBEF7DD,0x1B588D40,0xCCD2017F,0x6BB4E3BB,
|
||||
0xDDA26A7E,0x3A59FF45,0x3E350A44,0xBCB4CDD5,0x72EACEA8,0xFA6484BB,
|
||||
0x8D6612AE,0xBF3C6F47,0xD29BE463,0x542F5D9E,0xAEC2771B,0xF64E6370,
|
||||
0x740E0D8D,0xE75B1357,0xF8721671,0xAF537D5D,0x4040CB08,0x4EB4E2CC,
|
||||
0x34D2466A,0x0115AF84,0xE1B00428,0x95983A1D,0x06B89FB4,0xCE6EA048,
|
||||
0x6F3F3B82,0x3520AB82,0x011A1D4B,0x277227F8,0x611560B1,0xE7933FDC,
|
||||
0xBB3A792B,0x344525BD,0xA08839E1,0x51CE794B,0x2F32C9B7,0xA01FBAC9,
|
||||
0xE01CC87E,0xBCC7D1F6,0xCF0111C3,0xA1E8AAC7,0x1A908749,0xD44FBD9A,
|
||||
0xD0DADECB,0xD50ADA38,0x0339C32A,0xC6913667,0x8DF9317C,0xE0B12B4F,
|
||||
0xF79E59B7,0x43F5BB3A,0xF2D519FF,0x27D9459C,0xBF97222C,0x15E6FC2A,
|
||||
0x0F91FC71,0x9B941525,0xFAE59361,0xCEB69CEB,0xC2A86459,0x12BAA8D1,
|
||||
0xB6C1075E,0xE3056A0C,0x10D25065,0xCB03A442,0xE0EC6E0E,0x1698DB3B,
|
||||
0x4C98A0BE,0x3278E964,0x9F1F9532,0xE0D392DF,0xD3A0342B,0x8971F21E,
|
||||
0x1B0A7441,0x4BA3348C,0xC5BE7120,0xC37632D8,0xDF359F8D,0x9B992F2E,
|
||||
0xE60B6F47,0x0FE3F11D,0xE54CDA54,0x1EDAD891,0xCE6279CF,0xCD3E7E6F,
|
||||
0x1618B166,0xFD2C1D05,0x848FD2C5,0xF6FB2299,0xF523F357,0xA6327623,
|
||||
0x93A83531,0x56CCCD02,0xACF08162,0x5A75EBB5,0x6E163697,0x88D273CC,
|
||||
0xDE966292,0x81B949D0,0x4C50901B,0x71C65614,0xE6C6C7BD,0x327A140A,
|
||||
0x45E1D006,0xC3F27B9A,0xC9AA53FD,0x62A80F00,0xBB25BFE2,0x35BDD2F6,
|
||||
0x71126905,0xB2040222,0xB6CBCF7C,0xCD769C2B,0x53113EC0,0x1640E3D3,
|
||||
0x38ABBD60,0x2547ADF0,0xBA38209C,0xF746CE76,0x77AFA1C5,0x20756060,
|
||||
0x85CBFE4E,0x8AE88DD8,0x7AAAF9B0,0x4CF9AA7E,0x1948C25C,0x02FB8A8C,
|
||||
0x01C36AE4,0xD6EBE1F9,0x90D4F869,0xA65CDEA0,0x3F09252D,0xC208E69F,
|
||||
0xB74E6132,0xCE77E25B,0x578FDFE3,0x3AC372E6 };
|
||||
|
||||
static const u32 ps[BLOWFISH_ROUNDS+2] = {
|
||||
0x243F6A88,0x85A308D3,0x13198A2E,0x03707344,0xA4093822,0x299F31D0,
|
||||
0x082EFA98,0xEC4E6C89,0x452821E6,0x38D01377,0xBE5466CF,0x34E90C6C,
|
||||
0xC0AC29B7,0xC97C50DD,0x3F84D5B5,0xB5470917,0x9216D5D9,0x8979FB1B };
|
||||
|
||||
|
||||
|
||||
#if BLOWFISH_ROUNDS != 16
|
||||
static inline u32
|
||||
function_F( BLOWFISH_context *bc, u32 x )
|
||||
{
|
||||
u16 a, b, c, d;
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
a = ((byte*)&x)[0];
|
||||
b = ((byte*)&x)[1];
|
||||
c = ((byte*)&x)[2];
|
||||
d = ((byte*)&x)[3];
|
||||
#else
|
||||
a = ((byte*)&x)[3];
|
||||
b = ((byte*)&x)[2];
|
||||
c = ((byte*)&x)[1];
|
||||
d = ((byte*)&x)[0];
|
||||
#endif
|
||||
|
||||
return ((bc->s0[a] + bc->s1[b]) ^ bc->s2[c] ) + bc->s3[d];
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#define F(x) ((( s0[((byte*)&x)[0]] + s1[((byte*)&x)[1]]) \
|
||||
^ s2[((byte*)&x)[2]]) + s3[((byte*)&x)[3]] )
|
||||
#else
|
||||
#define F(x) ((( s0[((byte*)&x)[3]] + s1[((byte*)&x)[2]]) \
|
||||
^ s2[((byte*)&x)[1]]) + s3[((byte*)&x)[0]] )
|
||||
#endif
|
||||
#define R(l,r,i) do { l ^= p[i]; r ^= F(l); } while(0)
|
||||
|
||||
|
||||
static void
|
||||
do_encrypt ( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr )
|
||||
{
|
||||
#if BLOWFISH_ROUNDS == 16
|
||||
u32 xl, xr, *s0, *s1, *s2, *s3, *p;
|
||||
|
||||
xl = *ret_xl;
|
||||
xr = *ret_xr;
|
||||
p = bc->p;
|
||||
s0 = bc->s0;
|
||||
s1 = bc->s1;
|
||||
s2 = bc->s2;
|
||||
s3 = bc->s3;
|
||||
|
||||
R( xl, xr, 0);
|
||||
R( xr, xl, 1);
|
||||
R( xl, xr, 2);
|
||||
R( xr, xl, 3);
|
||||
R( xl, xr, 4);
|
||||
R( xr, xl, 5);
|
||||
R( xl, xr, 6);
|
||||
R( xr, xl, 7);
|
||||
R( xl, xr, 8);
|
||||
R( xr, xl, 9);
|
||||
R( xl, xr, 10);
|
||||
R( xr, xl, 11);
|
||||
R( xl, xr, 12);
|
||||
R( xr, xl, 13);
|
||||
R( xl, xr, 14);
|
||||
R( xr, xl, 15);
|
||||
|
||||
xl ^= p[BLOWFISH_ROUNDS];
|
||||
xr ^= p[BLOWFISH_ROUNDS+1];
|
||||
|
||||
*ret_xl = xr;
|
||||
*ret_xr = xl;
|
||||
|
||||
#else
|
||||
u32 xl, xr, temp, *p;
|
||||
int i;
|
||||
|
||||
xl = *ret_xl;
|
||||
xr = *ret_xr;
|
||||
p = bc->p;
|
||||
|
||||
for(i=0; i < BLOWFISH_ROUNDS; i++ )
|
||||
{
|
||||
xl ^= p[i];
|
||||
xr ^= function_F(bc, xl);
|
||||
temp = xl;
|
||||
xl = xr;
|
||||
xr = temp;
|
||||
}
|
||||
temp = xl;
|
||||
xl = xr;
|
||||
xr = temp;
|
||||
|
||||
xr ^= p[BLOWFISH_ROUNDS];
|
||||
xl ^= p[BLOWFISH_ROUNDS+1];
|
||||
|
||||
*ret_xl = xl;
|
||||
*ret_xr = xr;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
decrypt ( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr )
|
||||
{
|
||||
#if BLOWFISH_ROUNDS == 16
|
||||
u32 xl, xr, *s0, *s1, *s2, *s3, *p;
|
||||
|
||||
xl = *ret_xl;
|
||||
xr = *ret_xr;
|
||||
p = bc->p;
|
||||
s0 = bc->s0;
|
||||
s1 = bc->s1;
|
||||
s2 = bc->s2;
|
||||
s3 = bc->s3;
|
||||
|
||||
R( xl, xr, 17);
|
||||
R( xr, xl, 16);
|
||||
R( xl, xr, 15);
|
||||
R( xr, xl, 14);
|
||||
R( xl, xr, 13);
|
||||
R( xr, xl, 12);
|
||||
R( xl, xr, 11);
|
||||
R( xr, xl, 10);
|
||||
R( xl, xr, 9);
|
||||
R( xr, xl, 8);
|
||||
R( xl, xr, 7);
|
||||
R( xr, xl, 6);
|
||||
R( xl, xr, 5);
|
||||
R( xr, xl, 4);
|
||||
R( xl, xr, 3);
|
||||
R( xr, xl, 2);
|
||||
|
||||
xl ^= p[1];
|
||||
xr ^= p[0];
|
||||
|
||||
*ret_xl = xr;
|
||||
*ret_xr = xl;
|
||||
|
||||
#else
|
||||
u32 xl, xr, temp, *p;
|
||||
int i;
|
||||
|
||||
xl = *ret_xl;
|
||||
xr = *ret_xr;
|
||||
p = bc->p;
|
||||
|
||||
for (i=BLOWFISH_ROUNDS+1; i > 1; i-- )
|
||||
{
|
||||
xl ^= p[i];
|
||||
xr ^= function_F(bc, xl);
|
||||
temp = xl;
|
||||
xl = xr;
|
||||
xr = temp;
|
||||
}
|
||||
|
||||
temp = xl;
|
||||
xl = xr;
|
||||
xr = temp;
|
||||
|
||||
xr ^= p[1];
|
||||
xl ^= p[0];
|
||||
|
||||
*ret_xl = xl;
|
||||
*ret_xr = xr;
|
||||
#endif
|
||||
}
|
||||
|
||||
#undef F
|
||||
#undef R
|
||||
|
||||
static void
|
||||
do_encrypt_block ( BLOWFISH_context *bc, byte *outbuf, const byte *inbuf )
|
||||
{
|
||||
u32 d1, d2;
|
||||
|
||||
d1 = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3];
|
||||
d2 = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7];
|
||||
do_encrypt( bc, &d1, &d2 );
|
||||
outbuf[0] = (d1 >> 24) & 0xff;
|
||||
outbuf[1] = (d1 >> 16) & 0xff;
|
||||
outbuf[2] = (d1 >> 8) & 0xff;
|
||||
outbuf[3] = d1 & 0xff;
|
||||
outbuf[4] = (d2 >> 24) & 0xff;
|
||||
outbuf[5] = (d2 >> 16) & 0xff;
|
||||
outbuf[6] = (d2 >> 8) & 0xff;
|
||||
outbuf[7] = d2 & 0xff;
|
||||
}
|
||||
|
||||
static void
|
||||
encrypt_block (void *context, byte *outbuf, const byte *inbuf)
|
||||
{
|
||||
BLOWFISH_context *bc = (BLOWFISH_context *) context;
|
||||
do_encrypt_block (bc, outbuf, inbuf);
|
||||
_gcry_burn_stack (64);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
do_decrypt_block (BLOWFISH_context *bc, byte *outbuf, const byte *inbuf)
|
||||
{
|
||||
u32 d1, d2;
|
||||
|
||||
d1 = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3];
|
||||
d2 = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7];
|
||||
decrypt( bc, &d1, &d2 );
|
||||
outbuf[0] = (d1 >> 24) & 0xff;
|
||||
outbuf[1] = (d1 >> 16) & 0xff;
|
||||
outbuf[2] = (d1 >> 8) & 0xff;
|
||||
outbuf[3] = d1 & 0xff;
|
||||
outbuf[4] = (d2 >> 24) & 0xff;
|
||||
outbuf[5] = (d2 >> 16) & 0xff;
|
||||
outbuf[6] = (d2 >> 8) & 0xff;
|
||||
outbuf[7] = d2 & 0xff;
|
||||
}
|
||||
|
||||
static void
|
||||
decrypt_block (void *context, byte *outbuf, const byte *inbuf)
|
||||
{
|
||||
BLOWFISH_context *bc = (BLOWFISH_context *) context;
|
||||
do_decrypt_block (bc, outbuf, inbuf);
|
||||
_gcry_burn_stack (64);
|
||||
}
|
||||
|
||||
|
||||
static const char*
|
||||
selftest(void)
|
||||
{
|
||||
BLOWFISH_context c;
|
||||
byte plain[] = "BLOWFISH";
|
||||
byte buffer[8];
|
||||
byte plain3[] = { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 };
|
||||
byte key3[] = { 0x41, 0x79, 0x6E, 0xA0, 0x52, 0x61, 0x6E, 0xE4 };
|
||||
byte cipher3[] = { 0xE1, 0x13, 0xF4, 0x10, 0x2C, 0xFC, 0xCE, 0x43 };
|
||||
|
||||
bf_setkey( (void *) &c,
|
||||
(const unsigned char*)"abcdefghijklmnopqrstuvwxyz", 26 );
|
||||
encrypt_block( (void *) &c, buffer, plain );
|
||||
if( memcmp( buffer, "\x32\x4E\xD0\xFE\xF4\x13\xA2\x03", 8 ) )
|
||||
return "Blowfish selftest failed (1).";
|
||||
decrypt_block( (void *) &c, buffer, buffer );
|
||||
if( memcmp( buffer, plain, 8 ) )
|
||||
return "Blowfish selftest failed (2).";
|
||||
|
||||
bf_setkey( (void *) &c, key3, 8 );
|
||||
encrypt_block( (void *) &c, buffer, plain3 );
|
||||
if( memcmp( buffer, cipher3, 8 ) )
|
||||
return "Blowfish selftest failed (3).";
|
||||
decrypt_block( (void *) &c, buffer, buffer );
|
||||
if( memcmp( buffer, plain3, 8 ) )
|
||||
return "Blowfish selftest failed (4).";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static gcry_err_code_t
|
||||
do_bf_setkey (BLOWFISH_context *c, const byte *key, unsigned keylen)
|
||||
{
|
||||
int i, j;
|
||||
u32 data, datal, datar;
|
||||
static int initialized;
|
||||
static const char *selftest_failed;
|
||||
|
||||
if( !initialized )
|
||||
{
|
||||
initialized = 1;
|
||||
selftest_failed = selftest();
|
||||
if( selftest_failed )
|
||||
log_error ("%s\n", selftest_failed );
|
||||
}
|
||||
if( selftest_failed )
|
||||
return GPG_ERR_SELFTEST_FAILED;
|
||||
|
||||
for(i=0; i < BLOWFISH_ROUNDS+2; i++ )
|
||||
c->p[i] = ps[i];
|
||||
for(i=0; i < 256; i++ )
|
||||
{
|
||||
c->s0[i] = ks0[i];
|
||||
c->s1[i] = ks1[i];
|
||||
c->s2[i] = ks2[i];
|
||||
c->s3[i] = ks3[i];
|
||||
}
|
||||
|
||||
for(i=j=0; i < BLOWFISH_ROUNDS+2; i++ )
|
||||
{
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
((byte*)&data)[0] = key[j];
|
||||
((byte*)&data)[1] = key[(j+1)%keylen];
|
||||
((byte*)&data)[2] = key[(j+2)%keylen];
|
||||
((byte*)&data)[3] = key[(j+3)%keylen];
|
||||
#else
|
||||
((byte*)&data)[3] = key[j];
|
||||
((byte*)&data)[2] = key[(j+1)%keylen];
|
||||
((byte*)&data)[1] = key[(j+2)%keylen];
|
||||
((byte*)&data)[0] = key[(j+3)%keylen];
|
||||
#endif
|
||||
c->p[i] ^= data;
|
||||
j = (j+4) % keylen;
|
||||
}
|
||||
|
||||
datal = datar = 0;
|
||||
for(i=0; i < BLOWFISH_ROUNDS+2; i += 2 )
|
||||
{
|
||||
do_encrypt( c, &datal, &datar );
|
||||
c->p[i] = datal;
|
||||
c->p[i+1] = datar;
|
||||
}
|
||||
for(i=0; i < 256; i += 2 )
|
||||
{
|
||||
do_encrypt( c, &datal, &datar );
|
||||
c->s0[i] = datal;
|
||||
c->s0[i+1] = datar;
|
||||
}
|
||||
for(i=0; i < 256; i += 2 )
|
||||
{
|
||||
do_encrypt( c, &datal, &datar );
|
||||
c->s1[i] = datal;
|
||||
c->s1[i+1] = datar;
|
||||
}
|
||||
for(i=0; i < 256; i += 2 )
|
||||
{
|
||||
do_encrypt( c, &datal, &datar );
|
||||
c->s2[i] = datal;
|
||||
c->s2[i+1] = datar;
|
||||
}
|
||||
for(i=0; i < 256; i += 2 )
|
||||
{
|
||||
do_encrypt( c, &datal, &datar );
|
||||
c->s3[i] = datal;
|
||||
c->s3[i+1] = datar;
|
||||
}
|
||||
|
||||
|
||||
/* Check for weak key. A weak key is a key in which a value in
|
||||
the P-array (here c) occurs more than once per table. */
|
||||
for(i=0; i < 255; i++ )
|
||||
{
|
||||
for( j=i+1; j < 256; j++)
|
||||
{
|
||||
if( (c->s0[i] == c->s0[j]) || (c->s1[i] == c->s1[j]) ||
|
||||
(c->s2[i] == c->s2[j]) || (c->s3[i] == c->s3[j]) )
|
||||
return GPG_ERR_WEAK_KEY;
|
||||
}
|
||||
}
|
||||
|
||||
return GPG_ERR_NO_ERROR;
|
||||
}
|
||||
|
||||
|
||||
static gcry_err_code_t
|
||||
bf_setkey (void *context, const byte *key, unsigned keylen)
|
||||
{
|
||||
BLOWFISH_context *c = (BLOWFISH_context *) context;
|
||||
gcry_err_code_t rc = do_bf_setkey (c, key, keylen);
|
||||
_gcry_burn_stack (64);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
gcry_cipher_spec_t _gcry_cipher_spec_blowfish =
|
||||
{
|
||||
"BLOWFISH", NULL, NULL, BLOWFISH_BLOCKSIZE, 128,
|
||||
sizeof (BLOWFISH_context),
|
||||
bf_setkey, encrypt_block, decrypt_block
|
||||
};
|
253
lib/libgcrypt/cipher/camellia-glue.c
Normal file
253
lib/libgcrypt/cipher/camellia-glue.c
Normal file
|
@ -0,0 +1,253 @@
|
|||
/* camellia-glue.c - Glue for the Camellia cipher
|
||||
* Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of Libgcrypt.
|
||||
*
|
||||
* Libgcrypt is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Libgcrypt is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/* I put all the libgcrypt-specific stuff in this file to keep the
|
||||
camellia.c/camellia.h files exactly as provided by NTT. If they
|
||||
update their code, this should make it easier to bring the changes
|
||||
in. - dshaw
|
||||
|
||||
There is one small change which needs to be done: Include the
|
||||
following code at the top of camellia.h: */
|
||||
#if 0
|
||||
|
||||
/* To use Camellia with libraries it is often useful to keep the name
|
||||
* space of the library clean. The following macro is thus useful:
|
||||
*
|
||||
* #define CAMELLIA_EXT_SYM_PREFIX foo_
|
||||
*
|
||||
* This prefixes all external symbols with "foo_".
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
#ifdef CAMELLIA_EXT_SYM_PREFIX
|
||||
#define CAMELLIA_PREFIX1(x,y) x ## y
|
||||
#define CAMELLIA_PREFIX2(x,y) CAMELLIA_PREFIX1(x,y)
|
||||
#define CAMELLIA_PREFIX(x) CAMELLIA_PREFIX2(CAMELLIA_EXT_SYM_PREFIX,x)
|
||||
#define Camellia_Ekeygen CAMELLIA_PREFIX(Camellia_Ekeygen)
|
||||
#define Camellia_EncryptBlock CAMELLIA_PREFIX(Camellia_EncryptBlock)
|
||||
#define Camellia_DecryptBlock CAMELLIA_PREFIX(Camellia_DecryptBlock)
|
||||
#define camellia_decrypt128 CAMELLIA_PREFIX(camellia_decrypt128)
|
||||
#define camellia_decrypt256 CAMELLIA_PREFIX(camellia_decrypt256)
|
||||
#define camellia_encrypt128 CAMELLIA_PREFIX(camellia_encrypt128)
|
||||
#define camellia_encrypt256 CAMELLIA_PREFIX(camellia_encrypt256)
|
||||
#define camellia_setup128 CAMELLIA_PREFIX(camellia_setup128)
|
||||
#define camellia_setup192 CAMELLIA_PREFIX(camellia_setup192)
|
||||
#define camellia_setup256 CAMELLIA_PREFIX(camellia_setup256)
|
||||
#endif /*CAMELLIA_EXT_SYM_PREFIX*/
|
||||
|
||||
#endif /* Code sample. */
|
||||
|
||||
|
||||
#include <config.h>
|
||||
#include "types.h"
|
||||
#include "g10lib.h"
|
||||
#include "cipher.h"
|
||||
#include "camellia.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int keybitlength;
|
||||
KEY_TABLE_TYPE keytable;
|
||||
} CAMELLIA_context;
|
||||
|
||||
static const char *selftest(void);
|
||||
|
||||
static gcry_err_code_t
|
||||
camellia_setkey(void *c, const byte *key, unsigned keylen)
|
||||
{
|
||||
CAMELLIA_context *ctx=c;
|
||||
static int initialized=0;
|
||||
static const char *selftest_failed=NULL;
|
||||
|
||||
if(keylen!=16 && keylen!=24 && keylen!=32)
|
||||
return GPG_ERR_INV_KEYLEN;
|
||||
|
||||
if(!initialized)
|
||||
{
|
||||
initialized=1;
|
||||
selftest_failed=selftest();
|
||||
if(selftest_failed)
|
||||
log_error("%s\n",selftest_failed);
|
||||
}
|
||||
|
||||
if(selftest_failed)
|
||||
return GPG_ERR_SELFTEST_FAILED;
|
||||
|
||||
ctx->keybitlength=keylen*8;
|
||||
Camellia_Ekeygen(ctx->keybitlength,key,ctx->keytable);
|
||||
_gcry_burn_stack
|
||||
((19+34+34)*sizeof(u32)+2*sizeof(void*) /* camellia_setup256 */
|
||||
+(4+32)*sizeof(u32)+2*sizeof(void*) /* camellia_setup192 */
|
||||
+0+sizeof(int)+2*sizeof(void*) /* Camellia_Ekeygen */
|
||||
+3*2*sizeof(void*) /* Function calls. */
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
camellia_encrypt(void *c, byte *outbuf, const byte *inbuf)
|
||||
{
|
||||
CAMELLIA_context *ctx=c;
|
||||
|
||||
Camellia_EncryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf);
|
||||
_gcry_burn_stack
|
||||
(sizeof(int)+2*sizeof(unsigned char *)+sizeof(KEY_TABLE_TYPE)
|
||||
+4*sizeof(u32)
|
||||
+2*sizeof(u32*)+4*sizeof(u32)
|
||||
+2*2*sizeof(void*) /* Function calls. */
|
||||
);
|
||||
}
|
||||
|
||||
static void
|
||||
camellia_decrypt(void *c, byte *outbuf, const byte *inbuf)
|
||||
{
|
||||
CAMELLIA_context *ctx=c;
|
||||
|
||||
Camellia_DecryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf);
|
||||
_gcry_burn_stack
|
||||
(sizeof(int)+2*sizeof(unsigned char *)+sizeof(KEY_TABLE_TYPE)
|
||||
+4*sizeof(u32)
|
||||
+2*sizeof(u32*)+4*sizeof(u32)
|
||||
+2*2*sizeof(void*) /* Function calls. */
|
||||
);
|
||||
}
|
||||
|
||||
static const char *
|
||||
selftest(void)
|
||||
{
|
||||
CAMELLIA_context ctx;
|
||||
byte scratch[16];
|
||||
|
||||
/* These test vectors are from RFC-3713 */
|
||||
const byte plaintext[]=
|
||||
{
|
||||
0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
|
||||
0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10
|
||||
};
|
||||
const byte key_128[]=
|
||||
{
|
||||
0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
|
||||
0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10
|
||||
};
|
||||
const byte ciphertext_128[]=
|
||||
{
|
||||
0x67,0x67,0x31,0x38,0x54,0x96,0x69,0x73,
|
||||
0x08,0x57,0x06,0x56,0x48,0xea,0xbe,0x43
|
||||
};
|
||||
const byte key_192[]=
|
||||
{
|
||||
0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,
|
||||
0x76,0x54,0x32,0x10,0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77
|
||||
};
|
||||
const byte ciphertext_192[]=
|
||||
{
|
||||
0xb4,0x99,0x34,0x01,0xb3,0xe9,0x96,0xf8,
|
||||
0x4e,0xe5,0xce,0xe7,0xd7,0x9b,0x09,0xb9
|
||||
};
|
||||
const byte key_256[]=
|
||||
{
|
||||
0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,
|
||||
0x98,0x76,0x54,0x32,0x10,0x00,0x11,0x22,0x33,0x44,0x55,
|
||||
0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff
|
||||
};
|
||||
const byte ciphertext_256[]=
|
||||
{
|
||||
0x9a,0xcc,0x23,0x7d,0xff,0x16,0xd7,0x6c,
|
||||
0x20,0xef,0x7c,0x91,0x9e,0x3a,0x75,0x09
|
||||
};
|
||||
|
||||
camellia_setkey(&ctx,key_128,sizeof(key_128));
|
||||
camellia_encrypt(&ctx,scratch,plaintext);
|
||||
if(memcmp(scratch,ciphertext_128,sizeof(ciphertext_128))!=0)
|
||||
return "CAMELLIA-128 test encryption failed.";
|
||||
camellia_decrypt(&ctx,scratch,scratch);
|
||||
if(memcmp(scratch,plaintext,sizeof(plaintext))!=0)
|
||||
return "CAMELLIA-128 test decryption failed.";
|
||||
|
||||
camellia_setkey(&ctx,key_192,sizeof(key_192));
|
||||
camellia_encrypt(&ctx,scratch,plaintext);
|
||||
if(memcmp(scratch,ciphertext_192,sizeof(ciphertext_192))!=0)
|
||||
return "CAMELLIA-192 test encryption failed.";
|
||||
camellia_decrypt(&ctx,scratch,scratch);
|
||||
if(memcmp(scratch,plaintext,sizeof(plaintext))!=0)
|
||||
return "CAMELLIA-192 test decryption failed.";
|
||||
|
||||
camellia_setkey(&ctx,key_256,sizeof(key_256));
|
||||
camellia_encrypt(&ctx,scratch,plaintext);
|
||||
if(memcmp(scratch,ciphertext_256,sizeof(ciphertext_256))!=0)
|
||||
return "CAMELLIA-256 test encryption failed.";
|
||||
camellia_decrypt(&ctx,scratch,scratch);
|
||||
if(memcmp(scratch,plaintext,sizeof(plaintext))!=0)
|
||||
return "CAMELLIA-256 test decryption failed.";
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* These oids are from
|
||||
<http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications_oid.html>,
|
||||
retrieved May 1, 2007. */
|
||||
|
||||
static gcry_cipher_oid_spec_t camellia128_oids[] =
|
||||
{
|
||||
{"1.2.392.200011.61.1.1.1.2", GCRY_CIPHER_MODE_CBC},
|
||||
{"0.3.4401.5.3.1.9.1", GCRY_CIPHER_MODE_ECB},
|
||||
{"0.3.4401.5.3.1.9.3", GCRY_CIPHER_MODE_OFB},
|
||||
{"0.3.4401.5.3.1.9.4", GCRY_CIPHER_MODE_CFB},
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static gcry_cipher_oid_spec_t camellia192_oids[] =
|
||||
{
|
||||
{"1.2.392.200011.61.1.1.1.3", GCRY_CIPHER_MODE_CBC},
|
||||
{"0.3.4401.5.3.1.9.21", GCRY_CIPHER_MODE_ECB},
|
||||
{"0.3.4401.5.3.1.9.23", GCRY_CIPHER_MODE_OFB},
|
||||
{"0.3.4401.5.3.1.9.24", GCRY_CIPHER_MODE_CFB},
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static gcry_cipher_oid_spec_t camellia256_oids[] =
|
||||
{
|
||||
{"1.2.392.200011.61.1.1.1.4", GCRY_CIPHER_MODE_CBC},
|
||||
{"0.3.4401.5.3.1.9.41", GCRY_CIPHER_MODE_ECB},
|
||||
{"0.3.4401.5.3.1.9.43", GCRY_CIPHER_MODE_OFB},
|
||||
{"0.3.4401.5.3.1.9.44", GCRY_CIPHER_MODE_CFB},
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
gcry_cipher_spec_t _gcry_cipher_spec_camellia128 =
|
||||
{
|
||||
"CAMELLIA128",NULL,camellia128_oids,CAMELLIA_BLOCK_SIZE,128,
|
||||
sizeof(CAMELLIA_context),camellia_setkey,camellia_encrypt,camellia_decrypt
|
||||
};
|
||||
|
||||
gcry_cipher_spec_t _gcry_cipher_spec_camellia192 =
|
||||
{
|
||||
"CAMELLIA192",NULL,camellia192_oids,CAMELLIA_BLOCK_SIZE,192,
|
||||
sizeof(CAMELLIA_context),camellia_setkey,camellia_encrypt,camellia_decrypt
|
||||
};
|
||||
|
||||
gcry_cipher_spec_t _gcry_cipher_spec_camellia256 =
|
||||
{
|
||||
"CAMELLIA256",NULL,camellia256_oids,CAMELLIA_BLOCK_SIZE,256,
|
||||
sizeof(CAMELLIA_context),camellia_setkey,camellia_encrypt,camellia_decrypt
|
||||
};
|
1461
lib/libgcrypt/cipher/camellia.c
Normal file
1461
lib/libgcrypt/cipher/camellia.c
Normal file
File diff suppressed because it is too large
Load diff
81
lib/libgcrypt/cipher/camellia.h
Normal file
81
lib/libgcrypt/cipher/camellia.h
Normal file
|
@ -0,0 +1,81 @@
|
|||
/* camellia.h ver 1.2.0
|
||||
*
|
||||
* Copyright (C) 2006,2007
|
||||
* NTT (Nippon Telegraph and Telephone Corporation).
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef HEADER_CAMELLIA_H
|
||||
#define HEADER_CAMELLIA_H
|
||||
|
||||
/* To use Camellia with libraries it is often useful to keep the name
|
||||
* space of the library clean. The following macro is thus useful:
|
||||
*
|
||||
* #define CAMELLIA_EXT_SYM_PREFIX foo_
|
||||
*
|
||||
* This prefixes all external symbols with "foo_".
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
#ifdef CAMELLIA_EXT_SYM_PREFIX
|
||||
#define CAMELLIA_PREFIX1(x,y) x ## y
|
||||
#define CAMELLIA_PREFIX2(x,y) CAMELLIA_PREFIX1(x,y)
|
||||
#define CAMELLIA_PREFIX(x) CAMELLIA_PREFIX2(CAMELLIA_EXT_SYM_PREFIX,x)
|
||||
#define Camellia_Ekeygen CAMELLIA_PREFIX(Camellia_Ekeygen)
|
||||
#define Camellia_EncryptBlock CAMELLIA_PREFIX(Camellia_EncryptBlock)
|
||||
#define Camellia_DecryptBlock CAMELLIA_PREFIX(Camellia_DecryptBlock)
|
||||
#define camellia_decrypt128 CAMELLIA_PREFIX(camellia_decrypt128)
|
||||
#define camellia_decrypt256 CAMELLIA_PREFIX(camellia_decrypt256)
|
||||
#define camellia_encrypt128 CAMELLIA_PREFIX(camellia_encrypt128)
|
||||
#define camellia_encrypt256 CAMELLIA_PREFIX(camellia_encrypt256)
|
||||
#define camellia_setup128 CAMELLIA_PREFIX(camellia_setup128)
|
||||
#define camellia_setup192 CAMELLIA_PREFIX(camellia_setup192)
|
||||
#define camellia_setup256 CAMELLIA_PREFIX(camellia_setup256)
|
||||
#endif /*CAMELLIA_EXT_SYM_PREFIX*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define CAMELLIA_BLOCK_SIZE 16
|
||||
#define CAMELLIA_TABLE_BYTE_LEN 272
|
||||
#define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4)
|
||||
|
||||
typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN];
|
||||
|
||||
|
||||
void Camellia_Ekeygen(const int keyBitLength,
|
||||
const unsigned char *rawKey,
|
||||
KEY_TABLE_TYPE keyTable);
|
||||
|
||||
void Camellia_EncryptBlock(const int keyBitLength,
|
||||
const unsigned char *plaintext,
|
||||
const KEY_TABLE_TYPE keyTable,
|
||||
unsigned char *cipherText);
|
||||
|
||||
void Camellia_DecryptBlock(const int keyBitLength,
|
||||
const unsigned char *cipherText,
|
||||
const KEY_TABLE_TYPE keyTable,
|
||||
unsigned char *plaintext);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CAMELLIA_H */
|
620
lib/libgcrypt/cipher/cast5.c
Normal file
620
lib/libgcrypt/cipher/cast5.c
Normal file
|
@ -0,0 +1,620 @@
|
|||
/* cast5.c - CAST5 cipher (RFC2144)
|
||||
* Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of Libgcrypt.
|
||||
*
|
||||
* Libgcrypt is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser general Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Libgcrypt is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
/* Test vectors:
|
||||
*
|
||||
* 128-bit key = 01 23 45 67 12 34 56 78 23 45 67 89 34 56 78 9A
|
||||
* plaintext = 01 23 45 67 89 AB CD EF
|
||||
* ciphertext = 23 8B 4F E5 84 7E 44 B2
|
||||
*
|
||||
* 80-bit key = 01 23 45 67 12 34 56 78 23 45
|
||||
* = 01 23 45 67 12 34 56 78 23 45 00 00 00 00 00 00
|
||||
* plaintext = 01 23 45 67 89 AB CD EF
|
||||
* ciphertext = EB 6A 71 1A 2C 02 27 1B
|
||||
*
|
||||
* 40-bit key = 01 23 45 67 12
|
||||
* = 01 23 45 67 12 00 00 00 00 00 00 00 00 00 00 00
|
||||
* plaintext = 01 23 45 67 89 AB CD EF
|
||||
* ciphertext = 7A C8 16 D1 6E 9B 30 2E
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "g10lib.h"
|
||||
#include "types.h"
|
||||
#include "cipher.h"
|
||||
|
||||
#define CAST5_BLOCKSIZE 8
|
||||
|
||||
typedef struct {
|
||||
u32 Km[16];
|
||||
byte Kr[16];
|
||||
} CAST5_context;
|
||||
|
||||
static gcry_err_code_t cast_setkey (void *c, const byte *key, unsigned keylen);
|
||||
static void encrypt_block (void *c, byte *outbuf, const byte *inbuf);
|
||||
static void decrypt_block (void *c, byte *outbuf, const byte *inbuf);
|
||||
|
||||
|
||||
|
||||
|
||||
static const u32 s1[256] = {
|
||||
0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949,
|
||||
0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e,
|
||||
0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d,
|
||||
0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1, 0xaa54166b, 0x22568e3a, 0xa2d341d0,
|
||||
0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, 0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7,
|
||||
0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, 0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935,
|
||||
0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290, 0xe93b159f, 0xb48ee411, 0x4bff345d,
|
||||
0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, 0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50,
|
||||
0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe,
|
||||
0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5, 0x6a390493, 0xe63d37e0, 0x2a54f6b3,
|
||||
0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, 0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167,
|
||||
0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f, 0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291,
|
||||
0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d, 0x73e2bb14, 0xa0bebc3c, 0x54623779,
|
||||
0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6, 0x04ee002e, 0x89fe78e6, 0x3fab0950, 0x325ff6c2,
|
||||
0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9, 0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511,
|
||||
0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241, 0x051ef495, 0xaa573b04, 0x4a805d8d,
|
||||
0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e, 0x75c6372b, 0x50afd341, 0xa7c13275, 0x915a0bf5,
|
||||
0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82, 0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324,
|
||||
0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3, 0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c,
|
||||
0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f, 0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc,
|
||||
0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, 0xb4c332e6, 0x032268d4, 0xc9600acc, 0xce387e6d,
|
||||
0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da, 0x4736f464, 0x5ad328d8, 0xb347cc96,
|
||||
0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a, 0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a,
|
||||
0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79, 0x9ceb418f, 0x1cacd68d, 0x2ad37c96, 0x0175cb9d,
|
||||
0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4, 0xb11c3274, 0xdd24cb9e, 0x7e1c54bd,
|
||||
0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, 0xd47c27af, 0x51c85f4d, 0x56907596, 0xa5bb15e6,
|
||||
0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb, 0x35ba3e4a, 0x3526ffa0, 0xc37b4d09, 0xbc306ed9,
|
||||
0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf, 0x700b45e1, 0xd5ea50f1, 0x85a92872,
|
||||
0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, 0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814c,
|
||||
0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e,
|
||||
0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c, 0xe1e696ff, 0xb141ab08, 0x7cca89b9,
|
||||
0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf
|
||||
};
|
||||
static const u32 s2[256] = {
|
||||
0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a, 0xeec5207a, 0x55889c94, 0x72fc0651,
|
||||
0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, 0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3,
|
||||
0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb,
|
||||
0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb, 0xe4e7ef5b, 0x25a1ff41, 0xe180f806,
|
||||
0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, 0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b,
|
||||
0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, 0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359,
|
||||
0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181, 0x39f7627f, 0x361e3084, 0xe4eb573b,
|
||||
0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, 0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c,
|
||||
0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34,
|
||||
0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c, 0x1d804366, 0x721d9bfd, 0xa58684bb,
|
||||
0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, 0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd,
|
||||
0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801, 0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860,
|
||||
0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf, 0x68561be6, 0x83ca6b94, 0x2d6ed23b,
|
||||
0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, 0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304,
|
||||
0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b, 0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b,
|
||||
0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402, 0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf,
|
||||
0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, 0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c,
|
||||
0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3, 0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13,
|
||||
0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6, 0xa02b1741, 0x7cbad9a2, 0x2180036f,
|
||||
0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, 0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6,
|
||||
0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, 0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6,
|
||||
0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54, 0x157fd7fa, 0xef8579cc, 0xd152de58,
|
||||
0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, 0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906,
|
||||
0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171, 0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d,
|
||||
0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc, 0x301e16e6, 0x273be979, 0xb0ffeaa6,
|
||||
0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, 0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4,
|
||||
0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb, 0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6,
|
||||
0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb, 0x5eea29cb, 0x145892f5, 0x91584f7f,
|
||||
0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, 0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249,
|
||||
0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa,
|
||||
0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589, 0xa345415e, 0x5c038323, 0x3e5d3bb9,
|
||||
0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1
|
||||
};
|
||||
static const u32 s3[256] = {
|
||||
0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff, 0x369fe44b, 0x8c1fc644, 0xaececa90,
|
||||
0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5,
|
||||
0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e,
|
||||
0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee, 0x825b1bfd, 0x9255c5ed, 0x1257a240,
|
||||
0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, 0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5,
|
||||
0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, 0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b,
|
||||
0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c, 0x4a012d6e, 0xc5884a28, 0xccc36f71,
|
||||
0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, 0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04,
|
||||
0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380, 0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82,
|
||||
0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0, 0x1eac5790, 0x796fb449, 0x8252dc15,
|
||||
0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, 0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2,
|
||||
0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6, 0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176,
|
||||
0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83, 0x340ce5c8, 0x96bbb682, 0x93b4b148,
|
||||
0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, 0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc,
|
||||
0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1, 0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341,
|
||||
0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9, 0xbda8229c, 0x127dadaa, 0x438a074e,
|
||||
0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, 0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51,
|
||||
0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4, 0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f,
|
||||
0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623, 0x193cbcfa, 0x27627545, 0x825cf47a,
|
||||
0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, 0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b,
|
||||
0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, 0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b,
|
||||
0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11, 0x236a5cae, 0x12deca4d, 0x2c3f8cc5,
|
||||
0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, 0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45,
|
||||
0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49, 0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536,
|
||||
0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1, 0x006e1888, 0xa2e53f55, 0xb9e6d4bc,
|
||||
0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, 0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0,
|
||||
0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e, 0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69,
|
||||
0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2, 0x61efc8c2, 0xf1ac2571, 0xcc8239c2,
|
||||
0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, 0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49,
|
||||
0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d,
|
||||
0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31, 0x9c305a00, 0x52bce688, 0x1b03588a,
|
||||
0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783
|
||||
};
|
||||
static const u32 s4[256] = {
|
||||
0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb, 0x64ad8c57, 0x85510443, 0xfa020ed1,
|
||||
0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, 0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf,
|
||||
0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15,
|
||||
0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f, 0x0c13fefe, 0x081b08ca, 0x05170121,
|
||||
0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, 0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25,
|
||||
0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, 0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5,
|
||||
0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061, 0x11b638e1, 0x72500e03, 0xf80eb2bb,
|
||||
0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746, 0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5,
|
||||
0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, 0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d,
|
||||
0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8, 0x3fb6180c, 0x18f8931e, 0x281658e6,
|
||||
0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, 0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23,
|
||||
0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7, 0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003,
|
||||
0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de, 0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6,
|
||||
0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, 0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119,
|
||||
0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec, 0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24,
|
||||
0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a, 0xeca1d7c7, 0x041afa32, 0x1d16625a,
|
||||
0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, 0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79,
|
||||
0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5, 0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df,
|
||||
0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254, 0xe5b6a035, 0x213d42f6, 0x2c1c7c26,
|
||||
0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, 0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab,
|
||||
0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, 0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7,
|
||||
0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1, 0x1f9af36e, 0xcfcbd12f, 0xc1de8417,
|
||||
0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, 0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2,
|
||||
0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2, 0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2,
|
||||
0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415, 0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a,
|
||||
0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, 0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919,
|
||||
0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df, 0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef,
|
||||
0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb, 0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876,
|
||||
0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, 0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab,
|
||||
0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04,
|
||||
0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979, 0x932bcdf6, 0xb657c34d, 0x4edfd282,
|
||||
0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2
|
||||
};
|
||||
static const u32 s5[256] = {
|
||||
0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, 0xb86a7fff, 0x1dd358f5, 0x44dd9d44, 0x1731167f,
|
||||
0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00, 0x2ab722d8, 0x386381cb, 0xacf6243a, 0x69befd7a,
|
||||
0xe6a2e77f, 0xf0c720cd, 0xc4494816, 0xccf5c180, 0x38851640, 0x15b0a848, 0xe68b18cb, 0x4caadeff,
|
||||
0x5f480a01, 0x0412b2aa, 0x259814fc, 0x41d0efe2, 0x4e40b48d, 0x248eb6fb, 0x8dba1cfe, 0x41a99b02,
|
||||
0x1a550a04, 0xba8f65cb, 0x7251f4e7, 0x95a51725, 0xc106ecd7, 0x97a5980a, 0xc539b9aa, 0x4d79fe6a,
|
||||
0xf2f3f763, 0x68af8040, 0xed0c9e56, 0x11b4958b, 0xe1eb5a88, 0x8709e6b0, 0xd7e07156, 0x4e29fea7,
|
||||
0x6366e52d, 0x02d1c000, 0xc4ac8e05, 0x9377f571, 0x0c05372a, 0x578535f2, 0x2261be02, 0xd642a0c9,
|
||||
0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec, 0x53fb3ce8, 0xc8adedb3, 0x28a87fc9, 0x3d959981,
|
||||
0x5c1ff900, 0xfe38d399, 0x0c4eff0b, 0x062407ea, 0xaa2f4fb1, 0x4fb96976, 0x90c79505, 0xb0a8a774,
|
||||
0xef55a1ff, 0xe59ca2c2, 0xa6b62d27, 0xe66a4263, 0xdf65001f, 0x0ec50966, 0xdfdd55bc, 0x29de0655,
|
||||
0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468, 0x0d01e980, 0x524755f4, 0x03b63cc9, 0x0cc844b2,
|
||||
0xbcf3f0aa, 0x87ac36e9, 0xe53a7426, 0x01b3d82b, 0x1a9e7449, 0x64ee2d7e, 0xcddbb1da, 0x01c94910,
|
||||
0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284, 0x636737b6, 0x50f5b616, 0xf24766e3, 0x8eca36c1,
|
||||
0x136e05db, 0xfef18391, 0xfb887a37, 0xd6e7f7d4, 0xc7fb7dc9, 0x3063fcdf, 0xb6f589de, 0xec2941da,
|
||||
0x26e46695, 0xb7566419, 0xf654efc5, 0xd08d58b7, 0x48925401, 0xc1bacb7f, 0xe5ff550f, 0xb6083049,
|
||||
0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce, 0xc62bf3cd, 0x9e0885f9, 0x68cb3e47, 0x086c010f,
|
||||
0xa21de820, 0xd18b69de, 0xf3f65777, 0xfa02c3f6, 0x407edac3, 0xcbb3d550, 0x1793084d, 0xb0d70eba,
|
||||
0x0ab378d5, 0xd951fb0c, 0xded7da56, 0x4124bbe4, 0x94ca0b56, 0x0f5755d1, 0xe0e1e56e, 0x6184b5be,
|
||||
0x580a249f, 0x94f74bc0, 0xe327888e, 0x9f7b5561, 0xc3dc0280, 0x05687715, 0x646c6bd7, 0x44904db3,
|
||||
0x66b4f0a3, 0xc0f1648a, 0x697ed5af, 0x49e92ff6, 0x309e374f, 0x2cb6356a, 0x85808573, 0x4991f840,
|
||||
0x76f0ae02, 0x083be84d, 0x28421c9a, 0x44489406, 0x736e4cb8, 0xc1092910, 0x8bc95fc6, 0x7d869cf4,
|
||||
0x134f616f, 0x2e77118d, 0xb31b2be1, 0xaa90b472, 0x3ca5d717, 0x7d161bba, 0x9cad9010, 0xaf462ba2,
|
||||
0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487, 0xf3e4f94e, 0x176d486f, 0x097c13ea, 0x631da5c7,
|
||||
0x445f7382, 0x175683f4, 0xcdc66a97, 0x70be0288, 0xb3cdcf72, 0x6e5dd2f3, 0x20936079, 0x459b80a5,
|
||||
0xbe60e2db, 0xa9c23101, 0xeba5315c, 0x224e42f2, 0x1c5c1572, 0xf6721b2c, 0x1ad2fff3, 0x8c25404e,
|
||||
0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78, 0xdc0fd66e, 0x75922283, 0x784d6b17, 0x58ebb16e,
|
||||
0x44094f85, 0x3f481d87, 0xfcfeae7b, 0x77b5ff76, 0x8c2302bf, 0xaaf47556, 0x5f46b02a, 0x2b092801,
|
||||
0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0, 0xdf3b0874, 0x95055110, 0x1b5ad7a8, 0xf61ed5ad,
|
||||
0x6cf6e479, 0x20758184, 0xd0cefa65, 0x88f7be58, 0x4a046826, 0x0ff6f8f3, 0xa09c7f70, 0x5346aba0,
|
||||
0x5ce96c28, 0xe176eda3, 0x6bac307f, 0x376829d2, 0x85360fa9, 0x17e3fe2a, 0x24b79767, 0xf5a96b20,
|
||||
0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be, 0xf9e0659a, 0xeeb9491d, 0x34010718, 0xbb30cab8,
|
||||
0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55, 0x5e76ffa8, 0xb1534546, 0x6d47de08, 0xefe9e7d4
|
||||
};
|
||||
static const u32 s6[256] = {
|
||||
0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c, 0x95db08e7, 0x016843b4, 0xeced5cbc, 0x325553ac,
|
||||
0xbf9f0960, 0xdfa1e2ed, 0x83f0579d, 0x63ed86b9, 0x1ab6a6b8, 0xde5ebe39, 0xf38ff732, 0x8989b138,
|
||||
0x33f14961, 0xc01937bd, 0xf506c6da, 0xe4625e7e, 0xa308ea99, 0x4e23e33c, 0x79cbd7cc, 0x48a14367,
|
||||
0xa3149619, 0xfec94bd5, 0xa114174a, 0xeaa01866, 0xa084db2d, 0x09a8486f, 0xa888614a, 0x2900af98,
|
||||
0x01665991, 0xe1992863, 0xc8f30c60, 0x2e78ef3c, 0xd0d51932, 0xcf0fec14, 0xf7ca07d2, 0xd0a82072,
|
||||
0xfd41197e, 0x9305a6b0, 0xe86be3da, 0x74bed3cd, 0x372da53c, 0x4c7f4448, 0xdab5d440, 0x6dba0ec3,
|
||||
0x083919a7, 0x9fbaeed9, 0x49dbcfb0, 0x4e670c53, 0x5c3d9c01, 0x64bdb941, 0x2c0e636a, 0xba7dd9cd,
|
||||
0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d, 0xf0d48d8c, 0xb88153e2, 0x08a19866, 0x1ae2eac8,
|
||||
0x284caf89, 0xaa928223, 0x9334be53, 0x3b3a21bf, 0x16434be3, 0x9aea3906, 0xefe8c36e, 0xf890cdd9,
|
||||
0x80226dae, 0xc340a4a3, 0xdf7e9c09, 0xa694a807, 0x5b7c5ecc, 0x221db3a6, 0x9a69a02f, 0x68818a54,
|
||||
0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a, 0xb4628abc, 0xcf222ebf, 0x25ac6f48, 0xa9a99387,
|
||||
0x53bddb65, 0xe76ffbe7, 0xe967fd78, 0x0ba93563, 0x8e342bc1, 0xe8a11be9, 0x4980740d, 0xc8087dfc,
|
||||
0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0, 0xe81f994f, 0x9528cd89, 0xfd339fed, 0xb87834bf,
|
||||
0x5f04456d, 0x22258698, 0xc9c4c83b, 0x2dc156be, 0x4f628daa, 0x57f55ec5, 0xe2220abe, 0xd2916ebf,
|
||||
0x4ec75b95, 0x24f2c3c0, 0x42d15d99, 0xcd0d7fa0, 0x7b6e27ff, 0xa8dc8af0, 0x7345c106, 0xf41e232f,
|
||||
0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2, 0x372b74af, 0x692573e4, 0xe9a9d848, 0xf3160289,
|
||||
0x3a62ef1d, 0xa787e238, 0xf3a5f676, 0x74364853, 0x20951063, 0x4576698d, 0xb6fad407, 0x592af950,
|
||||
0x36f73523, 0x4cfb6e87, 0x7da4cec0, 0x6c152daa, 0xcb0396a8, 0xc50dfe5d, 0xfcd707ab, 0x0921c42f,
|
||||
0x89dff0bb, 0x5fe2be78, 0x448f4f33, 0x754613c9, 0x2b05d08d, 0x48b9d585, 0xdc049441, 0xc8098f9b,
|
||||
0x7dede786, 0xc39a3373, 0x42410005, 0x6a091751, 0x0ef3c8a6, 0x890072d6, 0x28207682, 0xa9a9f7be,
|
||||
0xbf32679d, 0xd45b5b75, 0xb353fd00, 0xcbb0e358, 0x830f220a, 0x1f8fb214, 0xd372cf08, 0xcc3c4a13,
|
||||
0x8cf63166, 0x061c87be, 0x88c98f88, 0x6062e397, 0x47cf8e7a, 0xb6c85283, 0x3cc2acfb, 0x3fc06976,
|
||||
0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459, 0xc10908f0, 0x513021a5, 0x6c5b68b7, 0x822f8aa0,
|
||||
0x3007cd3e, 0x74719eef, 0xdc872681, 0x073340d4, 0x7e432fd9, 0x0c5ec241, 0x8809286c, 0xf592d891,
|
||||
0x08a930f6, 0x957ef305, 0xb7fbffbd, 0xc266e96f, 0x6fe4ac98, 0xb173ecc0, 0xbc60b42a, 0x953498da,
|
||||
0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb, 0xe2969123, 0x257f0c3d, 0x9348af49, 0x361400bc,
|
||||
0xe8816f4a, 0x3814f200, 0xa3f94043, 0x9c7a54c2, 0xbc704f57, 0xda41e7f9, 0xc25ad33a, 0x54f4a084,
|
||||
0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab, 0xba5ac7b5, 0xb6f6deaf, 0x3a479c3a, 0x5302da25,
|
||||
0x653d7e6a, 0x54268d49, 0x51a477ea, 0x5017d55b, 0xd7d25d88, 0x44136c76, 0x0404a8c8, 0xb8e5a121,
|
||||
0xb81a928a, 0x60ed5869, 0x97c55b96, 0xeaec991b, 0x29935913, 0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5,
|
||||
0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855, 0xd36b4cf1, 0xf544edeb, 0xb0e93524, 0xbebb8fbd,
|
||||
0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454, 0x48392905, 0xa65b1db8, 0x851c97bd, 0xd675cf2f
|
||||
};
|
||||
static const u32 s7[256] = {
|
||||
0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693, 0x2a8d7f6f, 0xab9bc912, 0xde6008a1, 0x2028da1f,
|
||||
0x0227bce7, 0x4d642916, 0x18fac300, 0x50f18b82, 0x2cb2cb11, 0xb232e75c, 0x4b3695f2, 0xb28707de,
|
||||
0xa05fbcf6, 0xcd4181e9, 0xe150210c, 0xe24ef1bd, 0xb168c381, 0xfde4e789, 0x5c79b0d8, 0x1e8bfd43,
|
||||
0x4d495001, 0x38be4341, 0x913cee1d, 0x92a79c3f, 0x089766be, 0xbaeeadf4, 0x1286becf, 0xb6eacb19,
|
||||
0x2660c200, 0x7565bde4, 0x64241f7a, 0x8248dca9, 0xc3b3ad66, 0x28136086, 0x0bd8dfa8, 0x356d1cf2,
|
||||
0x107789be, 0xb3b2e9ce, 0x0502aa8f, 0x0bc0351e, 0x166bf52a, 0xeb12ff82, 0xe3486911, 0xd34d7516,
|
||||
0x4e7b3aff, 0x5f43671b, 0x9cf6e037, 0x4981ac83, 0x334266ce, 0x8c9341b7, 0xd0d854c0, 0xcb3a6c88,
|
||||
0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e, 0x0c5cbafa, 0x4437f107, 0xb6e79962, 0x42d2d816,
|
||||
0x0a961288, 0xe1a5c06e, 0x13749e67, 0x72fc081a, 0xb1d139f7, 0xf9583745, 0xcf19df58, 0xbec3f756,
|
||||
0xc06eba30, 0x07211b24, 0x45c28829, 0xc95e317f, 0xbc8ec511, 0x38bc46e9, 0xc6e6fa14, 0xbae8584a,
|
||||
0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b, 0x821dba9f, 0xaff60ff4, 0xea2c4e6d, 0x16e39264,
|
||||
0x92544a8b, 0x009b4fc3, 0xaba68ced, 0x9ac96f78, 0x06a5b79a, 0xb2856e6e, 0x1aec3ca9, 0xbe838688,
|
||||
0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d, 0xf7debb85, 0x61fe033c, 0x16746233, 0x3c034c28,
|
||||
0xda6d0c74, 0x79aac56c, 0x3ce4e1ad, 0x51f0c802, 0x98f8f35a, 0x1626a49f, 0xeed82b29, 0x1d382fe3,
|
||||
0x0c4fb99a, 0xbb325778, 0x3ec6d97b, 0x6e77a6a9, 0xcb658b5c, 0xd45230c7, 0x2bd1408b, 0x60c03eb7,
|
||||
0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302, 0xb96d8c32, 0xebd4e7be, 0xbe8b9d2d, 0x7979fb06,
|
||||
0xe7225308, 0x8b75cf77, 0x11ef8da4, 0xe083c858, 0x8d6b786f, 0x5a6317a6, 0xfa5cf7a0, 0x5dda0033,
|
||||
0xf28ebfb0, 0xf5b9c310, 0xa0eac280, 0x08b9767a, 0xa3d9d2b0, 0x79d34217, 0x021a718d, 0x9ac6336a,
|
||||
0x2711fd60, 0x438050e3, 0x069908a8, 0x3d7fedc4, 0x826d2bef, 0x4eeb8476, 0x488dcf25, 0x36c9d566,
|
||||
0x28e74e41, 0xc2610aca, 0x3d49a9cf, 0xbae3b9df, 0xb65f8de6, 0x92aeaf64, 0x3ac7d5e6, 0x9ea80509,
|
||||
0xf22b017d, 0xa4173f70, 0xdd1e16c3, 0x15e0d7f9, 0x50b1b887, 0x2b9f4fd5, 0x625aba82, 0x6a017962,
|
||||
0x2ec01b9c, 0x15488aa9, 0xd716e740, 0x40055a2c, 0x93d29a22, 0xe32dbf9a, 0x058745b9, 0x3453dc1e,
|
||||
0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07, 0xb87242d1, 0x19de7eae, 0x053e561a, 0x15ad6f8c,
|
||||
0x66626c1c, 0x7154c24c, 0xea082b2a, 0x93eb2939, 0x17dcb0f0, 0x58d4f2ae, 0x9ea294fb, 0x52cf564c,
|
||||
0x9883fe66, 0x2ec40581, 0x763953c3, 0x01d6692e, 0xd3a0c108, 0xa1e7160e, 0xe4f2dfa6, 0x693ed285,
|
||||
0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378, 0xa132234f, 0x3d321c5d, 0xc3f5e194, 0x4b269301,
|
||||
0xc79f022f, 0x3c997e7e, 0x5e4f9504, 0x3ffafbbd, 0x76f7ad0e, 0x296693f4, 0x3d1fce6f, 0xc61e45be,
|
||||
0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567, 0x5592a33d, 0xb5229301, 0xcfd2a87f, 0x60aeb767,
|
||||
0x1814386b, 0x30bcc33d, 0x38a0c07d, 0xfd1606f2, 0xc363519b, 0x589dd390, 0x5479f8e6, 0x1cb8d647,
|
||||
0x97fd61a9, 0xea7759f4, 0x2d57539d, 0x569a58cf, 0xe84e63ad, 0x462e1b78, 0x6580f87e, 0xf3817914,
|
||||
0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2, 0x3ffa50bc, 0x3d40f021, 0xc3c0bdae, 0x4958c24c,
|
||||
0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada, 0xf2a279c7, 0x94e01be8, 0x90716f4b, 0x954b8aa3
|
||||
};
|
||||
static const u32 s8[256] = {
|
||||
0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095, 0x7789f8b7, 0xe6c1121b, 0x0e241600, 0x052ce8b5,
|
||||
0x11a9cfb0, 0xe5952f11, 0xece7990a, 0x9386d174, 0x2a42931c, 0x76e38111, 0xb12def3a, 0x37ddddfc,
|
||||
0xde9adeb1, 0x0a0cc32c, 0xbe197029, 0x84a00940, 0xbb243a0f, 0xb4d137cf, 0xb44e79f0, 0x049eedfd,
|
||||
0x0b15a15d, 0x480d3168, 0x8bbbde5a, 0x669ded42, 0xc7ece831, 0x3f8f95e7, 0x72df191b, 0x7580330d,
|
||||
0x94074251, 0x5c7dcdfa, 0xabbe6d63, 0xaa402164, 0xb301d40a, 0x02e7d1ca, 0x53571dae, 0x7a3182a2,
|
||||
0x12a8ddec, 0xfdaa335d, 0x176f43e8, 0x71fb46d4, 0x38129022, 0xce949ad4, 0xb84769ad, 0x965bd862,
|
||||
0x82f3d055, 0x66fb9767, 0x15b80b4e, 0x1d5b47a0, 0x4cfde06f, 0xc28ec4b8, 0x57e8726e, 0x647a78fc,
|
||||
0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6, 0x5d0b00a3, 0xae63aff2, 0x7e8bd632, 0x70108c0c,
|
||||
0xbbd35049, 0x2998df04, 0x980cf42a, 0x9b6df491, 0x9e7edd53, 0x06918548, 0x58cb7e07, 0x3b74ef2e,
|
||||
0x522fffb1, 0xd24708cc, 0x1c7e27cd, 0xa4eb215b, 0x3cf1d2e2, 0x19b47a38, 0x424f7618, 0x35856039,
|
||||
0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8, 0x09c467cd, 0xc18910b1, 0xe11dbf7b, 0x06cd1af8,
|
||||
0x7170c608, 0x2d5e3354, 0xd4de495a, 0x64c6d006, 0xbcc0c62c, 0x3dd00db3, 0x708f8f34, 0x77d51b42,
|
||||
0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564, 0xf8d7e54e, 0x3e378160, 0x7895cda5, 0x859c15a5,
|
||||
0xe6459788, 0xc37bc75f, 0xdb07ba0c, 0x0676a3ab, 0x7f229b1e, 0x31842e7b, 0x24259fd7, 0xf8bef472,
|
||||
0x835ffcb8, 0x6df4c1f2, 0x96f5b195, 0xfd0af0fc, 0xb0fe134c, 0xe2506d3d, 0x4f9b12ea, 0xf215f225,
|
||||
0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8, 0xc4618187, 0xea7a6e98, 0x7cd16efc, 0x1436876c,
|
||||
0xf1544107, 0xbedeee14, 0x56e9af27, 0xa04aa441, 0x3cf7c899, 0x92ecbae6, 0xdd67016d, 0x151682eb,
|
||||
0xa842eedf, 0xfdba60b4, 0xf1907b75, 0x20e3030f, 0x24d8c29e, 0xe139673b, 0xefa63fb8, 0x71873054,
|
||||
0xb6f2cf3b, 0x9f326442, 0xcb15a4cc, 0xb01a4504, 0xf1e47d8d, 0x844a1be5, 0xbae7dfdc, 0x42cbda70,
|
||||
0xcd7dae0a, 0x57e85b7a, 0xd53f5af6, 0x20cf4d8c, 0xcea4d428, 0x79d130a4, 0x3486ebfb, 0x33d3cddc,
|
||||
0x77853b53, 0x37effcb5, 0xc5068778, 0xe580b3e6, 0x4e68b8f4, 0xc5c8b37e, 0x0d809ea2, 0x398feb7c,
|
||||
0x132a4f94, 0x43b7950e, 0x2fee7d1c, 0x223613bd, 0xdd06caa2, 0x37df932b, 0xc4248289, 0xacf3ebc3,
|
||||
0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4, 0x9052815e, 0x5e410fab, 0xb48a2465, 0x2eda7fa4,
|
||||
0xe87b40e4, 0xe98ea084, 0x5889e9e1, 0xefd390fc, 0xdd07d35b, 0xdb485694, 0x38d7e5b2, 0x57720101,
|
||||
0x730edebc, 0x5b643113, 0x94917e4f, 0x503c2fba, 0x646f1282, 0x7523d24a, 0xe0779695, 0xf9c17a8f,
|
||||
0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf, 0x81f47c9f, 0xad1163ed, 0xea7b5965, 0x1a00726e,
|
||||
0x11403092, 0x00da6d77, 0x4a0cdd61, 0xad1f4603, 0x605bdfb0, 0x9eedc364, 0x22ebe6a8, 0xcee7d28a,
|
||||
0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37, 0x2de705ca, 0x8951570f, 0xdf09822b, 0xbd691a6c,
|
||||
0xaa12e4f2, 0x87451c0f, 0xe0f6a27a, 0x3ada4819, 0x4cf1764f, 0x0d771c2b, 0x67cdb156, 0x350d8384,
|
||||
0x5938fa0f, 0x42399ef3, 0x36997b07, 0x0e84093d, 0x4aa93e61, 0x8360d87b, 0x1fa98b0c, 0x1149382c,
|
||||
0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347, 0x589e8d82, 0x0d2059d1, 0xa466bb1e, 0xf8da0a82,
|
||||
0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d, 0x50b2ad80, 0xeaee6801, 0x8db2a283, 0xea8bf59e
|
||||
};
|
||||
|
||||
|
||||
#if defined(__GNUC__) && defined(__i386__)
|
||||
static inline u32
|
||||
rol(int n, u32 x)
|
||||
{
|
||||
__asm__("roll %%cl,%0"
|
||||
:"=r" (x)
|
||||
:"0" (x),"c" (n));
|
||||
return x;
|
||||
}
|
||||
#else
|
||||
#define rol(n,x) ( ((x) << (n)) | ((x) >> (32-(n))) )
|
||||
#endif
|
||||
|
||||
#define F1(D,m,r) ( (I = ((m) + (D))), (I=rol((r),I)), \
|
||||
(((s1[I >> 24] ^ s2[(I>>16)&0xff]) - s3[(I>>8)&0xff]) + s4[I&0xff]) )
|
||||
#define F2(D,m,r) ( (I = ((m) ^ (D))), (I=rol((r),I)), \
|
||||
(((s1[I >> 24] - s2[(I>>16)&0xff]) + s3[(I>>8)&0xff]) ^ s4[I&0xff]) )
|
||||
#define F3(D,m,r) ( (I = ((m) - (D))), (I=rol((r),I)), \
|
||||
(((s1[I >> 24] + s2[(I>>16)&0xff]) ^ s3[(I>>8)&0xff]) - s4[I&0xff]) )
|
||||
|
||||
static void
|
||||
do_encrypt_block( CAST5_context *c, byte *outbuf, const byte *inbuf )
|
||||
{
|
||||
u32 l, r, t;
|
||||
u32 I; /* used by the Fx macros */
|
||||
u32 *Km;
|
||||
byte *Kr;
|
||||
|
||||
Km = c->Km;
|
||||
Kr = c->Kr;
|
||||
|
||||
/* (L0,R0) <-- (m1...m64). (Split the plaintext into left and
|
||||
* right 32-bit halves L0 = m1...m32 and R0 = m33...m64.)
|
||||
*/
|
||||
l = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3];
|
||||
r = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7];
|
||||
|
||||
/* (16 rounds) for i from 1 to 16, compute Li and Ri as follows:
|
||||
* Li = Ri-1;
|
||||
* Ri = Li-1 ^ f(Ri-1,Kmi,Kri), where f is defined in Section 2.2
|
||||
* Rounds 1, 4, 7, 10, 13, and 16 use f function Type 1.
|
||||
* Rounds 2, 5, 8, 11, and 14 use f function Type 2.
|
||||
* Rounds 3, 6, 9, 12, and 15 use f function Type 3.
|
||||
*/
|
||||
|
||||
t = l; l = r; r = t ^ F1(r, Km[ 0], Kr[ 0]);
|
||||
t = l; l = r; r = t ^ F2(r, Km[ 1], Kr[ 1]);
|
||||
t = l; l = r; r = t ^ F3(r, Km[ 2], Kr[ 2]);
|
||||
t = l; l = r; r = t ^ F1(r, Km[ 3], Kr[ 3]);
|
||||
t = l; l = r; r = t ^ F2(r, Km[ 4], Kr[ 4]);
|
||||
t = l; l = r; r = t ^ F3(r, Km[ 5], Kr[ 5]);
|
||||
t = l; l = r; r = t ^ F1(r, Km[ 6], Kr[ 6]);
|
||||
t = l; l = r; r = t ^ F2(r, Km[ 7], Kr[ 7]);
|
||||
t = l; l = r; r = t ^ F3(r, Km[ 8], Kr[ 8]);
|
||||
t = l; l = r; r = t ^ F1(r, Km[ 9], Kr[ 9]);
|
||||
t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]);
|
||||
t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]);
|
||||
t = l; l = r; r = t ^ F1(r, Km[12], Kr[12]);
|
||||
t = l; l = r; r = t ^ F2(r, Km[13], Kr[13]);
|
||||
t = l; l = r; r = t ^ F3(r, Km[14], Kr[14]);
|
||||
t = l; l = r; r = t ^ F1(r, Km[15], Kr[15]);
|
||||
|
||||
/* c1...c64 <-- (R16,L16). (Exchange final blocks L16, R16 and
|
||||
* concatenate to form the ciphertext.) */
|
||||
outbuf[0] = (r >> 24) & 0xff;
|
||||
outbuf[1] = (r >> 16) & 0xff;
|
||||
outbuf[2] = (r >> 8) & 0xff;
|
||||
outbuf[3] = r & 0xff;
|
||||
outbuf[4] = (l >> 24) & 0xff;
|
||||
outbuf[5] = (l >> 16) & 0xff;
|
||||
outbuf[6] = (l >> 8) & 0xff;
|
||||
outbuf[7] = l & 0xff;
|
||||
}
|
||||
|
||||
static void
|
||||
encrypt_block (void *context , byte *outbuf, const byte *inbuf)
|
||||
{
|
||||
CAST5_context *c = (CAST5_context *) context;
|
||||
do_encrypt_block (c, outbuf, inbuf);
|
||||
_gcry_burn_stack (20+4*sizeof(void*));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
do_decrypt_block (CAST5_context *c, byte *outbuf, const byte *inbuf )
|
||||
{
|
||||
u32 l, r, t;
|
||||
u32 I;
|
||||
u32 *Km;
|
||||
byte *Kr;
|
||||
|
||||
Km = c->Km;
|
||||
Kr = c->Kr;
|
||||
|
||||
l = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3];
|
||||
r = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7];
|
||||
|
||||
t = l; l = r; r = t ^ F1(r, Km[15], Kr[15]);
|
||||
t = l; l = r; r = t ^ F3(r, Km[14], Kr[14]);
|
||||
t = l; l = r; r = t ^ F2(r, Km[13], Kr[13]);
|
||||
t = l; l = r; r = t ^ F1(r, Km[12], Kr[12]);
|
||||
t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]);
|
||||
t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]);
|
||||
t = l; l = r; r = t ^ F1(r, Km[ 9], Kr[ 9]);
|
||||
t = l; l = r; r = t ^ F3(r, Km[ 8], Kr[ 8]);
|
||||
t = l; l = r; r = t ^ F2(r, Km[ 7], Kr[ 7]);
|
||||
t = l; l = r; r = t ^ F1(r, Km[ 6], Kr[ 6]);
|
||||
t = l; l = r; r = t ^ F3(r, Km[ 5], Kr[ 5]);
|
||||
t = l; l = r; r = t ^ F2(r, Km[ 4], Kr[ 4]);
|
||||
t = l; l = r; r = t ^ F1(r, Km[ 3], Kr[ 3]);
|
||||
t = l; l = r; r = t ^ F3(r, Km[ 2], Kr[ 2]);
|
||||
t = l; l = r; r = t ^ F2(r, Km[ 1], Kr[ 1]);
|
||||
t = l; l = r; r = t ^ F1(r, Km[ 0], Kr[ 0]);
|
||||
|
||||
outbuf[0] = (r >> 24) & 0xff;
|
||||
outbuf[1] = (r >> 16) & 0xff;
|
||||
outbuf[2] = (r >> 8) & 0xff;
|
||||
outbuf[3] = r & 0xff;
|
||||
outbuf[4] = (l >> 24) & 0xff;
|
||||
outbuf[5] = (l >> 16) & 0xff;
|
||||
outbuf[6] = (l >> 8) & 0xff;
|
||||
outbuf[7] = l & 0xff;
|
||||
}
|
||||
|
||||
static void
|
||||
decrypt_block (void *context, byte *outbuf, const byte *inbuf)
|
||||
{
|
||||
CAST5_context *c = (CAST5_context *) context;
|
||||
do_decrypt_block (c, outbuf, inbuf);
|
||||
_gcry_burn_stack (20+4*sizeof(void*));
|
||||
}
|
||||
|
||||
|
||||
static const char*
|
||||
selftest(void)
|
||||
{
|
||||
CAST5_context c;
|
||||
byte key[16] = { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78,
|
||||
0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A };
|
||||
byte plain[8] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF };
|
||||
byte cipher[8]= { 0x23, 0x8B, 0x4F, 0xE5, 0x84, 0x7E, 0x44, 0xB2 };
|
||||
byte buffer[8];
|
||||
|
||||
cast_setkey( &c, key, 16 );
|
||||
encrypt_block( &c, buffer, plain );
|
||||
if( memcmp( buffer, cipher, 8 ) )
|
||||
return "1";
|
||||
decrypt_block( &c, buffer, buffer );
|
||||
if( memcmp( buffer, plain, 8 ) )
|
||||
return "2";
|
||||
|
||||
#if 0 /* full maintenance test */
|
||||
{
|
||||
int i;
|
||||
byte a0[16] = { 0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,
|
||||
0x23,0x45,0x67,0x89,0x34,0x56,0x78,0x9A };
|
||||
byte b0[16] = { 0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,
|
||||
0x23,0x45,0x67,0x89,0x34,0x56,0x78,0x9A };
|
||||
byte a1[16] = { 0xEE,0xA9,0xD0,0xA2,0x49,0xFD,0x3B,0xA6,
|
||||
0xB3,0x43,0x6F,0xB8,0x9D,0x6D,0xCA,0x92 };
|
||||
byte b1[16] = { 0xB2,0xC9,0x5E,0xB0,0x0C,0x31,0xAD,0x71,
|
||||
0x80,0xAC,0x05,0xB8,0xE8,0x3D,0x69,0x6E };
|
||||
|
||||
for(i=0; i < 1000000; i++ ) {
|
||||
cast_setkey( &c, b0, 16 );
|
||||
encrypt_block( &c, a0, a0 );
|
||||
encrypt_block( &c, a0+8, a0+8 );
|
||||
cast_setkey( &c, a0, 16 );
|
||||
encrypt_block( &c, b0, b0 );
|
||||
encrypt_block( &c, b0+8, b0+8 );
|
||||
}
|
||||
if( memcmp( a0, a1, 16 ) || memcmp( b0, b1, 16 ) )
|
||||
return "3";
|
||||
|
||||
}
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
key_schedule( u32 *x, u32 *z, u32 *k )
|
||||
{
|
||||
|
||||
#define xi(i) ((x[(i)/4] >> (8*(3-((i)%4)))) & 0xff)
|
||||
#define zi(i) ((z[(i)/4] >> (8*(3-((i)%4)))) & 0xff)
|
||||
|
||||
z[0] = x[0] ^ s5[xi(13)]^s6[xi(15)]^s7[xi(12)]^s8[xi(14)]^s7[xi( 8)];
|
||||
z[1] = x[2] ^ s5[zi( 0)]^s6[zi( 2)]^s7[zi( 1)]^s8[zi( 3)]^s8[xi(10)];
|
||||
z[2] = x[3] ^ s5[zi( 7)]^s6[zi( 6)]^s7[zi( 5)]^s8[zi( 4)]^s5[xi( 9)];
|
||||
z[3] = x[1] ^ s5[zi(10)]^s6[zi( 9)]^s7[zi(11)]^s8[zi( 8)]^s6[xi(11)];
|
||||
k[0] = s5[zi( 8)]^s6[zi( 9)]^s7[zi( 7)]^s8[zi( 6)]^s5[zi( 2)];
|
||||
k[1] = s5[zi(10)]^s6[zi(11)]^s7[zi( 5)]^s8[zi( 4)]^s6[zi( 6)];
|
||||
k[2] = s5[zi(12)]^s6[zi(13)]^s7[zi( 3)]^s8[zi( 2)]^s7[zi( 9)];
|
||||
k[3] = s5[zi(14)]^s6[zi(15)]^s7[zi( 1)]^s8[zi( 0)]^s8[zi(12)];
|
||||
|
||||
x[0] = z[2] ^ s5[zi( 5)]^s6[zi( 7)]^s7[zi( 4)]^s8[zi( 6)]^s7[zi( 0)];
|
||||
x[1] = z[0] ^ s5[xi( 0)]^s6[xi( 2)]^s7[xi( 1)]^s8[xi( 3)]^s8[zi( 2)];
|
||||
x[2] = z[1] ^ s5[xi( 7)]^s6[xi( 6)]^s7[xi( 5)]^s8[xi( 4)]^s5[zi( 1)];
|
||||
x[3] = z[3] ^ s5[xi(10)]^s6[xi( 9)]^s7[xi(11)]^s8[xi( 8)]^s6[zi( 3)];
|
||||
k[4] = s5[xi( 3)]^s6[xi( 2)]^s7[xi(12)]^s8[xi(13)]^s5[xi( 8)];
|
||||
k[5] = s5[xi( 1)]^s6[xi( 0)]^s7[xi(14)]^s8[xi(15)]^s6[xi(13)];
|
||||
k[6] = s5[xi( 7)]^s6[xi( 6)]^s7[xi( 8)]^s8[xi( 9)]^s7[xi( 3)];
|
||||
k[7] = s5[xi( 5)]^s6[xi( 4)]^s7[xi(10)]^s8[xi(11)]^s8[xi( 7)];
|
||||
|
||||
z[0] = x[0] ^ s5[xi(13)]^s6[xi(15)]^s7[xi(12)]^s8[xi(14)]^s7[xi( 8)];
|
||||
z[1] = x[2] ^ s5[zi( 0)]^s6[zi( 2)]^s7[zi( 1)]^s8[zi( 3)]^s8[xi(10)];
|
||||
z[2] = x[3] ^ s5[zi( 7)]^s6[zi( 6)]^s7[zi( 5)]^s8[zi( 4)]^s5[xi( 9)];
|
||||
z[3] = x[1] ^ s5[zi(10)]^s6[zi( 9)]^s7[zi(11)]^s8[zi( 8)]^s6[xi(11)];
|
||||
k[8] = s5[zi( 3)]^s6[zi( 2)]^s7[zi(12)]^s8[zi(13)]^s5[zi( 9)];
|
||||
k[9] = s5[zi( 1)]^s6[zi( 0)]^s7[zi(14)]^s8[zi(15)]^s6[zi(12)];
|
||||
k[10]= s5[zi( 7)]^s6[zi( 6)]^s7[zi( 8)]^s8[zi( 9)]^s7[zi( 2)];
|
||||
k[11]= s5[zi( 5)]^s6[zi( 4)]^s7[zi(10)]^s8[zi(11)]^s8[zi( 6)];
|
||||
|
||||
x[0] = z[2] ^ s5[zi( 5)]^s6[zi( 7)]^s7[zi( 4)]^s8[zi( 6)]^s7[zi( 0)];
|
||||
x[1] = z[0] ^ s5[xi( 0)]^s6[xi( 2)]^s7[xi( 1)]^s8[xi( 3)]^s8[zi( 2)];
|
||||
x[2] = z[1] ^ s5[xi( 7)]^s6[xi( 6)]^s7[xi( 5)]^s8[xi( 4)]^s5[zi( 1)];
|
||||
x[3] = z[3] ^ s5[xi(10)]^s6[xi( 9)]^s7[xi(11)]^s8[xi( 8)]^s6[zi( 3)];
|
||||
k[12]= s5[xi( 8)]^s6[xi( 9)]^s7[xi( 7)]^s8[xi( 6)]^s5[xi( 3)];
|
||||
k[13]= s5[xi(10)]^s6[xi(11)]^s7[xi( 5)]^s8[xi( 4)]^s6[xi( 7)];
|
||||
k[14]= s5[xi(12)]^s6[xi(13)]^s7[xi( 3)]^s8[xi( 2)]^s7[xi( 8)];
|
||||
k[15]= s5[xi(14)]^s6[xi(15)]^s7[xi( 1)]^s8[xi( 0)]^s8[xi(13)];
|
||||
|
||||
#undef xi
|
||||
#undef zi
|
||||
}
|
||||
|
||||
|
||||
static gcry_err_code_t
|
||||
do_cast_setkey( CAST5_context *c, const byte *key, unsigned keylen )
|
||||
{
|
||||
static int initialized;
|
||||
static const char* selftest_failed;
|
||||
int i;
|
||||
u32 x[4];
|
||||
u32 z[4];
|
||||
u32 k[16];
|
||||
|
||||
if( !initialized )
|
||||
{
|
||||
initialized = 1;
|
||||
selftest_failed = selftest();
|
||||
if( selftest_failed )
|
||||
log_error ("CAST5 selftest failed (%s).\n", selftest_failed );
|
||||
}
|
||||
if( selftest_failed )
|
||||
return GPG_ERR_SELFTEST_FAILED;
|
||||
|
||||
if( keylen != 16 )
|
||||
return GPG_ERR_INV_KEYLEN;
|
||||
|
||||
x[0] = key[0] << 24 | key[1] << 16 | key[2] << 8 | key[3];
|
||||
x[1] = key[4] << 24 | key[5] << 16 | key[6] << 8 | key[7];
|
||||
x[2] = key[8] << 24 | key[9] << 16 | key[10] << 8 | key[11];
|
||||
x[3] = key[12] << 24 | key[13] << 16 | key[14] << 8 | key[15];
|
||||
|
||||
key_schedule( x, z, k );
|
||||
for(i=0; i < 16; i++ )
|
||||
c->Km[i] = k[i];
|
||||
key_schedule( x, z, k );
|
||||
for(i=0; i < 16; i++ )
|
||||
c->Kr[i] = k[i] & 0x1f;
|
||||
|
||||
memset(&x,0, sizeof x);
|
||||
memset(&z,0, sizeof z);
|
||||
memset(&k,0, sizeof k);
|
||||
|
||||
#undef xi
|
||||
#undef zi
|
||||
return GPG_ERR_NO_ERROR;
|
||||
}
|
||||
|
||||
static gcry_err_code_t
|
||||
cast_setkey (void *context, const byte *key, unsigned keylen )
|
||||
{
|
||||
CAST5_context *c = (CAST5_context *) context;
|
||||
gcry_err_code_t rc = do_cast_setkey (c, key, keylen);
|
||||
_gcry_burn_stack (96+7*sizeof(void*));
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
gcry_cipher_spec_t _gcry_cipher_spec_cast5 =
|
||||
{
|
||||
"CAST5", NULL, NULL, CAST5_BLOCKSIZE, 128, sizeof (CAST5_context),
|
||||
cast_setkey, encrypt_block, decrypt_block
|
||||
};
|
1932
lib/libgcrypt/cipher/cipher.c
Normal file
1932
lib/libgcrypt/cipher/cipher.c
Normal file
File diff suppressed because it is too large
Load diff
297
lib/libgcrypt/cipher/crc.c
Normal file
297
lib/libgcrypt/cipher/crc.c
Normal file
|
@ -0,0 +1,297 @@
|
|||
/* crc.c - Cyclic redundancy checks.
|
||||
* Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of Libgcrypt.
|
||||
*
|
||||
* Libgcrypt is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Libgcrypt is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "g10lib.h"
|
||||
#include "memory.h"
|
||||
#include "cipher.h"
|
||||
|
||||
#include "bithelp.h"
|
||||
|
||||
/* Table of CRCs of all 8-bit messages. Generated by running code
|
||||
from RFC 1952 modified to print out the table. */
|
||||
static u32 crc32_table[256] = {
|
||||
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
|
||||
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
|
||||
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
|
||||
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
|
||||
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
|
||||
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
|
||||
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
|
||||
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
|
||||
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
|
||||
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
|
||||
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
|
||||
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
|
||||
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
|
||||
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
|
||||
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
|
||||
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
|
||||
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
|
||||
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
|
||||
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
|
||||
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
|
||||
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
|
||||
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
|
||||
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
|
||||
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
|
||||
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
|
||||
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
|
||||
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
|
||||
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
|
||||
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
|
||||
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
|
||||
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
|
||||
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
|
||||
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
|
||||
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
|
||||
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
|
||||
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
|
||||
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
|
||||
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
|
||||
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
|
||||
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
|
||||
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
|
||||
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
|
||||
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
||||
};
|
||||
|
||||
/*
|
||||
* The following function was extracted from RFC 1952 by Simon
|
||||
* Josefsson, for the Shishi project, and modified to be compatible
|
||||
* with the modified CRC-32 used by RFC 1510, and subsequently
|
||||
* modified for GNU Libgcrypt to allow it to be used for calculating
|
||||
* both unmodified CRC-32 and modified CRC-32 values. Original
|
||||
* copyright and notice from the document follows:
|
||||
*
|
||||
* Copyright (c) 1996 L. Peter Deutsch
|
||||
*
|
||||
* Permission is granted to copy and distribute this document for
|
||||
* any purpose and without charge, including translations into
|
||||
* other languages and incorporation into compilations, provided
|
||||
* that the copyright notice and this notice are preserved, and
|
||||
* that any substantive changes or deletions from the original are
|
||||
* clearly marked.
|
||||
*
|
||||
* The copyright on RFCs, and consequently the function below, are
|
||||
* supposedly also retroactively claimed by the Internet Society
|
||||
* (according to rfc-editor@rfc-editor.org), with the following
|
||||
* copyright notice:
|
||||
*
|
||||
* Copyright (C) The Internet Society. All Rights Reserved.
|
||||
*
|
||||
* This document and translations of it may be copied and furnished
|
||||
* to others, and derivative works that comment on or otherwise
|
||||
* explain it or assist in its implementation may be prepared,
|
||||
* copied, published and distributed, in whole or in part, without
|
||||
* restriction of any kind, provided that the above copyright
|
||||
* notice and this paragraph are included on all such copies and
|
||||
* derivative works. However, this document itself may not be
|
||||
* modified in any way, such as by removing the copyright notice or
|
||||
* references to the Internet Society or other Internet
|
||||
* organizations, except as needed for the purpose of developing
|
||||
* Internet standards in which case the procedures for copyrights
|
||||
* defined in the Internet Standards process must be followed, or
|
||||
* as required to translate it into languages other than English.
|
||||
*
|
||||
* The limited permissions granted above are perpetual and will not be
|
||||
* revoked by the Internet Society or its successors or assigns.
|
||||
*
|
||||
* This document and the information contained herein is provided
|
||||
* on an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET
|
||||
* ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE
|
||||
* OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
|
||||
* PARTICULAR PURPOSE.
|
||||
*
|
||||
*/
|
||||
static u32
|
||||
update_crc32 (u32 crc, const void *buf_arg, size_t len)
|
||||
{
|
||||
const char *buf = buf_arg;
|
||||
size_t n;
|
||||
|
||||
for (n = 0; n < len; n++)
|
||||
crc = crc32_table[(crc ^ buf[n]) & 0xff] ^ (crc >> 8);
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 CRC;
|
||||
byte buf[4];
|
||||
}
|
||||
CRC_CONTEXT;
|
||||
|
||||
/* CRC32 */
|
||||
|
||||
static void
|
||||
crc32_init (void *context)
|
||||
{
|
||||
CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
|
||||
ctx->CRC = 0 ^ 0xffffffffL;
|
||||
}
|
||||
|
||||
static void
|
||||
crc32_write (void *context, const void *inbuf, size_t inlen)
|
||||
{
|
||||
CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
|
||||
if (!inbuf)
|
||||
return;
|
||||
ctx->CRC = update_crc32 (ctx->CRC, inbuf, inlen);
|
||||
}
|
||||
|
||||
static byte *
|
||||
crc32_read (void *context)
|
||||
{
|
||||
CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
|
||||
return ctx->buf;
|
||||
}
|
||||
|
||||
static void
|
||||
crc32_final (void *context)
|
||||
{
|
||||
CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
|
||||
ctx->CRC ^= 0xffffffffL;
|
||||
ctx->buf[0] = (ctx->CRC >> 24) & 0xFF;
|
||||
ctx->buf[1] = (ctx->CRC >> 16) & 0xFF;
|
||||
ctx->buf[2] = (ctx->CRC >> 8) & 0xFF;
|
||||
ctx->buf[3] = (ctx->CRC ) & 0xFF;
|
||||
}
|
||||
|
||||
/* CRC32 a'la RFC 1510 */
|
||||
static void
|
||||
crc32rfc1510_init (void *context)
|
||||
{
|
||||
CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
|
||||
ctx->CRC = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
crc32rfc1510_final (void *context)
|
||||
{
|
||||
CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
|
||||
ctx->buf[0] = (ctx->CRC >> 24) & 0xFF;
|
||||
ctx->buf[1] = (ctx->CRC >> 16) & 0xFF;
|
||||
ctx->buf[2] = (ctx->CRC >> 8) & 0xFF;
|
||||
ctx->buf[3] = (ctx->CRC ) & 0xFF;
|
||||
}
|
||||
|
||||
/* CRC24 a'la RFC 2440 */
|
||||
/*
|
||||
* The following CRC 24 routines are adapted from RFC 2440, which has
|
||||
* the following copyright notice:
|
||||
*
|
||||
* Copyright (C) The Internet Society (1998). All Rights Reserved.
|
||||
*
|
||||
* This document and translations of it may be copied and furnished
|
||||
* to others, and derivative works that comment on or otherwise
|
||||
* explain it or assist in its implementation may be prepared,
|
||||
* copied, published and distributed, in whole or in part, without
|
||||
* restriction of any kind, provided that the above copyright notice
|
||||
* and this paragraph are included on all such copies and derivative
|
||||
* works. However, this document itself may not be modified in any
|
||||
* way, such as by removing the copyright notice or references to
|
||||
* the Internet Society or other Internet organizations, except as
|
||||
* needed for the purpose of developing Internet standards in which
|
||||
* case the procedures for copyrights defined in the Internet
|
||||
* Standards process must be followed, or as required to translate
|
||||
* it into languages other than English.
|
||||
*
|
||||
* The limited permissions granted above are perpetual and will not be
|
||||
* revoked by the Internet Society or its successors or assigns.
|
||||
*
|
||||
* This document and the information contained herein is provided on
|
||||
* an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET
|
||||
* ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE
|
||||
* OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
|
||||
* PURPOSE.
|
||||
*/
|
||||
|
||||
#define CRC24_INIT 0xb704ceL
|
||||
#define CRC24_POLY 0x1864cfbL
|
||||
|
||||
static void
|
||||
crc24rfc2440_init (void *context)
|
||||
{
|
||||
CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
|
||||
ctx->CRC = CRC24_INIT;
|
||||
}
|
||||
|
||||
static void
|
||||
crc24rfc2440_write (void *context, const void *inbuf_arg, size_t inlen)
|
||||
{
|
||||
const unsigned char *inbuf = inbuf_arg;
|
||||
int i;
|
||||
CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
|
||||
|
||||
if (!inbuf)
|
||||
return;
|
||||
|
||||
while (inlen--) {
|
||||
ctx->CRC ^= (*inbuf++) << 16;
|
||||
for (i = 0; i < 8; i++) {
|
||||
ctx->CRC <<= 1;
|
||||
if (ctx->CRC & 0x1000000)
|
||||
ctx->CRC ^= CRC24_POLY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
crc24rfc2440_final (void *context)
|
||||
{
|
||||
CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
|
||||
ctx->buf[0] = (ctx->CRC >> 16) & 0xFF;
|
||||
ctx->buf[1] = (ctx->CRC >> 8) & 0xFF;
|
||||
ctx->buf[2] = (ctx->CRC ) & 0xFF;
|
||||
}
|
||||
|
||||
gcry_md_spec_t _gcry_digest_spec_crc32 =
|
||||
{
|
||||
"CRC32", NULL, 0, NULL, 4,
|
||||
crc32_init, crc32_write, crc32_final, crc32_read,
|
||||
sizeof (CRC_CONTEXT)
|
||||
};
|
||||
|
||||
gcry_md_spec_t _gcry_digest_spec_crc32_rfc1510 =
|
||||
{
|
||||
"CRC32RFC1510", NULL, 0, NULL, 4,
|
||||
crc32rfc1510_init, crc32_write,
|
||||
crc32rfc1510_final, crc32_read,
|
||||
sizeof (CRC_CONTEXT)
|
||||
};
|
||||
|
||||
gcry_md_spec_t _gcry_digest_spec_crc24_rfc2440 =
|
||||
{
|
||||
"CRC24RFC2440", NULL, 0, NULL, 3,
|
||||
crc24rfc2440_init, crc24rfc2440_write,
|
||||
crc24rfc2440_final, crc32_read,
|
||||
sizeof (CRC_CONTEXT)
|
||||
};
|
1196
lib/libgcrypt/cipher/des.c
Normal file
1196
lib/libgcrypt/cipher/des.c
Normal file
File diff suppressed because it is too large
Load diff
1181
lib/libgcrypt/cipher/dsa.c
Normal file
1181
lib/libgcrypt/cipher/dsa.c
Normal file
File diff suppressed because it is too large
Load diff
1390
lib/libgcrypt/cipher/ecc.c
Normal file
1390
lib/libgcrypt/cipher/ecc.c
Normal file
File diff suppressed because it is too large
Load diff
846
lib/libgcrypt/cipher/elgamal.c
Normal file
846
lib/libgcrypt/cipher/elgamal.c
Normal file
|
@ -0,0 +1,846 @@
|
|||
/* Elgamal.c - Elgamal Public Key encryption
|
||||
* Copyright (C) 1998, 2000, 2001, 2002, 2003,
|
||||
* 2008 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of Libgcrypt.
|
||||
*
|
||||
* Libgcrypt is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Libgcrypt is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* For a description of the algorithm, see:
|
||||
* Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996.
|
||||
* ISBN 0-471-11709-9. Pages 476 ff.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "g10lib.h"
|
||||
#include "mpi.h"
|
||||
#include "cipher.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gcry_mpi_t p; /* prime */
|
||||
gcry_mpi_t g; /* group generator */
|
||||
gcry_mpi_t y; /* g^x mod p */
|
||||
} ELG_public_key;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gcry_mpi_t p; /* prime */
|
||||
gcry_mpi_t g; /* group generator */
|
||||
gcry_mpi_t y; /* g^x mod p */
|
||||
gcry_mpi_t x; /* secret exponent */
|
||||
} ELG_secret_key;
|
||||
|
||||
|
||||
static int test_keys (ELG_secret_key *sk, unsigned int nbits, int nodie);
|
||||
static gcry_mpi_t gen_k (gcry_mpi_t p, int small_k);
|
||||
static void generate (ELG_secret_key *sk, unsigned nbits, gcry_mpi_t **factors);
|
||||
static int check_secret_key (ELG_secret_key *sk);
|
||||
static void do_encrypt (gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input,
|
||||
ELG_public_key *pkey);
|
||||
static void decrypt (gcry_mpi_t output, gcry_mpi_t a, gcry_mpi_t b,
|
||||
ELG_secret_key *skey);
|
||||
static void sign (gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input,
|
||||
ELG_secret_key *skey);
|
||||
static int verify (gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input,
|
||||
ELG_public_key *pkey);
|
||||
|
||||
|
||||
static void (*progress_cb) (void *, const char *, int, int, int);
|
||||
static void *progress_cb_data;
|
||||
|
||||
void
|
||||
_gcry_register_pk_elg_progress (void (*cb) (void *, const char *,
|
||||
int, int, int),
|
||||
void *cb_data)
|
||||
{
|
||||
progress_cb = cb;
|
||||
progress_cb_data = cb_data;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
progress (int c)
|
||||
{
|
||||
if (progress_cb)
|
||||
progress_cb (progress_cb_data, "pk_elg", c, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Michael Wiener's table on subgroup sizes to match field sizes.
|
||||
* (floating around somewhere, probably based on the paper from
|
||||
* Eurocrypt 96, page 332)
|
||||
*/
|
||||
static unsigned int
|
||||
wiener_map( unsigned int n )
|
||||
{
|
||||
static struct { unsigned int p_n, q_n; } t[] =
|
||||
{ /* p q attack cost */
|
||||
{ 512, 119 }, /* 9 x 10^17 */
|
||||
{ 768, 145 }, /* 6 x 10^21 */
|
||||
{ 1024, 165 }, /* 7 x 10^24 */
|
||||
{ 1280, 183 }, /* 3 x 10^27 */
|
||||
{ 1536, 198 }, /* 7 x 10^29 */
|
||||
{ 1792, 212 }, /* 9 x 10^31 */
|
||||
{ 2048, 225 }, /* 8 x 10^33 */
|
||||
{ 2304, 237 }, /* 5 x 10^35 */
|
||||
{ 2560, 249 }, /* 3 x 10^37 */
|
||||
{ 2816, 259 }, /* 1 x 10^39 */
|
||||
{ 3072, 269 }, /* 3 x 10^40 */
|
||||
{ 3328, 279 }, /* 8 x 10^41 */
|
||||
{ 3584, 288 }, /* 2 x 10^43 */
|
||||
{ 3840, 296 }, /* 4 x 10^44 */
|
||||
{ 4096, 305 }, /* 7 x 10^45 */
|
||||
{ 4352, 313 }, /* 1 x 10^47 */
|
||||
{ 4608, 320 }, /* 2 x 10^48 */
|
||||
{ 4864, 328 }, /* 2 x 10^49 */
|
||||
{ 5120, 335 }, /* 3 x 10^50 */
|
||||
{ 0, 0 }
|
||||
};
|
||||
int i;
|
||||
|
||||
for(i=0; t[i].p_n; i++ )
|
||||
{
|
||||
if( n <= t[i].p_n )
|
||||
return t[i].q_n;
|
||||
}
|
||||
/* Not in table - use an arbitrary high number. */
|
||||
return n / 8 + 200;
|
||||
}
|
||||
|
||||
static int
|
||||
test_keys ( ELG_secret_key *sk, unsigned int nbits, int nodie )
|
||||
{
|
||||
ELG_public_key pk;
|
||||
gcry_mpi_t test = gcry_mpi_new ( 0 );
|
||||
gcry_mpi_t out1_a = gcry_mpi_new ( nbits );
|
||||
gcry_mpi_t out1_b = gcry_mpi_new ( nbits );
|
||||
gcry_mpi_t out2 = gcry_mpi_new ( nbits );
|
||||
int failed = 0;
|
||||
|
||||
pk.p = sk->p;
|
||||
pk.g = sk->g;
|
||||
pk.y = sk->y;
|
||||
|
||||
gcry_mpi_randomize ( test, nbits, GCRY_WEAK_RANDOM );
|
||||
|
||||
do_encrypt ( out1_a, out1_b, test, &pk );
|
||||
decrypt ( out2, out1_a, out1_b, sk );
|
||||
if ( mpi_cmp( test, out2 ) )
|
||||
failed |= 1;
|
||||
|
||||
sign ( out1_a, out1_b, test, sk );
|
||||
if ( !verify( out1_a, out1_b, test, &pk ) )
|
||||
failed |= 2;
|
||||
|
||||
gcry_mpi_release ( test );
|
||||
gcry_mpi_release ( out1_a );
|
||||
gcry_mpi_release ( out1_b );
|
||||
gcry_mpi_release ( out2 );
|
||||
|
||||
if (failed && !nodie)
|
||||
log_fatal ("Elgamal test key for %s %s failed\n",
|
||||
(failed & 1)? "encrypt+decrypt":"",
|
||||
(failed & 2)? "sign+verify":"");
|
||||
if (failed && DBG_CIPHER)
|
||||
log_debug ("Elgamal test key for %s %s failed\n",
|
||||
(failed & 1)? "encrypt+decrypt":"",
|
||||
(failed & 2)? "sign+verify":"");
|
||||
|
||||
return failed;
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Generate a random secret exponent k from prime p, so that k is
|
||||
* relatively prime to p-1. With SMALL_K set, k will be selected for
|
||||
* better encryption performance - this must never be used signing!
|
||||
*/
|
||||
static gcry_mpi_t
|
||||
gen_k( gcry_mpi_t p, int small_k )
|
||||
{
|
||||
gcry_mpi_t k = mpi_alloc_secure( 0 );
|
||||
gcry_mpi_t temp = mpi_alloc( mpi_get_nlimbs(p) );
|
||||
gcry_mpi_t p_1 = mpi_copy(p);
|
||||
unsigned int orig_nbits = mpi_get_nbits(p);
|
||||
unsigned int nbits, nbytes;
|
||||
char *rndbuf = NULL;
|
||||
|
||||
if (small_k)
|
||||
{
|
||||
/* Using a k much lesser than p is sufficient for encryption and
|
||||
* it greatly improves the encryption performance. We use
|
||||
* Wiener's table and add a large safety margin. */
|
||||
nbits = wiener_map( orig_nbits ) * 3 / 2;
|
||||
if( nbits >= orig_nbits )
|
||||
BUG();
|
||||
}
|
||||
else
|
||||
nbits = orig_nbits;
|
||||
|
||||
|
||||
nbytes = (nbits+7)/8;
|
||||
if( DBG_CIPHER )
|
||||
log_debug("choosing a random k ");
|
||||
mpi_sub_ui( p_1, p, 1);
|
||||
for(;;)
|
||||
{
|
||||
if( !rndbuf || nbits < 32 )
|
||||
{
|
||||
gcry_free(rndbuf);
|
||||
rndbuf = gcry_random_bytes_secure( nbytes, GCRY_STRONG_RANDOM );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Change only some of the higher bits. We could improve
|
||||
this by directly requesting more memory at the first call
|
||||
to get_random_bytes() and use this the here maybe it is
|
||||
easier to do this directly in random.c Anyway, it is
|
||||
highly inlikely that we will ever reach this code. */
|
||||
char *pp = gcry_random_bytes_secure( 4, GCRY_STRONG_RANDOM );
|
||||
memcpy( rndbuf, pp, 4 );
|
||||
gcry_free(pp);
|
||||
}
|
||||
_gcry_mpi_set_buffer( k, rndbuf, nbytes, 0 );
|
||||
|
||||
for(;;)
|
||||
{
|
||||
if( !(mpi_cmp( k, p_1 ) < 0) ) /* check: k < (p-1) */
|
||||
{
|
||||
if( DBG_CIPHER )
|
||||
progress('+');
|
||||
break; /* no */
|
||||
}
|
||||
if( !(mpi_cmp_ui( k, 0 ) > 0) ) /* check: k > 0 */
|
||||
{
|
||||
if( DBG_CIPHER )
|
||||
progress('-');
|
||||
break; /* no */
|
||||
}
|
||||
if (gcry_mpi_gcd( temp, k, p_1 ))
|
||||
goto found; /* okay, k is relative prime to (p-1) */
|
||||
mpi_add_ui( k, k, 1 );
|
||||
if( DBG_CIPHER )
|
||||
progress('.');
|
||||
}
|
||||
}
|
||||
found:
|
||||
gcry_free(rndbuf);
|
||||
if( DBG_CIPHER )
|
||||
progress('\n');
|
||||
mpi_free(p_1);
|
||||
mpi_free(temp);
|
||||
|
||||
return k;
|
||||
}
|
||||
|
||||
/****************
|
||||
* Generate a key pair with a key of size NBITS
|
||||
* Returns: 2 structures filled with all needed values
|
||||
* and an array with n-1 factors of (p-1)
|
||||
*/
|
||||
static void
|
||||
generate ( ELG_secret_key *sk, unsigned int nbits, gcry_mpi_t **ret_factors )
|
||||
{
|
||||
gcry_mpi_t p; /* the prime */
|
||||
gcry_mpi_t p_min1;
|
||||
gcry_mpi_t g;
|
||||
gcry_mpi_t x; /* the secret exponent */
|
||||
gcry_mpi_t y;
|
||||
unsigned int qbits;
|
||||
unsigned int xbits;
|
||||
byte *rndbuf;
|
||||
|
||||
p_min1 = gcry_mpi_new ( nbits );
|
||||
qbits = wiener_map( nbits );
|
||||
if( qbits & 1 ) /* better have a even one */
|
||||
qbits++;
|
||||
g = mpi_alloc(1);
|
||||
p = _gcry_generate_elg_prime( 0, nbits, qbits, g, ret_factors );
|
||||
mpi_sub_ui(p_min1, p, 1);
|
||||
|
||||
|
||||
/* Select a random number which has these properties:
|
||||
* 0 < x < p-1
|
||||
* This must be a very good random number because this is the
|
||||
* secret part. The prime is public and may be shared anyway,
|
||||
* so a random generator level of 1 is used for the prime.
|
||||
*
|
||||
* I don't see a reason to have a x of about the same size
|
||||
* as the p. It should be sufficient to have one about the size
|
||||
* of q or the later used k plus a large safety margin. Decryption
|
||||
* will be much faster with such an x.
|
||||
*/
|
||||
xbits = qbits * 3 / 2;
|
||||
if( xbits >= nbits )
|
||||
BUG();
|
||||
x = gcry_mpi_snew ( xbits );
|
||||
if( DBG_CIPHER )
|
||||
log_debug("choosing a random x of size %u", xbits );
|
||||
rndbuf = NULL;
|
||||
do
|
||||
{
|
||||
if( DBG_CIPHER )
|
||||
progress('.');
|
||||
if( rndbuf )
|
||||
{ /* Change only some of the higher bits */
|
||||
if( xbits < 16 ) /* should never happen ... */
|
||||
{
|
||||
gcry_free(rndbuf);
|
||||
rndbuf = gcry_random_bytes_secure( (xbits+7)/8,
|
||||
GCRY_VERY_STRONG_RANDOM );
|
||||
}
|
||||
else
|
||||
{
|
||||
char *r = gcry_random_bytes_secure( 2,
|
||||
GCRY_VERY_STRONG_RANDOM );
|
||||
memcpy(rndbuf, r, 2 );
|
||||
gcry_free(r);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rndbuf = gcry_random_bytes_secure( (xbits+7)/8,
|
||||
GCRY_VERY_STRONG_RANDOM );
|
||||
}
|
||||
_gcry_mpi_set_buffer( x, rndbuf, (xbits+7)/8, 0 );
|
||||
mpi_clear_highbit( x, xbits+1 );
|
||||
}
|
||||
while( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, p_min1 )<0 ) );
|
||||
gcry_free(rndbuf);
|
||||
|
||||
y = gcry_mpi_new (nbits);
|
||||
gcry_mpi_powm( y, g, x, p );
|
||||
|
||||
if( DBG_CIPHER )
|
||||
{
|
||||
progress('\n');
|
||||
log_mpidump("elg p= ", p );
|
||||
log_mpidump("elg g= ", g );
|
||||
log_mpidump("elg y= ", y );
|
||||
log_mpidump("elg x= ", x );
|
||||
}
|
||||
|
||||
/* Copy the stuff to the key structures */
|
||||
sk->p = p;
|
||||
sk->g = g;
|
||||
sk->y = y;
|
||||
sk->x = x;
|
||||
|
||||
gcry_mpi_release ( p_min1 );
|
||||
|
||||
/* Now we can test our keys (this should never fail!) */
|
||||
test_keys ( sk, nbits - 64, 0 );
|
||||
}
|
||||
|
||||
|
||||
/* Generate a key pair with a key of size NBITS not using a random
|
||||
value for the secret key but the one given as X. This is useful to
|
||||
implement a passphrase based decryption for a public key based
|
||||
encryption. It has appliactions in backup systems.
|
||||
|
||||
Returns: A structure filled with all needed values and an array
|
||||
with n-1 factors of (p-1). */
|
||||
static gcry_err_code_t
|
||||
generate_using_x (ELG_secret_key *sk, unsigned int nbits, gcry_mpi_t x,
|
||||
gcry_mpi_t **ret_factors )
|
||||
{
|
||||
gcry_mpi_t p; /* The prime. */
|
||||
gcry_mpi_t p_min1; /* The prime minus 1. */
|
||||
gcry_mpi_t g; /* The generator. */
|
||||
gcry_mpi_t y; /* g^x mod p. */
|
||||
unsigned int qbits;
|
||||
unsigned int xbits;
|
||||
|
||||
sk->p = NULL;
|
||||
sk->g = NULL;
|
||||
sk->y = NULL;
|
||||
sk->x = NULL;
|
||||
|
||||
/* Do a quick check to see whether X is suitable. */
|
||||
xbits = mpi_get_nbits (x);
|
||||
if ( xbits < 64 || xbits >= nbits )
|
||||
return GPG_ERR_INV_VALUE;
|
||||
|
||||
p_min1 = gcry_mpi_new ( nbits );
|
||||
qbits = wiener_map ( nbits );
|
||||
if ( (qbits & 1) ) /* Better have an even one. */
|
||||
qbits++;
|
||||
g = mpi_alloc (1);
|
||||
p = _gcry_generate_elg_prime ( 0, nbits, qbits, g, ret_factors );
|
||||
mpi_sub_ui (p_min1, p, 1);
|
||||
|
||||
if (DBG_CIPHER)
|
||||
log_debug ("using a supplied x of size %u", xbits );
|
||||
if ( !(mpi_cmp_ui ( x, 0 ) > 0 && mpi_cmp ( x, p_min1 ) <0 ) )
|
||||
{
|
||||
gcry_mpi_release ( p_min1 );
|
||||
gcry_mpi_release ( p );
|
||||
gcry_mpi_release ( g );
|
||||
return GPG_ERR_INV_VALUE;
|
||||
}
|
||||
|
||||
y = gcry_mpi_new (nbits);
|
||||
gcry_mpi_powm ( y, g, x, p );
|
||||
|
||||
if ( DBG_CIPHER )
|
||||
{
|
||||
progress ('\n');
|
||||
log_mpidump ("elg p= ", p );
|
||||
log_mpidump ("elg g= ", g );
|
||||
log_mpidump ("elg y= ", y );
|
||||
log_mpidump ("elg x= ", x );
|
||||
}
|
||||
|
||||
/* Copy the stuff to the key structures */
|
||||
sk->p = p;
|
||||
sk->g = g;
|
||||
sk->y = y;
|
||||
sk->x = gcry_mpi_copy (x);
|
||||
|
||||
gcry_mpi_release ( p_min1 );
|
||||
|
||||
/* Now we can test our keys. */
|
||||
if ( test_keys ( sk, nbits - 64, 1 ) )
|
||||
{
|
||||
gcry_mpi_release ( sk->p ); sk->p = NULL;
|
||||
gcry_mpi_release ( sk->g ); sk->g = NULL;
|
||||
gcry_mpi_release ( sk->y ); sk->y = NULL;
|
||||
gcry_mpi_release ( sk->x ); sk->x = NULL;
|
||||
return GPG_ERR_BAD_SECKEY;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Test whether the secret key is valid.
|
||||
* Returns: if this is a valid key.
|
||||
*/
|
||||
static int
|
||||
check_secret_key( ELG_secret_key *sk )
|
||||
{
|
||||
int rc;
|
||||
gcry_mpi_t y = mpi_alloc( mpi_get_nlimbs(sk->y) );
|
||||
|
||||
gcry_mpi_powm( y, sk->g, sk->x, sk->p );
|
||||
rc = !mpi_cmp( y, sk->y );
|
||||
mpi_free( y );
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
do_encrypt(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_public_key *pkey )
|
||||
{
|
||||
gcry_mpi_t k;
|
||||
|
||||
/* Note: maybe we should change the interface, so that it
|
||||
* is possible to check that input is < p and return an
|
||||
* error code.
|
||||
*/
|
||||
|
||||
k = gen_k( pkey->p, 1 );
|
||||
gcry_mpi_powm( a, pkey->g, k, pkey->p );
|
||||
/* b = (y^k * input) mod p
|
||||
* = ((y^k mod p) * (input mod p)) mod p
|
||||
* and because input is < p
|
||||
* = ((y^k mod p) * input) mod p
|
||||
*/
|
||||
gcry_mpi_powm( b, pkey->y, k, pkey->p );
|
||||
gcry_mpi_mulm( b, b, input, pkey->p );
|
||||
#if 0
|
||||
if( DBG_CIPHER )
|
||||
{
|
||||
log_mpidump("elg encrypted y= ", pkey->y);
|
||||
log_mpidump("elg encrypted p= ", pkey->p);
|
||||
log_mpidump("elg encrypted k= ", k);
|
||||
log_mpidump("elg encrypted M= ", input);
|
||||
log_mpidump("elg encrypted a= ", a);
|
||||
log_mpidump("elg encrypted b= ", b);
|
||||
}
|
||||
#endif
|
||||
mpi_free(k);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void
|
||||
decrypt(gcry_mpi_t output, gcry_mpi_t a, gcry_mpi_t b, ELG_secret_key *skey )
|
||||
{
|
||||
gcry_mpi_t t1 = mpi_alloc_secure( mpi_get_nlimbs( skey->p ) );
|
||||
|
||||
/* output = b/(a^x) mod p */
|
||||
gcry_mpi_powm( t1, a, skey->x, skey->p );
|
||||
mpi_invm( t1, t1, skey->p );
|
||||
mpi_mulm( output, b, t1, skey->p );
|
||||
#if 0
|
||||
if( DBG_CIPHER )
|
||||
{
|
||||
log_mpidump("elg decrypted x= ", skey->x);
|
||||
log_mpidump("elg decrypted p= ", skey->p);
|
||||
log_mpidump("elg decrypted a= ", a);
|
||||
log_mpidump("elg decrypted b= ", b);
|
||||
log_mpidump("elg decrypted M= ", output);
|
||||
}
|
||||
#endif
|
||||
mpi_free(t1);
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Make an Elgamal signature out of INPUT
|
||||
*/
|
||||
|
||||
static void
|
||||
sign(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_secret_key *skey )
|
||||
{
|
||||
gcry_mpi_t k;
|
||||
gcry_mpi_t t = mpi_alloc( mpi_get_nlimbs(a) );
|
||||
gcry_mpi_t inv = mpi_alloc( mpi_get_nlimbs(a) );
|
||||
gcry_mpi_t p_1 = mpi_copy(skey->p);
|
||||
|
||||
/*
|
||||
* b = (t * inv) mod (p-1)
|
||||
* b = (t * inv(k,(p-1),(p-1)) mod (p-1)
|
||||
* b = (((M-x*a) mod (p-1)) * inv(k,(p-1),(p-1))) mod (p-1)
|
||||
*
|
||||
*/
|
||||
mpi_sub_ui(p_1, p_1, 1);
|
||||
k = gen_k( skey->p, 0 /* no small K ! */ );
|
||||
gcry_mpi_powm( a, skey->g, k, skey->p );
|
||||
mpi_mul(t, skey->x, a );
|
||||
mpi_subm(t, input, t, p_1 );
|
||||
mpi_invm(inv, k, p_1 );
|
||||
mpi_mulm(b, t, inv, p_1 );
|
||||
|
||||
#if 0
|
||||
if( DBG_CIPHER )
|
||||
{
|
||||
log_mpidump("elg sign p= ", skey->p);
|
||||
log_mpidump("elg sign g= ", skey->g);
|
||||
log_mpidump("elg sign y= ", skey->y);
|
||||
log_mpidump("elg sign x= ", skey->x);
|
||||
log_mpidump("elg sign k= ", k);
|
||||
log_mpidump("elg sign M= ", input);
|
||||
log_mpidump("elg sign a= ", a);
|
||||
log_mpidump("elg sign b= ", b);
|
||||
}
|
||||
#endif
|
||||
mpi_free(k);
|
||||
mpi_free(t);
|
||||
mpi_free(inv);
|
||||
mpi_free(p_1);
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Returns true if the signature composed of A and B is valid.
|
||||
*/
|
||||
static int
|
||||
verify(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_public_key *pkey )
|
||||
{
|
||||
int rc;
|
||||
gcry_mpi_t t1;
|
||||
gcry_mpi_t t2;
|
||||
gcry_mpi_t base[4];
|
||||
gcry_mpi_t ex[4];
|
||||
|
||||
if( !(mpi_cmp_ui( a, 0 ) > 0 && mpi_cmp( a, pkey->p ) < 0) )
|
||||
return 0; /* assertion 0 < a < p failed */
|
||||
|
||||
t1 = mpi_alloc( mpi_get_nlimbs(a) );
|
||||
t2 = mpi_alloc( mpi_get_nlimbs(a) );
|
||||
|
||||
#if 0
|
||||
/* t1 = (y^a mod p) * (a^b mod p) mod p */
|
||||
gcry_mpi_powm( t1, pkey->y, a, pkey->p );
|
||||
gcry_mpi_powm( t2, a, b, pkey->p );
|
||||
mpi_mulm( t1, t1, t2, pkey->p );
|
||||
|
||||
/* t2 = g ^ input mod p */
|
||||
gcry_mpi_powm( t2, pkey->g, input, pkey->p );
|
||||
|
||||
rc = !mpi_cmp( t1, t2 );
|
||||
#elif 0
|
||||
/* t1 = (y^a mod p) * (a^b mod p) mod p */
|
||||
base[0] = pkey->y; ex[0] = a;
|
||||
base[1] = a; ex[1] = b;
|
||||
base[2] = NULL; ex[2] = NULL;
|
||||
mpi_mulpowm( t1, base, ex, pkey->p );
|
||||
|
||||
/* t2 = g ^ input mod p */
|
||||
gcry_mpi_powm( t2, pkey->g, input, pkey->p );
|
||||
|
||||
rc = !mpi_cmp( t1, t2 );
|
||||
#else
|
||||
/* t1 = g ^ - input * y ^ a * a ^ b mod p */
|
||||
mpi_invm(t2, pkey->g, pkey->p );
|
||||
base[0] = t2 ; ex[0] = input;
|
||||
base[1] = pkey->y; ex[1] = a;
|
||||
base[2] = a; ex[2] = b;
|
||||
base[3] = NULL; ex[3] = NULL;
|
||||
mpi_mulpowm( t1, base, ex, pkey->p );
|
||||
rc = !mpi_cmp_ui( t1, 1 );
|
||||
|
||||
#endif
|
||||
|
||||
mpi_free(t1);
|
||||
mpi_free(t2);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
************** interface ******************
|
||||
*********************************************/
|
||||
|
||||
static gpg_err_code_t
|
||||
elg_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
|
||||
const gcry_sexp_t genparms,
|
||||
gcry_mpi_t *skey, gcry_mpi_t **retfactors,
|
||||
gcry_sexp_t *r_extrainfo)
|
||||
{
|
||||
gpg_err_code_t ec;
|
||||
ELG_secret_key sk;
|
||||
gcry_mpi_t xvalue = NULL;
|
||||
gcry_sexp_t l1;
|
||||
|
||||
(void)algo;
|
||||
(void)evalue;
|
||||
(void)r_extrainfo;
|
||||
|
||||
if (genparms)
|
||||
{
|
||||
/* Parse the optional xvalue element. */
|
||||
l1 = gcry_sexp_find_token (genparms, "xvalue", 0);
|
||||
if (l1)
|
||||
{
|
||||
xvalue = gcry_sexp_nth_mpi (l1, 1, 0);
|
||||
gcry_sexp_release (l1);
|
||||
if (!xvalue)
|
||||
return GPG_ERR_BAD_MPI;
|
||||
}
|
||||
}
|
||||
|
||||
if (xvalue)
|
||||
ec = generate_using_x (&sk, nbits, xvalue, retfactors);
|
||||
else
|
||||
{
|
||||
generate (&sk, nbits, retfactors);
|
||||
ec = 0;
|
||||
}
|
||||
|
||||
skey[0] = sk.p;
|
||||
skey[1] = sk.g;
|
||||
skey[2] = sk.y;
|
||||
skey[3] = sk.x;
|
||||
|
||||
return ec;
|
||||
}
|
||||
|
||||
|
||||
static gcry_err_code_t
|
||||
elg_generate (int algo, unsigned int nbits, unsigned long evalue,
|
||||
gcry_mpi_t *skey, gcry_mpi_t **retfactors)
|
||||
{
|
||||
ELG_secret_key sk;
|
||||
|
||||
(void)algo;
|
||||
(void)evalue;
|
||||
|
||||
generate (&sk, nbits, retfactors);
|
||||
skey[0] = sk.p;
|
||||
skey[1] = sk.g;
|
||||
skey[2] = sk.y;
|
||||
skey[3] = sk.x;
|
||||
|
||||
return GPG_ERR_NO_ERROR;
|
||||
}
|
||||
|
||||
|
||||
static gcry_err_code_t
|
||||
elg_check_secret_key (int algo, gcry_mpi_t *skey)
|
||||
{
|
||||
gcry_err_code_t err = GPG_ERR_NO_ERROR;
|
||||
ELG_secret_key sk;
|
||||
|
||||
(void)algo;
|
||||
|
||||
if ((! skey[0]) || (! skey[1]) || (! skey[2]) || (! skey[3]))
|
||||
err = GPG_ERR_BAD_MPI;
|
||||
else
|
||||
{
|
||||
sk.p = skey[0];
|
||||
sk.g = skey[1];
|
||||
sk.y = skey[2];
|
||||
sk.x = skey[3];
|
||||
|
||||
if (! check_secret_key (&sk))
|
||||
err = GPG_ERR_BAD_SECKEY;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
static gcry_err_code_t
|
||||
elg_encrypt (int algo, gcry_mpi_t *resarr,
|
||||
gcry_mpi_t data, gcry_mpi_t *pkey, int flags)
|
||||
{
|
||||
gcry_err_code_t err = GPG_ERR_NO_ERROR;
|
||||
ELG_public_key pk;
|
||||
|
||||
(void)algo;
|
||||
(void)flags;
|
||||
|
||||
if ((! data) || (! pkey[0]) || (! pkey[1]) || (! pkey[2]))
|
||||
err = GPG_ERR_BAD_MPI;
|
||||
else
|
||||
{
|
||||
pk.p = pkey[0];
|
||||
pk.g = pkey[1];
|
||||
pk.y = pkey[2];
|
||||
resarr[0] = mpi_alloc (mpi_get_nlimbs (pk.p));
|
||||
resarr[1] = mpi_alloc (mpi_get_nlimbs (pk.p));
|
||||
do_encrypt (resarr[0], resarr[1], data, &pk);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
static gcry_err_code_t
|
||||
elg_decrypt (int algo, gcry_mpi_t *result,
|
||||
gcry_mpi_t *data, gcry_mpi_t *skey, int flags)
|
||||
{
|
||||
gcry_err_code_t err = GPG_ERR_NO_ERROR;
|
||||
ELG_secret_key sk;
|
||||
|
||||
(void)algo;
|
||||
(void)flags;
|
||||
|
||||
if ((! data[0]) || (! data[1])
|
||||
|| (! skey[0]) || (! skey[1]) || (! skey[2]) || (! skey[3]))
|
||||
err = GPG_ERR_BAD_MPI;
|
||||
else
|
||||
{
|
||||
sk.p = skey[0];
|
||||
sk.g = skey[1];
|
||||
sk.y = skey[2];
|
||||
sk.x = skey[3];
|
||||
*result = mpi_alloc_secure (mpi_get_nlimbs (sk.p));
|
||||
decrypt (*result, data[0], data[1], &sk);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
static gcry_err_code_t
|
||||
elg_sign (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *skey)
|
||||
{
|
||||
gcry_err_code_t err = GPG_ERR_NO_ERROR;
|
||||
ELG_secret_key sk;
|
||||
|
||||
(void)algo;
|
||||
|
||||
if ((! data)
|
||||
|| (! skey[0]) || (! skey[1]) || (! skey[2]) || (! skey[3]))
|
||||
err = GPG_ERR_BAD_MPI;
|
||||
else
|
||||
{
|
||||
sk.p = skey[0];
|
||||
sk.g = skey[1];
|
||||
sk.y = skey[2];
|
||||
sk.x = skey[3];
|
||||
resarr[0] = mpi_alloc (mpi_get_nlimbs (sk.p));
|
||||
resarr[1] = mpi_alloc (mpi_get_nlimbs (sk.p));
|
||||
sign (resarr[0], resarr[1], data, &sk);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
static gcry_err_code_t
|
||||
elg_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey,
|
||||
int (*cmp) (void *, gcry_mpi_t), void *opaquev)
|
||||
{
|
||||
gcry_err_code_t err = GPG_ERR_NO_ERROR;
|
||||
ELG_public_key pk;
|
||||
|
||||
(void)algo;
|
||||
(void)cmp;
|
||||
(void)opaquev;
|
||||
|
||||
if ((! data[0]) || (! data[1]) || (! hash)
|
||||
|| (! pkey[0]) || (! pkey[1]) || (! pkey[2]))
|
||||
err = GPG_ERR_BAD_MPI;
|
||||
else
|
||||
{
|
||||
pk.p = pkey[0];
|
||||
pk.g = pkey[1];
|
||||
pk.y = pkey[2];
|
||||
if (! verify (data[0], data[1], hash, &pk))
|
||||
err = GPG_ERR_BAD_SIGNATURE;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
static unsigned int
|
||||
elg_get_nbits (int algo, gcry_mpi_t *pkey)
|
||||
{
|
||||
(void)algo;
|
||||
|
||||
return mpi_get_nbits (pkey[0]);
|
||||
}
|
||||
|
||||
|
||||
static const char *elg_names[] =
|
||||
{
|
||||
"elg",
|
||||
"openpgp-elg",
|
||||
"openpgp-elg-sig",
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
||||
gcry_pk_spec_t _gcry_pubkey_spec_elg =
|
||||
{
|
||||
"ELG", elg_names,
|
||||
"pgy", "pgyx", "ab", "rs", "pgy",
|
||||
GCRY_PK_USAGE_SIGN | GCRY_PK_USAGE_ENCR,
|
||||
elg_generate,
|
||||
elg_check_secret_key,
|
||||
elg_encrypt,
|
||||
elg_decrypt,
|
||||
elg_sign,
|
||||
elg_verify,
|
||||
elg_get_nbits
|
||||
};
|
||||
|
||||
pk_extra_spec_t _gcry_pubkey_extraspec_elg =
|
||||
{
|
||||
NULL,
|
||||
elg_generate_ext,
|
||||
NULL
|
||||
};
|
||||
|
94
lib/libgcrypt/cipher/hash-common.c
Normal file
94
lib/libgcrypt/cipher/hash-common.c
Normal file
|
@ -0,0 +1,94 @@
|
|||
/* hash-common.c - Common code for hash algorithms
|
||||
* Copyright (C) 2008 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of Libgcrypt.
|
||||
*
|
||||
* Libgcrypt is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Libgcrypt is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_STDINT_H
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
|
||||
#include "g10lib.h"
|
||||
#include "hash-common.h"
|
||||
|
||||
|
||||
/* Run a selftest for hash algorithm ALGO. If the resulting digest
|
||||
matches EXPECT/EXPECTLEN and everything else is fine as well,
|
||||
return NULL. If an error occurs, return a static text string
|
||||
describing the error.
|
||||
|
||||
DATAMODE controls what will be hashed according to this table:
|
||||
|
||||
0 - Hash the supplied DATA of DATALEN.
|
||||
1 - Hash one million times a 'a'. DATA and DATALEN are ignored.
|
||||
|
||||
*/
|
||||
const char *
|
||||
_gcry_hash_selftest_check_one (int algo,
|
||||
int datamode, const void *data, size_t datalen,
|
||||
const void *expect, size_t expectlen)
|
||||
{
|
||||
const char *result = NULL;
|
||||
gcry_error_t err = 0;
|
||||
gcry_md_hd_t hd;
|
||||
unsigned char *digest;
|
||||
|
||||
if (_gcry_md_get_algo_dlen (algo) != expectlen)
|
||||
return "digest size does not match expected size";
|
||||
|
||||
err = _gcry_md_open (&hd, algo, 0);
|
||||
if (err)
|
||||
return "gcry_md_open failed";
|
||||
|
||||
switch (datamode)
|
||||
{
|
||||
case 0:
|
||||
_gcry_md_write (hd, data, datalen);
|
||||
break;
|
||||
|
||||
case 1: /* Hash one million times an "a". */
|
||||
{
|
||||
char aaa[1000];
|
||||
int i;
|
||||
|
||||
/* Write in odd size chunks so that we test the buffering. */
|
||||
memset (aaa, 'a', 1000);
|
||||
for (i = 0; i < 1000; i++)
|
||||
_gcry_md_write (hd, aaa, 1000);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
result = "invalid DATAMODE";
|
||||
}
|
||||
|
||||
if (!result)
|
||||
{
|
||||
digest = _gcry_md_read (hd, algo);
|
||||
|
||||
if ( memcmp (digest, expect, expectlen) )
|
||||
result = "digest mismatch";
|
||||
}
|
||||
|
||||
_gcry_md_close (hd);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
33
lib/libgcrypt/cipher/hash-common.h
Normal file
33
lib/libgcrypt/cipher/hash-common.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/* hash-common.h - Declarations of common code for hash algorithms.
|
||||
* Copyright (C) 2008 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of Libgcrypt.
|
||||
*
|
||||
* Libgcrypt is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Libgcrypt is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef GCRY_HASH_COMMON_H
|
||||
#define GCRY_HASH_COMMON_H
|
||||
|
||||
|
||||
const char * _gcry_hash_selftest_check_one
|
||||
/**/ (int algo,
|
||||
int datamode, const void *data, size_t datalen,
|
||||
const void *expect, size_t expectlen);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /*GCRY_HASH_COMMON_H*/
|
732
lib/libgcrypt/cipher/hmac-tests.c
Normal file
732
lib/libgcrypt/cipher/hmac-tests.c
Normal file
|
@ -0,0 +1,732 @@
|
|||
/* hmac-tests.c - HMAC selftests.
|
||||
* Copyright (C) 2008 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of Libgcrypt.
|
||||
*
|
||||
* Libgcrypt is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Libgcrypt is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
Although algorithm self-tests are usually implemented in the module
|
||||
implementing the algorithm, the case for HMAC is different because
|
||||
HMAC is implemnetd on a higher level using a special feature of the
|
||||
gcry_md_ functions. It would be possible to do this also in the
|
||||
digest algorithm modules, but that would blow up the code too much
|
||||
and spread the hmac tests over several modules.
|
||||
|
||||
Thus we implement all HMAC tests in this test module and provide a
|
||||
function to run the tests.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_STDINT_H
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
|
||||
#include "g10lib.h"
|
||||
#include "cipher.h"
|
||||
#include "hmac256.h"
|
||||
|
||||
/* Check one HMAC with digest ALGO using the regualr HAMC
|
||||
API. (DATA,DATALEN) is the data to be MACed, (KEY,KEYLEN) the key
|
||||
and (EXPECT,EXPECTLEN) the expected result. Returns NULL on
|
||||
succdess or a string describing the failure. */
|
||||
static const char *
|
||||
check_one (int algo,
|
||||
const void *data, size_t datalen,
|
||||
const void *key, size_t keylen,
|
||||
const void *expect, size_t expectlen)
|
||||
{
|
||||
gcry_md_hd_t hd;
|
||||
const unsigned char *digest;
|
||||
|
||||
/* printf ("HMAC algo %d\n", algo); */
|
||||
if (_gcry_md_get_algo_dlen (algo) != expectlen)
|
||||
return "invalid tests data";
|
||||
if (_gcry_md_open (&hd, algo, GCRY_MD_FLAG_HMAC))
|
||||
return "gcry_md_open failed";
|
||||
if (_gcry_md_setkey (hd, key, keylen))
|
||||
{
|
||||
_gcry_md_close (hd);
|
||||
return "gcry_md_setkey failed";
|
||||
}
|
||||
_gcry_md_write (hd, data, datalen);
|
||||
digest = _gcry_md_read (hd, algo);
|
||||
if (!digest)
|
||||
{
|
||||
_gcry_md_close (hd);
|
||||
return "gcry_md_read failed";
|
||||
}
|
||||
if (memcmp (digest, expect, expectlen))
|
||||
{
|
||||
/* int i; */
|
||||
|
||||
/* fputs (" {", stdout); */
|
||||
/* for (i=0; i < expectlen-1; i++) */
|
||||
/* { */
|
||||
/* if (i && !(i % 8)) */
|
||||
/* fputs ("\n ", stdout); */
|
||||
/* printf (" 0x%02x,", digest[i]); */
|
||||
/* } */
|
||||
/* printf (" 0x%02x } },\n", digest[i]); */
|
||||
|
||||
_gcry_md_close (hd);
|
||||
return "does not match";
|
||||
}
|
||||
_gcry_md_close (hd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static gpg_err_code_t
|
||||
selftests_sha1 (int extended, selftest_report_func_t report)
|
||||
{
|
||||
const char *what;
|
||||
const char *errtxt;
|
||||
unsigned char key[128];
|
||||
int i, j;
|
||||
|
||||
what = "FIPS-198a, A.1";
|
||||
for (i=0; i < 64; i++)
|
||||
key[i] = i;
|
||||
errtxt = check_one (GCRY_MD_SHA1,
|
||||
"Sample #1", 9,
|
||||
key, 64,
|
||||
"\x4f\x4c\xa3\xd5\xd6\x8b\xa7\xcc\x0a\x12"
|
||||
"\x08\xc9\xc6\x1e\x9c\x5d\xa0\x40\x3c\x0a", 20);
|
||||
if (errtxt)
|
||||
goto failed;
|
||||
|
||||
if (extended)
|
||||
{
|
||||
what = "FIPS-198a, A.2";
|
||||
for (i=0, j=0x30; i < 20; i++)
|
||||
key[i] = j++;
|
||||
errtxt = check_one (GCRY_MD_SHA1,
|
||||
"Sample #2", 9,
|
||||
key, 20,
|
||||
"\x09\x22\xd3\x40\x5f\xaa\x3d\x19\x4f\x82"
|
||||
"\xa4\x58\x30\x73\x7d\x5c\xc6\xc7\x5d\x24", 20);
|
||||
if (errtxt)
|
||||
goto failed;
|
||||
|
||||
what = "FIPS-198a, A.3";
|
||||
for (i=0, j=0x50; i < 100; i++)
|
||||
key[i] = j++;
|
||||
errtxt = check_one (GCRY_MD_SHA1,
|
||||
"Sample #3", 9,
|
||||
key, 100,
|
||||
"\xbc\xf4\x1e\xab\x8b\xb2\xd8\x02\xf3\xd0"
|
||||
"\x5c\xaf\x7c\xb0\x92\xec\xf8\xd1\xa3\xaa", 20 );
|
||||
if (errtxt)
|
||||
goto failed;
|
||||
|
||||
what = "FIPS-198a, A.4";
|
||||
for (i=0, j=0x70; i < 49; i++)
|
||||
key[i] = j++;
|
||||
errtxt = check_one (GCRY_MD_SHA1,
|
||||
"Sample #4", 9,
|
||||
key, 49,
|
||||
"\x9e\xa8\x86\xef\xe2\x68\xdb\xec\xce\x42"
|
||||
"\x0c\x75\x24\xdf\x32\xe0\x75\x1a\x2a\x26", 20 );
|
||||
if (errtxt)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
return 0; /* Succeeded. */
|
||||
|
||||
failed:
|
||||
if (report)
|
||||
report ("hmac", GCRY_MD_SHA1, what, errtxt);
|
||||
return GPG_ERR_SELFTEST_FAILED;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static gpg_err_code_t
|
||||
selftests_sha224 (int extended, selftest_report_func_t report)
|
||||
{
|
||||
static struct
|
||||
{
|
||||
const char * const desc;
|
||||
const char * const data;
|
||||
const char * const key;
|
||||
const char expect[28];
|
||||
} tv[] =
|
||||
{
|
||||
{ "data-28 key-4",
|
||||
"what do ya want for nothing?",
|
||||
"Jefe",
|
||||
{ 0xa3, 0x0e, 0x01, 0x09, 0x8b, 0xc6, 0xdb, 0xbf,
|
||||
0x45, 0x69, 0x0f, 0x3a, 0x7e, 0x9e, 0x6d, 0x0f,
|
||||
0x8b, 0xbe, 0xa2, 0xa3, 0x9e, 0x61, 0x48, 0x00,
|
||||
0x8f, 0xd0, 0x5e, 0x44 } },
|
||||
|
||||
{ "data-9 key-20",
|
||||
"Hi There",
|
||||
"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
|
||||
"\x0b\x0b\x0b\x0b",
|
||||
{ 0x89, 0x6f, 0xb1, 0x12, 0x8a, 0xbb, 0xdf, 0x19,
|
||||
0x68, 0x32, 0x10, 0x7c, 0xd4, 0x9d, 0xf3, 0x3f,
|
||||
0x47, 0xb4, 0xb1, 0x16, 0x99, 0x12, 0xba, 0x4f,
|
||||
0x53, 0x68, 0x4b, 0x22 } },
|
||||
|
||||
{ "data-50 key-20",
|
||||
"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
|
||||
"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
|
||||
"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
|
||||
"\xdd\xdd",
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa",
|
||||
{ 0x7f, 0xb3, 0xcb, 0x35, 0x88, 0xc6, 0xc1, 0xf6,
|
||||
0xff, 0xa9, 0x69, 0x4d, 0x7d, 0x6a, 0xd2, 0x64,
|
||||
0x93, 0x65, 0xb0, 0xc1, 0xf6, 0x5d, 0x69, 0xd1,
|
||||
0xec, 0x83, 0x33, 0xea } },
|
||||
|
||||
{ "data-50 key-26",
|
||||
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
|
||||
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
|
||||
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
|
||||
"\xcd\xcd",
|
||||
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
|
||||
"\x11\x12\x13\x14\x15\x16\x17\x18\x19",
|
||||
{ 0x6c, 0x11, 0x50, 0x68, 0x74, 0x01, 0x3c, 0xac,
|
||||
0x6a, 0x2a, 0xbc, 0x1b, 0xb3, 0x82, 0x62, 0x7c,
|
||||
0xec, 0x6a, 0x90, 0xd8, 0x6e, 0xfc, 0x01, 0x2d,
|
||||
0xe7, 0xaf, 0xec, 0x5a } },
|
||||
|
||||
{ "data-54 key-131",
|
||||
"Test Using Larger Than Block-Size Key - Hash Key First",
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa",
|
||||
{ 0x95, 0xe9, 0xa0, 0xdb, 0x96, 0x20, 0x95, 0xad,
|
||||
0xae, 0xbe, 0x9b, 0x2d, 0x6f, 0x0d, 0xbc, 0xe2,
|
||||
0xd4, 0x99, 0xf1, 0x12, 0xf2, 0xd2, 0xb7, 0x27,
|
||||
0x3f, 0xa6, 0x87, 0x0e } },
|
||||
|
||||
{ "data-152 key-131",
|
||||
"This is a test using a larger than block-size key and a larger "
|
||||
"than block-size data. The key needs to be hashed before being "
|
||||
"used by the HMAC algorithm.",
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa",
|
||||
{ 0x3a, 0x85, 0x41, 0x66, 0xac, 0x5d, 0x9f, 0x02,
|
||||
0x3f, 0x54, 0xd5, 0x17, 0xd0, 0xb3, 0x9d, 0xbd,
|
||||
0x94, 0x67, 0x70, 0xdb, 0x9c, 0x2b, 0x95, 0xc9,
|
||||
0xf6, 0xf5, 0x65, 0xd1 } },
|
||||
|
||||
{ NULL }
|
||||
};
|
||||
const char *what;
|
||||
const char *errtxt;
|
||||
int tvidx;
|
||||
|
||||
for (tvidx=0; tv[tvidx].desc; tvidx++)
|
||||
{
|
||||
what = tv[tvidx].desc;
|
||||
errtxt = check_one (GCRY_MD_SHA224,
|
||||
tv[tvidx].data, strlen (tv[tvidx].data),
|
||||
tv[tvidx].key, strlen (tv[tvidx].key),
|
||||
tv[tvidx].expect, DIM (tv[tvidx].expect) );
|
||||
if (errtxt)
|
||||
goto failed;
|
||||
if (!extended)
|
||||
break;
|
||||
}
|
||||
|
||||
return 0; /* Succeeded. */
|
||||
|
||||
failed:
|
||||
if (report)
|
||||
report ("hmac", GCRY_MD_SHA224, what, errtxt);
|
||||
return GPG_ERR_SELFTEST_FAILED;
|
||||
}
|
||||
|
||||
|
||||
static gpg_err_code_t
|
||||
selftests_sha256 (int extended, selftest_report_func_t report)
|
||||
{
|
||||
static struct
|
||||
{
|
||||
const char * const desc;
|
||||
const char * const data;
|
||||
const char * const key;
|
||||
const char expect[32];
|
||||
} tv[] =
|
||||
{
|
||||
{ "data-28 key-4",
|
||||
"what do ya want for nothing?",
|
||||
"Jefe",
|
||||
{ 0x5b, 0xdc, 0xc1, 0x46, 0xbf, 0x60, 0x75, 0x4e,
|
||||
0x6a, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xc7,
|
||||
0x5a, 0x00, 0x3f, 0x08, 0x9d, 0x27, 0x39, 0x83,
|
||||
0x9d, 0xec, 0x58, 0xb9, 0x64, 0xec, 0x38, 0x43 } },
|
||||
|
||||
{ "data-9 key-20",
|
||||
"Hi There",
|
||||
"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
|
||||
"\x0b\x0b\x0b\x0b",
|
||||
{ 0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53,
|
||||
0x5c, 0xa8, 0xaf, 0xce, 0xaf, 0x0b, 0xf1, 0x2b,
|
||||
0x88, 0x1d, 0xc2, 0x00, 0xc9, 0x83, 0x3d, 0xa7,
|
||||
0x26, 0xe9, 0x37, 0x6c, 0x2e, 0x32, 0xcf, 0xf7 } },
|
||||
|
||||
{ "data-50 key-20",
|
||||
"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
|
||||
"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
|
||||
"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
|
||||
"\xdd\xdd",
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa",
|
||||
{ 0x77, 0x3e, 0xa9, 0x1e, 0x36, 0x80, 0x0e, 0x46,
|
||||
0x85, 0x4d, 0xb8, 0xeb, 0xd0, 0x91, 0x81, 0xa7,
|
||||
0x29, 0x59, 0x09, 0x8b, 0x3e, 0xf8, 0xc1, 0x22,
|
||||
0xd9, 0x63, 0x55, 0x14, 0xce, 0xd5, 0x65, 0xfe } },
|
||||
|
||||
{ "data-50 key-26",
|
||||
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
|
||||
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
|
||||
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
|
||||
"\xcd\xcd",
|
||||
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
|
||||
"\x11\x12\x13\x14\x15\x16\x17\x18\x19",
|
||||
{ 0x82, 0x55, 0x8a, 0x38, 0x9a, 0x44, 0x3c, 0x0e,
|
||||
0xa4, 0xcc, 0x81, 0x98, 0x99, 0xf2, 0x08, 0x3a,
|
||||
0x85, 0xf0, 0xfa, 0xa3, 0xe5, 0x78, 0xf8, 0x07,
|
||||
0x7a, 0x2e, 0x3f, 0xf4, 0x67, 0x29, 0x66, 0x5b } },
|
||||
|
||||
{ "data-54 key-131",
|
||||
"Test Using Larger Than Block-Size Key - Hash Key First",
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa",
|
||||
{ 0x60, 0xe4, 0x31, 0x59, 0x1e, 0xe0, 0xb6, 0x7f,
|
||||
0x0d, 0x8a, 0x26, 0xaa, 0xcb, 0xf5, 0xb7, 0x7f,
|
||||
0x8e, 0x0b, 0xc6, 0x21, 0x37, 0x28, 0xc5, 0x14,
|
||||
0x05, 0x46, 0x04, 0x0f, 0x0e, 0xe3, 0x7f, 0x54 } },
|
||||
|
||||
{ "data-152 key-131",
|
||||
"This is a test using a larger than block-size key and a larger "
|
||||
"than block-size data. The key needs to be hashed before being "
|
||||
"used by the HMAC algorithm.",
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa",
|
||||
{ 0x9b, 0x09, 0xff, 0xa7, 0x1b, 0x94, 0x2f, 0xcb,
|
||||
0x27, 0x63, 0x5f, 0xbc, 0xd5, 0xb0, 0xe9, 0x44,
|
||||
0xbf, 0xdc, 0x63, 0x64, 0x4f, 0x07, 0x13, 0x93,
|
||||
0x8a, 0x7f, 0x51, 0x53, 0x5c, 0x3a, 0x35, 0xe2 } },
|
||||
|
||||
{ NULL }
|
||||
};
|
||||
const char *what;
|
||||
const char *errtxt;
|
||||
int tvidx;
|
||||
|
||||
for (tvidx=0; tv[tvidx].desc; tvidx++)
|
||||
{
|
||||
hmac256_context_t hmachd;
|
||||
const unsigned char *digest;
|
||||
size_t dlen;
|
||||
|
||||
what = tv[tvidx].desc;
|
||||
errtxt = check_one (GCRY_MD_SHA256,
|
||||
tv[tvidx].data, strlen (tv[tvidx].data),
|
||||
tv[tvidx].key, strlen (tv[tvidx].key),
|
||||
tv[tvidx].expect, DIM (tv[tvidx].expect) );
|
||||
if (errtxt)
|
||||
goto failed;
|
||||
|
||||
hmachd = _gcry_hmac256_new (tv[tvidx].key, strlen (tv[tvidx].key));
|
||||
if (!hmachd)
|
||||
{
|
||||
errtxt = "_gcry_hmac256_new failed";
|
||||
goto failed;
|
||||
}
|
||||
_gcry_hmac256_update (hmachd, tv[tvidx].data, strlen (tv[tvidx].data));
|
||||
digest = _gcry_hmac256_finalize (hmachd, &dlen);
|
||||
if (!digest)
|
||||
{
|
||||
errtxt = "_gcry_hmac256_finalize failed";
|
||||
_gcry_hmac256_release (hmachd);
|
||||
goto failed;
|
||||
}
|
||||
if (dlen != DIM (tv[tvidx].expect)
|
||||
|| memcmp (digest, tv[tvidx].expect, DIM (tv[tvidx].expect)))
|
||||
{
|
||||
errtxt = "does not match in second implementation";
|
||||
_gcry_hmac256_release (hmachd);
|
||||
goto failed;
|
||||
}
|
||||
_gcry_hmac256_release (hmachd);
|
||||
|
||||
if (!extended)
|
||||
break;
|
||||
}
|
||||
|
||||
return 0; /* Succeeded. */
|
||||
|
||||
failed:
|
||||
if (report)
|
||||
report ("hmac", GCRY_MD_SHA256, what, errtxt);
|
||||
return GPG_ERR_SELFTEST_FAILED;
|
||||
}
|
||||
|
||||
|
||||
static gpg_err_code_t
|
||||
selftests_sha384 (int extended, selftest_report_func_t report)
|
||||
{
|
||||
static struct
|
||||
{
|
||||
const char * const desc;
|
||||
const char * const data;
|
||||
const char * const key;
|
||||
const char expect[48];
|
||||
} tv[] =
|
||||
{
|
||||
{ "data-28 key-4",
|
||||
"what do ya want for nothing?",
|
||||
"Jefe",
|
||||
{ 0xaf, 0x45, 0xd2, 0xe3, 0x76, 0x48, 0x40, 0x31,
|
||||
0x61, 0x7f, 0x78, 0xd2, 0xb5, 0x8a, 0x6b, 0x1b,
|
||||
0x9c, 0x7e, 0xf4, 0x64, 0xf5, 0xa0, 0x1b, 0x47,
|
||||
0xe4, 0x2e, 0xc3, 0x73, 0x63, 0x22, 0x44, 0x5e,
|
||||
0x8e, 0x22, 0x40, 0xca, 0x5e, 0x69, 0xe2, 0xc7,
|
||||
0x8b, 0x32, 0x39, 0xec, 0xfa, 0xb2, 0x16, 0x49 } },
|
||||
|
||||
{ "data-9 key-20",
|
||||
"Hi There",
|
||||
"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
|
||||
"\x0b\x0b\x0b\x0b",
|
||||
{ 0xaf, 0xd0, 0x39, 0x44, 0xd8, 0x48, 0x95, 0x62,
|
||||
0x6b, 0x08, 0x25, 0xf4, 0xab, 0x46, 0x90, 0x7f,
|
||||
0x15, 0xf9, 0xda, 0xdb, 0xe4, 0x10, 0x1e, 0xc6,
|
||||
0x82, 0xaa, 0x03, 0x4c, 0x7c, 0xeb, 0xc5, 0x9c,
|
||||
0xfa, 0xea, 0x9e, 0xa9, 0x07, 0x6e, 0xde, 0x7f,
|
||||
0x4a, 0xf1, 0x52, 0xe8, 0xb2, 0xfa, 0x9c, 0xb6 } },
|
||||
|
||||
{ "data-50 key-20",
|
||||
"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
|
||||
"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
|
||||
"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
|
||||
"\xdd\xdd",
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa",
|
||||
{ 0x88, 0x06, 0x26, 0x08, 0xd3, 0xe6, 0xad, 0x8a,
|
||||
0x0a, 0xa2, 0xac, 0xe0, 0x14, 0xc8, 0xa8, 0x6f,
|
||||
0x0a, 0xa6, 0x35, 0xd9, 0x47, 0xac, 0x9f, 0xeb,
|
||||
0xe8, 0x3e, 0xf4, 0xe5, 0x59, 0x66, 0x14, 0x4b,
|
||||
0x2a, 0x5a, 0xb3, 0x9d, 0xc1, 0x38, 0x14, 0xb9,
|
||||
0x4e, 0x3a, 0xb6, 0xe1, 0x01, 0xa3, 0x4f, 0x27 } },
|
||||
|
||||
{ "data-50 key-26",
|
||||
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
|
||||
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
|
||||
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
|
||||
"\xcd\xcd",
|
||||
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
|
||||
"\x11\x12\x13\x14\x15\x16\x17\x18\x19",
|
||||
{ 0x3e, 0x8a, 0x69, 0xb7, 0x78, 0x3c, 0x25, 0x85,
|
||||
0x19, 0x33, 0xab, 0x62, 0x90, 0xaf, 0x6c, 0xa7,
|
||||
0x7a, 0x99, 0x81, 0x48, 0x08, 0x50, 0x00, 0x9c,
|
||||
0xc5, 0x57, 0x7c, 0x6e, 0x1f, 0x57, 0x3b, 0x4e,
|
||||
0x68, 0x01, 0xdd, 0x23, 0xc4, 0xa7, 0xd6, 0x79,
|
||||
0xcc, 0xf8, 0xa3, 0x86, 0xc6, 0x74, 0xcf, 0xfb } },
|
||||
|
||||
{ "data-54 key-131",
|
||||
"Test Using Larger Than Block-Size Key - Hash Key First",
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa",
|
||||
{ 0x4e, 0xce, 0x08, 0x44, 0x85, 0x81, 0x3e, 0x90,
|
||||
0x88, 0xd2, 0xc6, 0x3a, 0x04, 0x1b, 0xc5, 0xb4,
|
||||
0x4f, 0x9e, 0xf1, 0x01, 0x2a, 0x2b, 0x58, 0x8f,
|
||||
0x3c, 0xd1, 0x1f, 0x05, 0x03, 0x3a, 0xc4, 0xc6,
|
||||
0x0c, 0x2e, 0xf6, 0xab, 0x40, 0x30, 0xfe, 0x82,
|
||||
0x96, 0x24, 0x8d, 0xf1, 0x63, 0xf4, 0x49, 0x52 } },
|
||||
|
||||
{ "data-152 key-131",
|
||||
"This is a test using a larger than block-size key and a larger "
|
||||
"than block-size data. The key needs to be hashed before being "
|
||||
"used by the HMAC algorithm.",
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa",
|
||||
{ 0x66, 0x17, 0x17, 0x8e, 0x94, 0x1f, 0x02, 0x0d,
|
||||
0x35, 0x1e, 0x2f, 0x25, 0x4e, 0x8f, 0xd3, 0x2c,
|
||||
0x60, 0x24, 0x20, 0xfe, 0xb0, 0xb8, 0xfb, 0x9a,
|
||||
0xdc, 0xce, 0xbb, 0x82, 0x46, 0x1e, 0x99, 0xc5,
|
||||
0xa6, 0x78, 0xcc, 0x31, 0xe7, 0x99, 0x17, 0x6d,
|
||||
0x38, 0x60, 0xe6, 0x11, 0x0c, 0x46, 0x52, 0x3e } },
|
||||
|
||||
{ NULL }
|
||||
};
|
||||
const char *what;
|
||||
const char *errtxt;
|
||||
int tvidx;
|
||||
|
||||
for (tvidx=0; tv[tvidx].desc; tvidx++)
|
||||
{
|
||||
what = tv[tvidx].desc;
|
||||
errtxt = check_one (GCRY_MD_SHA384,
|
||||
tv[tvidx].data, strlen (tv[tvidx].data),
|
||||
tv[tvidx].key, strlen (tv[tvidx].key),
|
||||
tv[tvidx].expect, DIM (tv[tvidx].expect) );
|
||||
if (errtxt)
|
||||
goto failed;
|
||||
if (!extended)
|
||||
break;
|
||||
}
|
||||
|
||||
return 0; /* Succeeded. */
|
||||
|
||||
failed:
|
||||
if (report)
|
||||
report ("hmac", GCRY_MD_SHA384, what, errtxt);
|
||||
return GPG_ERR_SELFTEST_FAILED;
|
||||
}
|
||||
|
||||
|
||||
static gpg_err_code_t
|
||||
selftests_sha512 (int extended, selftest_report_func_t report)
|
||||
{
|
||||
static struct
|
||||
{
|
||||
const char * const desc;
|
||||
const char * const data;
|
||||
const char * const key;
|
||||
const char expect[64];
|
||||
} tv[] =
|
||||
{
|
||||
{ "data-28 key-4",
|
||||
"what do ya want for nothing?",
|
||||
"Jefe",
|
||||
{ 0x16, 0x4b, 0x7a, 0x7b, 0xfc, 0xf8, 0x19, 0xe2,
|
||||
0xe3, 0x95, 0xfb, 0xe7, 0x3b, 0x56, 0xe0, 0xa3,
|
||||
0x87, 0xbd, 0x64, 0x22, 0x2e, 0x83, 0x1f, 0xd6,
|
||||
0x10, 0x27, 0x0c, 0xd7, 0xea, 0x25, 0x05, 0x54,
|
||||
0x97, 0x58, 0xbf, 0x75, 0xc0, 0x5a, 0x99, 0x4a,
|
||||
0x6d, 0x03, 0x4f, 0x65, 0xf8, 0xf0, 0xe6, 0xfd,
|
||||
0xca, 0xea, 0xb1, 0xa3, 0x4d, 0x4a, 0x6b, 0x4b,
|
||||
0x63, 0x6e, 0x07, 0x0a, 0x38, 0xbc, 0xe7, 0x37 } },
|
||||
|
||||
{ "data-9 key-20",
|
||||
"Hi There",
|
||||
"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
|
||||
"\x0b\x0b\x0b\x0b",
|
||||
{ 0x87, 0xaa, 0x7c, 0xde, 0xa5, 0xef, 0x61, 0x9d,
|
||||
0x4f, 0xf0, 0xb4, 0x24, 0x1a, 0x1d, 0x6c, 0xb0,
|
||||
0x23, 0x79, 0xf4, 0xe2, 0xce, 0x4e, 0xc2, 0x78,
|
||||
0x7a, 0xd0, 0xb3, 0x05, 0x45, 0xe1, 0x7c, 0xde,
|
||||
0xda, 0xa8, 0x33, 0xb7, 0xd6, 0xb8, 0xa7, 0x02,
|
||||
0x03, 0x8b, 0x27, 0x4e, 0xae, 0xa3, 0xf4, 0xe4,
|
||||
0xbe, 0x9d, 0x91, 0x4e, 0xeb, 0x61, 0xf1, 0x70,
|
||||
0x2e, 0x69, 0x6c, 0x20, 0x3a, 0x12, 0x68, 0x54 } },
|
||||
|
||||
{ "data-50 key-20",
|
||||
"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
|
||||
"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
|
||||
"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
|
||||
"\xdd\xdd",
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa",
|
||||
{ 0xfa, 0x73, 0xb0, 0x08, 0x9d, 0x56, 0xa2, 0x84,
|
||||
0xef, 0xb0, 0xf0, 0x75, 0x6c, 0x89, 0x0b, 0xe9,
|
||||
0xb1, 0xb5, 0xdb, 0xdd, 0x8e, 0xe8, 0x1a, 0x36,
|
||||
0x55, 0xf8, 0x3e, 0x33, 0xb2, 0x27, 0x9d, 0x39,
|
||||
0xbf, 0x3e, 0x84, 0x82, 0x79, 0xa7, 0x22, 0xc8,
|
||||
0x06, 0xb4, 0x85, 0xa4, 0x7e, 0x67, 0xc8, 0x07,
|
||||
0xb9, 0x46, 0xa3, 0x37, 0xbe, 0xe8, 0x94, 0x26,
|
||||
0x74, 0x27, 0x88, 0x59, 0xe1, 0x32, 0x92, 0xfb } },
|
||||
|
||||
{ "data-50 key-26",
|
||||
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
|
||||
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
|
||||
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
|
||||
"\xcd\xcd",
|
||||
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
|
||||
"\x11\x12\x13\x14\x15\x16\x17\x18\x19",
|
||||
{ 0xb0, 0xba, 0x46, 0x56, 0x37, 0x45, 0x8c, 0x69,
|
||||
0x90, 0xe5, 0xa8, 0xc5, 0xf6, 0x1d, 0x4a, 0xf7,
|
||||
0xe5, 0x76, 0xd9, 0x7f, 0xf9, 0x4b, 0x87, 0x2d,
|
||||
0xe7, 0x6f, 0x80, 0x50, 0x36, 0x1e, 0xe3, 0xdb,
|
||||
0xa9, 0x1c, 0xa5, 0xc1, 0x1a, 0xa2, 0x5e, 0xb4,
|
||||
0xd6, 0x79, 0x27, 0x5c, 0xc5, 0x78, 0x80, 0x63,
|
||||
0xa5, 0xf1, 0x97, 0x41, 0x12, 0x0c, 0x4f, 0x2d,
|
||||
0xe2, 0xad, 0xeb, 0xeb, 0x10, 0xa2, 0x98, 0xdd } },
|
||||
|
||||
{ "data-54 key-131",
|
||||
"Test Using Larger Than Block-Size Key - Hash Key First",
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa",
|
||||
{ 0x80, 0xb2, 0x42, 0x63, 0xc7, 0xc1, 0xa3, 0xeb,
|
||||
0xb7, 0x14, 0x93, 0xc1, 0xdd, 0x7b, 0xe8, 0xb4,
|
||||
0x9b, 0x46, 0xd1, 0xf4, 0x1b, 0x4a, 0xee, 0xc1,
|
||||
0x12, 0x1b, 0x01, 0x37, 0x83, 0xf8, 0xf3, 0x52,
|
||||
0x6b, 0x56, 0xd0, 0x37, 0xe0, 0x5f, 0x25, 0x98,
|
||||
0xbd, 0x0f, 0xd2, 0x21, 0x5d, 0x6a, 0x1e, 0x52,
|
||||
0x95, 0xe6, 0x4f, 0x73, 0xf6, 0x3f, 0x0a, 0xec,
|
||||
0x8b, 0x91, 0x5a, 0x98, 0x5d, 0x78, 0x65, 0x98 } },
|
||||
|
||||
{ "data-152 key-131",
|
||||
"This is a test using a larger than block-size key and a larger "
|
||||
"than block-size data. The key needs to be hashed before being "
|
||||
"used by the HMAC algorithm.",
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa",
|
||||
{ 0xe3, 0x7b, 0x6a, 0x77, 0x5d, 0xc8, 0x7d, 0xba,
|
||||
0xa4, 0xdf, 0xa9, 0xf9, 0x6e, 0x5e, 0x3f, 0xfd,
|
||||
0xde, 0xbd, 0x71, 0xf8, 0x86, 0x72, 0x89, 0x86,
|
||||
0x5d, 0xf5, 0xa3, 0x2d, 0x20, 0xcd, 0xc9, 0x44,
|
||||
0xb6, 0x02, 0x2c, 0xac, 0x3c, 0x49, 0x82, 0xb1,
|
||||
0x0d, 0x5e, 0xeb, 0x55, 0xc3, 0xe4, 0xde, 0x15,
|
||||
0x13, 0x46, 0x76, 0xfb, 0x6d, 0xe0, 0x44, 0x60,
|
||||
0x65, 0xc9, 0x74, 0x40, 0xfa, 0x8c, 0x6a, 0x58 } },
|
||||
|
||||
{ NULL }
|
||||
};
|
||||
const char *what;
|
||||
const char *errtxt;
|
||||
int tvidx;
|
||||
|
||||
for (tvidx=0; tv[tvidx].desc; tvidx++)
|
||||
{
|
||||
what = tv[tvidx].desc;
|
||||
errtxt = check_one (GCRY_MD_SHA512,
|
||||
tv[tvidx].data, strlen (tv[tvidx].data),
|
||||
tv[tvidx].key, strlen (tv[tvidx].key),
|
||||
tv[tvidx].expect, DIM (tv[tvidx].expect) );
|
||||
if (errtxt)
|
||||
goto failed;
|
||||
if (!extended)
|
||||
break;
|
||||
}
|
||||
|
||||
return 0; /* Succeeded. */
|
||||
|
||||
failed:
|
||||
if (report)
|
||||
report ("hmac", GCRY_MD_SHA512, what, errtxt);
|
||||
return GPG_ERR_SELFTEST_FAILED;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Run a full self-test for ALGO and return 0 on success. */
|
||||
static gpg_err_code_t
|
||||
run_selftests (int algo, int extended, selftest_report_func_t report)
|
||||
{
|
||||
gpg_err_code_t ec;
|
||||
|
||||
switch (algo)
|
||||
{
|
||||
case GCRY_MD_SHA1:
|
||||
ec = selftests_sha1 (extended, report);
|
||||
break;
|
||||
case GCRY_MD_SHA224:
|
||||
ec = selftests_sha224 (extended, report);
|
||||
break;
|
||||
case GCRY_MD_SHA256:
|
||||
ec = selftests_sha256 (extended, report);
|
||||
break;
|
||||
case GCRY_MD_SHA384:
|
||||
ec = selftests_sha384 (extended, report);
|
||||
break;
|
||||
case GCRY_MD_SHA512:
|
||||
ec = selftests_sha512 (extended, report);
|
||||
break;
|
||||
default:
|
||||
ec = GPG_ERR_DIGEST_ALGO;
|
||||
break;
|
||||
}
|
||||
return ec;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Run the selftests for HMAC with digest algorithm ALGO with optional
|
||||
reporting function REPORT. */
|
||||
gpg_error_t
|
||||
_gcry_hmac_selftest (int algo, int extended, selftest_report_func_t report)
|
||||
{
|
||||
gcry_err_code_t ec = 0;
|
||||
|
||||
if (!gcry_md_test_algo (algo))
|
||||
{
|
||||
ec = run_selftests (algo, extended, report);
|
||||
}
|
||||
else
|
||||
{
|
||||
ec = GPG_ERR_DIGEST_ALGO;
|
||||
if (report)
|
||||
report ("hmac", algo, "module", "algorithm not available");
|
||||
}
|
||||
return gpg_error (ec);
|
||||
}
|
1375
lib/libgcrypt/cipher/md.c
Normal file
1375
lib/libgcrypt/cipher/md.c
Normal file
File diff suppressed because it is too large
Load diff
328
lib/libgcrypt/cipher/md4.c
Normal file
328
lib/libgcrypt/cipher/md4.c
Normal file
|
@ -0,0 +1,328 @@
|
|||
/* md4.c - MD4 Message-Digest Algorithm
|
||||
* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of Libgcrypt.
|
||||
*
|
||||
* Libgcrypt is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Libgcrypt is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*
|
||||
* Based on md5.c in libgcrypt, but rewritten to compute md4 checksums
|
||||
* using a public domain md4 implementation with the following comments:
|
||||
*
|
||||
* Modified by Wei Dai from Andrew M. Kuchling's md4.c
|
||||
* The original code and all modifications are in the public domain.
|
||||
*
|
||||
* This is the original introductory comment:
|
||||
*
|
||||
* md4.c : MD4 hash algorithm.
|
||||
*
|
||||
* Part of the Python Cryptography Toolkit, version 1.1
|
||||
*
|
||||
* Distribute and use freely; there are no restrictions on further
|
||||
* dissemination and usage except those imposed by the laws of your
|
||||
* country of residence.
|
||||
*
|
||||
*/
|
||||
|
||||
/* MD4 test suite:
|
||||
* MD4 ("") = 31d6cfe0d16ae931b73c59d7e0c089c0
|
||||
* MD4 ("a") = bde52cb31de33e46245e05fbdbd6fb24
|
||||
* MD4 ("abc") = a448017aaf21d8525fc10ae87aa6729d
|
||||
* MD4 ("message digest") = d9130a8164549fe818874806e1c7014b
|
||||
* MD4 ("abcdefghijklmnopqrstuvwxyz") = d79e1c308aa5bbcdeea8ed63df412da9
|
||||
* MD4 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") =
|
||||
* 043f8582f241db351ce627e153e7f0e4
|
||||
* MD4 ("123456789012345678901234567890123456789012345678901234567890123456
|
||||
* 78901234567890") = e33b4ddc9c38f2199c3e7b164fcc0536
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "g10lib.h"
|
||||
#include "memory.h"
|
||||
#include "cipher.h"
|
||||
|
||||
#include "bithelp.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
u32 A,B,C,D; /* chaining variables */
|
||||
u32 nblocks;
|
||||
byte buf[64];
|
||||
int count;
|
||||
} MD4_CONTEXT;
|
||||
|
||||
|
||||
static void
|
||||
md4_init( void *context )
|
||||
{
|
||||
MD4_CONTEXT *ctx = context;
|
||||
|
||||
ctx->A = 0x67452301;
|
||||
ctx->B = 0xefcdab89;
|
||||
ctx->C = 0x98badcfe;
|
||||
ctx->D = 0x10325476;
|
||||
|
||||
ctx->nblocks = 0;
|
||||
ctx->count = 0;
|
||||
}
|
||||
|
||||
#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
|
||||
#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
|
||||
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
||||
|
||||
|
||||
/****************
|
||||
* transform 64 bytes
|
||||
*/
|
||||
static void
|
||||
transform ( MD4_CONTEXT *ctx, const unsigned char *data )
|
||||
{
|
||||
u32 in[16];
|
||||
register u32 A = ctx->A;
|
||||
register u32 B = ctx->B;
|
||||
register u32 C = ctx->C;
|
||||
register u32 D = ctx->D;
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
{
|
||||
int i;
|
||||
byte *p2, *p1;
|
||||
for(i=0, p1=data, p2=(byte*)in; i < 16; i++, p2 += 4 )
|
||||
{
|
||||
p2[3] = *p1++;
|
||||
p2[2] = *p1++;
|
||||
p2[1] = *p1++;
|
||||
p2[0] = *p1++;
|
||||
}
|
||||
}
|
||||
#else
|
||||
memcpy (in, data, 64);
|
||||
#endif
|
||||
|
||||
/* Round 1. */
|
||||
#define function(a,b,c,d,k,s) a=rol(a+F(b,c,d)+in[k],s);
|
||||
function(A,B,C,D, 0, 3);
|
||||
function(D,A,B,C, 1, 7);
|
||||
function(C,D,A,B, 2,11);
|
||||
function(B,C,D,A, 3,19);
|
||||
function(A,B,C,D, 4, 3);
|
||||
function(D,A,B,C, 5, 7);
|
||||
function(C,D,A,B, 6,11);
|
||||
function(B,C,D,A, 7,19);
|
||||
function(A,B,C,D, 8, 3);
|
||||
function(D,A,B,C, 9, 7);
|
||||
function(C,D,A,B,10,11);
|
||||
function(B,C,D,A,11,19);
|
||||
function(A,B,C,D,12, 3);
|
||||
function(D,A,B,C,13, 7);
|
||||
function(C,D,A,B,14,11);
|
||||
function(B,C,D,A,15,19);
|
||||
|
||||
#undef function
|
||||
|
||||
/* Round 2. */
|
||||
#define function(a,b,c,d,k,s) a=rol(a+G(b,c,d)+in[k]+0x5a827999,s);
|
||||
|
||||
function(A,B,C,D, 0, 3);
|
||||
function(D,A,B,C, 4, 5);
|
||||
function(C,D,A,B, 8, 9);
|
||||
function(B,C,D,A,12,13);
|
||||
function(A,B,C,D, 1, 3);
|
||||
function(D,A,B,C, 5, 5);
|
||||
function(C,D,A,B, 9, 9);
|
||||
function(B,C,D,A,13,13);
|
||||
function(A,B,C,D, 2, 3);
|
||||
function(D,A,B,C, 6, 5);
|
||||
function(C,D,A,B,10, 9);
|
||||
function(B,C,D,A,14,13);
|
||||
function(A,B,C,D, 3, 3);
|
||||
function(D,A,B,C, 7, 5);
|
||||
function(C,D,A,B,11, 9);
|
||||
function(B,C,D,A,15,13);
|
||||
|
||||
#undef function
|
||||
|
||||
/* Round 3. */
|
||||
#define function(a,b,c,d,k,s) a=rol(a+H(b,c,d)+in[k]+0x6ed9eba1,s);
|
||||
|
||||
function(A,B,C,D, 0, 3);
|
||||
function(D,A,B,C, 8, 9);
|
||||
function(C,D,A,B, 4,11);
|
||||
function(B,C,D,A,12,15);
|
||||
function(A,B,C,D, 2, 3);
|
||||
function(D,A,B,C,10, 9);
|
||||
function(C,D,A,B, 6,11);
|
||||
function(B,C,D,A,14,15);
|
||||
function(A,B,C,D, 1, 3);
|
||||
function(D,A,B,C, 9, 9);
|
||||
function(C,D,A,B, 5,11);
|
||||
function(B,C,D,A,13,15);
|
||||
function(A,B,C,D, 3, 3);
|
||||
function(D,A,B,C,11, 9);
|
||||
function(C,D,A,B, 7,11);
|
||||
function(B,C,D,A,15,15);
|
||||
|
||||
|
||||
/* Put checksum in context given as argument. */
|
||||
ctx->A += A;
|
||||
ctx->B += B;
|
||||
ctx->C += C;
|
||||
ctx->D += D;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* The routine updates the message-digest context to
|
||||
* account for the presence of each of the characters inBuf[0..inLen-1]
|
||||
* in the message whose digest is being computed.
|
||||
*/
|
||||
static void
|
||||
md4_write ( void *context, const void *inbuf_arg, size_t inlen)
|
||||
{
|
||||
const unsigned char *inbuf = inbuf_arg;
|
||||
MD4_CONTEXT *hd = context;
|
||||
|
||||
if( hd->count == 64 ) /* flush the buffer */
|
||||
{
|
||||
transform( hd, hd->buf );
|
||||
_gcry_burn_stack (80+6*sizeof(void*));
|
||||
hd->count = 0;
|
||||
hd->nblocks++;
|
||||
}
|
||||
if( !inbuf )
|
||||
return;
|
||||
|
||||
if( hd->count )
|
||||
{
|
||||
for( ; inlen && hd->count < 64; inlen-- )
|
||||
hd->buf[hd->count++] = *inbuf++;
|
||||
md4_write( hd, NULL, 0 );
|
||||
if( !inlen )
|
||||
return;
|
||||
}
|
||||
_gcry_burn_stack (80+6*sizeof(void*));
|
||||
|
||||
while( inlen >= 64 )
|
||||
{
|
||||
transform( hd, inbuf );
|
||||
hd->count = 0;
|
||||
hd->nblocks++;
|
||||
inlen -= 64;
|
||||
inbuf += 64;
|
||||
}
|
||||
for( ; inlen && hd->count < 64; inlen-- )
|
||||
hd->buf[hd->count++] = *inbuf++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* The routine final terminates the message-digest computation and
|
||||
* ends with the desired message digest in mdContext->digest[0...15].
|
||||
* The handle is prepared for a new MD4 cycle.
|
||||
* Returns 16 bytes representing the digest.
|
||||
*/
|
||||
|
||||
static void
|
||||
md4_final( void *context )
|
||||
{
|
||||
MD4_CONTEXT *hd = context;
|
||||
u32 t, msb, lsb;
|
||||
byte *p;
|
||||
|
||||
md4_write(hd, NULL, 0); /* flush */;
|
||||
|
||||
t = hd->nblocks;
|
||||
/* multiply by 64 to make a byte count */
|
||||
lsb = t << 6;
|
||||
msb = t >> 26;
|
||||
/* add the count */
|
||||
t = lsb;
|
||||
if( (lsb += hd->count) < t )
|
||||
msb++;
|
||||
/* multiply by 8 to make a bit count */
|
||||
t = lsb;
|
||||
lsb <<= 3;
|
||||
msb <<= 3;
|
||||
msb |= t >> 29;
|
||||
|
||||
if( hd->count < 56 ) /* enough room */
|
||||
{
|
||||
hd->buf[hd->count++] = 0x80; /* pad */
|
||||
while( hd->count < 56 )
|
||||
hd->buf[hd->count++] = 0; /* pad */
|
||||
}
|
||||
else /* need one extra block */
|
||||
{
|
||||
hd->buf[hd->count++] = 0x80; /* pad character */
|
||||
while( hd->count < 64 )
|
||||
hd->buf[hd->count++] = 0;
|
||||
md4_write(hd, NULL, 0); /* flush */;
|
||||
memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
|
||||
}
|
||||
/* append the 64 bit count */
|
||||
hd->buf[56] = lsb ;
|
||||
hd->buf[57] = lsb >> 8;
|
||||
hd->buf[58] = lsb >> 16;
|
||||
hd->buf[59] = lsb >> 24;
|
||||
hd->buf[60] = msb ;
|
||||
hd->buf[61] = msb >> 8;
|
||||
hd->buf[62] = msb >> 16;
|
||||
hd->buf[63] = msb >> 24;
|
||||
transform( hd, hd->buf );
|
||||
_gcry_burn_stack (80+6*sizeof(void*));
|
||||
|
||||
p = hd->buf;
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#define X(a) do { *p++ = hd->a ; *p++ = hd->a >> 8; \
|
||||
*p++ = hd->a >> 16; *p++ = hd->a >> 24; } while(0)
|
||||
#else /* little endian */
|
||||
#define X(a) do { *(u32*)p = (*hd).a ; p += 4; } while(0)
|
||||
#endif
|
||||
X(A);
|
||||
X(B);
|
||||
X(C);
|
||||
X(D);
|
||||
#undef X
|
||||
|
||||
}
|
||||
|
||||
static byte *
|
||||
md4_read (void *context)
|
||||
{
|
||||
MD4_CONTEXT *hd = context;
|
||||
return hd->buf;
|
||||
}
|
||||
|
||||
static byte asn[18] = /* Object ID is 1.2.840.113549.2.4 */
|
||||
{ 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,0x48,
|
||||
0x86, 0xf7, 0x0d, 0x02, 0x04, 0x05, 0x00, 0x04, 0x10 };
|
||||
|
||||
static gcry_md_oid_spec_t oid_spec_md4[] =
|
||||
{
|
||||
/* iso.member-body.us.rsadsi.digestAlgorithm.md4 */
|
||||
{ "1.2.840.113549.2.4" },
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
gcry_md_spec_t _gcry_digest_spec_md4 =
|
||||
{
|
||||
"MD4", asn, DIM (asn), oid_spec_md4,16,
|
||||
md4_init, md4_write, md4_final, md4_read,
|
||||
sizeof (MD4_CONTEXT)
|
||||
};
|
||||
|
355
lib/libgcrypt/cipher/md5.c
Normal file
355
lib/libgcrypt/cipher/md5.c
Normal file
|
@ -0,0 +1,355 @@
|
|||
/* md5.c - MD5 Message-Digest Algorithm
|
||||
* Copyright (C) 1995,1996,1998,1999,2001,2002,
|
||||
* 2003 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of Libgcrypt.
|
||||
*
|
||||
* Libgcrypt is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Libgcrypt is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*
|
||||
* According to the definition of MD5 in RFC 1321 from April 1992.
|
||||
* NOTE: This is *not* the same file as the one from glibc.
|
||||
* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
|
||||
* heavily modified for GnuPG by Werner Koch <wk@gnupg.org>
|
||||
*/
|
||||
|
||||
/* Test values:
|
||||
* "" D4 1D 8C D9 8F 00 B2 04 E9 80 09 98 EC F8 42 7E
|
||||
* "a" 0C C1 75 B9 C0 F1 B6 A8 31 C3 99 E2 69 77 26 61
|
||||
* "abc 90 01 50 98 3C D2 4F B0 D6 96 3F 7D 28 E1 7F 72
|
||||
* "message digest" F9 6B 69 7D 7C B7 93 8D 52 5A 2F 31 AA F1 61 D0
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "g10lib.h"
|
||||
#include "memory.h"
|
||||
#include "cipher.h"
|
||||
|
||||
#include "bithelp.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
u32 A,B,C,D; /* chaining variables */
|
||||
u32 nblocks;
|
||||
byte buf[64];
|
||||
int count;
|
||||
} MD5_CONTEXT;
|
||||
|
||||
|
||||
static void
|
||||
md5_init( void *context )
|
||||
{
|
||||
MD5_CONTEXT *ctx = context;
|
||||
|
||||
ctx->A = 0x67452301;
|
||||
ctx->B = 0xefcdab89;
|
||||
ctx->C = 0x98badcfe;
|
||||
ctx->D = 0x10325476;
|
||||
|
||||
ctx->nblocks = 0;
|
||||
ctx->count = 0;
|
||||
}
|
||||
|
||||
|
||||
/* These are the four functions used in the four steps of the MD5 algorithm
|
||||
and defined in the RFC 1321. The first function is a little bit optimized
|
||||
(as found in Colin Plumbs public domain implementation). */
|
||||
/* #define FF(b, c, d) ((b & c) | (~b & d)) */
|
||||
#define FF(b, c, d) (d ^ (b & (c ^ d)))
|
||||
#define FG(b, c, d) FF (d, b, c)
|
||||
#define FH(b, c, d) (b ^ c ^ d)
|
||||
#define FI(b, c, d) (c ^ (b | ~d))
|
||||
|
||||
|
||||
/****************
|
||||
* transform n*64 bytes
|
||||
*/
|
||||
static void
|
||||
transform ( MD5_CONTEXT *ctx, const unsigned char *data )
|
||||
{
|
||||
u32 correct_words[16];
|
||||
register u32 A = ctx->A;
|
||||
register u32 B = ctx->B;
|
||||
register u32 C = ctx->C;
|
||||
register u32 D = ctx->D;
|
||||
u32 *cwp = correct_words;
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
{
|
||||
int i;
|
||||
byte *p2, *p1;
|
||||
for(i=0, p1=data, p2=(byte*)correct_words; i < 16; i++, p2 += 4 )
|
||||
{
|
||||
p2[3] = *p1++;
|
||||
p2[2] = *p1++;
|
||||
p2[1] = *p1++;
|
||||
p2[0] = *p1++;
|
||||
}
|
||||
}
|
||||
#else
|
||||
memcpy( correct_words, data, 64 );
|
||||
#endif
|
||||
|
||||
|
||||
#define OP(a, b, c, d, s, T) \
|
||||
do \
|
||||
{ \
|
||||
a += FF (b, c, d) + (*cwp++) + T; \
|
||||
a = rol(a, s); \
|
||||
a += b; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* Before we start, one word about the strange constants.
|
||||
They are defined in RFC 1321 as
|
||||
|
||||
T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
|
||||
*/
|
||||
|
||||
/* Round 1. */
|
||||
OP (A, B, C, D, 7, 0xd76aa478);
|
||||
OP (D, A, B, C, 12, 0xe8c7b756);
|
||||
OP (C, D, A, B, 17, 0x242070db);
|
||||
OP (B, C, D, A, 22, 0xc1bdceee);
|
||||
OP (A, B, C, D, 7, 0xf57c0faf);
|
||||
OP (D, A, B, C, 12, 0x4787c62a);
|
||||
OP (C, D, A, B, 17, 0xa8304613);
|
||||
OP (B, C, D, A, 22, 0xfd469501);
|
||||
OP (A, B, C, D, 7, 0x698098d8);
|
||||
OP (D, A, B, C, 12, 0x8b44f7af);
|
||||
OP (C, D, A, B, 17, 0xffff5bb1);
|
||||
OP (B, C, D, A, 22, 0x895cd7be);
|
||||
OP (A, B, C, D, 7, 0x6b901122);
|
||||
OP (D, A, B, C, 12, 0xfd987193);
|
||||
OP (C, D, A, B, 17, 0xa679438e);
|
||||
OP (B, C, D, A, 22, 0x49b40821);
|
||||
|
||||
#undef OP
|
||||
#define OP(f, a, b, c, d, k, s, T) \
|
||||
do \
|
||||
{ \
|
||||
a += f (b, c, d) + correct_words[k] + T; \
|
||||
a = rol(a, s); \
|
||||
a += b; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* Round 2. */
|
||||
OP (FG, A, B, C, D, 1, 5, 0xf61e2562);
|
||||
OP (FG, D, A, B, C, 6, 9, 0xc040b340);
|
||||
OP (FG, C, D, A, B, 11, 14, 0x265e5a51);
|
||||
OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa);
|
||||
OP (FG, A, B, C, D, 5, 5, 0xd62f105d);
|
||||
OP (FG, D, A, B, C, 10, 9, 0x02441453);
|
||||
OP (FG, C, D, A, B, 15, 14, 0xd8a1e681);
|
||||
OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8);
|
||||
OP (FG, A, B, C, D, 9, 5, 0x21e1cde6);
|
||||
OP (FG, D, A, B, C, 14, 9, 0xc33707d6);
|
||||
OP (FG, C, D, A, B, 3, 14, 0xf4d50d87);
|
||||
OP (FG, B, C, D, A, 8, 20, 0x455a14ed);
|
||||
OP (FG, A, B, C, D, 13, 5, 0xa9e3e905);
|
||||
OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8);
|
||||
OP (FG, C, D, A, B, 7, 14, 0x676f02d9);
|
||||
OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
|
||||
|
||||
/* Round 3. */
|
||||
OP (FH, A, B, C, D, 5, 4, 0xfffa3942);
|
||||
OP (FH, D, A, B, C, 8, 11, 0x8771f681);
|
||||
OP (FH, C, D, A, B, 11, 16, 0x6d9d6122);
|
||||
OP (FH, B, C, D, A, 14, 23, 0xfde5380c);
|
||||
OP (FH, A, B, C, D, 1, 4, 0xa4beea44);
|
||||
OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9);
|
||||
OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60);
|
||||
OP (FH, B, C, D, A, 10, 23, 0xbebfbc70);
|
||||
OP (FH, A, B, C, D, 13, 4, 0x289b7ec6);
|
||||
OP (FH, D, A, B, C, 0, 11, 0xeaa127fa);
|
||||
OP (FH, C, D, A, B, 3, 16, 0xd4ef3085);
|
||||
OP (FH, B, C, D, A, 6, 23, 0x04881d05);
|
||||
OP (FH, A, B, C, D, 9, 4, 0xd9d4d039);
|
||||
OP (FH, D, A, B, C, 12, 11, 0xe6db99e5);
|
||||
OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8);
|
||||
OP (FH, B, C, D, A, 2, 23, 0xc4ac5665);
|
||||
|
||||
/* Round 4. */
|
||||
OP (FI, A, B, C, D, 0, 6, 0xf4292244);
|
||||
OP (FI, D, A, B, C, 7, 10, 0x432aff97);
|
||||
OP (FI, C, D, A, B, 14, 15, 0xab9423a7);
|
||||
OP (FI, B, C, D, A, 5, 21, 0xfc93a039);
|
||||
OP (FI, A, B, C, D, 12, 6, 0x655b59c3);
|
||||
OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92);
|
||||
OP (FI, C, D, A, B, 10, 15, 0xffeff47d);
|
||||
OP (FI, B, C, D, A, 1, 21, 0x85845dd1);
|
||||
OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f);
|
||||
OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
|
||||
OP (FI, C, D, A, B, 6, 15, 0xa3014314);
|
||||
OP (FI, B, C, D, A, 13, 21, 0x4e0811a1);
|
||||
OP (FI, A, B, C, D, 4, 6, 0xf7537e82);
|
||||
OP (FI, D, A, B, C, 11, 10, 0xbd3af235);
|
||||
OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
|
||||
OP (FI, B, C, D, A, 9, 21, 0xeb86d391);
|
||||
|
||||
/* Put checksum in context given as argument. */
|
||||
ctx->A += A;
|
||||
ctx->B += B;
|
||||
ctx->C += C;
|
||||
ctx->D += D;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* The routine updates the message-digest context to
|
||||
* account for the presence of each of the characters inBuf[0..inLen-1]
|
||||
* in the message whose digest is being computed.
|
||||
*/
|
||||
static void
|
||||
md5_write( void *context, const void *inbuf_arg , size_t inlen)
|
||||
{
|
||||
const unsigned char *inbuf = inbuf_arg;
|
||||
MD5_CONTEXT *hd = context;
|
||||
|
||||
if( hd->count == 64 ) /* flush the buffer */
|
||||
{
|
||||
transform( hd, hd->buf );
|
||||
_gcry_burn_stack (80+6*sizeof(void*));
|
||||
hd->count = 0;
|
||||
hd->nblocks++;
|
||||
}
|
||||
if( !inbuf )
|
||||
return;
|
||||
|
||||
if( hd->count )
|
||||
{
|
||||
for( ; inlen && hd->count < 64; inlen-- )
|
||||
hd->buf[hd->count++] = *inbuf++;
|
||||
md5_write( hd, NULL, 0 );
|
||||
if( !inlen )
|
||||
return;
|
||||
}
|
||||
_gcry_burn_stack (80+6*sizeof(void*));
|
||||
|
||||
while( inlen >= 64 )
|
||||
{
|
||||
transform( hd, inbuf );
|
||||
hd->count = 0;
|
||||
hd->nblocks++;
|
||||
inlen -= 64;
|
||||
inbuf += 64;
|
||||
}
|
||||
for( ; inlen && hd->count < 64; inlen-- )
|
||||
hd->buf[hd->count++] = *inbuf++;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* The routine final terminates the message-digest computation and
|
||||
* ends with the desired message digest in mdContext->digest[0...15].
|
||||
* The handle is prepared for a new MD5 cycle.
|
||||
* Returns 16 bytes representing the digest.
|
||||
*/
|
||||
|
||||
static void
|
||||
md5_final( void *context)
|
||||
{
|
||||
MD5_CONTEXT *hd = context;
|
||||
u32 t, msb, lsb;
|
||||
byte *p;
|
||||
|
||||
md5_write(hd, NULL, 0); /* flush */;
|
||||
|
||||
t = hd->nblocks;
|
||||
/* multiply by 64 to make a byte count */
|
||||
lsb = t << 6;
|
||||
msb = t >> 26;
|
||||
/* add the count */
|
||||
t = lsb;
|
||||
if( (lsb += hd->count) < t )
|
||||
msb++;
|
||||
/* multiply by 8 to make a bit count */
|
||||
t = lsb;
|
||||
lsb <<= 3;
|
||||
msb <<= 3;
|
||||
msb |= t >> 29;
|
||||
|
||||
if( hd->count < 56 ) /* enough room */
|
||||
{
|
||||
hd->buf[hd->count++] = 0x80; /* pad */
|
||||
while( hd->count < 56 )
|
||||
hd->buf[hd->count++] = 0; /* pad */
|
||||
}
|
||||
else /* need one extra block */
|
||||
{
|
||||
hd->buf[hd->count++] = 0x80; /* pad character */
|
||||
while( hd->count < 64 )
|
||||
hd->buf[hd->count++] = 0;
|
||||
md5_write(hd, NULL, 0); /* flush */;
|
||||
memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
|
||||
}
|
||||
/* append the 64 bit count */
|
||||
hd->buf[56] = lsb ;
|
||||
hd->buf[57] = lsb >> 8;
|
||||
hd->buf[58] = lsb >> 16;
|
||||
hd->buf[59] = lsb >> 24;
|
||||
hd->buf[60] = msb ;
|
||||
hd->buf[61] = msb >> 8;
|
||||
hd->buf[62] = msb >> 16;
|
||||
hd->buf[63] = msb >> 24;
|
||||
transform( hd, hd->buf );
|
||||
_gcry_burn_stack (80+6*sizeof(void*));
|
||||
|
||||
p = hd->buf;
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#define X(a) do { *p++ = hd->a ; *p++ = hd->a >> 8; \
|
||||
*p++ = hd->a >> 16; *p++ = hd->a >> 24; } while(0)
|
||||
#else /* little endian */
|
||||
#define X(a) do { *(u32*)p = (*hd).a ; p += 4; } while(0)
|
||||
#endif
|
||||
X(A);
|
||||
X(B);
|
||||
X(C);
|
||||
X(D);
|
||||
#undef X
|
||||
|
||||
}
|
||||
|
||||
static byte *
|
||||
md5_read( void *context )
|
||||
{
|
||||
MD5_CONTEXT *hd = (MD5_CONTEXT *) context;
|
||||
return hd->buf;
|
||||
}
|
||||
|
||||
static byte asn[18] = /* Object ID is 1.2.840.113549.2.5 */
|
||||
{ 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,0x48,
|
||||
0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10 };
|
||||
|
||||
static gcry_md_oid_spec_t oid_spec_md5[] =
|
||||
{
|
||||
/* iso.member-body.us.rsadsi.pkcs.pkcs-1.4 (md5WithRSAEncryption) */
|
||||
{ "1.2.840.113549.1.1.4" },
|
||||
/* RSADSI digestAlgorithm MD5 */
|
||||
{ "1.2.840.113549.2.5" },
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
gcry_md_spec_t _gcry_digest_spec_md5 =
|
||||
{
|
||||
"MD5", asn, DIM (asn), oid_spec_md5, 16,
|
||||
md5_init, md5_write, md5_final, md5_read,
|
||||
sizeof (MD5_CONTEXT)
|
||||
};
|
1862
lib/libgcrypt/cipher/primegen.c
Normal file
1862
lib/libgcrypt/cipher/primegen.c
Normal file
File diff suppressed because it is too large
Load diff
2749
lib/libgcrypt/cipher/pubkey.c
Normal file
2749
lib/libgcrypt/cipher/pubkey.c
Normal file
File diff suppressed because it is too large
Load diff
345
lib/libgcrypt/cipher/rfc2268.c
Normal file
345
lib/libgcrypt/cipher/rfc2268.c
Normal file
|
@ -0,0 +1,345 @@
|
|||
/* rfc2268.c - The cipher described in rfc2268; aka Ron's Cipher 2.
|
||||
* Copyright (C) 2003 Nikos Mavroyanopoulos
|
||||
* Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of Libgcrypt
|
||||
*
|
||||
* Libgcrypt is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser general Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Libgcrypt is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
/* This implementation was written by Nikos Mavroyanopoulos for GNUTLS
|
||||
* as a Libgcrypt module (gnutls/lib/x509/rc2.c) and later adapted for
|
||||
* direct use by Libgcrypt by Werner Koch. This implementation is
|
||||
* only useful for pkcs#12 descryption.
|
||||
*
|
||||
* The implementation here is based on Peter Gutmann's RRC.2 paper.
|
||||
*/
|
||||
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "g10lib.h"
|
||||
#include "types.h"
|
||||
#include "cipher.h"
|
||||
|
||||
#define RFC2268_BLOCKSIZE 8
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u16 S[64];
|
||||
} RFC2268_context;
|
||||
|
||||
static const unsigned char rfc2268_sbox[] = {
|
||||
217, 120, 249, 196, 25, 221, 181, 237,
|
||||
40, 233, 253, 121, 74, 160, 216, 157,
|
||||
198, 126, 55, 131, 43, 118, 83, 142,
|
||||
98, 76, 100, 136, 68, 139, 251, 162,
|
||||
23, 154, 89, 245, 135, 179, 79, 19,
|
||||
97, 69, 109, 141, 9, 129, 125, 50,
|
||||
189, 143, 64, 235, 134, 183, 123, 11,
|
||||
240, 149, 33, 34, 92, 107, 78, 130,
|
||||
84, 214, 101, 147, 206, 96, 178, 28,
|
||||
115, 86, 192, 20, 167, 140, 241, 220,
|
||||
18, 117, 202, 31, 59, 190, 228, 209,
|
||||
66, 61, 212, 48, 163, 60, 182, 38,
|
||||
111, 191, 14, 218, 70, 105, 7, 87,
|
||||
39, 242, 29, 155, 188, 148, 67, 3,
|
||||
248, 17, 199, 246, 144, 239, 62, 231,
|
||||
6, 195, 213, 47, 200, 102, 30, 215,
|
||||
8, 232, 234, 222, 128, 82, 238, 247,
|
||||
132, 170, 114, 172, 53, 77, 106, 42,
|
||||
150, 26, 210, 113, 90, 21, 73, 116,
|
||||
75, 159, 208, 94, 4, 24, 164, 236,
|
||||
194, 224, 65, 110, 15, 81, 203, 204,
|
||||
36, 145, 175, 80, 161, 244, 112, 57,
|
||||
153, 124, 58, 133, 35, 184, 180, 122,
|
||||
252, 2, 54, 91, 37, 85, 151, 49,
|
||||
45, 93, 250, 152, 227, 138, 146, 174,
|
||||
5, 223, 41, 16, 103, 108, 186, 201,
|
||||
211, 0, 230, 207, 225, 158, 168, 44,
|
||||
99, 22, 1, 63, 88, 226, 137, 169,
|
||||
13, 56, 52, 27, 171, 51, 255, 176,
|
||||
187, 72, 12, 95, 185, 177, 205, 46,
|
||||
197, 243, 219, 71, 229, 165, 156, 119,
|
||||
10, 166, 32, 104, 254, 127, 193, 173
|
||||
};
|
||||
|
||||
#define rotl16(x,n) (((x) << ((u16)(n))) | ((x) >> (16 - (u16)(n))))
|
||||
#define rotr16(x,n) (((x) >> ((u16)(n))) | ((x) << (16 - (u16)(n))))
|
||||
|
||||
static const char *selftest (void);
|
||||
|
||||
|
||||
static void
|
||||
do_encrypt (void *context, unsigned char *outbuf, const unsigned char *inbuf)
|
||||
{
|
||||
RFC2268_context *ctx = context;
|
||||
register int i, j;
|
||||
u16 word0 = 0, word1 = 0, word2 = 0, word3 = 0;
|
||||
|
||||
word0 = (word0 << 8) | inbuf[1];
|
||||
word0 = (word0 << 8) | inbuf[0];
|
||||
word1 = (word1 << 8) | inbuf[3];
|
||||
word1 = (word1 << 8) | inbuf[2];
|
||||
word2 = (word2 << 8) | inbuf[5];
|
||||
word2 = (word2 << 8) | inbuf[4];
|
||||
word3 = (word3 << 8) | inbuf[7];
|
||||
word3 = (word3 << 8) | inbuf[6];
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
j = i * 4;
|
||||
/* For some reason I cannot combine those steps. */
|
||||
word0 += (word1 & ~word3) + (word2 & word3) + ctx->S[j];
|
||||
word0 = rotl16(word0, 1);
|
||||
|
||||
word1 += (word2 & ~word0) + (word3 & word0) + ctx->S[j + 1];
|
||||
word1 = rotl16(word1, 2);
|
||||
|
||||
word2 += (word3 & ~word1) + (word0 & word1) + ctx->S[j + 2];
|
||||
word2 = rotl16(word2, 3);
|
||||
|
||||
word3 += (word0 & ~word2) + (word1 & word2) + ctx->S[j + 3];
|
||||
word3 = rotl16(word3, 5);
|
||||
|
||||
if (i == 4 || i == 10)
|
||||
{
|
||||
word0 += ctx->S[word3 & 63];
|
||||
word1 += ctx->S[word0 & 63];
|
||||
word2 += ctx->S[word1 & 63];
|
||||
word3 += ctx->S[word2 & 63];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
outbuf[0] = word0 & 255;
|
||||
outbuf[1] = word0 >> 8;
|
||||
outbuf[2] = word1 & 255;
|
||||
outbuf[3] = word1 >> 8;
|
||||
outbuf[4] = word2 & 255;
|
||||
outbuf[5] = word2 >> 8;
|
||||
outbuf[6] = word3 & 255;
|
||||
outbuf[7] = word3 >> 8;
|
||||
}
|
||||
|
||||
static void
|
||||
do_decrypt (void *context, unsigned char *outbuf, const unsigned char *inbuf)
|
||||
{
|
||||
RFC2268_context *ctx = context;
|
||||
register int i, j;
|
||||
u16 word0 = 0, word1 = 0, word2 = 0, word3 = 0;
|
||||
|
||||
word0 = (word0 << 8) | inbuf[1];
|
||||
word0 = (word0 << 8) | inbuf[0];
|
||||
word1 = (word1 << 8) | inbuf[3];
|
||||
word1 = (word1 << 8) | inbuf[2];
|
||||
word2 = (word2 << 8) | inbuf[5];
|
||||
word2 = (word2 << 8) | inbuf[4];
|
||||
word3 = (word3 << 8) | inbuf[7];
|
||||
word3 = (word3 << 8) | inbuf[6];
|
||||
|
||||
for (i = 15; i >= 0; i--)
|
||||
{
|
||||
j = i * 4;
|
||||
|
||||
word3 = rotr16(word3, 5);
|
||||
word3 -= (word0 & ~word2) + (word1 & word2) + ctx->S[j + 3];
|
||||
|
||||
word2 = rotr16(word2, 3);
|
||||
word2 -= (word3 & ~word1) + (word0 & word1) + ctx->S[j + 2];
|
||||
|
||||
word1 = rotr16(word1, 2);
|
||||
word1 -= (word2 & ~word0) + (word3 & word0) + ctx->S[j + 1];
|
||||
|
||||
word0 = rotr16(word0, 1);
|
||||
word0 -= (word1 & ~word3) + (word2 & word3) + ctx->S[j];
|
||||
|
||||
if (i == 5 || i == 11)
|
||||
{
|
||||
word3 = word3 - ctx->S[word2 & 63];
|
||||
word2 = word2 - ctx->S[word1 & 63];
|
||||
word1 = word1 - ctx->S[word0 & 63];
|
||||
word0 = word0 - ctx->S[word3 & 63];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
outbuf[0] = word0 & 255;
|
||||
outbuf[1] = word0 >> 8;
|
||||
outbuf[2] = word1 & 255;
|
||||
outbuf[3] = word1 >> 8;
|
||||
outbuf[4] = word2 & 255;
|
||||
outbuf[5] = word2 >> 8;
|
||||
outbuf[6] = word3 & 255;
|
||||
outbuf[7] = word3 >> 8;
|
||||
}
|
||||
|
||||
|
||||
static gpg_err_code_t
|
||||
setkey_core (void *context, const unsigned char *key, unsigned int keylen, int with_phase2)
|
||||
{
|
||||
static int initialized;
|
||||
static const char *selftest_failed;
|
||||
RFC2268_context *ctx = context;
|
||||
unsigned int i;
|
||||
unsigned char *S, x;
|
||||
int len;
|
||||
int bits = keylen * 8;
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
initialized = 1;
|
||||
selftest_failed = selftest ();
|
||||
if (selftest_failed)
|
||||
log_error ("RFC2268 selftest failed (%s).\n", selftest_failed);
|
||||
}
|
||||
if (selftest_failed)
|
||||
return GPG_ERR_SELFTEST_FAILED;
|
||||
|
||||
if (keylen < 40 / 8) /* We want at least 40 bits. */
|
||||
return GPG_ERR_INV_KEYLEN;
|
||||
|
||||
S = (unsigned char *) ctx->S;
|
||||
|
||||
for (i = 0; i < keylen; i++)
|
||||
S[i] = key[i];
|
||||
|
||||
for (i = keylen; i < 128; i++)
|
||||
S[i] = rfc2268_sbox[(S[i - keylen] + S[i - 1]) & 255];
|
||||
|
||||
S[0] = rfc2268_sbox[S[0]];
|
||||
|
||||
/* Phase 2 - reduce effective key size to "bits". This was not
|
||||
* discussed in Gutmann's paper. I've copied that from the public
|
||||
* domain code posted in sci.crypt. */
|
||||
if (with_phase2)
|
||||
{
|
||||
len = (bits + 7) >> 3;
|
||||
i = 128 - len;
|
||||
x = rfc2268_sbox[S[i] & (255 >> (7 & -bits))];
|
||||
S[i] = x;
|
||||
|
||||
while (i--)
|
||||
{
|
||||
x = rfc2268_sbox[x ^ S[i + len]];
|
||||
S[i] = x;
|
||||
}
|
||||
}
|
||||
|
||||
/* Make the expanded key, endian independent. */
|
||||
for (i = 0; i < 64; i++)
|
||||
ctx->S[i] = ( (u16) S[i * 2] | (((u16) S[i * 2 + 1]) << 8));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static gpg_err_code_t
|
||||
do_setkey (void *context, const unsigned char *key, unsigned int keylen)
|
||||
{
|
||||
return setkey_core (context, key, keylen, 1);
|
||||
}
|
||||
|
||||
static const char *
|
||||
selftest (void)
|
||||
{
|
||||
RFC2268_context ctx;
|
||||
unsigned char scratch[16];
|
||||
|
||||
/* Test vectors from Peter Gutmann's paper. */
|
||||
static unsigned char key_1[] =
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
static unsigned char plaintext_1[] =
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
static const unsigned char ciphertext_1[] =
|
||||
{ 0x1C, 0x19, 0x8A, 0x83, 0x8D, 0xF0, 0x28, 0xB7 };
|
||||
|
||||
static unsigned char key_2[] =
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
|
||||
};
|
||||
static unsigned char plaintext_2[] =
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
static unsigned char ciphertext_2[] =
|
||||
{ 0x50, 0xDC, 0x01, 0x62, 0xBD, 0x75, 0x7F, 0x31 };
|
||||
|
||||
/* This one was checked against libmcrypt's RFC2268. */
|
||||
static unsigned char key_3[] =
|
||||
{ 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
static unsigned char plaintext_3[] =
|
||||
{ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
static unsigned char ciphertext_3[] =
|
||||
{ 0x8f, 0xd1, 0x03, 0x89, 0x33, 0x6b, 0xf9, 0x5e };
|
||||
|
||||
|
||||
/* First test. */
|
||||
setkey_core (&ctx, key_1, sizeof(key_1), 0);
|
||||
do_encrypt (&ctx, scratch, plaintext_1);
|
||||
|
||||
if (memcmp (scratch, ciphertext_1, sizeof(ciphertext_1)))
|
||||
return "RFC2268 encryption test 1 failed.";
|
||||
|
||||
setkey_core (&ctx, key_1, sizeof(key_1), 0);
|
||||
do_decrypt (&ctx, scratch, scratch);
|
||||
if (memcmp (scratch, plaintext_1, sizeof(plaintext_1)))
|
||||
return "RFC2268 decryption test 1 failed.";
|
||||
|
||||
/* Second test. */
|
||||
setkey_core (&ctx, key_2, sizeof(key_2), 0);
|
||||
do_encrypt (&ctx, scratch, plaintext_2);
|
||||
if (memcmp (scratch, ciphertext_2, sizeof(ciphertext_2)))
|
||||
return "RFC2268 encryption test 2 failed.";
|
||||
|
||||
setkey_core (&ctx, key_2, sizeof(key_2), 0);
|
||||
do_decrypt (&ctx, scratch, scratch);
|
||||
if (memcmp (scratch, plaintext_2, sizeof(plaintext_2)))
|
||||
return "RFC2268 decryption test 2 failed.";
|
||||
|
||||
/* Third test. */
|
||||
setkey_core(&ctx, key_3, sizeof(key_3), 0);
|
||||
do_encrypt(&ctx, scratch, plaintext_3);
|
||||
|
||||
if (memcmp(scratch, ciphertext_3, sizeof(ciphertext_3)))
|
||||
return "RFC2268 encryption test 3 failed.";
|
||||
|
||||
setkey_core (&ctx, key_3, sizeof(key_3), 0);
|
||||
do_decrypt (&ctx, scratch, scratch);
|
||||
if (memcmp(scratch, plaintext_3, sizeof(plaintext_3)))
|
||||
return "RFC2268 decryption test 3 failed.";
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static gcry_cipher_oid_spec_t oids_rfc2268_40[] =
|
||||
{
|
||||
/*{ "1.2.840.113549.3.2", GCRY_CIPHER_MODE_CBC },*/
|
||||
/* pbeWithSHAAnd40BitRC2_CBC */
|
||||
{ "1.2.840.113549.1.12.1.6", GCRY_CIPHER_MODE_CBC },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
gcry_cipher_spec_t _gcry_cipher_spec_rfc2268_40 = {
|
||||
"RFC2268_40", NULL, oids_rfc2268_40,
|
||||
RFC2268_BLOCKSIZE, 40, sizeof(RFC2268_context),
|
||||
do_setkey, do_encrypt, do_decrypt
|
||||
};
|
||||
|
1687
lib/libgcrypt/cipher/rijndael-tables.h
Normal file
1687
lib/libgcrypt/cipher/rijndael-tables.h
Normal file
File diff suppressed because it is too large
Load diff
1253
lib/libgcrypt/cipher/rijndael.c
Normal file
1253
lib/libgcrypt/cipher/rijndael.c
Normal file
File diff suppressed because it is too large
Load diff
37
lib/libgcrypt/cipher/rmd.h
Normal file
37
lib/libgcrypt/cipher/rmd.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/* rmd.h - RIPE-MD hash functions
|
||||
* Copyright (C) 1998, 2001, 2002 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of Libgcrypt.
|
||||
*
|
||||
* Libgcrypt is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Libgcrypt is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifndef G10_RMD_H
|
||||
#define G10_RMD_H
|
||||
|
||||
|
||||
/* We need this here because random.c must have direct access. */
|
||||
typedef struct
|
||||
{
|
||||
u32 h0,h1,h2,h3,h4;
|
||||
u32 nblocks;
|
||||
byte buf[64];
|
||||
int count;
|
||||
} RMD160_CONTEXT;
|
||||
|
||||
void _gcry_rmd160_init ( void *context );
|
||||
void _gcry_rmd160_mixblock ( RMD160_CONTEXT *hd, void *blockof64byte );
|
||||
|
||||
#endif /*G10_RMD_H*/
|
||||
|
572
lib/libgcrypt/cipher/rmd160.c
Normal file
572
lib/libgcrypt/cipher/rmd160.c
Normal file
|
@ -0,0 +1,572 @@
|
|||
/* rmd160.c - RIPE-MD160
|
||||
* Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of Libgcrypt.
|
||||
*
|
||||
* Libgcrypt is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Libgcrypt is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "g10lib.h"
|
||||
#include "memory.h"
|
||||
#include "rmd.h"
|
||||
#include "cipher.h" /* Only used for the rmd160_hash_buffer() prototype. */
|
||||
|
||||
#include "bithelp.h"
|
||||
|
||||
/*********************************
|
||||
* RIPEMD-160 is not patented, see (as of 25.10.97)
|
||||
* http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html
|
||||
* Note that the code uses Little Endian byteorder, which is good for
|
||||
* 386 etc, but we must add some conversion when used on a big endian box.
|
||||
*
|
||||
*
|
||||
* Pseudo-code for RIPEMD-160
|
||||
*
|
||||
* RIPEMD-160 is an iterative hash function that operates on 32-bit words.
|
||||
* The round function takes as input a 5-word chaining variable and a 16-word
|
||||
* message block and maps this to a new chaining variable. All operations are
|
||||
* defined on 32-bit words. Padding is identical to that of MD4.
|
||||
*
|
||||
*
|
||||
* RIPEMD-160: definitions
|
||||
*
|
||||
*
|
||||
* nonlinear functions at bit level: exor, mux, -, mux, -
|
||||
*
|
||||
* f(j, x, y, z) = x XOR y XOR z (0 <= j <= 15)
|
||||
* f(j, x, y, z) = (x AND y) OR (NOT(x) AND z) (16 <= j <= 31)
|
||||
* f(j, x, y, z) = (x OR NOT(y)) XOR z (32 <= j <= 47)
|
||||
* f(j, x, y, z) = (x AND z) OR (y AND NOT(z)) (48 <= j <= 63)
|
||||
* f(j, x, y, z) = x XOR (y OR NOT(z)) (64 <= j <= 79)
|
||||
*
|
||||
*
|
||||
* added constants (hexadecimal)
|
||||
*
|
||||
* K(j) = 0x00000000 (0 <= j <= 15)
|
||||
* K(j) = 0x5A827999 (16 <= j <= 31) int(2**30 x sqrt(2))
|
||||
* K(j) = 0x6ED9EBA1 (32 <= j <= 47) int(2**30 x sqrt(3))
|
||||
* K(j) = 0x8F1BBCDC (48 <= j <= 63) int(2**30 x sqrt(5))
|
||||
* K(j) = 0xA953FD4E (64 <= j <= 79) int(2**30 x sqrt(7))
|
||||
* K'(j) = 0x50A28BE6 (0 <= j <= 15) int(2**30 x cbrt(2))
|
||||
* K'(j) = 0x5C4DD124 (16 <= j <= 31) int(2**30 x cbrt(3))
|
||||
* K'(j) = 0x6D703EF3 (32 <= j <= 47) int(2**30 x cbrt(5))
|
||||
* K'(j) = 0x7A6D76E9 (48 <= j <= 63) int(2**30 x cbrt(7))
|
||||
* K'(j) = 0x00000000 (64 <= j <= 79)
|
||||
*
|
||||
*
|
||||
* selection of message word
|
||||
*
|
||||
* r(j) = j (0 <= j <= 15)
|
||||
* r(16..31) = 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8
|
||||
* r(32..47) = 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12
|
||||
* r(48..63) = 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2
|
||||
* r(64..79) = 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
|
||||
* r0(0..15) = 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12
|
||||
* r0(16..31)= 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2
|
||||
* r0(32..47)= 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13
|
||||
* r0(48..63)= 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14
|
||||
* r0(64..79)= 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
|
||||
*
|
||||
*
|
||||
* amount for rotate left (rol)
|
||||
*
|
||||
* s(0..15) = 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8
|
||||
* s(16..31) = 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12
|
||||
* s(32..47) = 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5
|
||||
* s(48..63) = 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12
|
||||
* s(64..79) = 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
|
||||
* s'(0..15) = 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6
|
||||
* s'(16..31)= 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11
|
||||
* s'(32..47)= 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5
|
||||
* s'(48..63)= 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8
|
||||
* s'(64..79)= 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
|
||||
*
|
||||
*
|
||||
* initial value (hexadecimal)
|
||||
*
|
||||
* h0 = 0x67452301; h1 = 0xEFCDAB89; h2 = 0x98BADCFE; h3 = 0x10325476;
|
||||
* h4 = 0xC3D2E1F0;
|
||||
*
|
||||
*
|
||||
* RIPEMD-160: pseudo-code
|
||||
*
|
||||
* It is assumed that the message after padding consists of t 16-word blocks
|
||||
* that will be denoted with X[i][j], with 0 <= i <= t-1 and 0 <= j <= 15.
|
||||
* The symbol [+] denotes addition modulo 2**32 and rol_s denotes cyclic left
|
||||
* shift (rotate) over s positions.
|
||||
*
|
||||
*
|
||||
* for i := 0 to t-1 {
|
||||
* A := h0; B := h1; C := h2; D = h3; E = h4;
|
||||
* A' := h0; B' := h1; C' := h2; D' = h3; E' = h4;
|
||||
* for j := 0 to 79 {
|
||||
* T := rol_s(j)(A [+] f(j, B, C, D) [+] X[i][r(j)] [+] K(j)) [+] E;
|
||||
* A := E; E := D; D := rol_10(C); C := B; B := T;
|
||||
* T := rol_s'(j)(A' [+] f(79-j, B', C', D') [+] X[i][r'(j)]
|
||||
[+] K'(j)) [+] E';
|
||||
* A' := E'; E' := D'; D' := rol_10(C'); C' := B'; B' := T;
|
||||
* }
|
||||
* T := h1 [+] C [+] D'; h1 := h2 [+] D [+] E'; h2 := h3 [+] E [+] A';
|
||||
* h3 := h4 [+] A [+] B'; h4 := h0 [+] B [+] C'; h0 := T;
|
||||
* }
|
||||
*/
|
||||
|
||||
/* Some examples:
|
||||
* "" 9c1185a5c5e9fc54612808977ee8f548b2258d31
|
||||
* "a" 0bdc9d2d256b3ee9daae347be6f4dc835a467ffe
|
||||
* "abc" 8eb208f7e05d987a9b044a8e98c6b087f15a0bfc
|
||||
* "message digest" 5d0689ef49d2fae572b881b123a85ffa21595f36
|
||||
* "a...z" f71c27109c692c1b56bbdceb5b9d2865b3708dbc
|
||||
* "abcdbcde...nopq" 12a053384a9c0c88e405a06c27dcf49ada62eb2b
|
||||
* "A...Za...z0...9" b0e20b6e3116640286ed3a87a5713079b21f5189
|
||||
* 8 times "1234567890" 9b752e45573d4b39f4dbd3323cab82bf63326bfb
|
||||
* 1 million times "a" 52783243c1697bdbe16d37f97f68f08325dc1528
|
||||
*/
|
||||
|
||||
|
||||
void
|
||||
_gcry_rmd160_init (void *context)
|
||||
{
|
||||
RMD160_CONTEXT *hd = context;
|
||||
|
||||
hd->h0 = 0x67452301;
|
||||
hd->h1 = 0xEFCDAB89;
|
||||
hd->h2 = 0x98BADCFE;
|
||||
hd->h3 = 0x10325476;
|
||||
hd->h4 = 0xC3D2E1F0;
|
||||
hd->nblocks = 0;
|
||||
hd->count = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* Transform the message X which consists of 16 32-bit-words
|
||||
*/
|
||||
static void
|
||||
transform ( RMD160_CONTEXT *hd, const unsigned char *data )
|
||||
{
|
||||
register u32 a,b,c,d,e;
|
||||
u32 aa,bb,cc,dd,ee,t;
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
u32 x[16];
|
||||
{
|
||||
int i;
|
||||
byte *p2, *p1;
|
||||
for (i=0, p1=data, p2=(byte*)x; i < 16; i++, p2 += 4 )
|
||||
{
|
||||
p2[3] = *p1++;
|
||||
p2[2] = *p1++;
|
||||
p2[1] = *p1++;
|
||||
p2[0] = *p1++;
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* This version is better because it is always aligned;
|
||||
* The performance penalty on a 586-100 is about 6% which
|
||||
* is acceptable - because the data is more local it might
|
||||
* also be possible that this is faster on some machines.
|
||||
* This function (when compiled with -02 on gcc 2.7.2)
|
||||
* executes on a 586-100 (39.73 bogomips) at about 1900kb/sec;
|
||||
* [measured with a 4MB data and "gpgm --print-md rmd160"] */
|
||||
u32 x[16];
|
||||
memcpy( x, data, 64 );
|
||||
#endif
|
||||
|
||||
|
||||
#define K0 0x00000000
|
||||
#define K1 0x5A827999
|
||||
#define K2 0x6ED9EBA1
|
||||
#define K3 0x8F1BBCDC
|
||||
#define K4 0xA953FD4E
|
||||
#define KK0 0x50A28BE6
|
||||
#define KK1 0x5C4DD124
|
||||
#define KK2 0x6D703EF3
|
||||
#define KK3 0x7A6D76E9
|
||||
#define KK4 0x00000000
|
||||
#define F0(x,y,z) ( (x) ^ (y) ^ (z) )
|
||||
#define F1(x,y,z) ( ((x) & (y)) | (~(x) & (z)) )
|
||||
#define F2(x,y,z) ( ((x) | ~(y)) ^ (z) )
|
||||
#define F3(x,y,z) ( ((x) & (z)) | ((y) & ~(z)) )
|
||||
#define F4(x,y,z) ( (x) ^ ((y) | ~(z)) )
|
||||
#define R(a,b,c,d,e,f,k,r,s) do { t = a + f(b,c,d) + k + x[r]; \
|
||||
a = rol(t,s) + e; \
|
||||
c = rol(c,10); \
|
||||
} while(0)
|
||||
|
||||
/* left lane */
|
||||
a = hd->h0;
|
||||
b = hd->h1;
|
||||
c = hd->h2;
|
||||
d = hd->h3;
|
||||
e = hd->h4;
|
||||
R( a, b, c, d, e, F0, K0, 0, 11 );
|
||||
R( e, a, b, c, d, F0, K0, 1, 14 );
|
||||
R( d, e, a, b, c, F0, K0, 2, 15 );
|
||||
R( c, d, e, a, b, F0, K0, 3, 12 );
|
||||
R( b, c, d, e, a, F0, K0, 4, 5 );
|
||||
R( a, b, c, d, e, F0, K0, 5, 8 );
|
||||
R( e, a, b, c, d, F0, K0, 6, 7 );
|
||||
R( d, e, a, b, c, F0, K0, 7, 9 );
|
||||
R( c, d, e, a, b, F0, K0, 8, 11 );
|
||||
R( b, c, d, e, a, F0, K0, 9, 13 );
|
||||
R( a, b, c, d, e, F0, K0, 10, 14 );
|
||||
R( e, a, b, c, d, F0, K0, 11, 15 );
|
||||
R( d, e, a, b, c, F0, K0, 12, 6 );
|
||||
R( c, d, e, a, b, F0, K0, 13, 7 );
|
||||
R( b, c, d, e, a, F0, K0, 14, 9 );
|
||||
R( a, b, c, d, e, F0, K0, 15, 8 );
|
||||
R( e, a, b, c, d, F1, K1, 7, 7 );
|
||||
R( d, e, a, b, c, F1, K1, 4, 6 );
|
||||
R( c, d, e, a, b, F1, K1, 13, 8 );
|
||||
R( b, c, d, e, a, F1, K1, 1, 13 );
|
||||
R( a, b, c, d, e, F1, K1, 10, 11 );
|
||||
R( e, a, b, c, d, F1, K1, 6, 9 );
|
||||
R( d, e, a, b, c, F1, K1, 15, 7 );
|
||||
R( c, d, e, a, b, F1, K1, 3, 15 );
|
||||
R( b, c, d, e, a, F1, K1, 12, 7 );
|
||||
R( a, b, c, d, e, F1, K1, 0, 12 );
|
||||
R( e, a, b, c, d, F1, K1, 9, 15 );
|
||||
R( d, e, a, b, c, F1, K1, 5, 9 );
|
||||
R( c, d, e, a, b, F1, K1, 2, 11 );
|
||||
R( b, c, d, e, a, F1, K1, 14, 7 );
|
||||
R( a, b, c, d, e, F1, K1, 11, 13 );
|
||||
R( e, a, b, c, d, F1, K1, 8, 12 );
|
||||
R( d, e, a, b, c, F2, K2, 3, 11 );
|
||||
R( c, d, e, a, b, F2, K2, 10, 13 );
|
||||
R( b, c, d, e, a, F2, K2, 14, 6 );
|
||||
R( a, b, c, d, e, F2, K2, 4, 7 );
|
||||
R( e, a, b, c, d, F2, K2, 9, 14 );
|
||||
R( d, e, a, b, c, F2, K2, 15, 9 );
|
||||
R( c, d, e, a, b, F2, K2, 8, 13 );
|
||||
R( b, c, d, e, a, F2, K2, 1, 15 );
|
||||
R( a, b, c, d, e, F2, K2, 2, 14 );
|
||||
R( e, a, b, c, d, F2, K2, 7, 8 );
|
||||
R( d, e, a, b, c, F2, K2, 0, 13 );
|
||||
R( c, d, e, a, b, F2, K2, 6, 6 );
|
||||
R( b, c, d, e, a, F2, K2, 13, 5 );
|
||||
R( a, b, c, d, e, F2, K2, 11, 12 );
|
||||
R( e, a, b, c, d, F2, K2, 5, 7 );
|
||||
R( d, e, a, b, c, F2, K2, 12, 5 );
|
||||
R( c, d, e, a, b, F3, K3, 1, 11 );
|
||||
R( b, c, d, e, a, F3, K3, 9, 12 );
|
||||
R( a, b, c, d, e, F3, K3, 11, 14 );
|
||||
R( e, a, b, c, d, F3, K3, 10, 15 );
|
||||
R( d, e, a, b, c, F3, K3, 0, 14 );
|
||||
R( c, d, e, a, b, F3, K3, 8, 15 );
|
||||
R( b, c, d, e, a, F3, K3, 12, 9 );
|
||||
R( a, b, c, d, e, F3, K3, 4, 8 );
|
||||
R( e, a, b, c, d, F3, K3, 13, 9 );
|
||||
R( d, e, a, b, c, F3, K3, 3, 14 );
|
||||
R( c, d, e, a, b, F3, K3, 7, 5 );
|
||||
R( b, c, d, e, a, F3, K3, 15, 6 );
|
||||
R( a, b, c, d, e, F3, K3, 14, 8 );
|
||||
R( e, a, b, c, d, F3, K3, 5, 6 );
|
||||
R( d, e, a, b, c, F3, K3, 6, 5 );
|
||||
R( c, d, e, a, b, F3, K3, 2, 12 );
|
||||
R( b, c, d, e, a, F4, K4, 4, 9 );
|
||||
R( a, b, c, d, e, F4, K4, 0, 15 );
|
||||
R( e, a, b, c, d, F4, K4, 5, 5 );
|
||||
R( d, e, a, b, c, F4, K4, 9, 11 );
|
||||
R( c, d, e, a, b, F4, K4, 7, 6 );
|
||||
R( b, c, d, e, a, F4, K4, 12, 8 );
|
||||
R( a, b, c, d, e, F4, K4, 2, 13 );
|
||||
R( e, a, b, c, d, F4, K4, 10, 12 );
|
||||
R( d, e, a, b, c, F4, K4, 14, 5 );
|
||||
R( c, d, e, a, b, F4, K4, 1, 12 );
|
||||
R( b, c, d, e, a, F4, K4, 3, 13 );
|
||||
R( a, b, c, d, e, F4, K4, 8, 14 );
|
||||
R( e, a, b, c, d, F4, K4, 11, 11 );
|
||||
R( d, e, a, b, c, F4, K4, 6, 8 );
|
||||
R( c, d, e, a, b, F4, K4, 15, 5 );
|
||||
R( b, c, d, e, a, F4, K4, 13, 6 );
|
||||
|
||||
aa = a; bb = b; cc = c; dd = d; ee = e;
|
||||
|
||||
/* right lane */
|
||||
a = hd->h0;
|
||||
b = hd->h1;
|
||||
c = hd->h2;
|
||||
d = hd->h3;
|
||||
e = hd->h4;
|
||||
R( a, b, c, d, e, F4, KK0, 5, 8);
|
||||
R( e, a, b, c, d, F4, KK0, 14, 9);
|
||||
R( d, e, a, b, c, F4, KK0, 7, 9);
|
||||
R( c, d, e, a, b, F4, KK0, 0, 11);
|
||||
R( b, c, d, e, a, F4, KK0, 9, 13);
|
||||
R( a, b, c, d, e, F4, KK0, 2, 15);
|
||||
R( e, a, b, c, d, F4, KK0, 11, 15);
|
||||
R( d, e, a, b, c, F4, KK0, 4, 5);
|
||||
R( c, d, e, a, b, F4, KK0, 13, 7);
|
||||
R( b, c, d, e, a, F4, KK0, 6, 7);
|
||||
R( a, b, c, d, e, F4, KK0, 15, 8);
|
||||
R( e, a, b, c, d, F4, KK0, 8, 11);
|
||||
R( d, e, a, b, c, F4, KK0, 1, 14);
|
||||
R( c, d, e, a, b, F4, KK0, 10, 14);
|
||||
R( b, c, d, e, a, F4, KK0, 3, 12);
|
||||
R( a, b, c, d, e, F4, KK0, 12, 6);
|
||||
R( e, a, b, c, d, F3, KK1, 6, 9);
|
||||
R( d, e, a, b, c, F3, KK1, 11, 13);
|
||||
R( c, d, e, a, b, F3, KK1, 3, 15);
|
||||
R( b, c, d, e, a, F3, KK1, 7, 7);
|
||||
R( a, b, c, d, e, F3, KK1, 0, 12);
|
||||
R( e, a, b, c, d, F3, KK1, 13, 8);
|
||||
R( d, e, a, b, c, F3, KK1, 5, 9);
|
||||
R( c, d, e, a, b, F3, KK1, 10, 11);
|
||||
R( b, c, d, e, a, F3, KK1, 14, 7);
|
||||
R( a, b, c, d, e, F3, KK1, 15, 7);
|
||||
R( e, a, b, c, d, F3, KK1, 8, 12);
|
||||
R( d, e, a, b, c, F3, KK1, 12, 7);
|
||||
R( c, d, e, a, b, F3, KK1, 4, 6);
|
||||
R( b, c, d, e, a, F3, KK1, 9, 15);
|
||||
R( a, b, c, d, e, F3, KK1, 1, 13);
|
||||
R( e, a, b, c, d, F3, KK1, 2, 11);
|
||||
R( d, e, a, b, c, F2, KK2, 15, 9);
|
||||
R( c, d, e, a, b, F2, KK2, 5, 7);
|
||||
R( b, c, d, e, a, F2, KK2, 1, 15);
|
||||
R( a, b, c, d, e, F2, KK2, 3, 11);
|
||||
R( e, a, b, c, d, F2, KK2, 7, 8);
|
||||
R( d, e, a, b, c, F2, KK2, 14, 6);
|
||||
R( c, d, e, a, b, F2, KK2, 6, 6);
|
||||
R( b, c, d, e, a, F2, KK2, 9, 14);
|
||||
R( a, b, c, d, e, F2, KK2, 11, 12);
|
||||
R( e, a, b, c, d, F2, KK2, 8, 13);
|
||||
R( d, e, a, b, c, F2, KK2, 12, 5);
|
||||
R( c, d, e, a, b, F2, KK2, 2, 14);
|
||||
R( b, c, d, e, a, F2, KK2, 10, 13);
|
||||
R( a, b, c, d, e, F2, KK2, 0, 13);
|
||||
R( e, a, b, c, d, F2, KK2, 4, 7);
|
||||
R( d, e, a, b, c, F2, KK2, 13, 5);
|
||||
R( c, d, e, a, b, F1, KK3, 8, 15);
|
||||
R( b, c, d, e, a, F1, KK3, 6, 5);
|
||||
R( a, b, c, d, e, F1, KK3, 4, 8);
|
||||
R( e, a, b, c, d, F1, KK3, 1, 11);
|
||||
R( d, e, a, b, c, F1, KK3, 3, 14);
|
||||
R( c, d, e, a, b, F1, KK3, 11, 14);
|
||||
R( b, c, d, e, a, F1, KK3, 15, 6);
|
||||
R( a, b, c, d, e, F1, KK3, 0, 14);
|
||||
R( e, a, b, c, d, F1, KK3, 5, 6);
|
||||
R( d, e, a, b, c, F1, KK3, 12, 9);
|
||||
R( c, d, e, a, b, F1, KK3, 2, 12);
|
||||
R( b, c, d, e, a, F1, KK3, 13, 9);
|
||||
R( a, b, c, d, e, F1, KK3, 9, 12);
|
||||
R( e, a, b, c, d, F1, KK3, 7, 5);
|
||||
R( d, e, a, b, c, F1, KK3, 10, 15);
|
||||
R( c, d, e, a, b, F1, KK3, 14, 8);
|
||||
R( b, c, d, e, a, F0, KK4, 12, 8);
|
||||
R( a, b, c, d, e, F0, KK4, 15, 5);
|
||||
R( e, a, b, c, d, F0, KK4, 10, 12);
|
||||
R( d, e, a, b, c, F0, KK4, 4, 9);
|
||||
R( c, d, e, a, b, F0, KK4, 1, 12);
|
||||
R( b, c, d, e, a, F0, KK4, 5, 5);
|
||||
R( a, b, c, d, e, F0, KK4, 8, 14);
|
||||
R( e, a, b, c, d, F0, KK4, 7, 6);
|
||||
R( d, e, a, b, c, F0, KK4, 6, 8);
|
||||
R( c, d, e, a, b, F0, KK4, 2, 13);
|
||||
R( b, c, d, e, a, F0, KK4, 13, 6);
|
||||
R( a, b, c, d, e, F0, KK4, 14, 5);
|
||||
R( e, a, b, c, d, F0, KK4, 0, 15);
|
||||
R( d, e, a, b, c, F0, KK4, 3, 13);
|
||||
R( c, d, e, a, b, F0, KK4, 9, 11);
|
||||
R( b, c, d, e, a, F0, KK4, 11, 11);
|
||||
|
||||
|
||||
t = hd->h1 + d + cc;
|
||||
hd->h1 = hd->h2 + e + dd;
|
||||
hd->h2 = hd->h3 + a + ee;
|
||||
hd->h3 = hd->h4 + b + aa;
|
||||
hd->h4 = hd->h0 + c + bb;
|
||||
hd->h0 = t;
|
||||
}
|
||||
|
||||
|
||||
/* Update the message digest with the contents
|
||||
* of INBUF with length INLEN.
|
||||
*/
|
||||
static void
|
||||
rmd160_write ( void *context, const void *inbuf_arg, size_t inlen)
|
||||
{
|
||||
const unsigned char *inbuf = inbuf_arg;
|
||||
RMD160_CONTEXT *hd = context;
|
||||
|
||||
if( hd->count == 64 ) /* flush the buffer */
|
||||
{
|
||||
transform( hd, hd->buf );
|
||||
_gcry_burn_stack (108+5*sizeof(void*));
|
||||
hd->count = 0;
|
||||
hd->nblocks++;
|
||||
}
|
||||
if( !inbuf )
|
||||
return;
|
||||
if( hd->count )
|
||||
{
|
||||
for( ; inlen && hd->count < 64; inlen-- )
|
||||
hd->buf[hd->count++] = *inbuf++;
|
||||
rmd160_write( hd, NULL, 0 );
|
||||
if( !inlen )
|
||||
return;
|
||||
}
|
||||
|
||||
while( inlen >= 64 )
|
||||
{
|
||||
transform( hd, inbuf );
|
||||
hd->count = 0;
|
||||
hd->nblocks++;
|
||||
inlen -= 64;
|
||||
inbuf += 64;
|
||||
}
|
||||
_gcry_burn_stack (108+5*sizeof(void*));
|
||||
for( ; inlen && hd->count < 64; inlen-- )
|
||||
hd->buf[hd->count++] = *inbuf++;
|
||||
}
|
||||
|
||||
/****************
|
||||
* Apply the rmd160 transform function on the buffer which must have
|
||||
* a length 64 bytes. Do not use this function together with the
|
||||
* other functions, use rmd160_init to initialize internal variables.
|
||||
* Returns: 16 bytes in buffer with the mixed contentes of buffer.
|
||||
*/
|
||||
void
|
||||
_gcry_rmd160_mixblock ( RMD160_CONTEXT *hd, void *blockof64byte )
|
||||
{
|
||||
char *p = blockof64byte;
|
||||
|
||||
transform ( hd, blockof64byte );
|
||||
#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
|
||||
X(0);
|
||||
X(1);
|
||||
X(2);
|
||||
X(3);
|
||||
X(4);
|
||||
#undef X
|
||||
}
|
||||
|
||||
|
||||
/* The routine terminates the computation
|
||||
*/
|
||||
|
||||
static void
|
||||
rmd160_final( void *context )
|
||||
{
|
||||
RMD160_CONTEXT *hd = context;
|
||||
u32 t, msb, lsb;
|
||||
byte *p;
|
||||
|
||||
rmd160_write(hd, NULL, 0); /* flush */;
|
||||
|
||||
t = hd->nblocks;
|
||||
/* multiply by 64 to make a byte count */
|
||||
lsb = t << 6;
|
||||
msb = t >> 26;
|
||||
/* add the count */
|
||||
t = lsb;
|
||||
if( (lsb += hd->count) < t )
|
||||
msb++;
|
||||
/* multiply by 8 to make a bit count */
|
||||
t = lsb;
|
||||
lsb <<= 3;
|
||||
msb <<= 3;
|
||||
msb |= t >> 29;
|
||||
|
||||
if( hd->count < 56 ) /* enough room */
|
||||
{
|
||||
hd->buf[hd->count++] = 0x80; /* pad */
|
||||
while( hd->count < 56 )
|
||||
hd->buf[hd->count++] = 0; /* pad */
|
||||
}
|
||||
else /* need one extra block */
|
||||
{
|
||||
hd->buf[hd->count++] = 0x80; /* pad character */
|
||||
while( hd->count < 64 )
|
||||
hd->buf[hd->count++] = 0;
|
||||
rmd160_write(hd, NULL, 0); /* flush */;
|
||||
memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
|
||||
}
|
||||
/* append the 64 bit count */
|
||||
hd->buf[56] = lsb ;
|
||||
hd->buf[57] = lsb >> 8;
|
||||
hd->buf[58] = lsb >> 16;
|
||||
hd->buf[59] = lsb >> 24;
|
||||
hd->buf[60] = msb ;
|
||||
hd->buf[61] = msb >> 8;
|
||||
hd->buf[62] = msb >> 16;
|
||||
hd->buf[63] = msb >> 24;
|
||||
transform( hd, hd->buf );
|
||||
_gcry_burn_stack (108+5*sizeof(void*));
|
||||
|
||||
p = hd->buf;
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#define X(a) do { *p++ = hd->h##a ; *p++ = hd->h##a >> 8; \
|
||||
*p++ = hd->h##a >> 16; *p++ = hd->h##a >> 24; } while(0)
|
||||
#else /* little endian */
|
||||
#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
|
||||
#endif
|
||||
X(0);
|
||||
X(1);
|
||||
X(2);
|
||||
X(3);
|
||||
X(4);
|
||||
#undef X
|
||||
}
|
||||
|
||||
static byte *
|
||||
rmd160_read( void *context )
|
||||
{
|
||||
RMD160_CONTEXT *hd = context;
|
||||
|
||||
return hd->buf;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* Shortcut functions which puts the hash value of the supplied buffer
|
||||
* into outbuf which must have a size of 20 bytes.
|
||||
*/
|
||||
void
|
||||
_gcry_rmd160_hash_buffer (void *outbuf, const void *buffer, size_t length )
|
||||
{
|
||||
RMD160_CONTEXT hd;
|
||||
|
||||
_gcry_rmd160_init ( &hd );
|
||||
rmd160_write ( &hd, buffer, length );
|
||||
rmd160_final ( &hd );
|
||||
memcpy ( outbuf, hd.buf, 20 );
|
||||
}
|
||||
|
||||
static byte asn[15] = /* Object ID is 1.3.36.3.2.1 */
|
||||
{ 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03,
|
||||
0x02, 0x01, 0x05, 0x00, 0x04, 0x14 };
|
||||
|
||||
static gcry_md_oid_spec_t oid_spec_rmd160[] =
|
||||
{
|
||||
/* rsaSignatureWithripemd160 */
|
||||
{ "1.3.36.3.3.1.2" },
|
||||
/* TeleTrust hash algorithm. */
|
||||
{ "1.3.36.3.2.1" },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
gcry_md_spec_t _gcry_digest_spec_rmd160 =
|
||||
{
|
||||
"RIPEMD160", asn, DIM (asn), oid_spec_rmd160, 20,
|
||||
_gcry_rmd160_init, rmd160_write, rmd160_final, rmd160_read,
|
||||
sizeof (RMD160_CONTEXT)
|
||||
};
|
1379
lib/libgcrypt/cipher/rsa.c
Normal file
1379
lib/libgcrypt/cipher/rsa.c
Normal file
File diff suppressed because it is too large
Load diff
478
lib/libgcrypt/cipher/seed.c
Normal file
478
lib/libgcrypt/cipher/seed.c
Normal file
|
@ -0,0 +1,478 @@
|
|||
/* SEED for libgcrypt
|
||||
* Copyright (C) 2006 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of Libgcrypt.
|
||||
*
|
||||
* Libgcrypt is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Libgcrypt is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*
|
||||
* --
|
||||
* This implementation was provided for libgcrypt in public domain
|
||||
* by Hye-Shik Chang <perky@FreeBSD.org>, July 2006.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "types.h" /* for byte and u32 typedefs */
|
||||
#include "g10lib.h"
|
||||
#include "cipher.h"
|
||||
|
||||
#define NUMKC 16
|
||||
|
||||
#define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ \
|
||||
((u32)(pt)[2] << 8) ^ ((u32)(pt)[3]))
|
||||
#define PUTU32(ct, st) { (ct)[0] = (byte)((st) >> 24); \
|
||||
(ct)[1] = (byte)((st) >> 16); \
|
||||
(ct)[2] = (byte)((st) >> 8); \
|
||||
(ct)[3] = (byte)(st); }
|
||||
|
||||
union wordbuf
|
||||
{
|
||||
u32 w;
|
||||
byte b[4];
|
||||
};
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#define b0 b[3]
|
||||
#define b1 b[2]
|
||||
#define b2 b[1]
|
||||
#define b3 b[0]
|
||||
#else
|
||||
#define b0 b[0]
|
||||
#define b1 b[1]
|
||||
#define b2 b[2]
|
||||
#define b3 b[3]
|
||||
#endif
|
||||
|
||||
static const char *selftest(void);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 keyschedule[32];
|
||||
} SEED_context;
|
||||
|
||||
static const u32 SS0[256] = {
|
||||
0x2989a1a8, 0x05858184, 0x16c6d2d4, 0x13c3d3d0, 0x14445054, 0x1d0d111c,
|
||||
0x2c8ca0ac, 0x25052124, 0x1d4d515c, 0x03434340, 0x18081018, 0x1e0e121c,
|
||||
0x11415150, 0x3cccf0fc, 0x0acac2c8, 0x23436360, 0x28082028, 0x04444044,
|
||||
0x20002020, 0x1d8d919c, 0x20c0e0e0, 0x22c2e2e0, 0x08c8c0c8, 0x17071314,
|
||||
0x2585a1a4, 0x0f8f838c, 0x03030300, 0x3b4b7378, 0x3b8bb3b8, 0x13031310,
|
||||
0x12c2d2d0, 0x2ecee2ec, 0x30407070, 0x0c8c808c, 0x3f0f333c, 0x2888a0a8,
|
||||
0x32023230, 0x1dcdd1dc, 0x36c6f2f4, 0x34447074, 0x2ccce0ec, 0x15859194,
|
||||
0x0b0b0308, 0x17475354, 0x1c4c505c, 0x1b4b5358, 0x3d8db1bc, 0x01010100,
|
||||
0x24042024, 0x1c0c101c, 0x33437370, 0x18889098, 0x10001010, 0x0cccc0cc,
|
||||
0x32c2f2f0, 0x19c9d1d8, 0x2c0c202c, 0x27c7e3e4, 0x32427270, 0x03838380,
|
||||
0x1b8b9398, 0x11c1d1d0, 0x06868284, 0x09c9c1c8, 0x20406060, 0x10405050,
|
||||
0x2383a3a0, 0x2bcbe3e8, 0x0d0d010c, 0x3686b2b4, 0x1e8e929c, 0x0f4f434c,
|
||||
0x3787b3b4, 0x1a4a5258, 0x06c6c2c4, 0x38487078, 0x2686a2a4, 0x12021210,
|
||||
0x2f8fa3ac, 0x15c5d1d4, 0x21416160, 0x03c3c3c0, 0x3484b0b4, 0x01414140,
|
||||
0x12425250, 0x3d4d717c, 0x0d8d818c, 0x08080008, 0x1f0f131c, 0x19899198,
|
||||
0x00000000, 0x19091118, 0x04040004, 0x13435350, 0x37c7f3f4, 0x21c1e1e0,
|
||||
0x3dcdf1fc, 0x36467274, 0x2f0f232c, 0x27072324, 0x3080b0b0, 0x0b8b8388,
|
||||
0x0e0e020c, 0x2b8ba3a8, 0x2282a2a0, 0x2e4e626c, 0x13839390, 0x0d4d414c,
|
||||
0x29496168, 0x3c4c707c, 0x09090108, 0x0a0a0208, 0x3f8fb3bc, 0x2fcfe3ec,
|
||||
0x33c3f3f0, 0x05c5c1c4, 0x07878384, 0x14041014, 0x3ecef2fc, 0x24446064,
|
||||
0x1eced2dc, 0x2e0e222c, 0x0b4b4348, 0x1a0a1218, 0x06060204, 0x21012120,
|
||||
0x2b4b6368, 0x26466264, 0x02020200, 0x35c5f1f4, 0x12829290, 0x0a8a8288,
|
||||
0x0c0c000c, 0x3383b3b0, 0x3e4e727c, 0x10c0d0d0, 0x3a4a7278, 0x07474344,
|
||||
0x16869294, 0x25c5e1e4, 0x26062224, 0x00808080, 0x2d8da1ac, 0x1fcfd3dc,
|
||||
0x2181a1a0, 0x30003030, 0x37073334, 0x2e8ea2ac, 0x36063234, 0x15051114,
|
||||
0x22022220, 0x38083038, 0x34c4f0f4, 0x2787a3a4, 0x05454144, 0x0c4c404c,
|
||||
0x01818180, 0x29c9e1e8, 0x04848084, 0x17879394, 0x35053134, 0x0bcbc3c8,
|
||||
0x0ecec2cc, 0x3c0c303c, 0x31417170, 0x11011110, 0x07c7c3c4, 0x09898188,
|
||||
0x35457174, 0x3bcbf3f8, 0x1acad2d8, 0x38c8f0f8, 0x14849094, 0x19495158,
|
||||
0x02828280, 0x04c4c0c4, 0x3fcff3fc, 0x09494148, 0x39093138, 0x27476364,
|
||||
0x00c0c0c0, 0x0fcfc3cc, 0x17c7d3d4, 0x3888b0b8, 0x0f0f030c, 0x0e8e828c,
|
||||
0x02424240, 0x23032320, 0x11819190, 0x2c4c606c, 0x1bcbd3d8, 0x2484a0a4,
|
||||
0x34043034, 0x31c1f1f0, 0x08484048, 0x02c2c2c0, 0x2f4f636c, 0x3d0d313c,
|
||||
0x2d0d212c, 0x00404040, 0x3e8eb2bc, 0x3e0e323c, 0x3c8cb0bc, 0x01c1c1c0,
|
||||
0x2a8aa2a8, 0x3a8ab2b8, 0x0e4e424c, 0x15455154, 0x3b0b3338, 0x1cccd0dc,
|
||||
0x28486068, 0x3f4f737c, 0x1c8c909c, 0x18c8d0d8, 0x0a4a4248, 0x16465254,
|
||||
0x37477374, 0x2080a0a0, 0x2dcde1ec, 0x06464244, 0x3585b1b4, 0x2b0b2328,
|
||||
0x25456164, 0x3acaf2f8, 0x23c3e3e0, 0x3989b1b8, 0x3181b1b0, 0x1f8f939c,
|
||||
0x1e4e525c, 0x39c9f1f8, 0x26c6e2e4, 0x3282b2b0, 0x31013130, 0x2acae2e8,
|
||||
0x2d4d616c, 0x1f4f535c, 0x24c4e0e4, 0x30c0f0f0, 0x0dcdc1cc, 0x08888088,
|
||||
0x16061214, 0x3a0a3238, 0x18485058, 0x14c4d0d4, 0x22426260, 0x29092128,
|
||||
0x07070304, 0x33033330, 0x28c8e0e8, 0x1b0b1318, 0x05050104, 0x39497178,
|
||||
0x10809090, 0x2a4a6268, 0x2a0a2228, 0x1a8a9298,
|
||||
};
|
||||
|
||||
static const u32 SS1[256] = {
|
||||
0x38380830, 0xe828c8e0, 0x2c2d0d21, 0xa42686a2, 0xcc0fcfc3, 0xdc1eced2,
|
||||
0xb03383b3, 0xb83888b0, 0xac2f8fa3, 0x60204060, 0x54154551, 0xc407c7c3,
|
||||
0x44044440, 0x6c2f4f63, 0x682b4b63, 0x581b4b53, 0xc003c3c3, 0x60224262,
|
||||
0x30330333, 0xb43585b1, 0x28290921, 0xa02080a0, 0xe022c2e2, 0xa42787a3,
|
||||
0xd013c3d3, 0x90118191, 0x10110111, 0x04060602, 0x1c1c0c10, 0xbc3c8cb0,
|
||||
0x34360632, 0x480b4b43, 0xec2fcfe3, 0x88088880, 0x6c2c4c60, 0xa82888a0,
|
||||
0x14170713, 0xc404c4c0, 0x14160612, 0xf434c4f0, 0xc002c2c2, 0x44054541,
|
||||
0xe021c1e1, 0xd416c6d2, 0x3c3f0f33, 0x3c3d0d31, 0x8c0e8e82, 0x98188890,
|
||||
0x28280820, 0x4c0e4e42, 0xf436c6f2, 0x3c3e0e32, 0xa42585a1, 0xf839c9f1,
|
||||
0x0c0d0d01, 0xdc1fcfd3, 0xd818c8d0, 0x282b0b23, 0x64264662, 0x783a4a72,
|
||||
0x24270723, 0x2c2f0f23, 0xf031c1f1, 0x70324272, 0x40024242, 0xd414c4d0,
|
||||
0x40014141, 0xc000c0c0, 0x70334373, 0x64274763, 0xac2c8ca0, 0x880b8b83,
|
||||
0xf437c7f3, 0xac2d8da1, 0x80008080, 0x1c1f0f13, 0xc80acac2, 0x2c2c0c20,
|
||||
0xa82a8aa2, 0x34340430, 0xd012c2d2, 0x080b0b03, 0xec2ecee2, 0xe829c9e1,
|
||||
0x5c1d4d51, 0x94148490, 0x18180810, 0xf838c8f0, 0x54174753, 0xac2e8ea2,
|
||||
0x08080800, 0xc405c5c1, 0x10130313, 0xcc0dcdc1, 0x84068682, 0xb83989b1,
|
||||
0xfc3fcff3, 0x7c3d4d71, 0xc001c1c1, 0x30310131, 0xf435c5f1, 0x880a8a82,
|
||||
0x682a4a62, 0xb03181b1, 0xd011c1d1, 0x20200020, 0xd417c7d3, 0x00020202,
|
||||
0x20220222, 0x04040400, 0x68284860, 0x70314171, 0x04070703, 0xd81bcbd3,
|
||||
0x9c1d8d91, 0x98198991, 0x60214161, 0xbc3e8eb2, 0xe426c6e2, 0x58194951,
|
||||
0xdc1dcdd1, 0x50114151, 0x90108090, 0xdc1cccd0, 0x981a8a92, 0xa02383a3,
|
||||
0xa82b8ba3, 0xd010c0d0, 0x80018181, 0x0c0f0f03, 0x44074743, 0x181a0a12,
|
||||
0xe023c3e3, 0xec2ccce0, 0x8c0d8d81, 0xbc3f8fb3, 0x94168692, 0x783b4b73,
|
||||
0x5c1c4c50, 0xa02282a2, 0xa02181a1, 0x60234363, 0x20230323, 0x4c0d4d41,
|
||||
0xc808c8c0, 0x9c1e8e92, 0x9c1c8c90, 0x383a0a32, 0x0c0c0c00, 0x2c2e0e22,
|
||||
0xb83a8ab2, 0x6c2e4e62, 0x9c1f8f93, 0x581a4a52, 0xf032c2f2, 0x90128292,
|
||||
0xf033c3f3, 0x48094941, 0x78384870, 0xcc0cccc0, 0x14150511, 0xf83bcbf3,
|
||||
0x70304070, 0x74354571, 0x7c3f4f73, 0x34350531, 0x10100010, 0x00030303,
|
||||
0x64244460, 0x6c2d4d61, 0xc406c6c2, 0x74344470, 0xd415c5d1, 0xb43484b0,
|
||||
0xe82acae2, 0x08090901, 0x74364672, 0x18190911, 0xfc3ecef2, 0x40004040,
|
||||
0x10120212, 0xe020c0e0, 0xbc3d8db1, 0x04050501, 0xf83acaf2, 0x00010101,
|
||||
0xf030c0f0, 0x282a0a22, 0x5c1e4e52, 0xa82989a1, 0x54164652, 0x40034343,
|
||||
0x84058581, 0x14140410, 0x88098981, 0x981b8b93, 0xb03080b0, 0xe425c5e1,
|
||||
0x48084840, 0x78394971, 0x94178793, 0xfc3cccf0, 0x1c1e0e12, 0x80028282,
|
||||
0x20210121, 0x8c0c8c80, 0x181b0b13, 0x5c1f4f53, 0x74374773, 0x54144450,
|
||||
0xb03282b2, 0x1c1d0d11, 0x24250521, 0x4c0f4f43, 0x00000000, 0x44064642,
|
||||
0xec2dcde1, 0x58184850, 0x50124252, 0xe82bcbe3, 0x7c3e4e72, 0xd81acad2,
|
||||
0xc809c9c1, 0xfc3dcdf1, 0x30300030, 0x94158591, 0x64254561, 0x3c3c0c30,
|
||||
0xb43686b2, 0xe424c4e0, 0xb83b8bb3, 0x7c3c4c70, 0x0c0e0e02, 0x50104050,
|
||||
0x38390931, 0x24260622, 0x30320232, 0x84048480, 0x68294961, 0x90138393,
|
||||
0x34370733, 0xe427c7e3, 0x24240420, 0xa42484a0, 0xc80bcbc3, 0x50134353,
|
||||
0x080a0a02, 0x84078783, 0xd819c9d1, 0x4c0c4c40, 0x80038383, 0x8c0f8f83,
|
||||
0xcc0ecec2, 0x383b0b33, 0x480a4a42, 0xb43787b3,
|
||||
};
|
||||
|
||||
static const u32 SS2[256] = {
|
||||
0xa1a82989, 0x81840585, 0xd2d416c6, 0xd3d013c3, 0x50541444, 0x111c1d0d,
|
||||
0xa0ac2c8c, 0x21242505, 0x515c1d4d, 0x43400343, 0x10181808, 0x121c1e0e,
|
||||
0x51501141, 0xf0fc3ccc, 0xc2c80aca, 0x63602343, 0x20282808, 0x40440444,
|
||||
0x20202000, 0x919c1d8d, 0xe0e020c0, 0xe2e022c2, 0xc0c808c8, 0x13141707,
|
||||
0xa1a42585, 0x838c0f8f, 0x03000303, 0x73783b4b, 0xb3b83b8b, 0x13101303,
|
||||
0xd2d012c2, 0xe2ec2ece, 0x70703040, 0x808c0c8c, 0x333c3f0f, 0xa0a82888,
|
||||
0x32303202, 0xd1dc1dcd, 0xf2f436c6, 0x70743444, 0xe0ec2ccc, 0x91941585,
|
||||
0x03080b0b, 0x53541747, 0x505c1c4c, 0x53581b4b, 0xb1bc3d8d, 0x01000101,
|
||||
0x20242404, 0x101c1c0c, 0x73703343, 0x90981888, 0x10101000, 0xc0cc0ccc,
|
||||
0xf2f032c2, 0xd1d819c9, 0x202c2c0c, 0xe3e427c7, 0x72703242, 0x83800383,
|
||||
0x93981b8b, 0xd1d011c1, 0x82840686, 0xc1c809c9, 0x60602040, 0x50501040,
|
||||
0xa3a02383, 0xe3e82bcb, 0x010c0d0d, 0xb2b43686, 0x929c1e8e, 0x434c0f4f,
|
||||
0xb3b43787, 0x52581a4a, 0xc2c406c6, 0x70783848, 0xa2a42686, 0x12101202,
|
||||
0xa3ac2f8f, 0xd1d415c5, 0x61602141, 0xc3c003c3, 0xb0b43484, 0x41400141,
|
||||
0x52501242, 0x717c3d4d, 0x818c0d8d, 0x00080808, 0x131c1f0f, 0x91981989,
|
||||
0x00000000, 0x11181909, 0x00040404, 0x53501343, 0xf3f437c7, 0xe1e021c1,
|
||||
0xf1fc3dcd, 0x72743646, 0x232c2f0f, 0x23242707, 0xb0b03080, 0x83880b8b,
|
||||
0x020c0e0e, 0xa3a82b8b, 0xa2a02282, 0x626c2e4e, 0x93901383, 0x414c0d4d,
|
||||
0x61682949, 0x707c3c4c, 0x01080909, 0x02080a0a, 0xb3bc3f8f, 0xe3ec2fcf,
|
||||
0xf3f033c3, 0xc1c405c5, 0x83840787, 0x10141404, 0xf2fc3ece, 0x60642444,
|
||||
0xd2dc1ece, 0x222c2e0e, 0x43480b4b, 0x12181a0a, 0x02040606, 0x21202101,
|
||||
0x63682b4b, 0x62642646, 0x02000202, 0xf1f435c5, 0x92901282, 0x82880a8a,
|
||||
0x000c0c0c, 0xb3b03383, 0x727c3e4e, 0xd0d010c0, 0x72783a4a, 0x43440747,
|
||||
0x92941686, 0xe1e425c5, 0x22242606, 0x80800080, 0xa1ac2d8d, 0xd3dc1fcf,
|
||||
0xa1a02181, 0x30303000, 0x33343707, 0xa2ac2e8e, 0x32343606, 0x11141505,
|
||||
0x22202202, 0x30383808, 0xf0f434c4, 0xa3a42787, 0x41440545, 0x404c0c4c,
|
||||
0x81800181, 0xe1e829c9, 0x80840484, 0x93941787, 0x31343505, 0xc3c80bcb,
|
||||
0xc2cc0ece, 0x303c3c0c, 0x71703141, 0x11101101, 0xc3c407c7, 0x81880989,
|
||||
0x71743545, 0xf3f83bcb, 0xd2d81aca, 0xf0f838c8, 0x90941484, 0x51581949,
|
||||
0x82800282, 0xc0c404c4, 0xf3fc3fcf, 0x41480949, 0x31383909, 0x63642747,
|
||||
0xc0c000c0, 0xc3cc0fcf, 0xd3d417c7, 0xb0b83888, 0x030c0f0f, 0x828c0e8e,
|
||||
0x42400242, 0x23202303, 0x91901181, 0x606c2c4c, 0xd3d81bcb, 0xa0a42484,
|
||||
0x30343404, 0xf1f031c1, 0x40480848, 0xc2c002c2, 0x636c2f4f, 0x313c3d0d,
|
||||
0x212c2d0d, 0x40400040, 0xb2bc3e8e, 0x323c3e0e, 0xb0bc3c8c, 0xc1c001c1,
|
||||
0xa2a82a8a, 0xb2b83a8a, 0x424c0e4e, 0x51541545, 0x33383b0b, 0xd0dc1ccc,
|
||||
0x60682848, 0x737c3f4f, 0x909c1c8c, 0xd0d818c8, 0x42480a4a, 0x52541646,
|
||||
0x73743747, 0xa0a02080, 0xe1ec2dcd, 0x42440646, 0xb1b43585, 0x23282b0b,
|
||||
0x61642545, 0xf2f83aca, 0xe3e023c3, 0xb1b83989, 0xb1b03181, 0x939c1f8f,
|
||||
0x525c1e4e, 0xf1f839c9, 0xe2e426c6, 0xb2b03282, 0x31303101, 0xe2e82aca,
|
||||
0x616c2d4d, 0x535c1f4f, 0xe0e424c4, 0xf0f030c0, 0xc1cc0dcd, 0x80880888,
|
||||
0x12141606, 0x32383a0a, 0x50581848, 0xd0d414c4, 0x62602242, 0x21282909,
|
||||
0x03040707, 0x33303303, 0xe0e828c8, 0x13181b0b, 0x01040505, 0x71783949,
|
||||
0x90901080, 0x62682a4a, 0x22282a0a, 0x92981a8a,
|
||||
};
|
||||
|
||||
static const u32 SS3[256] = {
|
||||
0x08303838, 0xc8e0e828, 0x0d212c2d, 0x86a2a426, 0xcfc3cc0f, 0xced2dc1e,
|
||||
0x83b3b033, 0x88b0b838, 0x8fa3ac2f, 0x40606020, 0x45515415, 0xc7c3c407,
|
||||
0x44404404, 0x4f636c2f, 0x4b63682b, 0x4b53581b, 0xc3c3c003, 0x42626022,
|
||||
0x03333033, 0x85b1b435, 0x09212829, 0x80a0a020, 0xc2e2e022, 0x87a3a427,
|
||||
0xc3d3d013, 0x81919011, 0x01111011, 0x06020406, 0x0c101c1c, 0x8cb0bc3c,
|
||||
0x06323436, 0x4b43480b, 0xcfe3ec2f, 0x88808808, 0x4c606c2c, 0x88a0a828,
|
||||
0x07131417, 0xc4c0c404, 0x06121416, 0xc4f0f434, 0xc2c2c002, 0x45414405,
|
||||
0xc1e1e021, 0xc6d2d416, 0x0f333c3f, 0x0d313c3d, 0x8e828c0e, 0x88909818,
|
||||
0x08202828, 0x4e424c0e, 0xc6f2f436, 0x0e323c3e, 0x85a1a425, 0xc9f1f839,
|
||||
0x0d010c0d, 0xcfd3dc1f, 0xc8d0d818, 0x0b23282b, 0x46626426, 0x4a72783a,
|
||||
0x07232427, 0x0f232c2f, 0xc1f1f031, 0x42727032, 0x42424002, 0xc4d0d414,
|
||||
0x41414001, 0xc0c0c000, 0x43737033, 0x47636427, 0x8ca0ac2c, 0x8b83880b,
|
||||
0xc7f3f437, 0x8da1ac2d, 0x80808000, 0x0f131c1f, 0xcac2c80a, 0x0c202c2c,
|
||||
0x8aa2a82a, 0x04303434, 0xc2d2d012, 0x0b03080b, 0xcee2ec2e, 0xc9e1e829,
|
||||
0x4d515c1d, 0x84909414, 0x08101818, 0xc8f0f838, 0x47535417, 0x8ea2ac2e,
|
||||
0x08000808, 0xc5c1c405, 0x03131013, 0xcdc1cc0d, 0x86828406, 0x89b1b839,
|
||||
0xcff3fc3f, 0x4d717c3d, 0xc1c1c001, 0x01313031, 0xc5f1f435, 0x8a82880a,
|
||||
0x4a62682a, 0x81b1b031, 0xc1d1d011, 0x00202020, 0xc7d3d417, 0x02020002,
|
||||
0x02222022, 0x04000404, 0x48606828, 0x41717031, 0x07030407, 0xcbd3d81b,
|
||||
0x8d919c1d, 0x89919819, 0x41616021, 0x8eb2bc3e, 0xc6e2e426, 0x49515819,
|
||||
0xcdd1dc1d, 0x41515011, 0x80909010, 0xccd0dc1c, 0x8a92981a, 0x83a3a023,
|
||||
0x8ba3a82b, 0xc0d0d010, 0x81818001, 0x0f030c0f, 0x47434407, 0x0a12181a,
|
||||
0xc3e3e023, 0xcce0ec2c, 0x8d818c0d, 0x8fb3bc3f, 0x86929416, 0x4b73783b,
|
||||
0x4c505c1c, 0x82a2a022, 0x81a1a021, 0x43636023, 0x03232023, 0x4d414c0d,
|
||||
0xc8c0c808, 0x8e929c1e, 0x8c909c1c, 0x0a32383a, 0x0c000c0c, 0x0e222c2e,
|
||||
0x8ab2b83a, 0x4e626c2e, 0x8f939c1f, 0x4a52581a, 0xc2f2f032, 0x82929012,
|
||||
0xc3f3f033, 0x49414809, 0x48707838, 0xccc0cc0c, 0x05111415, 0xcbf3f83b,
|
||||
0x40707030, 0x45717435, 0x4f737c3f, 0x05313435, 0x00101010, 0x03030003,
|
||||
0x44606424, 0x4d616c2d, 0xc6c2c406, 0x44707434, 0xc5d1d415, 0x84b0b434,
|
||||
0xcae2e82a, 0x09010809, 0x46727436, 0x09111819, 0xcef2fc3e, 0x40404000,
|
||||
0x02121012, 0xc0e0e020, 0x8db1bc3d, 0x05010405, 0xcaf2f83a, 0x01010001,
|
||||
0xc0f0f030, 0x0a22282a, 0x4e525c1e, 0x89a1a829, 0x46525416, 0x43434003,
|
||||
0x85818405, 0x04101414, 0x89818809, 0x8b93981b, 0x80b0b030, 0xc5e1e425,
|
||||
0x48404808, 0x49717839, 0x87939417, 0xccf0fc3c, 0x0e121c1e, 0x82828002,
|
||||
0x01212021, 0x8c808c0c, 0x0b13181b, 0x4f535c1f, 0x47737437, 0x44505414,
|
||||
0x82b2b032, 0x0d111c1d, 0x05212425, 0x4f434c0f, 0x00000000, 0x46424406,
|
||||
0xcde1ec2d, 0x48505818, 0x42525012, 0xcbe3e82b, 0x4e727c3e, 0xcad2d81a,
|
||||
0xc9c1c809, 0xcdf1fc3d, 0x00303030, 0x85919415, 0x45616425, 0x0c303c3c,
|
||||
0x86b2b436, 0xc4e0e424, 0x8bb3b83b, 0x4c707c3c, 0x0e020c0e, 0x40505010,
|
||||
0x09313839, 0x06222426, 0x02323032, 0x84808404, 0x49616829, 0x83939013,
|
||||
0x07333437, 0xc7e3e427, 0x04202424, 0x84a0a424, 0xcbc3c80b, 0x43535013,
|
||||
0x0a02080a, 0x87838407, 0xc9d1d819, 0x4c404c0c, 0x83838003, 0x8f838c0f,
|
||||
0xcec2cc0e, 0x0b33383b, 0x4a42480a, 0x87b3b437,
|
||||
};
|
||||
|
||||
static const u32 KC[NUMKC] = {
|
||||
0x9e3779b9, 0x3c6ef373, 0x78dde6e6, 0xf1bbcdcc,
|
||||
0xe3779b99, 0xc6ef3733, 0x8dde6e67, 0x1bbcdccf,
|
||||
0x3779b99e, 0x6ef3733c, 0xdde6e678, 0xbbcdccf1,
|
||||
0x779b99e3, 0xef3733c6, 0xde6e678d, 0xbcdccf1b,
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* Perform the key setup.
|
||||
*/
|
||||
static gcry_err_code_t
|
||||
do_setkey (SEED_context *ctx, const byte *key, const unsigned keylen)
|
||||
{
|
||||
static int initialized = 0;
|
||||
static const char *selftest_failed=0;
|
||||
u32 x1, x2, x3, x4;
|
||||
union wordbuf t0, t1;
|
||||
u32 *keyout = ctx->keyschedule;
|
||||
int i;
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
initialized = 1;
|
||||
selftest_failed = selftest ();
|
||||
if( selftest_failed )
|
||||
log_error ("%s\n", selftest_failed );
|
||||
}
|
||||
if (selftest_failed)
|
||||
return GPG_ERR_SELFTEST_FAILED;
|
||||
|
||||
if (keylen != 16)
|
||||
return GPG_ERR_INV_KEYLEN;
|
||||
|
||||
x1 = GETU32 (key);
|
||||
x2 = GETU32 (key+4);
|
||||
x3 = GETU32 (key+8);
|
||||
x4 = GETU32 (key+12);
|
||||
|
||||
for (i = 0; i < NUMKC; i++)
|
||||
{
|
||||
t0.w = x1 + x3 - KC[i];
|
||||
t1.w = x2 + KC[i] - x4;
|
||||
*(keyout++) = SS0[t0.b0] ^ SS1[t0.b1] ^ SS2[t0.b2] ^ SS3[t0.b3];
|
||||
*(keyout++) = SS0[t1.b0] ^ SS1[t1.b1] ^ SS2[t1.b2] ^ SS3[t1.b3];
|
||||
|
||||
if (i % 2 == 0)
|
||||
{
|
||||
t0.w = x1;
|
||||
x1 = (x1>>8) ^ (x2<<24);
|
||||
x2 = (x2>>8) ^ (t0.w<<24);
|
||||
}
|
||||
else
|
||||
{
|
||||
t0.w = x3;
|
||||
x3 = (x3<<8) ^ (x4>>24);
|
||||
x4 = (x4<<8) ^ (t0.w>>24);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static gcry_err_code_t
|
||||
seed_setkey (void *context, const byte *key, const unsigned keylen)
|
||||
{
|
||||
SEED_context *ctx = context;
|
||||
|
||||
int rc = do_setkey (ctx, key, keylen);
|
||||
_gcry_burn_stack (4*6 + sizeof(void*)*2 + sizeof(int)*2);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define OP(X1, X2, X3, X4, rbase) \
|
||||
t0.w = X3 ^ ctx->keyschedule[rbase]; \
|
||||
t1.w = X4 ^ ctx->keyschedule[rbase+1]; \
|
||||
t1.w ^= t0.w; \
|
||||
t1.w = SS0[t1.b0] ^ SS1[t1.b1] ^ SS2[t1.b2] ^ SS3[t1.b3]; \
|
||||
t0.w += t1.w; \
|
||||
t0.w = SS0[t0.b0] ^ SS1[t0.b1] ^ SS2[t0.b2] ^ SS3[t0.b3]; \
|
||||
t1.w += t0.w; \
|
||||
t1.w = SS0[t1.b0] ^ SS1[t1.b1] ^ SS2[t1.b2] ^ SS3[t1.b3]; \
|
||||
t0.w += t1.w; \
|
||||
X1 ^= t0.w; \
|
||||
X2 ^= t1.w;
|
||||
|
||||
/* Encrypt one block. inbuf and outbuf may be the same. */
|
||||
static void
|
||||
do_encrypt (const SEED_context *ctx, byte *outbuf, const byte *inbuf)
|
||||
{
|
||||
u32 x1, x2, x3, x4;
|
||||
union wordbuf t0, t1;
|
||||
|
||||
x1 = GETU32 (inbuf);
|
||||
x2 = GETU32 (inbuf+4);
|
||||
x3 = GETU32 (inbuf+8);
|
||||
x4 = GETU32 (inbuf+12);
|
||||
|
||||
OP (x1, x2, x3, x4, 0);
|
||||
OP (x3, x4, x1, x2, 2);
|
||||
OP (x1, x2, x3, x4, 4);
|
||||
OP (x3, x4, x1, x2, 6);
|
||||
OP (x1, x2, x3, x4, 8);
|
||||
OP (x3, x4, x1, x2, 10);
|
||||
OP (x1, x2, x3, x4, 12);
|
||||
OP (x3, x4, x1, x2, 14);
|
||||
OP (x1, x2, x3, x4, 16);
|
||||
OP (x3, x4, x1, x2, 18);
|
||||
OP (x1, x2, x3, x4, 20);
|
||||
OP (x3, x4, x1, x2, 22);
|
||||
OP (x1, x2, x3, x4, 24);
|
||||
OP (x3, x4, x1, x2, 26);
|
||||
OP (x1, x2, x3, x4, 28);
|
||||
OP (x3, x4, x1, x2, 30);
|
||||
|
||||
PUTU32 (outbuf, x3);
|
||||
PUTU32 (outbuf+4, x4);
|
||||
PUTU32 (outbuf+8, x1);
|
||||
PUTU32 (outbuf+12, x2);
|
||||
}
|
||||
|
||||
static void
|
||||
seed_encrypt (void *context, byte *outbuf, const byte *inbuf)
|
||||
{
|
||||
SEED_context *ctx = context;
|
||||
|
||||
do_encrypt (ctx, outbuf, inbuf);
|
||||
_gcry_burn_stack (4*6);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Decrypt one block. inbuf and outbuf may be the same. */
|
||||
static void
|
||||
do_decrypt (SEED_context *ctx, byte *outbuf, const byte *inbuf)
|
||||
{
|
||||
u32 x1, x2, x3, x4;
|
||||
union wordbuf t0, t1;
|
||||
|
||||
x1 = GETU32 (inbuf);
|
||||
x2 = GETU32 (inbuf+4);
|
||||
x3 = GETU32 (inbuf+8);
|
||||
x4 = GETU32 (inbuf+12);
|
||||
|
||||
OP (x1, x2, x3, x4, 30);
|
||||
OP (x3, x4, x1, x2, 28);
|
||||
OP (x1, x2, x3, x4, 26);
|
||||
OP (x3, x4, x1, x2, 24);
|
||||
OP (x1, x2, x3, x4, 22);
|
||||
OP (x3, x4, x1, x2, 20);
|
||||
OP (x1, x2, x3, x4, 18);
|
||||
OP (x3, x4, x1, x2, 16);
|
||||
OP (x1, x2, x3, x4, 14);
|
||||
OP (x3, x4, x1, x2, 12);
|
||||
OP (x1, x2, x3, x4, 10);
|
||||
OP (x3, x4, x1, x2, 8);
|
||||
OP (x1, x2, x3, x4, 6);
|
||||
OP (x3, x4, x1, x2, 4);
|
||||
OP (x1, x2, x3, x4, 2);
|
||||
OP (x3, x4, x1, x2, 0);
|
||||
|
||||
PUTU32 (outbuf, x3);
|
||||
PUTU32 (outbuf+4, x4);
|
||||
PUTU32 (outbuf+8, x1);
|
||||
PUTU32 (outbuf+12, x2);
|
||||
}
|
||||
|
||||
static void
|
||||
seed_decrypt (void *context, byte *outbuf, const byte *inbuf)
|
||||
{
|
||||
SEED_context *ctx = context;
|
||||
|
||||
do_decrypt (ctx, outbuf, inbuf);
|
||||
_gcry_burn_stack (4*6);
|
||||
}
|
||||
|
||||
|
||||
/* Test a single encryption and decryption with each key size. */
|
||||
static const char*
|
||||
selftest (void)
|
||||
{
|
||||
SEED_context ctx;
|
||||
byte scratch[16];
|
||||
|
||||
/* The test vector is taken from the appendix section B.3 of RFC4269.
|
||||
*/
|
||||
static const byte plaintext[16] = {
|
||||
0x83, 0xA2, 0xF8, 0xA2, 0x88, 0x64, 0x1F, 0xB9,
|
||||
0xA4, 0xE9, 0xA5, 0xCC, 0x2F, 0x13, 0x1C, 0x7D
|
||||
};
|
||||
static const byte key[16] = {
|
||||
0x47, 0x06, 0x48, 0x08, 0x51, 0xE6, 0x1B, 0xE8,
|
||||
0x5D, 0x74, 0xBF, 0xB3, 0xFD, 0x95, 0x61, 0x85
|
||||
};
|
||||
static const byte ciphertext[16] = {
|
||||
0xEE, 0x54, 0xD1, 0x3E, 0xBC, 0xAE, 0x70, 0x6D,
|
||||
0x22, 0x6B, 0xC3, 0x14, 0x2C, 0xD4, 0x0D, 0x4A,
|
||||
};
|
||||
|
||||
seed_setkey (&ctx, key, sizeof(key));
|
||||
seed_encrypt (&ctx, scratch, plaintext);
|
||||
if (memcmp (scratch, ciphertext, sizeof (ciphertext)))
|
||||
return "SEED test encryption failed.";
|
||||
seed_decrypt (&ctx, scratch, scratch);
|
||||
if (memcmp (scratch, plaintext, sizeof (plaintext)))
|
||||
return "SEED test decryption failed.";
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static gcry_cipher_oid_spec_t seed_oids[] =
|
||||
{
|
||||
{ "1.2.410.200004.1.3", GCRY_CIPHER_MODE_ECB },
|
||||
{ "1.2.410.200004.1.4", GCRY_CIPHER_MODE_CBC },
|
||||
{ "1.2.410.200004.1.5", GCRY_CIPHER_MODE_CFB },
|
||||
{ "1.2.410.200004.1.6", GCRY_CIPHER_MODE_OFB },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
gcry_cipher_spec_t _gcry_cipher_spec_seed =
|
||||
{
|
||||
"SEED", NULL, seed_oids, 16, 128, sizeof (SEED_context),
|
||||
seed_setkey, seed_encrypt, seed_decrypt,
|
||||
};
|
978
lib/libgcrypt/cipher/serpent.c
Normal file
978
lib/libgcrypt/cipher/serpent.c
Normal file
|
@ -0,0 +1,978 @@
|
|||
/* serpent.c - Implementation of the Serpent encryption algorithm.
|
||||
* Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of Libgcrypt.
|
||||
*
|
||||
* Libgcrypt is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser general Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Libgcrypt is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "g10lib.h"
|
||||
#include "cipher.h"
|
||||
#include "bithelp.h"
|
||||
|
||||
/* Number of rounds per Serpent encrypt/decrypt operation. */
|
||||
#define ROUNDS 32
|
||||
|
||||
/* Magic number, used during generating of the subkeys. */
|
||||
#define PHI 0x9E3779B9
|
||||
|
||||
/* Serpent works on 128 bit blocks. */
|
||||
typedef u32 serpent_block_t[4];
|
||||
|
||||
/* Serpent key, provided by the user. If the original key is shorter
|
||||
than 256 bits, it is padded. */
|
||||
typedef u32 serpent_key_t[8];
|
||||
|
||||
/* The key schedule consists of 33 128 bit subkeys. */
|
||||
typedef u32 serpent_subkeys_t[ROUNDS + 1][4];
|
||||
|
||||
/* A Serpent context. */
|
||||
typedef struct serpent_context
|
||||
{
|
||||
serpent_subkeys_t keys; /* Generated subkeys. */
|
||||
} serpent_context_t;
|
||||
|
||||
|
||||
/* A prototype. */
|
||||
static const char *serpent_test (void);
|
||||
|
||||
|
||||
#define byte_swap_32(x) \
|
||||
(0 \
|
||||
| (((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) \
|
||||
| (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
|
||||
|
||||
/* These are the S-Boxes of Serpent. They are copied from Serpents
|
||||
reference implementation (the optimized one, contained in
|
||||
`floppy2') and are therefore:
|
||||
|
||||
Copyright (C) 1998 Ross Anderson, Eli Biham, Lars Knudsen.
|
||||
|
||||
To quote the Serpent homepage
|
||||
(http://www.cl.cam.ac.uk/~rja14/serpent.html):
|
||||
|
||||
"Serpent is now completely in the public domain, and we impose no
|
||||
restrictions on its use. This was announced on the 21st August at
|
||||
the First AES Candidate Conference. The optimised implementations
|
||||
in the submission package are now under the GNU PUBLIC LICENSE
|
||||
(GPL), although some comments in the code still say otherwise. You
|
||||
are welcome to use Serpent for any application." */
|
||||
|
||||
#define SBOX0(a, b, c, d, w, x, y, z) \
|
||||
{ \
|
||||
u32 t02, t03, t05, t06, t07, t08, t09; \
|
||||
u32 t11, t12, t13, t14, t15, t17, t01; \
|
||||
t01 = b ^ c ; \
|
||||
t02 = a | d ; \
|
||||
t03 = a ^ b ; \
|
||||
z = t02 ^ t01; \
|
||||
t05 = c | z ; \
|
||||
t06 = a ^ d ; \
|
||||
t07 = b | c ; \
|
||||
t08 = d & t05; \
|
||||
t09 = t03 & t07; \
|
||||
y = t09 ^ t08; \
|
||||
t11 = t09 & y ; \
|
||||
t12 = c ^ d ; \
|
||||
t13 = t07 ^ t11; \
|
||||
t14 = b & t06; \
|
||||
t15 = t06 ^ t13; \
|
||||
w = ~ t15; \
|
||||
t17 = w ^ t14; \
|
||||
x = t12 ^ t17; \
|
||||
}
|
||||
|
||||
#define SBOX0_INVERSE(a, b, c, d, w, x, y, z) \
|
||||
{ \
|
||||
u32 t02, t03, t04, t05, t06, t08, t09, t10; \
|
||||
u32 t12, t13, t14, t15, t17, t18, t01; \
|
||||
t01 = c ^ d ; \
|
||||
t02 = a | b ; \
|
||||
t03 = b | c ; \
|
||||
t04 = c & t01; \
|
||||
t05 = t02 ^ t01; \
|
||||
t06 = a | t04; \
|
||||
y = ~ t05; \
|
||||
t08 = b ^ d ; \
|
||||
t09 = t03 & t08; \
|
||||
t10 = d | y ; \
|
||||
x = t09 ^ t06; \
|
||||
t12 = a | t05; \
|
||||
t13 = x ^ t12; \
|
||||
t14 = t03 ^ t10; \
|
||||
t15 = a ^ c ; \
|
||||
z = t14 ^ t13; \
|
||||
t17 = t05 & t13; \
|
||||
t18 = t14 | t17; \
|
||||
w = t15 ^ t18; \
|
||||
}
|
||||
|
||||
#define SBOX1(a, b, c, d, w, x, y, z) \
|
||||
{ \
|
||||
u32 t02, t03, t04, t05, t06, t07, t08; \
|
||||
u32 t10, t11, t12, t13, t16, t17, t01; \
|
||||
t01 = a | d ; \
|
||||
t02 = c ^ d ; \
|
||||
t03 = ~ b ; \
|
||||
t04 = a ^ c ; \
|
||||
t05 = a | t03; \
|
||||
t06 = d & t04; \
|
||||
t07 = t01 & t02; \
|
||||
t08 = b | t06; \
|
||||
y = t02 ^ t05; \
|
||||
t10 = t07 ^ t08; \
|
||||
t11 = t01 ^ t10; \
|
||||
t12 = y ^ t11; \
|
||||
t13 = b & d ; \
|
||||
z = ~ t10; \
|
||||
x = t13 ^ t12; \
|
||||
t16 = t10 | x ; \
|
||||
t17 = t05 & t16; \
|
||||
w = c ^ t17; \
|
||||
}
|
||||
|
||||
#define SBOX1_INVERSE(a, b, c, d, w, x, y, z) \
|
||||
{ \
|
||||
u32 t02, t03, t04, t05, t06, t07, t08; \
|
||||
u32 t09, t10, t11, t14, t15, t17, t01; \
|
||||
t01 = a ^ b ; \
|
||||
t02 = b | d ; \
|
||||
t03 = a & c ; \
|
||||
t04 = c ^ t02; \
|
||||
t05 = a | t04; \
|
||||
t06 = t01 & t05; \
|
||||
t07 = d | t03; \
|
||||
t08 = b ^ t06; \
|
||||
t09 = t07 ^ t06; \
|
||||
t10 = t04 | t03; \
|
||||
t11 = d & t08; \
|
||||
y = ~ t09; \
|
||||
x = t10 ^ t11; \
|
||||
t14 = a | y ; \
|
||||
t15 = t06 ^ x ; \
|
||||
z = t01 ^ t04; \
|
||||
t17 = c ^ t15; \
|
||||
w = t14 ^ t17; \
|
||||
}
|
||||
|
||||
#define SBOX2(a, b, c, d, w, x, y, z) \
|
||||
{ \
|
||||
u32 t02, t03, t05, t06, t07, t08; \
|
||||
u32 t09, t10, t12, t13, t14, t01; \
|
||||
t01 = a | c ; \
|
||||
t02 = a ^ b ; \
|
||||
t03 = d ^ t01; \
|
||||
w = t02 ^ t03; \
|
||||
t05 = c ^ w ; \
|
||||
t06 = b ^ t05; \
|
||||
t07 = b | t05; \
|
||||
t08 = t01 & t06; \
|
||||
t09 = t03 ^ t07; \
|
||||
t10 = t02 | t09; \
|
||||
x = t10 ^ t08; \
|
||||
t12 = a | d ; \
|
||||
t13 = t09 ^ x ; \
|
||||
t14 = b ^ t13; \
|
||||
z = ~ t09; \
|
||||
y = t12 ^ t14; \
|
||||
}
|
||||
|
||||
#define SBOX2_INVERSE(a, b, c, d, w, x, y, z) \
|
||||
{ \
|
||||
u32 t02, t03, t04, t06, t07, t08, t09; \
|
||||
u32 t10, t11, t12, t15, t16, t17, t01; \
|
||||
t01 = a ^ d ; \
|
||||
t02 = c ^ d ; \
|
||||
t03 = a & c ; \
|
||||
t04 = b | t02; \
|
||||
w = t01 ^ t04; \
|
||||
t06 = a | c ; \
|
||||
t07 = d | w ; \
|
||||
t08 = ~ d ; \
|
||||
t09 = b & t06; \
|
||||
t10 = t08 | t03; \
|
||||
t11 = b & t07; \
|
||||
t12 = t06 & t02; \
|
||||
z = t09 ^ t10; \
|
||||
x = t12 ^ t11; \
|
||||
t15 = c & z ; \
|
||||
t16 = w ^ x ; \
|
||||
t17 = t10 ^ t15; \
|
||||
y = t16 ^ t17; \
|
||||
}
|
||||
|
||||
#define SBOX3(a, b, c, d, w, x, y, z) \
|
||||
{ \
|
||||
u32 t02, t03, t04, t05, t06, t07, t08; \
|
||||
u32 t09, t10, t11, t13, t14, t15, t01; \
|
||||
t01 = a ^ c ; \
|
||||
t02 = a | d ; \
|
||||
t03 = a & d ; \
|
||||
t04 = t01 & t02; \
|
||||
t05 = b | t03; \
|
||||
t06 = a & b ; \
|
||||
t07 = d ^ t04; \
|
||||
t08 = c | t06; \
|
||||
t09 = b ^ t07; \
|
||||
t10 = d & t05; \
|
||||
t11 = t02 ^ t10; \
|
||||
z = t08 ^ t09; \
|
||||
t13 = d | z ; \
|
||||
t14 = a | t07; \
|
||||
t15 = b & t13; \
|
||||
y = t08 ^ t11; \
|
||||
w = t14 ^ t15; \
|
||||
x = t05 ^ t04; \
|
||||
}
|
||||
|
||||
#define SBOX3_INVERSE(a, b, c, d, w, x, y, z) \
|
||||
{ \
|
||||
u32 t02, t03, t04, t05, t06, t07, t09; \
|
||||
u32 t11, t12, t13, t14, t16, t01; \
|
||||
t01 = c | d ; \
|
||||
t02 = a | d ; \
|
||||
t03 = c ^ t02; \
|
||||
t04 = b ^ t02; \
|
||||
t05 = a ^ d ; \
|
||||
t06 = t04 & t03; \
|
||||
t07 = b & t01; \
|
||||
y = t05 ^ t06; \
|
||||
t09 = a ^ t03; \
|
||||
w = t07 ^ t03; \
|
||||
t11 = w | t05; \
|
||||
t12 = t09 & t11; \
|
||||
t13 = a & y ; \
|
||||
t14 = t01 ^ t05; \
|
||||
x = b ^ t12; \
|
||||
t16 = b | t13; \
|
||||
z = t14 ^ t16; \
|
||||
}
|
||||
|
||||
#define SBOX4(a, b, c, d, w, x, y, z) \
|
||||
{ \
|
||||
u32 t02, t03, t04, t05, t06, t08, t09; \
|
||||
u32 t10, t11, t12, t13, t14, t15, t16, t01; \
|
||||
t01 = a | b ; \
|
||||
t02 = b | c ; \
|
||||
t03 = a ^ t02; \
|
||||
t04 = b ^ d ; \
|
||||
t05 = d | t03; \
|
||||
t06 = d & t01; \
|
||||
z = t03 ^ t06; \
|
||||
t08 = z & t04; \
|
||||
t09 = t04 & t05; \
|
||||
t10 = c ^ t06; \
|
||||
t11 = b & c ; \
|
||||
t12 = t04 ^ t08; \
|
||||
t13 = t11 | t03; \
|
||||
t14 = t10 ^ t09; \
|
||||
t15 = a & t05; \
|
||||
t16 = t11 | t12; \
|
||||
y = t13 ^ t08; \
|
||||
x = t15 ^ t16; \
|
||||
w = ~ t14; \
|
||||
}
|
||||
|
||||
#define SBOX4_INVERSE(a, b, c, d, w, x, y, z) \
|
||||
{ \
|
||||
u32 t02, t03, t04, t05, t06, t07, t09; \
|
||||
u32 t10, t11, t12, t13, t15, t01; \
|
||||
t01 = b | d ; \
|
||||
t02 = c | d ; \
|
||||
t03 = a & t01; \
|
||||
t04 = b ^ t02; \
|
||||
t05 = c ^ d ; \
|
||||
t06 = ~ t03; \
|
||||
t07 = a & t04; \
|
||||
x = t05 ^ t07; \
|
||||
t09 = x | t06; \
|
||||
t10 = a ^ t07; \
|
||||
t11 = t01 ^ t09; \
|
||||
t12 = d ^ t04; \
|
||||
t13 = c | t10; \
|
||||
z = t03 ^ t12; \
|
||||
t15 = a ^ t04; \
|
||||
y = t11 ^ t13; \
|
||||
w = t15 ^ t09; \
|
||||
}
|
||||
|
||||
#define SBOX5(a, b, c, d, w, x, y, z) \
|
||||
{ \
|
||||
u32 t02, t03, t04, t05, t07, t08, t09; \
|
||||
u32 t10, t11, t12, t13, t14, t01; \
|
||||
t01 = b ^ d ; \
|
||||
t02 = b | d ; \
|
||||
t03 = a & t01; \
|
||||
t04 = c ^ t02; \
|
||||
t05 = t03 ^ t04; \
|
||||
w = ~ t05; \
|
||||
t07 = a ^ t01; \
|
||||
t08 = d | w ; \
|
||||
t09 = b | t05; \
|
||||
t10 = d ^ t08; \
|
||||
t11 = b | t07; \
|
||||
t12 = t03 | w ; \
|
||||
t13 = t07 | t10; \
|
||||
t14 = t01 ^ t11; \
|
||||
y = t09 ^ t13; \
|
||||
x = t07 ^ t08; \
|
||||
z = t12 ^ t14; \
|
||||
}
|
||||
|
||||
#define SBOX5_INVERSE(a, b, c, d, w, x, y, z) \
|
||||
{ \
|
||||
u32 t02, t03, t04, t05, t07, t08, t09; \
|
||||
u32 t10, t12, t13, t15, t16, t01; \
|
||||
t01 = a & d ; \
|
||||
t02 = c ^ t01; \
|
||||
t03 = a ^ d ; \
|
||||
t04 = b & t02; \
|
||||
t05 = a & c ; \
|
||||
w = t03 ^ t04; \
|
||||
t07 = a & w ; \
|
||||
t08 = t01 ^ w ; \
|
||||
t09 = b | t05; \
|
||||
t10 = ~ b ; \
|
||||
x = t08 ^ t09; \
|
||||
t12 = t10 | t07; \
|
||||
t13 = w | x ; \
|
||||
z = t02 ^ t12; \
|
||||
t15 = t02 ^ t13; \
|
||||
t16 = b ^ d ; \
|
||||
y = t16 ^ t15; \
|
||||
}
|
||||
|
||||
#define SBOX6(a, b, c, d, w, x, y, z) \
|
||||
{ \
|
||||
u32 t02, t03, t04, t05, t07, t08, t09, t10; \
|
||||
u32 t11, t12, t13, t15, t17, t18, t01; \
|
||||
t01 = a & d ; \
|
||||
t02 = b ^ c ; \
|
||||
t03 = a ^ d ; \
|
||||
t04 = t01 ^ t02; \
|
||||
t05 = b | c ; \
|
||||
x = ~ t04; \
|
||||
t07 = t03 & t05; \
|
||||
t08 = b & x ; \
|
||||
t09 = a | c ; \
|
||||
t10 = t07 ^ t08; \
|
||||
t11 = b | d ; \
|
||||
t12 = c ^ t11; \
|
||||
t13 = t09 ^ t10; \
|
||||
y = ~ t13; \
|
||||
t15 = x & t03; \
|
||||
z = t12 ^ t07; \
|
||||
t17 = a ^ b ; \
|
||||
t18 = y ^ t15; \
|
||||
w = t17 ^ t18; \
|
||||
}
|
||||
|
||||
#define SBOX6_INVERSE(a, b, c, d, w, x, y, z) \
|
||||
{ \
|
||||
u32 t02, t03, t04, t05, t06, t07, t08, t09; \
|
||||
u32 t12, t13, t14, t15, t16, t17, t01; \
|
||||
t01 = a ^ c ; \
|
||||
t02 = ~ c ; \
|
||||
t03 = b & t01; \
|
||||
t04 = b | t02; \
|
||||
t05 = d | t03; \
|
||||
t06 = b ^ d ; \
|
||||
t07 = a & t04; \
|
||||
t08 = a | t02; \
|
||||
t09 = t07 ^ t05; \
|
||||
x = t06 ^ t08; \
|
||||
w = ~ t09; \
|
||||
t12 = b & w ; \
|
||||
t13 = t01 & t05; \
|
||||
t14 = t01 ^ t12; \
|
||||
t15 = t07 ^ t13; \
|
||||
t16 = d | t02; \
|
||||
t17 = a ^ x ; \
|
||||
z = t17 ^ t15; \
|
||||
y = t16 ^ t14; \
|
||||
}
|
||||
|
||||
#define SBOX7(a, b, c, d, w, x, y, z) \
|
||||
{ \
|
||||
u32 t02, t03, t04, t05, t06, t08, t09, t10; \
|
||||
u32 t11, t13, t14, t15, t16, t17, t01; \
|
||||
t01 = a & c ; \
|
||||
t02 = ~ d ; \
|
||||
t03 = a & t02; \
|
||||
t04 = b | t01; \
|
||||
t05 = a & b ; \
|
||||
t06 = c ^ t04; \
|
||||
z = t03 ^ t06; \
|
||||
t08 = c | z ; \
|
||||
t09 = d | t05; \
|
||||
t10 = a ^ t08; \
|
||||
t11 = t04 & z ; \
|
||||
x = t09 ^ t10; \
|
||||
t13 = b ^ x ; \
|
||||
t14 = t01 ^ x ; \
|
||||
t15 = c ^ t05; \
|
||||
t16 = t11 | t13; \
|
||||
t17 = t02 | t14; \
|
||||
w = t15 ^ t17; \
|
||||
y = a ^ t16; \
|
||||
}
|
||||
|
||||
#define SBOX7_INVERSE(a, b, c, d, w, x, y, z) \
|
||||
{ \
|
||||
u32 t02, t03, t04, t06, t07, t08, t09; \
|
||||
u32 t10, t11, t13, t14, t15, t16, t01; \
|
||||
t01 = a & b ; \
|
||||
t02 = a | b ; \
|
||||
t03 = c | t01; \
|
||||
t04 = d & t02; \
|
||||
z = t03 ^ t04; \
|
||||
t06 = b ^ t04; \
|
||||
t07 = d ^ z ; \
|
||||
t08 = ~ t07; \
|
||||
t09 = t06 | t08; \
|
||||
t10 = b ^ d ; \
|
||||
t11 = a | d ; \
|
||||
x = a ^ t09; \
|
||||
t13 = c ^ t06; \
|
||||
t14 = c & t11; \
|
||||
t15 = d | x ; \
|
||||
t16 = t01 | t10; \
|
||||
w = t13 ^ t15; \
|
||||
y = t14 ^ t16; \
|
||||
}
|
||||
|
||||
/* XOR BLOCK1 into BLOCK0. */
|
||||
#define BLOCK_XOR(block0, block1) \
|
||||
{ \
|
||||
block0[0] ^= block1[0]; \
|
||||
block0[1] ^= block1[1]; \
|
||||
block0[2] ^= block1[2]; \
|
||||
block0[3] ^= block1[3]; \
|
||||
}
|
||||
|
||||
/* Copy BLOCK_SRC to BLOCK_DST. */
|
||||
#define BLOCK_COPY(block_dst, block_src) \
|
||||
{ \
|
||||
block_dst[0] = block_src[0]; \
|
||||
block_dst[1] = block_src[1]; \
|
||||
block_dst[2] = block_src[2]; \
|
||||
block_dst[3] = block_src[3]; \
|
||||
}
|
||||
|
||||
/* Apply SBOX number WHICH to to the block found in ARRAY0 at index
|
||||
INDEX, writing the output to the block found in ARRAY1 at index
|
||||
INDEX. */
|
||||
#define SBOX(which, array0, array1, index) \
|
||||
SBOX##which (array0[index + 0], array0[index + 1], \
|
||||
array0[index + 2], array0[index + 3], \
|
||||
array1[index + 0], array1[index + 1], \
|
||||
array1[index + 2], array1[index + 3]);
|
||||
|
||||
/* Apply inverse SBOX number WHICH to to the block found in ARRAY0 at
|
||||
index INDEX, writing the output to the block found in ARRAY1 at
|
||||
index INDEX. */
|
||||
#define SBOX_INVERSE(which, array0, array1, index) \
|
||||
SBOX##which##_INVERSE (array0[index + 0], array0[index + 1], \
|
||||
array0[index + 2], array0[index + 3], \
|
||||
array1[index + 0], array1[index + 1], \
|
||||
array1[index + 2], array1[index + 3]);
|
||||
|
||||
/* Apply the linear transformation to BLOCK. */
|
||||
#define LINEAR_TRANSFORMATION(block) \
|
||||
{ \
|
||||
block[0] = rol (block[0], 13); \
|
||||
block[2] = rol (block[2], 3); \
|
||||
block[1] = block[1] ^ block[0] ^ block[2]; \
|
||||
block[3] = block[3] ^ block[2] ^ (block[0] << 3); \
|
||||
block[1] = rol (block[1], 1); \
|
||||
block[3] = rol (block[3], 7); \
|
||||
block[0] = block[0] ^ block[1] ^ block[3]; \
|
||||
block[2] = block[2] ^ block[3] ^ (block[1] << 7); \
|
||||
block[0] = rol (block[0], 5); \
|
||||
block[2] = rol (block[2], 22); \
|
||||
}
|
||||
|
||||
/* Apply the inverse linear transformation to BLOCK. */
|
||||
#define LINEAR_TRANSFORMATION_INVERSE(block) \
|
||||
{ \
|
||||
block[2] = ror (block[2], 22); \
|
||||
block[0] = ror (block[0] , 5); \
|
||||
block[2] = block[2] ^ block[3] ^ (block[1] << 7); \
|
||||
block[0] = block[0] ^ block[1] ^ block[3]; \
|
||||
block[3] = ror (block[3], 7); \
|
||||
block[1] = ror (block[1], 1); \
|
||||
block[3] = block[3] ^ block[2] ^ (block[0] << 3); \
|
||||
block[1] = block[1] ^ block[0] ^ block[2]; \
|
||||
block[2] = ror (block[2], 3); \
|
||||
block[0] = ror (block[0], 13); \
|
||||
}
|
||||
|
||||
/* Apply a Serpent round to BLOCK, using the SBOX number WHICH and the
|
||||
subkeys contained in SUBKEYS. Use BLOCK_TMP as temporary storage.
|
||||
This macro increments `round'. */
|
||||
#define ROUND(which, subkeys, block, block_tmp) \
|
||||
{ \
|
||||
BLOCK_XOR (block, subkeys[round]); \
|
||||
round++; \
|
||||
SBOX (which, block, block_tmp, 0); \
|
||||
LINEAR_TRANSFORMATION (block_tmp); \
|
||||
BLOCK_COPY (block, block_tmp); \
|
||||
}
|
||||
|
||||
/* Apply the last Serpent round to BLOCK, using the SBOX number WHICH
|
||||
and the subkeys contained in SUBKEYS. Use BLOCK_TMP as temporary
|
||||
storage. The result will be stored in BLOCK_TMP. This macro
|
||||
increments `round'. */
|
||||
#define ROUND_LAST(which, subkeys, block, block_tmp) \
|
||||
{ \
|
||||
BLOCK_XOR (block, subkeys[round]); \
|
||||
round++; \
|
||||
SBOX (which, block, block_tmp, 0); \
|
||||
BLOCK_XOR (block_tmp, subkeys[round]); \
|
||||
round++; \
|
||||
}
|
||||
|
||||
/* Apply an inverse Serpent round to BLOCK, using the SBOX number
|
||||
WHICH and the subkeys contained in SUBKEYS. Use BLOCK_TMP as
|
||||
temporary storage. This macro increments `round'. */
|
||||
#define ROUND_INVERSE(which, subkey, block, block_tmp) \
|
||||
{ \
|
||||
LINEAR_TRANSFORMATION_INVERSE (block); \
|
||||
SBOX_INVERSE (which, block, block_tmp, 0); \
|
||||
BLOCK_XOR (block_tmp, subkey[round]); \
|
||||
round--; \
|
||||
BLOCK_COPY (block, block_tmp); \
|
||||
}
|
||||
|
||||
/* Apply the first Serpent round to BLOCK, using the SBOX number WHICH
|
||||
and the subkeys contained in SUBKEYS. Use BLOCK_TMP as temporary
|
||||
storage. The result will be stored in BLOCK_TMP. This macro
|
||||
increments `round'. */
|
||||
#define ROUND_FIRST_INVERSE(which, subkeys, block, block_tmp) \
|
||||
{ \
|
||||
BLOCK_XOR (block, subkeys[round]); \
|
||||
round--; \
|
||||
SBOX_INVERSE (which, block, block_tmp, 0); \
|
||||
BLOCK_XOR (block_tmp, subkeys[round]); \
|
||||
round--; \
|
||||
}
|
||||
|
||||
/* Convert the user provided key KEY of KEY_LENGTH bytes into the
|
||||
internally used format. */
|
||||
static void
|
||||
serpent_key_prepare (const byte *key, unsigned int key_length,
|
||||
serpent_key_t key_prepared)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Copy key. */
|
||||
for (i = 0; i < key_length / 4; i++)
|
||||
{
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
key_prepared[i] = byte_swap_32 (((u32 *) key)[i]);
|
||||
#else
|
||||
key_prepared[i] = ((u32 *) key)[i];
|
||||
#endif
|
||||
}
|
||||
|
||||
if (i < 8)
|
||||
{
|
||||
/* Key must be padded according to the Serpent
|
||||
specification. */
|
||||
key_prepared[i] = 0x00000001;
|
||||
|
||||
for (i++; i < 8; i++)
|
||||
key_prepared[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Derive the 33 subkeys from KEY and store them in SUBKEYS. */
|
||||
static void
|
||||
serpent_subkeys_generate (serpent_key_t key, serpent_subkeys_t subkeys)
|
||||
{
|
||||
u32 w_real[140]; /* The `prekey'. */
|
||||
u32 k[132];
|
||||
u32 *w = &w_real[8];
|
||||
int i, j;
|
||||
|
||||
/* Initialize with key values. */
|
||||
for (i = 0; i < 8; i++)
|
||||
w[i - 8] = key[i];
|
||||
|
||||
/* Expand to intermediate key using the affine recurrence. */
|
||||
for (i = 0; i < 132; i++)
|
||||
w[i] = rol (w[i - 8] ^ w[i - 5] ^ w[i - 3] ^ w[i - 1] ^ PHI ^ i, 11);
|
||||
|
||||
/* Calculate subkeys via S-Boxes, in bitslice mode. */
|
||||
SBOX (3, w, k, 0);
|
||||
SBOX (2, w, k, 4);
|
||||
SBOX (1, w, k, 8);
|
||||
SBOX (0, w, k, 12);
|
||||
SBOX (7, w, k, 16);
|
||||
SBOX (6, w, k, 20);
|
||||
SBOX (5, w, k, 24);
|
||||
SBOX (4, w, k, 28);
|
||||
SBOX (3, w, k, 32);
|
||||
SBOX (2, w, k, 36);
|
||||
SBOX (1, w, k, 40);
|
||||
SBOX (0, w, k, 44);
|
||||
SBOX (7, w, k, 48);
|
||||
SBOX (6, w, k, 52);
|
||||
SBOX (5, w, k, 56);
|
||||
SBOX (4, w, k, 60);
|
||||
SBOX (3, w, k, 64);
|
||||
SBOX (2, w, k, 68);
|
||||
SBOX (1, w, k, 72);
|
||||
SBOX (0, w, k, 76);
|
||||
SBOX (7, w, k, 80);
|
||||
SBOX (6, w, k, 84);
|
||||
SBOX (5, w, k, 88);
|
||||
SBOX (4, w, k, 92);
|
||||
SBOX (3, w, k, 96);
|
||||
SBOX (2, w, k, 100);
|
||||
SBOX (1, w, k, 104);
|
||||
SBOX (0, w, k, 108);
|
||||
SBOX (7, w, k, 112);
|
||||
SBOX (6, w, k, 116);
|
||||
SBOX (5, w, k, 120);
|
||||
SBOX (4, w, k, 124);
|
||||
SBOX (3, w, k, 128);
|
||||
|
||||
/* Renumber subkeys. */
|
||||
for (i = 0; i < ROUNDS + 1; i++)
|
||||
for (j = 0; j < 4; j++)
|
||||
subkeys[i][j] = k[4 * i + j];
|
||||
}
|
||||
|
||||
/* Initialize CONTEXT with the key KEY of KEY_LENGTH bits. */
|
||||
static void
|
||||
serpent_setkey_internal (serpent_context_t *context,
|
||||
const byte *key, unsigned int key_length)
|
||||
{
|
||||
serpent_key_t key_prepared;
|
||||
|
||||
serpent_key_prepare (key, key_length, key_prepared);
|
||||
serpent_subkeys_generate (key_prepared, context->keys);
|
||||
_gcry_burn_stack (272 * sizeof (u32));
|
||||
}
|
||||
|
||||
/* Initialize CTX with the key KEY of KEY_LENGTH bytes. */
|
||||
static gcry_err_code_t
|
||||
serpent_setkey (void *ctx,
|
||||
const byte *key, unsigned int key_length)
|
||||
{
|
||||
serpent_context_t *context = ctx;
|
||||
static const char *serpent_test_ret;
|
||||
static int serpent_init_done;
|
||||
gcry_err_code_t ret = GPG_ERR_NO_ERROR;
|
||||
|
||||
if (! serpent_init_done)
|
||||
{
|
||||
/* Execute a self-test the first time, Serpent is used. */
|
||||
serpent_test_ret = serpent_test ();
|
||||
if (serpent_test_ret)
|
||||
log_error ("Serpent test failure: %s\n", serpent_test_ret);
|
||||
serpent_init_done = 1;
|
||||
}
|
||||
|
||||
if (serpent_test_ret)
|
||||
ret = GPG_ERR_SELFTEST_FAILED;
|
||||
else
|
||||
{
|
||||
serpent_setkey_internal (context, key, key_length);
|
||||
_gcry_burn_stack (sizeof (serpent_key_t));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
serpent_encrypt_internal (serpent_context_t *context,
|
||||
const serpent_block_t input, serpent_block_t output)
|
||||
{
|
||||
serpent_block_t b, b_next;
|
||||
int round = 0;
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
b[0] = byte_swap_32 (input[0]);
|
||||
b[1] = byte_swap_32 (input[1]);
|
||||
b[2] = byte_swap_32 (input[2]);
|
||||
b[3] = byte_swap_32 (input[3]);
|
||||
#else
|
||||
b[0] = input[0];
|
||||
b[1] = input[1];
|
||||
b[2] = input[2];
|
||||
b[3] = input[3];
|
||||
#endif
|
||||
|
||||
ROUND (0, context->keys, b, b_next);
|
||||
ROUND (1, context->keys, b, b_next);
|
||||
ROUND (2, context->keys, b, b_next);
|
||||
ROUND (3, context->keys, b, b_next);
|
||||
ROUND (4, context->keys, b, b_next);
|
||||
ROUND (5, context->keys, b, b_next);
|
||||
ROUND (6, context->keys, b, b_next);
|
||||
ROUND (7, context->keys, b, b_next);
|
||||
ROUND (0, context->keys, b, b_next);
|
||||
ROUND (1, context->keys, b, b_next);
|
||||
ROUND (2, context->keys, b, b_next);
|
||||
ROUND (3, context->keys, b, b_next);
|
||||
ROUND (4, context->keys, b, b_next);
|
||||
ROUND (5, context->keys, b, b_next);
|
||||
ROUND (6, context->keys, b, b_next);
|
||||
ROUND (7, context->keys, b, b_next);
|
||||
ROUND (0, context->keys, b, b_next);
|
||||
ROUND (1, context->keys, b, b_next);
|
||||
ROUND (2, context->keys, b, b_next);
|
||||
ROUND (3, context->keys, b, b_next);
|
||||
ROUND (4, context->keys, b, b_next);
|
||||
ROUND (5, context->keys, b, b_next);
|
||||
ROUND (6, context->keys, b, b_next);
|
||||
ROUND (7, context->keys, b, b_next);
|
||||
ROUND (0, context->keys, b, b_next);
|
||||
ROUND (1, context->keys, b, b_next);
|
||||
ROUND (2, context->keys, b, b_next);
|
||||
ROUND (3, context->keys, b, b_next);
|
||||
ROUND (4, context->keys, b, b_next);
|
||||
ROUND (5, context->keys, b, b_next);
|
||||
ROUND (6, context->keys, b, b_next);
|
||||
|
||||
ROUND_LAST (7, context->keys, b, b_next);
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
output[0] = byte_swap_32 (b_next[0]);
|
||||
output[1] = byte_swap_32 (b_next[1]);
|
||||
output[2] = byte_swap_32 (b_next[2]);
|
||||
output[3] = byte_swap_32 (b_next[3]);
|
||||
#else
|
||||
output[0] = b_next[0];
|
||||
output[1] = b_next[1];
|
||||
output[2] = b_next[2];
|
||||
output[3] = b_next[3];
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
serpent_decrypt_internal (serpent_context_t *context,
|
||||
const serpent_block_t input, serpent_block_t output)
|
||||
{
|
||||
serpent_block_t b, b_next;
|
||||
int round = ROUNDS;
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
b_next[0] = byte_swap_32 (input[0]);
|
||||
b_next[1] = byte_swap_32 (input[1]);
|
||||
b_next[2] = byte_swap_32 (input[2]);
|
||||
b_next[3] = byte_swap_32 (input[3]);
|
||||
#else
|
||||
b_next[0] = input[0];
|
||||
b_next[1] = input[1];
|
||||
b_next[2] = input[2];
|
||||
b_next[3] = input[3];
|
||||
#endif
|
||||
|
||||
ROUND_FIRST_INVERSE (7, context->keys, b_next, b);
|
||||
|
||||
ROUND_INVERSE (6, context->keys, b, b_next);
|
||||
ROUND_INVERSE (5, context->keys, b, b_next);
|
||||
ROUND_INVERSE (4, context->keys, b, b_next);
|
||||
ROUND_INVERSE (3, context->keys, b, b_next);
|
||||
ROUND_INVERSE (2, context->keys, b, b_next);
|
||||
ROUND_INVERSE (1, context->keys, b, b_next);
|
||||
ROUND_INVERSE (0, context->keys, b, b_next);
|
||||
ROUND_INVERSE (7, context->keys, b, b_next);
|
||||
ROUND_INVERSE (6, context->keys, b, b_next);
|
||||
ROUND_INVERSE (5, context->keys, b, b_next);
|
||||
ROUND_INVERSE (4, context->keys, b, b_next);
|
||||
ROUND_INVERSE (3, context->keys, b, b_next);
|
||||
ROUND_INVERSE (2, context->keys, b, b_next);
|
||||
ROUND_INVERSE (1, context->keys, b, b_next);
|
||||
ROUND_INVERSE (0, context->keys, b, b_next);
|
||||
ROUND_INVERSE (7, context->keys, b, b_next);
|
||||
ROUND_INVERSE (6, context->keys, b, b_next);
|
||||
ROUND_INVERSE (5, context->keys, b, b_next);
|
||||
ROUND_INVERSE (4, context->keys, b, b_next);
|
||||
ROUND_INVERSE (3, context->keys, b, b_next);
|
||||
ROUND_INVERSE (2, context->keys, b, b_next);
|
||||
ROUND_INVERSE (1, context->keys, b, b_next);
|
||||
ROUND_INVERSE (0, context->keys, b, b_next);
|
||||
ROUND_INVERSE (7, context->keys, b, b_next);
|
||||
ROUND_INVERSE (6, context->keys, b, b_next);
|
||||
ROUND_INVERSE (5, context->keys, b, b_next);
|
||||
ROUND_INVERSE (4, context->keys, b, b_next);
|
||||
ROUND_INVERSE (3, context->keys, b, b_next);
|
||||
ROUND_INVERSE (2, context->keys, b, b_next);
|
||||
ROUND_INVERSE (1, context->keys, b, b_next);
|
||||
ROUND_INVERSE (0, context->keys, b, b_next);
|
||||
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
output[0] = byte_swap_32 (b_next[0]);
|
||||
output[1] = byte_swap_32 (b_next[1]);
|
||||
output[2] = byte_swap_32 (b_next[2]);
|
||||
output[3] = byte_swap_32 (b_next[3]);
|
||||
#else
|
||||
output[0] = b_next[0];
|
||||
output[1] = b_next[1];
|
||||
output[2] = b_next[2];
|
||||
output[3] = b_next[3];
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
serpent_encrypt (void *ctx, byte *buffer_out, const byte *buffer_in)
|
||||
{
|
||||
serpent_context_t *context = ctx;
|
||||
|
||||
serpent_encrypt_internal (context,
|
||||
(const u32 *) buffer_in, (u32 *) buffer_out);
|
||||
_gcry_burn_stack (2 * sizeof (serpent_block_t));
|
||||
}
|
||||
|
||||
static void
|
||||
serpent_decrypt (void *ctx, byte *buffer_out, const byte *buffer_in)
|
||||
{
|
||||
serpent_context_t *context = ctx;
|
||||
|
||||
serpent_decrypt_internal (context,
|
||||
(const u32 *) buffer_in,
|
||||
(u32 *) buffer_out);
|
||||
_gcry_burn_stack (2 * sizeof (serpent_block_t));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Serpent test. */
|
||||
|
||||
static const char *
|
||||
serpent_test (void)
|
||||
{
|
||||
serpent_context_t context;
|
||||
unsigned char scratch[16];
|
||||
unsigned int i;
|
||||
|
||||
static struct test
|
||||
{
|
||||
int key_length;
|
||||
unsigned char key[32];
|
||||
unsigned char text_plain[16];
|
||||
unsigned char text_cipher[16];
|
||||
} test_data[] =
|
||||
{
|
||||
{
|
||||
16,
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
|
||||
"\xD2\x9D\x57\x6F\xCE\xA3\xA3\xA7\xED\x90\x99\xF2\x92\x73\xD7\x8E",
|
||||
"\xB2\x28\x8B\x96\x8A\xE8\xB0\x86\x48\xD1\xCE\x96\x06\xFD\x99\x2D"
|
||||
},
|
||||
{
|
||||
24,
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00",
|
||||
"\xD2\x9D\x57\x6F\xCE\xAB\xA3\xA7\xED\x98\x99\xF2\x92\x7B\xD7\x8E",
|
||||
"\x13\x0E\x35\x3E\x10\x37\xC2\x24\x05\xE8\xFA\xEF\xB2\xC3\xC3\xE9"
|
||||
},
|
||||
{
|
||||
32,
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
|
||||
"\xD0\x95\x57\x6F\xCE\xA3\xE3\xA7\xED\x98\xD9\xF2\x90\x73\xD7\x8E",
|
||||
"\xB9\x0E\xE5\x86\x2D\xE6\x91\x68\xF2\xBD\xD5\x12\x5B\x45\x47\x2B"
|
||||
},
|
||||
{
|
||||
32,
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
|
||||
"\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00",
|
||||
"\x20\x61\xA4\x27\x82\xBD\x52\xEC\x69\x1E\xC3\x83\xB0\x3B\xA7\x7C"
|
||||
},
|
||||
{
|
||||
0
|
||||
},
|
||||
};
|
||||
|
||||
for (i = 0; test_data[i].key_length; i++)
|
||||
{
|
||||
serpent_setkey_internal (&context, test_data[i].key,
|
||||
test_data[i].key_length);
|
||||
serpent_encrypt_internal (&context,
|
||||
(const u32 *) test_data[i].text_plain,
|
||||
(u32 *) scratch);
|
||||
|
||||
if (memcmp (scratch, test_data[i].text_cipher, sizeof (serpent_block_t)))
|
||||
switch (test_data[i].key_length)
|
||||
{
|
||||
case 16:
|
||||
return "Serpent-128 test encryption failed.";
|
||||
case 24:
|
||||
return "Serpent-192 test encryption failed.";
|
||||
case 32:
|
||||
return "Serpent-256 test encryption failed.";
|
||||
}
|
||||
|
||||
serpent_decrypt_internal (&context,
|
||||
(const u32 *) test_data[i].text_cipher,
|
||||
(u32 *) scratch);
|
||||
if (memcmp (scratch, test_data[i].text_plain, sizeof (serpent_block_t)))
|
||||
switch (test_data[i].key_length)
|
||||
{
|
||||
case 16:
|
||||
return "Serpent-128 test decryption failed.";
|
||||
case 24:
|
||||
return "Serpent-192 test decryption failed.";
|
||||
case 32:
|
||||
return "Serpent-256 test decryption failed.";
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* "SERPENT" is an alias for "SERPENT128". */
|
||||
static const char *cipher_spec_serpent128_aliases[] =
|
||||
{
|
||||
"SERPENT",
|
||||
NULL
|
||||
};
|
||||
|
||||
gcry_cipher_spec_t _gcry_cipher_spec_serpent128 =
|
||||
{
|
||||
"SERPENT128", cipher_spec_serpent128_aliases, NULL, 16, 128,
|
||||
sizeof (serpent_context_t),
|
||||
serpent_setkey, serpent_encrypt, serpent_decrypt
|
||||
};
|
||||
|
||||
gcry_cipher_spec_t _gcry_cipher_spec_serpent192 =
|
||||
{
|
||||
"SERPENT192", NULL, NULL, 16, 192,
|
||||
sizeof (serpent_context_t),
|
||||
serpent_setkey, serpent_encrypt, serpent_decrypt
|
||||
};
|
||||
|
||||
gcry_cipher_spec_t _gcry_cipher_spec_serpent256 =
|
||||
{
|
||||
"SERPENT256", NULL, NULL, 16, 256,
|
||||
sizeof (serpent_context_t),
|
||||
serpent_setkey, serpent_encrypt, serpent_decrypt
|
||||
};
|
479
lib/libgcrypt/cipher/sha1.c
Normal file
479
lib/libgcrypt/cipher/sha1.c
Normal file
|
@ -0,0 +1,479 @@
|
|||
/* sha1.c - SHA1 hash function
|
||||
* Copyright (C) 1998, 2001, 2002, 2003, 2008 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of Libgcrypt.
|
||||
*
|
||||
* Libgcrypt is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Libgcrypt is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
/* Test vectors:
|
||||
*
|
||||
* "abc"
|
||||
* A999 3E36 4706 816A BA3E 2571 7850 C26C 9CD0 D89D
|
||||
*
|
||||
* "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
|
||||
* 8498 3E44 1C3B D26E BAAE 4AA1 F951 29E5 E546 70F1
|
||||
*/
|
||||
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_STDINT_H
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
|
||||
#include "g10lib.h"
|
||||
#include "memory.h"
|
||||
#include "bithelp.h"
|
||||
#include "cipher.h"
|
||||
#include "hash-common.h"
|
||||
|
||||
|
||||
/* A macro to test whether P is properly aligned for an u32 type.
|
||||
Note that config.h provides a suitable replacement for uintptr_t if
|
||||
it does not exist in stdint.h. */
|
||||
/* #if __GNUC__ >= 2 */
|
||||
/* # define U32_ALIGNED_P(p) (!(((uintptr_t)p) % __alignof__ (u32))) */
|
||||
/* #else */
|
||||
/* # define U32_ALIGNED_P(p) (!(((uintptr_t)p) % sizeof (u32))) */
|
||||
/* #endif */
|
||||
|
||||
#define TRANSFORM(x,d,n) transform ((x), (d), (n))
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 h0,h1,h2,h3,h4;
|
||||
u32 nblocks;
|
||||
unsigned char buf[64];
|
||||
int count;
|
||||
} SHA1_CONTEXT;
|
||||
|
||||
|
||||
|
||||
static void
|
||||
sha1_init (void *context)
|
||||
{
|
||||
SHA1_CONTEXT *hd = context;
|
||||
|
||||
hd->h0 = 0x67452301;
|
||||
hd->h1 = 0xefcdab89;
|
||||
hd->h2 = 0x98badcfe;
|
||||
hd->h3 = 0x10325476;
|
||||
hd->h4 = 0xc3d2e1f0;
|
||||
hd->nblocks = 0;
|
||||
hd->count = 0;
|
||||
}
|
||||
|
||||
|
||||
/* Round function macros. */
|
||||
#define K1 0x5A827999L
|
||||
#define K2 0x6ED9EBA1L
|
||||
#define K3 0x8F1BBCDCL
|
||||
#define K4 0xCA62C1D6L
|
||||
#define F1(x,y,z) ( z ^ ( x & ( y ^ z ) ) )
|
||||
#define F2(x,y,z) ( x ^ y ^ z )
|
||||
#define F3(x,y,z) ( ( x & y ) | ( z & ( x | y ) ) )
|
||||
#define F4(x,y,z) ( x ^ y ^ z )
|
||||
#define M(i) ( tm = x[ i &0x0f] \
|
||||
^ x[(i-14)&0x0f] \
|
||||
^ x[(i-8) &0x0f] \
|
||||
^ x[(i-3) &0x0f], \
|
||||
(x[i&0x0f] = rol(tm, 1)))
|
||||
#define R(a,b,c,d,e,f,k,m) do { e += rol( a, 5 ) \
|
||||
+ f( b, c, d ) \
|
||||
+ k \
|
||||
+ m; \
|
||||
b = rol( b, 30 ); \
|
||||
} while(0)
|
||||
|
||||
|
||||
/*
|
||||
* Transform NBLOCKS of each 64 bytes (16 32-bit words) at DATA.
|
||||
*/
|
||||
static void
|
||||
transform (SHA1_CONTEXT *hd, const unsigned char *data, size_t nblocks)
|
||||
{
|
||||
register u32 a, b, c, d, e; /* Local copies of the chaining variables. */
|
||||
register u32 tm; /* Helper. */
|
||||
u32 x[16]; /* The array we work on. */
|
||||
|
||||
/* Loop over all blocks. */
|
||||
for ( ;nblocks; nblocks--)
|
||||
{
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
memcpy (x, data, 64);
|
||||
data += 64;
|
||||
#else
|
||||
{
|
||||
int i;
|
||||
unsigned char *p;
|
||||
|
||||
for(i=0, p=(unsigned char*)x; i < 16; i++, p += 4 )
|
||||
{
|
||||
p[3] = *data++;
|
||||
p[2] = *data++;
|
||||
p[1] = *data++;
|
||||
p[0] = *data++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* Get the values of the chaining variables. */
|
||||
a = hd->h0;
|
||||
b = hd->h1;
|
||||
c = hd->h2;
|
||||
d = hd->h3;
|
||||
e = hd->h4;
|
||||
|
||||
/* Transform. */
|
||||
R( a, b, c, d, e, F1, K1, x[ 0] );
|
||||
R( e, a, b, c, d, F1, K1, x[ 1] );
|
||||
R( d, e, a, b, c, F1, K1, x[ 2] );
|
||||
R( c, d, e, a, b, F1, K1, x[ 3] );
|
||||
R( b, c, d, e, a, F1, K1, x[ 4] );
|
||||
R( a, b, c, d, e, F1, K1, x[ 5] );
|
||||
R( e, a, b, c, d, F1, K1, x[ 6] );
|
||||
R( d, e, a, b, c, F1, K1, x[ 7] );
|
||||
R( c, d, e, a, b, F1, K1, x[ 8] );
|
||||
R( b, c, d, e, a, F1, K1, x[ 9] );
|
||||
R( a, b, c, d, e, F1, K1, x[10] );
|
||||
R( e, a, b, c, d, F1, K1, x[11] );
|
||||
R( d, e, a, b, c, F1, K1, x[12] );
|
||||
R( c, d, e, a, b, F1, K1, x[13] );
|
||||
R( b, c, d, e, a, F1, K1, x[14] );
|
||||
R( a, b, c, d, e, F1, K1, x[15] );
|
||||
R( e, a, b, c, d, F1, K1, M(16) );
|
||||
R( d, e, a, b, c, F1, K1, M(17) );
|
||||
R( c, d, e, a, b, F1, K1, M(18) );
|
||||
R( b, c, d, e, a, F1, K1, M(19) );
|
||||
R( a, b, c, d, e, F2, K2, M(20) );
|
||||
R( e, a, b, c, d, F2, K2, M(21) );
|
||||
R( d, e, a, b, c, F2, K2, M(22) );
|
||||
R( c, d, e, a, b, F2, K2, M(23) );
|
||||
R( b, c, d, e, a, F2, K2, M(24) );
|
||||
R( a, b, c, d, e, F2, K2, M(25) );
|
||||
R( e, a, b, c, d, F2, K2, M(26) );
|
||||
R( d, e, a, b, c, F2, K2, M(27) );
|
||||
R( c, d, e, a, b, F2, K2, M(28) );
|
||||
R( b, c, d, e, a, F2, K2, M(29) );
|
||||
R( a, b, c, d, e, F2, K2, M(30) );
|
||||
R( e, a, b, c, d, F2, K2, M(31) );
|
||||
R( d, e, a, b, c, F2, K2, M(32) );
|
||||
R( c, d, e, a, b, F2, K2, M(33) );
|
||||
R( b, c, d, e, a, F2, K2, M(34) );
|
||||
R( a, b, c, d, e, F2, K2, M(35) );
|
||||
R( e, a, b, c, d, F2, K2, M(36) );
|
||||
R( d, e, a, b, c, F2, K2, M(37) );
|
||||
R( c, d, e, a, b, F2, K2, M(38) );
|
||||
R( b, c, d, e, a, F2, K2, M(39) );
|
||||
R( a, b, c, d, e, F3, K3, M(40) );
|
||||
R( e, a, b, c, d, F3, K3, M(41) );
|
||||
R( d, e, a, b, c, F3, K3, M(42) );
|
||||
R( c, d, e, a, b, F3, K3, M(43) );
|
||||
R( b, c, d, e, a, F3, K3, M(44) );
|
||||
R( a, b, c, d, e, F3, K3, M(45) );
|
||||
R( e, a, b, c, d, F3, K3, M(46) );
|
||||
R( d, e, a, b, c, F3, K3, M(47) );
|
||||
R( c, d, e, a, b, F3, K3, M(48) );
|
||||
R( b, c, d, e, a, F3, K3, M(49) );
|
||||
R( a, b, c, d, e, F3, K3, M(50) );
|
||||
R( e, a, b, c, d, F3, K3, M(51) );
|
||||
R( d, e, a, b, c, F3, K3, M(52) );
|
||||
R( c, d, e, a, b, F3, K3, M(53) );
|
||||
R( b, c, d, e, a, F3, K3, M(54) );
|
||||
R( a, b, c, d, e, F3, K3, M(55) );
|
||||
R( e, a, b, c, d, F3, K3, M(56) );
|
||||
R( d, e, a, b, c, F3, K3, M(57) );
|
||||
R( c, d, e, a, b, F3, K3, M(58) );
|
||||
R( b, c, d, e, a, F3, K3, M(59) );
|
||||
R( a, b, c, d, e, F4, K4, M(60) );
|
||||
R( e, a, b, c, d, F4, K4, M(61) );
|
||||
R( d, e, a, b, c, F4, K4, M(62) );
|
||||
R( c, d, e, a, b, F4, K4, M(63) );
|
||||
R( b, c, d, e, a, F4, K4, M(64) );
|
||||
R( a, b, c, d, e, F4, K4, M(65) );
|
||||
R( e, a, b, c, d, F4, K4, M(66) );
|
||||
R( d, e, a, b, c, F4, K4, M(67) );
|
||||
R( c, d, e, a, b, F4, K4, M(68) );
|
||||
R( b, c, d, e, a, F4, K4, M(69) );
|
||||
R( a, b, c, d, e, F4, K4, M(70) );
|
||||
R( e, a, b, c, d, F4, K4, M(71) );
|
||||
R( d, e, a, b, c, F4, K4, M(72) );
|
||||
R( c, d, e, a, b, F4, K4, M(73) );
|
||||
R( b, c, d, e, a, F4, K4, M(74) );
|
||||
R( a, b, c, d, e, F4, K4, M(75) );
|
||||
R( e, a, b, c, d, F4, K4, M(76) );
|
||||
R( d, e, a, b, c, F4, K4, M(77) );
|
||||
R( c, d, e, a, b, F4, K4, M(78) );
|
||||
R( b, c, d, e, a, F4, K4, M(79) );
|
||||
|
||||
/* Update the chaining variables. */
|
||||
hd->h0 += a;
|
||||
hd->h1 += b;
|
||||
hd->h2 += c;
|
||||
hd->h3 += d;
|
||||
hd->h4 += e;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Update the message digest with the contents
|
||||
* of INBUF with length INLEN.
|
||||
*/
|
||||
static void
|
||||
sha1_write( void *context, const void *inbuf_arg, size_t inlen)
|
||||
{
|
||||
const unsigned char *inbuf = inbuf_arg;
|
||||
SHA1_CONTEXT *hd = context;
|
||||
size_t nblocks;
|
||||
|
||||
if (hd->count == 64) /* Flush the buffer. */
|
||||
{
|
||||
TRANSFORM( hd, hd->buf, 1 );
|
||||
_gcry_burn_stack (88+4*sizeof(void*));
|
||||
hd->count = 0;
|
||||
hd->nblocks++;
|
||||
}
|
||||
if (!inbuf)
|
||||
return;
|
||||
|
||||
if (hd->count)
|
||||
{
|
||||
for (; inlen && hd->count < 64; inlen--)
|
||||
hd->buf[hd->count++] = *inbuf++;
|
||||
sha1_write (hd, NULL, 0);
|
||||
if (!inlen)
|
||||
return;
|
||||
}
|
||||
|
||||
nblocks = inlen / 64;
|
||||
if (nblocks)
|
||||
{
|
||||
TRANSFORM (hd, inbuf, nblocks);
|
||||
hd->count = 0;
|
||||
hd->nblocks += nblocks;
|
||||
inlen -= nblocks * 64;
|
||||
inbuf += nblocks * 64;
|
||||
}
|
||||
_gcry_burn_stack (88+4*sizeof(void*));
|
||||
|
||||
/* Save remaining bytes. */
|
||||
for (; inlen && hd->count < 64; inlen--)
|
||||
hd->buf[hd->count++] = *inbuf++;
|
||||
}
|
||||
|
||||
|
||||
/* The routine final terminates the computation and
|
||||
* returns the digest.
|
||||
* The handle is prepared for a new cycle, but adding bytes to the
|
||||
* handle will the destroy the returned buffer.
|
||||
* Returns: 20 bytes representing the digest.
|
||||
*/
|
||||
|
||||
static void
|
||||
sha1_final(void *context)
|
||||
{
|
||||
SHA1_CONTEXT *hd = context;
|
||||
|
||||
u32 t, msb, lsb;
|
||||
unsigned char *p;
|
||||
|
||||
sha1_write(hd, NULL, 0); /* flush */;
|
||||
|
||||
t = hd->nblocks;
|
||||
/* multiply by 64 to make a byte count */
|
||||
lsb = t << 6;
|
||||
msb = t >> 26;
|
||||
/* add the count */
|
||||
t = lsb;
|
||||
if( (lsb += hd->count) < t )
|
||||
msb++;
|
||||
/* multiply by 8 to make a bit count */
|
||||
t = lsb;
|
||||
lsb <<= 3;
|
||||
msb <<= 3;
|
||||
msb |= t >> 29;
|
||||
|
||||
if( hd->count < 56 ) /* enough room */
|
||||
{
|
||||
hd->buf[hd->count++] = 0x80; /* pad */
|
||||
while( hd->count < 56 )
|
||||
hd->buf[hd->count++] = 0; /* pad */
|
||||
}
|
||||
else /* need one extra block */
|
||||
{
|
||||
hd->buf[hd->count++] = 0x80; /* pad character */
|
||||
while( hd->count < 64 )
|
||||
hd->buf[hd->count++] = 0;
|
||||
sha1_write(hd, NULL, 0); /* flush */;
|
||||
memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
|
||||
}
|
||||
/* append the 64 bit count */
|
||||
hd->buf[56] = msb >> 24;
|
||||
hd->buf[57] = msb >> 16;
|
||||
hd->buf[58] = msb >> 8;
|
||||
hd->buf[59] = msb ;
|
||||
hd->buf[60] = lsb >> 24;
|
||||
hd->buf[61] = lsb >> 16;
|
||||
hd->buf[62] = lsb >> 8;
|
||||
hd->buf[63] = lsb ;
|
||||
TRANSFORM( hd, hd->buf, 1 );
|
||||
_gcry_burn_stack (88+4*sizeof(void*));
|
||||
|
||||
p = hd->buf;
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
|
||||
#else /* little endian */
|
||||
#define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16; \
|
||||
*p++ = hd->h##a >> 8; *p++ = hd->h##a; } while(0)
|
||||
#endif
|
||||
X(0);
|
||||
X(1);
|
||||
X(2);
|
||||
X(3);
|
||||
X(4);
|
||||
#undef X
|
||||
|
||||
}
|
||||
|
||||
static unsigned char *
|
||||
sha1_read( void *context )
|
||||
{
|
||||
SHA1_CONTEXT *hd = context;
|
||||
|
||||
return hd->buf;
|
||||
}
|
||||
|
||||
/****************
|
||||
* Shortcut functions which puts the hash value of the supplied buffer
|
||||
* into outbuf which must have a size of 20 bytes.
|
||||
*/
|
||||
void
|
||||
_gcry_sha1_hash_buffer (void *outbuf, const void *buffer, size_t length)
|
||||
{
|
||||
SHA1_CONTEXT hd;
|
||||
|
||||
sha1_init (&hd);
|
||||
sha1_write (&hd, buffer, length);
|
||||
sha1_final (&hd);
|
||||
memcpy (outbuf, hd.buf, 20);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Self-test section.
|
||||
*/
|
||||
|
||||
|
||||
static gpg_err_code_t
|
||||
selftests_sha1 (int extended, selftest_report_func_t report)
|
||||
{
|
||||
const char *what;
|
||||
const char *errtxt;
|
||||
|
||||
what = "short string";
|
||||
errtxt = _gcry_hash_selftest_check_one
|
||||
(GCRY_MD_SHA1, 0,
|
||||
"abc", 3,
|
||||
"\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E"
|
||||
"\x25\x71\x78\x50\xC2\x6C\x9C\xD0\xD8\x9D", 20);
|
||||
if (errtxt)
|
||||
goto failed;
|
||||
|
||||
if (extended)
|
||||
{
|
||||
what = "long string";
|
||||
errtxt = _gcry_hash_selftest_check_one
|
||||
(GCRY_MD_SHA1, 0,
|
||||
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56,
|
||||
"\x84\x98\x3E\x44\x1C\x3B\xD2\x6E\xBA\xAE"
|
||||
"\x4A\xA1\xF9\x51\x29\xE5\xE5\x46\x70\xF1", 20);
|
||||
if (errtxt)
|
||||
goto failed;
|
||||
|
||||
what = "one million \"a\"";
|
||||
errtxt = _gcry_hash_selftest_check_one
|
||||
(GCRY_MD_SHA1, 1,
|
||||
NULL, 0,
|
||||
"\x34\xAA\x97\x3C\xD4\xC4\xDA\xA4\xF6\x1E"
|
||||
"\xEB\x2B\xDB\xAD\x27\x31\x65\x34\x01\x6F", 20);
|
||||
if (errtxt)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
return 0; /* Succeeded. */
|
||||
|
||||
failed:
|
||||
if (report)
|
||||
report ("digest", GCRY_MD_SHA1, what, errtxt);
|
||||
return GPG_ERR_SELFTEST_FAILED;
|
||||
}
|
||||
|
||||
|
||||
/* Run a full self-test for ALGO and return 0 on success. */
|
||||
static gpg_err_code_t
|
||||
run_selftests (int algo, int extended, selftest_report_func_t report)
|
||||
{
|
||||
gpg_err_code_t ec;
|
||||
|
||||
switch (algo)
|
||||
{
|
||||
case GCRY_MD_SHA1:
|
||||
ec = selftests_sha1 (extended, report);
|
||||
break;
|
||||
default:
|
||||
ec = GPG_ERR_DIGEST_ALGO;
|
||||
break;
|
||||
|
||||
}
|
||||
return ec;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static unsigned char asn[15] = /* Object ID is 1.3.14.3.2.26 */
|
||||
{ 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
|
||||
0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 };
|
||||
|
||||
static gcry_md_oid_spec_t oid_spec_sha1[] =
|
||||
{
|
||||
/* iso.member-body.us.rsadsi.pkcs.pkcs-1.5 (sha1WithRSAEncryption) */
|
||||
{ "1.2.840.113549.1.1.5" },
|
||||
/* iso.member-body.us.x9-57.x9cm.3 (dsaWithSha1)*/
|
||||
{ "1.2.840.10040.4.3" },
|
||||
/* from NIST's OIW (sha1) */
|
||||
{ "1.3.14.3.2.26" },
|
||||
/* from NIST OIW (sha-1WithRSAEncryption) */
|
||||
{ "1.3.14.3.2.29" },
|
||||
/* iso.member-body.us.ansi-x9-62.signatures.ecdsa-with-sha1 */
|
||||
{ "1.2.840.10045.4.1" },
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
gcry_md_spec_t _gcry_digest_spec_sha1 =
|
||||
{
|
||||
"SHA1", asn, DIM (asn), oid_spec_sha1, 20,
|
||||
sha1_init, sha1_write, sha1_final, sha1_read,
|
||||
sizeof (SHA1_CONTEXT)
|
||||
};
|
||||
md_extra_spec_t _gcry_digest_extraspec_sha1 =
|
||||
{
|
||||
run_selftests
|
||||
};
|
||||
|
487
lib/libgcrypt/cipher/sha256.c
Normal file
487
lib/libgcrypt/cipher/sha256.c
Normal file
|
@ -0,0 +1,487 @@
|
|||
/* sha256.c - SHA256 hash function
|
||||
* Copyright (C) 2003, 2006, 2008 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of Libgcrypt.
|
||||
*
|
||||
* Libgcrypt is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Libgcrypt is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
/* Test vectors:
|
||||
|
||||
"abc"
|
||||
SHA224: 23097d22 3405d822 8642a477 bda255b3 2aadbce4 bda0b3f7 e36c9da7
|
||||
SHA256: ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad
|
||||
|
||||
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
|
||||
SHA224: 75388b16 512776cc 5dba5da1 fd890150 b0c6455c b4f58b19 52522525
|
||||
SHA256: 248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1
|
||||
|
||||
"a" one million times
|
||||
SHA224: 20794655 980c91d8 bbb4c1ea 97618a4b f03f4258 1948b2ee 4ee7ad67
|
||||
SHA256: cdc76e5c 9914fb92 81a1c7e2 84d73e67 f1809a48 a497200e 046d39cc c7112cd0
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "g10lib.h"
|
||||
#include "memory.h"
|
||||
#include "bithelp.h"
|
||||
#include "cipher.h"
|
||||
#include "hash-common.h"
|
||||
|
||||
typedef struct {
|
||||
u32 h0,h1,h2,h3,h4,h5,h6,h7;
|
||||
u32 nblocks;
|
||||
byte buf[64];
|
||||
int count;
|
||||
} SHA256_CONTEXT;
|
||||
|
||||
|
||||
static void
|
||||
sha256_init (void *context)
|
||||
{
|
||||
SHA256_CONTEXT *hd = context;
|
||||
|
||||
hd->h0 = 0x6a09e667;
|
||||
hd->h1 = 0xbb67ae85;
|
||||
hd->h2 = 0x3c6ef372;
|
||||
hd->h3 = 0xa54ff53a;
|
||||
hd->h4 = 0x510e527f;
|
||||
hd->h5 = 0x9b05688c;
|
||||
hd->h6 = 0x1f83d9ab;
|
||||
hd->h7 = 0x5be0cd19;
|
||||
|
||||
hd->nblocks = 0;
|
||||
hd->count = 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sha224_init (void *context)
|
||||
{
|
||||
SHA256_CONTEXT *hd = context;
|
||||
|
||||
hd->h0 = 0xc1059ed8;
|
||||
hd->h1 = 0x367cd507;
|
||||
hd->h2 = 0x3070dd17;
|
||||
hd->h3 = 0xf70e5939;
|
||||
hd->h4 = 0xffc00b31;
|
||||
hd->h5 = 0x68581511;
|
||||
hd->h6 = 0x64f98fa7;
|
||||
hd->h7 = 0xbefa4fa4;
|
||||
|
||||
hd->nblocks = 0;
|
||||
hd->count = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Transform the message X which consists of 16 32-bit-words. See FIPS
|
||||
180-2 for details. */
|
||||
#define Cho(x,y,z) (z ^ (x & (y ^ z))) /* (4.2) same as SHA-1's F1 */
|
||||
#define Maj(x,y,z) ((x & y) | (z & (x|y))) /* (4.3) same as SHA-1's F3 */
|
||||
#define Sum0(x) (ror ((x), 2) ^ ror ((x), 13) ^ ror ((x), 22)) /* (4.4) */
|
||||
#define Sum1(x) (ror ((x), 6) ^ ror ((x), 11) ^ ror ((x), 25)) /* (4.5) */
|
||||
#define S0(x) (ror ((x), 7) ^ ror ((x), 18) ^ ((x) >> 3)) /* (4.6) */
|
||||
#define S1(x) (ror ((x), 17) ^ ror ((x), 19) ^ ((x) >> 10)) /* (4.7) */
|
||||
#define R(a,b,c,d,e,f,g,h,k,w) do \
|
||||
{ \
|
||||
t1 = (h) + Sum1((e)) + Cho((e),(f),(g)) + (k) + (w); \
|
||||
t2 = Sum0((a)) + Maj((a),(b),(c)); \
|
||||
h = g; \
|
||||
g = f; \
|
||||
f = e; \
|
||||
e = d + t1; \
|
||||
d = c; \
|
||||
c = b; \
|
||||
b = a; \
|
||||
a = t1 + t2; \
|
||||
} while (0)
|
||||
|
||||
static void
|
||||
transform (SHA256_CONTEXT *hd, const unsigned char *data)
|
||||
{
|
||||
static const u32 K[64] = {
|
||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
|
||||
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
|
||||
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
||||
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
|
||||
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||||
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
|
||||
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
||||
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
|
||||
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
||||
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
|
||||
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
||||
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
|
||||
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
||||
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
|
||||
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
||||
};
|
||||
|
||||
u32 a,b,c,d,e,f,g,h,t1,t2;
|
||||
u32 x[16];
|
||||
u32 w[64];
|
||||
int i;
|
||||
|
||||
a = hd->h0;
|
||||
b = hd->h1;
|
||||
c = hd->h2;
|
||||
d = hd->h3;
|
||||
e = hd->h4;
|
||||
f = hd->h5;
|
||||
g = hd->h6;
|
||||
h = hd->h7;
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
memcpy (x, data, 64);
|
||||
#else
|
||||
{
|
||||
byte *p2;
|
||||
|
||||
for (i=0, p2=(byte*)x; i < 16; i++, p2 += 4 )
|
||||
{
|
||||
p2[3] = *data++;
|
||||
p2[2] = *data++;
|
||||
p2[1] = *data++;
|
||||
p2[0] = *data++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i=0; i < 16; i++)
|
||||
w[i] = x[i];
|
||||
for (; i < 64; i++)
|
||||
w[i] = S1(w[i-2]) + w[i-7] + S0(w[i-15]) + w[i-16];
|
||||
|
||||
for (i=0; i < 64; i++)
|
||||
R(a,b,c,d,e,f,g,h,K[i],w[i]);
|
||||
|
||||
hd->h0 += a;
|
||||
hd->h1 += b;
|
||||
hd->h2 += c;
|
||||
hd->h3 += d;
|
||||
hd->h4 += e;
|
||||
hd->h5 += f;
|
||||
hd->h6 += g;
|
||||
hd->h7 += h;
|
||||
}
|
||||
#undef Cho
|
||||
#undef Maj
|
||||
#undef Sum0
|
||||
#undef Sum1
|
||||
#undef S0
|
||||
#undef S1
|
||||
#undef R
|
||||
|
||||
|
||||
/* Update the message digest with the contents of INBUF with length
|
||||
INLEN. */
|
||||
static void
|
||||
sha256_write (void *context, const void *inbuf_arg, size_t inlen)
|
||||
{
|
||||
const unsigned char *inbuf = inbuf_arg;
|
||||
SHA256_CONTEXT *hd = context;
|
||||
|
||||
if (hd->count == 64)
|
||||
{ /* flush the buffer */
|
||||
transform (hd, hd->buf);
|
||||
_gcry_burn_stack (74*4+32);
|
||||
hd->count = 0;
|
||||
hd->nblocks++;
|
||||
}
|
||||
if (!inbuf)
|
||||
return;
|
||||
if (hd->count)
|
||||
{
|
||||
for (; inlen && hd->count < 64; inlen--)
|
||||
hd->buf[hd->count++] = *inbuf++;
|
||||
sha256_write (hd, NULL, 0);
|
||||
if (!inlen)
|
||||
return;
|
||||
}
|
||||
|
||||
while (inlen >= 64)
|
||||
{
|
||||
transform (hd, inbuf);
|
||||
hd->count = 0;
|
||||
hd->nblocks++;
|
||||
inlen -= 64;
|
||||
inbuf += 64;
|
||||
}
|
||||
_gcry_burn_stack (74*4+32);
|
||||
for (; inlen && hd->count < 64; inlen--)
|
||||
hd->buf[hd->count++] = *inbuf++;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
The routine finally terminates the computation and returns the
|
||||
digest. The handle is prepared for a new cycle, but adding bytes
|
||||
to the handle will the destroy the returned buffer. Returns: 32
|
||||
bytes with the message the digest. */
|
||||
static void
|
||||
sha256_final(void *context)
|
||||
{
|
||||
SHA256_CONTEXT *hd = context;
|
||||
u32 t, msb, lsb;
|
||||
byte *p;
|
||||
|
||||
sha256_write (hd, NULL, 0); /* flush */;
|
||||
|
||||
t = hd->nblocks;
|
||||
/* multiply by 64 to make a byte count */
|
||||
lsb = t << 6;
|
||||
msb = t >> 26;
|
||||
/* add the count */
|
||||
t = lsb;
|
||||
if ((lsb += hd->count) < t)
|
||||
msb++;
|
||||
/* multiply by 8 to make a bit count */
|
||||
t = lsb;
|
||||
lsb <<= 3;
|
||||
msb <<= 3;
|
||||
msb |= t >> 29;
|
||||
|
||||
if (hd->count < 56)
|
||||
{ /* enough room */
|
||||
hd->buf[hd->count++] = 0x80; /* pad */
|
||||
while (hd->count < 56)
|
||||
hd->buf[hd->count++] = 0; /* pad */
|
||||
}
|
||||
else
|
||||
{ /* need one extra block */
|
||||
hd->buf[hd->count++] = 0x80; /* pad character */
|
||||
while (hd->count < 64)
|
||||
hd->buf[hd->count++] = 0;
|
||||
sha256_write (hd, NULL, 0); /* flush */;
|
||||
memset (hd->buf, 0, 56 ); /* fill next block with zeroes */
|
||||
}
|
||||
/* append the 64 bit count */
|
||||
hd->buf[56] = msb >> 24;
|
||||
hd->buf[57] = msb >> 16;
|
||||
hd->buf[58] = msb >> 8;
|
||||
hd->buf[59] = msb;
|
||||
hd->buf[60] = lsb >> 24;
|
||||
hd->buf[61] = lsb >> 16;
|
||||
hd->buf[62] = lsb >> 8;
|
||||
hd->buf[63] = lsb;
|
||||
transform (hd, hd->buf);
|
||||
_gcry_burn_stack (74*4+32);
|
||||
|
||||
p = hd->buf;
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
|
||||
#else /* little endian */
|
||||
#define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16; \
|
||||
*p++ = hd->h##a >> 8; *p++ = hd->h##a; } while(0)
|
||||
#endif
|
||||
X(0);
|
||||
X(1);
|
||||
X(2);
|
||||
X(3);
|
||||
X(4);
|
||||
X(5);
|
||||
X(6);
|
||||
X(7);
|
||||
#undef X
|
||||
}
|
||||
|
||||
static byte *
|
||||
sha256_read (void *context)
|
||||
{
|
||||
SHA256_CONTEXT *hd = context;
|
||||
|
||||
return hd->buf;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Self-test section.
|
||||
*/
|
||||
|
||||
|
||||
static gpg_err_code_t
|
||||
selftests_sha224 (int extended, selftest_report_func_t report)
|
||||
{
|
||||
const char *what;
|
||||
const char *errtxt;
|
||||
|
||||
what = "short string";
|
||||
errtxt = _gcry_hash_selftest_check_one
|
||||
(GCRY_MD_SHA224, 0,
|
||||
"abc", 3,
|
||||
"\x23\x09\x7d\x22\x34\x05\xd8\x22\x86\x42\xa4\x77\xbd\xa2\x55\xb3"
|
||||
"\x2a\xad\xbc\xe4\xbd\xa0\xb3\xf7\xe3\x6c\x9d\xa7", 28);
|
||||
if (errtxt)
|
||||
goto failed;
|
||||
|
||||
if (extended)
|
||||
{
|
||||
what = "long string";
|
||||
errtxt = _gcry_hash_selftest_check_one
|
||||
(GCRY_MD_SHA224, 0,
|
||||
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56,
|
||||
"\x75\x38\x8b\x16\x51\x27\x76\xcc\x5d\xba\x5d\xa1\xfd\x89\x01\x50"
|
||||
"\xb0\xc6\x45\x5c\xb4\xf5\x8b\x19\x52\x52\x25\x25", 28);
|
||||
if (errtxt)
|
||||
goto failed;
|
||||
|
||||
what = "one million \"a\"";
|
||||
errtxt = _gcry_hash_selftest_check_one
|
||||
(GCRY_MD_SHA224, 1,
|
||||
NULL, 0,
|
||||
"\x20\x79\x46\x55\x98\x0c\x91\xd8\xbb\xb4\xc1\xea\x97\x61\x8a\x4b"
|
||||
"\xf0\x3f\x42\x58\x19\x48\xb2\xee\x4e\xe7\xad\x67", 28);
|
||||
if (errtxt)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
return 0; /* Succeeded. */
|
||||
|
||||
failed:
|
||||
if (report)
|
||||
report ("digest", GCRY_MD_SHA224, what, errtxt);
|
||||
return GPG_ERR_SELFTEST_FAILED;
|
||||
}
|
||||
|
||||
static gpg_err_code_t
|
||||
selftests_sha256 (int extended, selftest_report_func_t report)
|
||||
{
|
||||
const char *what;
|
||||
const char *errtxt;
|
||||
|
||||
what = "short string";
|
||||
errtxt = _gcry_hash_selftest_check_one
|
||||
(GCRY_MD_SHA256, 0,
|
||||
"abc", 3,
|
||||
"\xba\x78\x16\xbf\x8f\x01\xcf\xea\x41\x41\x40\xde\x5d\xae\x22\x23"
|
||||
"\xb0\x03\x61\xa3\x96\x17\x7a\x9c\xb4\x10\xff\x61\xf2\x00\x15\xad", 32);
|
||||
if (errtxt)
|
||||
goto failed;
|
||||
|
||||
if (extended)
|
||||
{
|
||||
what = "long string";
|
||||
errtxt = _gcry_hash_selftest_check_one
|
||||
(GCRY_MD_SHA256, 0,
|
||||
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56,
|
||||
"\x24\x8d\x6a\x61\xd2\x06\x38\xb8\xe5\xc0\x26\x93\x0c\x3e\x60\x39"
|
||||
"\xa3\x3c\xe4\x59\x64\xff\x21\x67\xf6\xec\xed\xd4\x19\xdb\x06\xc1",
|
||||
32);
|
||||
if (errtxt)
|
||||
goto failed;
|
||||
|
||||
what = "one million \"a\"";
|
||||
errtxt = _gcry_hash_selftest_check_one
|
||||
(GCRY_MD_SHA256, 1,
|
||||
NULL, 0,
|
||||
"\xcd\xc7\x6e\x5c\x99\x14\xfb\x92\x81\xa1\xc7\xe2\x84\xd7\x3e\x67"
|
||||
"\xf1\x80\x9a\x48\xa4\x97\x20\x0e\x04\x6d\x39\xcc\xc7\x11\x2c\xd0",
|
||||
32);
|
||||
if (errtxt)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
return 0; /* Succeeded. */
|
||||
|
||||
failed:
|
||||
if (report)
|
||||
report ("digest", GCRY_MD_SHA256, what, errtxt);
|
||||
return GPG_ERR_SELFTEST_FAILED;
|
||||
}
|
||||
|
||||
|
||||
/* Run a full self-test for ALGO and return 0 on success. */
|
||||
static gpg_err_code_t
|
||||
run_selftests (int algo, int extended, selftest_report_func_t report)
|
||||
{
|
||||
gpg_err_code_t ec;
|
||||
|
||||
switch (algo)
|
||||
{
|
||||
case GCRY_MD_SHA224:
|
||||
ec = selftests_sha224 (extended, report);
|
||||
break;
|
||||
case GCRY_MD_SHA256:
|
||||
ec = selftests_sha256 (extended, report);
|
||||
break;
|
||||
default:
|
||||
ec = GPG_ERR_DIGEST_ALGO;
|
||||
break;
|
||||
|
||||
}
|
||||
return ec;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static byte asn224[19] = /* Object ID is 2.16.840.1.101.3.4.2.4 */
|
||||
{ 0x30, 0x2D, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
|
||||
0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04,
|
||||
0x1C
|
||||
};
|
||||
|
||||
static gcry_md_oid_spec_t oid_spec_sha224[] =
|
||||
{
|
||||
/* From RFC3874, Section 4 */
|
||||
{ "2.16.840.1.101.3.4.2.4" },
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
static byte asn256[19] = /* Object ID is 2.16.840.1.101.3.4.2.1 */
|
||||
{ 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
|
||||
0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
|
||||
0x00, 0x04, 0x20 };
|
||||
|
||||
static gcry_md_oid_spec_t oid_spec_sha256[] =
|
||||
{
|
||||
/* According to the OpenPGP draft rfc2440-bis06 */
|
||||
{ "2.16.840.1.101.3.4.2.1" },
|
||||
/* PKCS#1 sha256WithRSAEncryption */
|
||||
{ "1.2.840.113549.1.1.11" },
|
||||
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
gcry_md_spec_t _gcry_digest_spec_sha224 =
|
||||
{
|
||||
"SHA224", asn224, DIM (asn224), oid_spec_sha224, 28,
|
||||
sha224_init, sha256_write, sha256_final, sha256_read,
|
||||
sizeof (SHA256_CONTEXT)
|
||||
};
|
||||
md_extra_spec_t _gcry_digest_extraspec_sha224 =
|
||||
{
|
||||
run_selftests
|
||||
};
|
||||
|
||||
gcry_md_spec_t _gcry_digest_spec_sha256 =
|
||||
{
|
||||
"SHA256", asn256, DIM (asn256), oid_spec_sha256, 32,
|
||||
sha256_init, sha256_write, sha256_final, sha256_read,
|
||||
sizeof (SHA256_CONTEXT)
|
||||
};
|
||||
md_extra_spec_t _gcry_digest_extraspec_sha256 =
|
||||
{
|
||||
run_selftests
|
||||
};
|
553
lib/libgcrypt/cipher/sha512.c
Normal file
553
lib/libgcrypt/cipher/sha512.c
Normal file
|
@ -0,0 +1,553 @@
|
|||
/* sha512.c - SHA384 and SHA512 hash functions
|
||||
* Copyright (C) 2003, 2008 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of Libgcrypt.
|
||||
*
|
||||
* Libgcrypt is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser general Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Libgcrypt is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
/* Test vectors from FIPS-180-2:
|
||||
*
|
||||
* "abc"
|
||||
* 384:
|
||||
* CB00753F 45A35E8B B5A03D69 9AC65007 272C32AB 0EDED163
|
||||
* 1A8B605A 43FF5BED 8086072B A1E7CC23 58BAECA1 34C825A7
|
||||
* 512:
|
||||
* DDAF35A1 93617ABA CC417349 AE204131 12E6FA4E 89A97EA2 0A9EEEE6 4B55D39A
|
||||
* 2192992A 274FC1A8 36BA3C23 A3FEEBBD 454D4423 643CE80E 2A9AC94F A54CA49F
|
||||
*
|
||||
* "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
|
||||
* 384:
|
||||
* 09330C33 F71147E8 3D192FC7 82CD1B47 53111B17 3B3B05D2
|
||||
* 2FA08086 E3B0F712 FCC7C71A 557E2DB9 66C3E9FA 91746039
|
||||
* 512:
|
||||
* 8E959B75 DAE313DA 8CF4F728 14FC143F 8F7779C6 EB9F7FA1 7299AEAD B6889018
|
||||
* 501D289E 4900F7E4 331B99DE C4B5433A C7D329EE B6DD2654 5E96E55B 874BE909
|
||||
*
|
||||
* "a" x 1000000
|
||||
* 384:
|
||||
* 9D0E1809 716474CB 086E834E 310A4A1C ED149E9C 00F24852
|
||||
* 7972CEC5 704C2A5B 07B8B3DC 38ECC4EB AE97DDD8 7F3D8985
|
||||
* 512:
|
||||
* E718483D 0CE76964 4E2E42C7 BC15B463 8E1F98B1 3B204428 5632A803 AFA973EB
|
||||
* DE0FF244 877EA60A 4CB0432C E577C31B EB009C5C 2C49AA2E 4EADB217 AD8CC09B
|
||||
*/
|
||||
|
||||
|
||||
#include <config.h>
|
||||
#include <string.h>
|
||||
#include "g10lib.h"
|
||||
#include "bithelp.h"
|
||||
#include "cipher.h"
|
||||
#include "hash-common.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u64 h0, h1, h2, h3, h4, h5, h6, h7;
|
||||
u64 nblocks;
|
||||
byte buf[128];
|
||||
int count;
|
||||
} SHA512_CONTEXT;
|
||||
|
||||
static void
|
||||
sha512_init (void *context)
|
||||
{
|
||||
SHA512_CONTEXT *hd = context;
|
||||
|
||||
hd->h0 = U64_C(0x6a09e667f3bcc908);
|
||||
hd->h1 = U64_C(0xbb67ae8584caa73b);
|
||||
hd->h2 = U64_C(0x3c6ef372fe94f82b);
|
||||
hd->h3 = U64_C(0xa54ff53a5f1d36f1);
|
||||
hd->h4 = U64_C(0x510e527fade682d1);
|
||||
hd->h5 = U64_C(0x9b05688c2b3e6c1f);
|
||||
hd->h6 = U64_C(0x1f83d9abfb41bd6b);
|
||||
hd->h7 = U64_C(0x5be0cd19137e2179);
|
||||
|
||||
hd->nblocks = 0;
|
||||
hd->count = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
sha384_init (void *context)
|
||||
{
|
||||
SHA512_CONTEXT *hd = context;
|
||||
|
||||
hd->h0 = U64_C(0xcbbb9d5dc1059ed8);
|
||||
hd->h1 = U64_C(0x629a292a367cd507);
|
||||
hd->h2 = U64_C(0x9159015a3070dd17);
|
||||
hd->h3 = U64_C(0x152fecd8f70e5939);
|
||||
hd->h4 = U64_C(0x67332667ffc00b31);
|
||||
hd->h5 = U64_C(0x8eb44a8768581511);
|
||||
hd->h6 = U64_C(0xdb0c2e0d64f98fa7);
|
||||
hd->h7 = U64_C(0x47b5481dbefa4fa4);
|
||||
|
||||
hd->nblocks = 0;
|
||||
hd->count = 0;
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Transform the message W which consists of 16 64-bit-words
|
||||
*/
|
||||
static void
|
||||
transform (SHA512_CONTEXT *hd, const unsigned char *data)
|
||||
{
|
||||
u64 a, b, c, d, e, f, g, h;
|
||||
u64 w[80];
|
||||
int t;
|
||||
static const u64 k[] =
|
||||
{
|
||||
U64_C(0x428a2f98d728ae22), U64_C(0x7137449123ef65cd),
|
||||
U64_C(0xb5c0fbcfec4d3b2f), U64_C(0xe9b5dba58189dbbc),
|
||||
U64_C(0x3956c25bf348b538), U64_C(0x59f111f1b605d019),
|
||||
U64_C(0x923f82a4af194f9b), U64_C(0xab1c5ed5da6d8118),
|
||||
U64_C(0xd807aa98a3030242), U64_C(0x12835b0145706fbe),
|
||||
U64_C(0x243185be4ee4b28c), U64_C(0x550c7dc3d5ffb4e2),
|
||||
U64_C(0x72be5d74f27b896f), U64_C(0x80deb1fe3b1696b1),
|
||||
U64_C(0x9bdc06a725c71235), U64_C(0xc19bf174cf692694),
|
||||
U64_C(0xe49b69c19ef14ad2), U64_C(0xefbe4786384f25e3),
|
||||
U64_C(0x0fc19dc68b8cd5b5), U64_C(0x240ca1cc77ac9c65),
|
||||
U64_C(0x2de92c6f592b0275), U64_C(0x4a7484aa6ea6e483),
|
||||
U64_C(0x5cb0a9dcbd41fbd4), U64_C(0x76f988da831153b5),
|
||||
U64_C(0x983e5152ee66dfab), U64_C(0xa831c66d2db43210),
|
||||
U64_C(0xb00327c898fb213f), U64_C(0xbf597fc7beef0ee4),
|
||||
U64_C(0xc6e00bf33da88fc2), U64_C(0xd5a79147930aa725),
|
||||
U64_C(0x06ca6351e003826f), U64_C(0x142929670a0e6e70),
|
||||
U64_C(0x27b70a8546d22ffc), U64_C(0x2e1b21385c26c926),
|
||||
U64_C(0x4d2c6dfc5ac42aed), U64_C(0x53380d139d95b3df),
|
||||
U64_C(0x650a73548baf63de), U64_C(0x766a0abb3c77b2a8),
|
||||
U64_C(0x81c2c92e47edaee6), U64_C(0x92722c851482353b),
|
||||
U64_C(0xa2bfe8a14cf10364), U64_C(0xa81a664bbc423001),
|
||||
U64_C(0xc24b8b70d0f89791), U64_C(0xc76c51a30654be30),
|
||||
U64_C(0xd192e819d6ef5218), U64_C(0xd69906245565a910),
|
||||
U64_C(0xf40e35855771202a), U64_C(0x106aa07032bbd1b8),
|
||||
U64_C(0x19a4c116b8d2d0c8), U64_C(0x1e376c085141ab53),
|
||||
U64_C(0x2748774cdf8eeb99), U64_C(0x34b0bcb5e19b48a8),
|
||||
U64_C(0x391c0cb3c5c95a63), U64_C(0x4ed8aa4ae3418acb),
|
||||
U64_C(0x5b9cca4f7763e373), U64_C(0x682e6ff3d6b2b8a3),
|
||||
U64_C(0x748f82ee5defb2fc), U64_C(0x78a5636f43172f60),
|
||||
U64_C(0x84c87814a1f0ab72), U64_C(0x8cc702081a6439ec),
|
||||
U64_C(0x90befffa23631e28), U64_C(0xa4506cebde82bde9),
|
||||
U64_C(0xbef9a3f7b2c67915), U64_C(0xc67178f2e372532b),
|
||||
U64_C(0xca273eceea26619c), U64_C(0xd186b8c721c0c207),
|
||||
U64_C(0xeada7dd6cde0eb1e), U64_C(0xf57d4f7fee6ed178),
|
||||
U64_C(0x06f067aa72176fba), U64_C(0x0a637dc5a2c898a6),
|
||||
U64_C(0x113f9804bef90dae), U64_C(0x1b710b35131c471b),
|
||||
U64_C(0x28db77f523047d84), U64_C(0x32caab7b40c72493),
|
||||
U64_C(0x3c9ebe0a15c9bebc), U64_C(0x431d67c49c100d4c),
|
||||
U64_C(0x4cc5d4becb3e42b6), U64_C(0x597f299cfc657e2a),
|
||||
U64_C(0x5fcb6fab3ad6faec), U64_C(0x6c44198c4a475817)
|
||||
};
|
||||
|
||||
/* get values from the chaining vars */
|
||||
a = hd->h0;
|
||||
b = hd->h1;
|
||||
c = hd->h2;
|
||||
d = hd->h3;
|
||||
e = hd->h4;
|
||||
f = hd->h5;
|
||||
g = hd->h6;
|
||||
h = hd->h7;
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
memcpy (w, data, 128);
|
||||
#else
|
||||
{
|
||||
int i;
|
||||
byte *p2;
|
||||
|
||||
for (i = 0, p2 = (byte *) w; i < 16; i++, p2 += 8)
|
||||
{
|
||||
p2[7] = *data++;
|
||||
p2[6] = *data++;
|
||||
p2[5] = *data++;
|
||||
p2[4] = *data++;
|
||||
p2[3] = *data++;
|
||||
p2[2] = *data++;
|
||||
p2[1] = *data++;
|
||||
p2[0] = *data++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#define ROTR(x,n) (((x)>>(n)) | ((x)<<(64-(n))))
|
||||
#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
|
||||
#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
|
||||
#define Sum0(x) (ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39))
|
||||
#define Sum1(x) (ROTR((x),14) ^ ROTR((x),18) ^ ROTR((x),41))
|
||||
#define S0(x) (ROTR((x),1) ^ ROTR((x),8) ^ ((x)>>7))
|
||||
#define S1(x) (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6))
|
||||
|
||||
for (t = 16; t < 80; t++)
|
||||
w[t] = S1 (w[t - 2]) + w[t - 7] + S0 (w[t - 15]) + w[t - 16];
|
||||
|
||||
for (t = 0; t < 80; t++)
|
||||
{
|
||||
u64 t1, t2;
|
||||
|
||||
t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[t];
|
||||
t2 = Sum0 (a) + Maj (a, b, c);
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + t1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = t1 + t2;
|
||||
|
||||
/* printf("t=%d a=%016llX b=%016llX c=%016llX d=%016llX "
|
||||
"e=%016llX f=%016llX g=%016llX h=%016llX\n",t,a,b,c,d,e,f,g,h); */
|
||||
}
|
||||
|
||||
/* update chaining vars */
|
||||
hd->h0 += a;
|
||||
hd->h1 += b;
|
||||
hd->h2 += c;
|
||||
hd->h3 += d;
|
||||
hd->h4 += e;
|
||||
hd->h5 += f;
|
||||
hd->h6 += g;
|
||||
hd->h7 += h;
|
||||
}
|
||||
|
||||
|
||||
/* Update the message digest with the contents
|
||||
* of INBUF with length INLEN.
|
||||
*/
|
||||
static void
|
||||
sha512_write (void *context, const void *inbuf_arg, size_t inlen)
|
||||
{
|
||||
const unsigned char *inbuf = inbuf_arg;
|
||||
SHA512_CONTEXT *hd = context;
|
||||
|
||||
if (hd->count == 128)
|
||||
{ /* flush the buffer */
|
||||
transform (hd, hd->buf);
|
||||
_gcry_burn_stack (768);
|
||||
hd->count = 0;
|
||||
hd->nblocks++;
|
||||
}
|
||||
if (!inbuf)
|
||||
return;
|
||||
if (hd->count)
|
||||
{
|
||||
for (; inlen && hd->count < 128; inlen--)
|
||||
hd->buf[hd->count++] = *inbuf++;
|
||||
sha512_write (context, NULL, 0);
|
||||
if (!inlen)
|
||||
return;
|
||||
}
|
||||
|
||||
while (inlen >= 128)
|
||||
{
|
||||
transform (hd, inbuf);
|
||||
hd->count = 0;
|
||||
hd->nblocks++;
|
||||
inlen -= 128;
|
||||
inbuf += 128;
|
||||
}
|
||||
_gcry_burn_stack (768);
|
||||
for (; inlen && hd->count < 128; inlen--)
|
||||
hd->buf[hd->count++] = *inbuf++;
|
||||
}
|
||||
|
||||
|
||||
/* The routine final terminates the computation and
|
||||
* returns the digest.
|
||||
* The handle is prepared for a new cycle, but adding bytes to the
|
||||
* handle will the destroy the returned buffer.
|
||||
* Returns: 64 bytes representing the digest. When used for sha384,
|
||||
* we take the leftmost 48 of those bytes.
|
||||
*/
|
||||
|
||||
static void
|
||||
sha512_final (void *context)
|
||||
{
|
||||
SHA512_CONTEXT *hd = context;
|
||||
u64 t, msb, lsb;
|
||||
byte *p;
|
||||
|
||||
sha512_write (context, NULL, 0); /* flush */ ;
|
||||
|
||||
t = hd->nblocks;
|
||||
/* multiply by 128 to make a byte count */
|
||||
lsb = t << 7;
|
||||
msb = t >> 57;
|
||||
/* add the count */
|
||||
t = lsb;
|
||||
if ((lsb += hd->count) < t)
|
||||
msb++;
|
||||
/* multiply by 8 to make a bit count */
|
||||
t = lsb;
|
||||
lsb <<= 3;
|
||||
msb <<= 3;
|
||||
msb |= t >> 61;
|
||||
|
||||
if (hd->count < 112)
|
||||
{ /* enough room */
|
||||
hd->buf[hd->count++] = 0x80; /* pad */
|
||||
while (hd->count < 112)
|
||||
hd->buf[hd->count++] = 0; /* pad */
|
||||
}
|
||||
else
|
||||
{ /* need one extra block */
|
||||
hd->buf[hd->count++] = 0x80; /* pad character */
|
||||
while (hd->count < 128)
|
||||
hd->buf[hd->count++] = 0;
|
||||
sha512_write (context, NULL, 0); /* flush */ ;
|
||||
memset (hd->buf, 0, 112); /* fill next block with zeroes */
|
||||
}
|
||||
/* append the 128 bit count */
|
||||
hd->buf[112] = msb >> 56;
|
||||
hd->buf[113] = msb >> 48;
|
||||
hd->buf[114] = msb >> 40;
|
||||
hd->buf[115] = msb >> 32;
|
||||
hd->buf[116] = msb >> 24;
|
||||
hd->buf[117] = msb >> 16;
|
||||
hd->buf[118] = msb >> 8;
|
||||
hd->buf[119] = msb;
|
||||
|
||||
hd->buf[120] = lsb >> 56;
|
||||
hd->buf[121] = lsb >> 48;
|
||||
hd->buf[122] = lsb >> 40;
|
||||
hd->buf[123] = lsb >> 32;
|
||||
hd->buf[124] = lsb >> 24;
|
||||
hd->buf[125] = lsb >> 16;
|
||||
hd->buf[126] = lsb >> 8;
|
||||
hd->buf[127] = lsb;
|
||||
transform (hd, hd->buf);
|
||||
_gcry_burn_stack (768);
|
||||
|
||||
p = hd->buf;
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#define X(a) do { *(u64*)p = hd->h##a ; p += 8; } while (0)
|
||||
#else /* little endian */
|
||||
#define X(a) do { *p++ = hd->h##a >> 56; *p++ = hd->h##a >> 48; \
|
||||
*p++ = hd->h##a >> 40; *p++ = hd->h##a >> 32; \
|
||||
*p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16; \
|
||||
*p++ = hd->h##a >> 8; *p++ = hd->h##a; } while (0)
|
||||
#endif
|
||||
X (0);
|
||||
X (1);
|
||||
X (2);
|
||||
X (3);
|
||||
X (4);
|
||||
X (5);
|
||||
/* Note that these last two chunks are included even for SHA384.
|
||||
We just ignore them. */
|
||||
X (6);
|
||||
X (7);
|
||||
#undef X
|
||||
}
|
||||
|
||||
static byte *
|
||||
sha512_read (void *context)
|
||||
{
|
||||
SHA512_CONTEXT *hd = (SHA512_CONTEXT *) context;
|
||||
return hd->buf;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Self-test section.
|
||||
*/
|
||||
|
||||
|
||||
static gpg_err_code_t
|
||||
selftests_sha384 (int extended, selftest_report_func_t report)
|
||||
{
|
||||
const char *what;
|
||||
const char *errtxt;
|
||||
|
||||
what = "short string";
|
||||
errtxt = _gcry_hash_selftest_check_one
|
||||
(GCRY_MD_SHA384, 0,
|
||||
"abc", 3,
|
||||
"\xcb\x00\x75\x3f\x45\xa3\x5e\x8b\xb5\xa0\x3d\x69\x9a\xc6\x50\x07"
|
||||
"\x27\x2c\x32\xab\x0e\xde\xd1\x63\x1a\x8b\x60\x5a\x43\xff\x5b\xed"
|
||||
"\x80\x86\x07\x2b\xa1\xe7\xcc\x23\x58\xba\xec\xa1\x34\xc8\x25\xa7", 48);
|
||||
if (errtxt)
|
||||
goto failed;
|
||||
|
||||
if (extended)
|
||||
{
|
||||
what = "long string";
|
||||
errtxt = _gcry_hash_selftest_check_one
|
||||
(GCRY_MD_SHA384, 0,
|
||||
"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
|
||||
"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112,
|
||||
"\x09\x33\x0C\x33\xF7\x11\x47\xE8\x3D\x19\x2F\xC7\x82\xCD\x1B\x47"
|
||||
"\x53\x11\x1B\x17\x3B\x3B\x05\xD2\x2F\xA0\x80\x86\xE3\xB0\xF7\x12"
|
||||
"\xFC\xC7\xC7\x1A\x55\x7E\x2D\xB9\x66\xC3\xE9\xFA\x91\x74\x60\x39",
|
||||
48);
|
||||
if (errtxt)
|
||||
goto failed;
|
||||
|
||||
what = "one million \"a\"";
|
||||
errtxt = _gcry_hash_selftest_check_one
|
||||
(GCRY_MD_SHA384, 1,
|
||||
NULL, 0,
|
||||
"\x9D\x0E\x18\x09\x71\x64\x74\xCB\x08\x6E\x83\x4E\x31\x0A\x4A\x1C"
|
||||
"\xED\x14\x9E\x9C\x00\xF2\x48\x52\x79\x72\xCE\xC5\x70\x4C\x2A\x5B"
|
||||
"\x07\xB8\xB3\xDC\x38\xEC\xC4\xEB\xAE\x97\xDD\xD8\x7F\x3D\x89\x85",
|
||||
48);
|
||||
if (errtxt)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
return 0; /* Succeeded. */
|
||||
|
||||
failed:
|
||||
if (report)
|
||||
report ("digest", GCRY_MD_SHA384, what, errtxt);
|
||||
return GPG_ERR_SELFTEST_FAILED;
|
||||
}
|
||||
|
||||
static gpg_err_code_t
|
||||
selftests_sha512 (int extended, selftest_report_func_t report)
|
||||
{
|
||||
const char *what;
|
||||
const char *errtxt;
|
||||
|
||||
what = "short string";
|
||||
errtxt = _gcry_hash_selftest_check_one
|
||||
(GCRY_MD_SHA512, 0,
|
||||
"abc", 3,
|
||||
"\xDD\xAF\x35\xA1\x93\x61\x7A\xBA\xCC\x41\x73\x49\xAE\x20\x41\x31"
|
||||
"\x12\xE6\xFA\x4E\x89\xA9\x7E\xA2\x0A\x9E\xEE\xE6\x4B\x55\xD3\x9A"
|
||||
"\x21\x92\x99\x2A\x27\x4F\xC1\xA8\x36\xBA\x3C\x23\xA3\xFE\xEB\xBD"
|
||||
"\x45\x4D\x44\x23\x64\x3C\xE8\x0E\x2A\x9A\xC9\x4F\xA5\x4C\xA4\x9F", 64);
|
||||
if (errtxt)
|
||||
goto failed;
|
||||
|
||||
if (extended)
|
||||
{
|
||||
what = "long string";
|
||||
errtxt = _gcry_hash_selftest_check_one
|
||||
(GCRY_MD_SHA512, 0,
|
||||
"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
|
||||
"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112,
|
||||
"\x8E\x95\x9B\x75\xDA\xE3\x13\xDA\x8C\xF4\xF7\x28\x14\xFC\x14\x3F"
|
||||
"\x8F\x77\x79\xC6\xEB\x9F\x7F\xA1\x72\x99\xAE\xAD\xB6\x88\x90\x18"
|
||||
"\x50\x1D\x28\x9E\x49\x00\xF7\xE4\x33\x1B\x99\xDE\xC4\xB5\x43\x3A"
|
||||
"\xC7\xD3\x29\xEE\xB6\xDD\x26\x54\x5E\x96\xE5\x5B\x87\x4B\xE9\x09",
|
||||
64);
|
||||
if (errtxt)
|
||||
goto failed;
|
||||
|
||||
what = "one million \"a\"";
|
||||
errtxt = _gcry_hash_selftest_check_one
|
||||
(GCRY_MD_SHA512, 1,
|
||||
NULL, 0,
|
||||
"\xE7\x18\x48\x3D\x0C\xE7\x69\x64\x4E\x2E\x42\xC7\xBC\x15\xB4\x63"
|
||||
"\x8E\x1F\x98\xB1\x3B\x20\x44\x28\x56\x32\xA8\x03\xAF\xA9\x73\xEB"
|
||||
"\xDE\x0F\xF2\x44\x87\x7E\xA6\x0A\x4C\xB0\x43\x2C\xE5\x77\xC3\x1B"
|
||||
"\xEB\x00\x9C\x5C\x2C\x49\xAA\x2E\x4E\xAD\xB2\x17\xAD\x8C\xC0\x9B",
|
||||
64);
|
||||
if (errtxt)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
return 0; /* Succeeded. */
|
||||
|
||||
failed:
|
||||
if (report)
|
||||
report ("digest", GCRY_MD_SHA512, what, errtxt);
|
||||
return GPG_ERR_SELFTEST_FAILED;
|
||||
}
|
||||
|
||||
|
||||
/* Run a full self-test for ALGO and return 0 on success. */
|
||||
static gpg_err_code_t
|
||||
run_selftests (int algo, int extended, selftest_report_func_t report)
|
||||
{
|
||||
gpg_err_code_t ec;
|
||||
|
||||
switch (algo)
|
||||
{
|
||||
case GCRY_MD_SHA384:
|
||||
ec = selftests_sha384 (extended, report);
|
||||
break;
|
||||
case GCRY_MD_SHA512:
|
||||
ec = selftests_sha512 (extended, report);
|
||||
break;
|
||||
default:
|
||||
ec = GPG_ERR_DIGEST_ALGO;
|
||||
break;
|
||||
|
||||
}
|
||||
return ec;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static byte sha512_asn[] = /* Object ID is 2.16.840.1.101.3.4.2.3 */
|
||||
{
|
||||
0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
|
||||
0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
|
||||
0x00, 0x04, 0x40
|
||||
};
|
||||
|
||||
static gcry_md_oid_spec_t oid_spec_sha512[] =
|
||||
{
|
||||
{ "2.16.840.1.101.3.4.2.3" },
|
||||
|
||||
/* PKCS#1 sha512WithRSAEncryption */
|
||||
{ "1.2.840.113549.1.1.13" },
|
||||
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
gcry_md_spec_t _gcry_digest_spec_sha512 =
|
||||
{
|
||||
"SHA512", sha512_asn, DIM (sha512_asn), oid_spec_sha512, 64,
|
||||
sha512_init, sha512_write, sha512_final, sha512_read,
|
||||
sizeof (SHA512_CONTEXT),
|
||||
};
|
||||
md_extra_spec_t _gcry_digest_extraspec_sha512 =
|
||||
{
|
||||
run_selftests
|
||||
};
|
||||
|
||||
static byte sha384_asn[] = /* Object ID is 2.16.840.1.101.3.4.2.2 */
|
||||
{
|
||||
0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
|
||||
0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05,
|
||||
0x00, 0x04, 0x30
|
||||
};
|
||||
|
||||
static gcry_md_oid_spec_t oid_spec_sha384[] =
|
||||
{
|
||||
{ "2.16.840.1.101.3.4.2.2" },
|
||||
|
||||
/* PKCS#1 sha384WithRSAEncryption */
|
||||
{ "1.2.840.113549.1.1.12" },
|
||||
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
gcry_md_spec_t _gcry_digest_spec_sha384 =
|
||||
{
|
||||
"SHA384", sha384_asn, DIM (sha384_asn), oid_spec_sha384, 48,
|
||||
sha384_init, sha512_write, sha512_final, sha512_read,
|
||||
sizeof (SHA512_CONTEXT),
|
||||
};
|
||||
md_extra_spec_t _gcry_digest_extraspec_sha384 =
|
||||
{
|
||||
run_selftests
|
||||
};
|
851
lib/libgcrypt/cipher/tiger.c
Normal file
851
lib/libgcrypt/cipher/tiger.c
Normal file
|
@ -0,0 +1,851 @@
|
|||
/* tiger.c - The TIGER hash function
|
||||
* Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of Libgcrypt.
|
||||
*
|
||||
* Libgcrypt is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Libgcrypt is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "g10lib.h"
|
||||
#include "memory.h"
|
||||
#include "cipher.h"
|
||||
|
||||
#ifdef HAVE_U64_TYPEDEF
|
||||
|
||||
/* we really need it here, but as this is only experiment we
|
||||
* can live without Tiger */
|
||||
|
||||
typedef struct {
|
||||
u64 a, b, c;
|
||||
byte buf[64];
|
||||
int count;
|
||||
u32 nblocks;
|
||||
} TIGER_CONTEXT;
|
||||
|
||||
|
||||
/*********************************
|
||||
* Okay, okay, this is not the fastest code - improvements are welcome.
|
||||
*
|
||||
*/
|
||||
|
||||
/* Some test vectors:
|
||||
* "" 24F0130C63AC9332 16166E76B1BB925F F373DE2D49584E7A
|
||||
* "abc" F258C1E88414AB2A 527AB541FFC5B8BF 935F7B951C132951
|
||||
* "Tiger" 9F00F599072300DD 276ABB38C8EB6DEC 37790C116F9D2BDF
|
||||
* "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-"
|
||||
* 87FB2A9083851CF7 470D2CF810E6DF9E B586445034A5A386
|
||||
* "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789"
|
||||
* 467DB80863EBCE48 8DF1CD1261655DE9 57896565975F9197
|
||||
* "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham"
|
||||
* 0C410A042968868A 1671DA5A3FD29A72 5EC1E457D3CDB303
|
||||
* "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proc"
|
||||
* "eedings of Fast Software Encryption 3, Cambridge."
|
||||
* EBF591D5AFA655CE 7F22894FF87F54AC 89C811B6B0DA3193
|
||||
* "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proc"
|
||||
* "eedings of Fast Software Encryption 3, Cambridge, 1996."
|
||||
* 3D9AEB03D1BD1A63 57B2774DFD6D5B24 DD68151D503974FC
|
||||
* "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-ABCDEF"
|
||||
* "GHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-"
|
||||
* 00B83EB4E53440C5 76AC6AAEE0A74858 25FD15E70A59FFE4
|
||||
*/
|
||||
|
||||
static u64 sbox1[256] = {
|
||||
U64_C(0x02aab17cf7e90c5e) /* 0 */, U64_C(0xac424b03e243a8ec) /* 1 */,
|
||||
U64_C(0x72cd5be30dd5fcd3) /* 2 */, U64_C(0x6d019b93f6f97f3a) /* 3 */,
|
||||
U64_C(0xcd9978ffd21f9193) /* 4 */, U64_C(0x7573a1c9708029e2) /* 5 */,
|
||||
U64_C(0xb164326b922a83c3) /* 6 */, U64_C(0x46883eee04915870) /* 7 */,
|
||||
U64_C(0xeaace3057103ece6) /* 8 */, U64_C(0xc54169b808a3535c) /* 9 */,
|
||||
U64_C(0x4ce754918ddec47c) /* 10 */, U64_C(0x0aa2f4dfdc0df40c) /* 11 */,
|
||||
U64_C(0x10b76f18a74dbefa) /* 12 */, U64_C(0xc6ccb6235ad1ab6a) /* 13 */,
|
||||
U64_C(0x13726121572fe2ff) /* 14 */, U64_C(0x1a488c6f199d921e) /* 15 */,
|
||||
U64_C(0x4bc9f9f4da0007ca) /* 16 */, U64_C(0x26f5e6f6e85241c7) /* 17 */,
|
||||
U64_C(0x859079dbea5947b6) /* 18 */, U64_C(0x4f1885c5c99e8c92) /* 19 */,
|
||||
U64_C(0xd78e761ea96f864b) /* 20 */, U64_C(0x8e36428c52b5c17d) /* 21 */,
|
||||
U64_C(0x69cf6827373063c1) /* 22 */, U64_C(0xb607c93d9bb4c56e) /* 23 */,
|
||||
U64_C(0x7d820e760e76b5ea) /* 24 */, U64_C(0x645c9cc6f07fdc42) /* 25 */,
|
||||
U64_C(0xbf38a078243342e0) /* 26 */, U64_C(0x5f6b343c9d2e7d04) /* 27 */,
|
||||
U64_C(0xf2c28aeb600b0ec6) /* 28 */, U64_C(0x6c0ed85f7254bcac) /* 29 */,
|
||||
U64_C(0x71592281a4db4fe5) /* 30 */, U64_C(0x1967fa69ce0fed9f) /* 31 */,
|
||||
U64_C(0xfd5293f8b96545db) /* 32 */, U64_C(0xc879e9d7f2a7600b) /* 33 */,
|
||||
U64_C(0x860248920193194e) /* 34 */, U64_C(0xa4f9533b2d9cc0b3) /* 35 */,
|
||||
U64_C(0x9053836c15957613) /* 36 */, U64_C(0xdb6dcf8afc357bf1) /* 37 */,
|
||||
U64_C(0x18beea7a7a370f57) /* 38 */, U64_C(0x037117ca50b99066) /* 39 */,
|
||||
U64_C(0x6ab30a9774424a35) /* 40 */, U64_C(0xf4e92f02e325249b) /* 41 */,
|
||||
U64_C(0x7739db07061ccae1) /* 42 */, U64_C(0xd8f3b49ceca42a05) /* 43 */,
|
||||
U64_C(0xbd56be3f51382f73) /* 44 */, U64_C(0x45faed5843b0bb28) /* 45 */,
|
||||
U64_C(0x1c813d5c11bf1f83) /* 46 */, U64_C(0x8af0e4b6d75fa169) /* 47 */,
|
||||
U64_C(0x33ee18a487ad9999) /* 48 */, U64_C(0x3c26e8eab1c94410) /* 49 */,
|
||||
U64_C(0xb510102bc0a822f9) /* 50 */, U64_C(0x141eef310ce6123b) /* 51 */,
|
||||
U64_C(0xfc65b90059ddb154) /* 52 */, U64_C(0xe0158640c5e0e607) /* 53 */,
|
||||
U64_C(0x884e079826c3a3cf) /* 54 */, U64_C(0x930d0d9523c535fd) /* 55 */,
|
||||
U64_C(0x35638d754e9a2b00) /* 56 */, U64_C(0x4085fccf40469dd5) /* 57 */,
|
||||
U64_C(0xc4b17ad28be23a4c) /* 58 */, U64_C(0xcab2f0fc6a3e6a2e) /* 59 */,
|
||||
U64_C(0x2860971a6b943fcd) /* 60 */, U64_C(0x3dde6ee212e30446) /* 61 */,
|
||||
U64_C(0x6222f32ae01765ae) /* 62 */, U64_C(0x5d550bb5478308fe) /* 63 */,
|
||||
U64_C(0xa9efa98da0eda22a) /* 64 */, U64_C(0xc351a71686c40da7) /* 65 */,
|
||||
U64_C(0x1105586d9c867c84) /* 66 */, U64_C(0xdcffee85fda22853) /* 67 */,
|
||||
U64_C(0xccfbd0262c5eef76) /* 68 */, U64_C(0xbaf294cb8990d201) /* 69 */,
|
||||
U64_C(0xe69464f52afad975) /* 70 */, U64_C(0x94b013afdf133e14) /* 71 */,
|
||||
U64_C(0x06a7d1a32823c958) /* 72 */, U64_C(0x6f95fe5130f61119) /* 73 */,
|
||||
U64_C(0xd92ab34e462c06c0) /* 74 */, U64_C(0xed7bde33887c71d2) /* 75 */,
|
||||
U64_C(0x79746d6e6518393e) /* 76 */, U64_C(0x5ba419385d713329) /* 77 */,
|
||||
U64_C(0x7c1ba6b948a97564) /* 78 */, U64_C(0x31987c197bfdac67) /* 79 */,
|
||||
U64_C(0xde6c23c44b053d02) /* 80 */, U64_C(0x581c49fed002d64d) /* 81 */,
|
||||
U64_C(0xdd474d6338261571) /* 82 */, U64_C(0xaa4546c3e473d062) /* 83 */,
|
||||
U64_C(0x928fce349455f860) /* 84 */, U64_C(0x48161bbacaab94d9) /* 85 */,
|
||||
U64_C(0x63912430770e6f68) /* 86 */, U64_C(0x6ec8a5e602c6641c) /* 87 */,
|
||||
U64_C(0x87282515337ddd2b) /* 88 */, U64_C(0x2cda6b42034b701b) /* 89 */,
|
||||
U64_C(0xb03d37c181cb096d) /* 90 */, U64_C(0xe108438266c71c6f) /* 91 */,
|
||||
U64_C(0x2b3180c7eb51b255) /* 92 */, U64_C(0xdf92b82f96c08bbc) /* 93 */,
|
||||
U64_C(0x5c68c8c0a632f3ba) /* 94 */, U64_C(0x5504cc861c3d0556) /* 95 */,
|
||||
U64_C(0xabbfa4e55fb26b8f) /* 96 */, U64_C(0x41848b0ab3baceb4) /* 97 */,
|
||||
U64_C(0xb334a273aa445d32) /* 98 */, U64_C(0xbca696f0a85ad881) /* 99 */,
|
||||
U64_C(0x24f6ec65b528d56c) /* 100 */, U64_C(0x0ce1512e90f4524a) /* 101 */,
|
||||
U64_C(0x4e9dd79d5506d35a) /* 102 */, U64_C(0x258905fac6ce9779) /* 103 */,
|
||||
U64_C(0x2019295b3e109b33) /* 104 */, U64_C(0xf8a9478b73a054cc) /* 105 */,
|
||||
U64_C(0x2924f2f934417eb0) /* 106 */, U64_C(0x3993357d536d1bc4) /* 107 */,
|
||||
U64_C(0x38a81ac21db6ff8b) /* 108 */, U64_C(0x47c4fbf17d6016bf) /* 109 */,
|
||||
U64_C(0x1e0faadd7667e3f5) /* 110 */, U64_C(0x7abcff62938beb96) /* 111 */,
|
||||
U64_C(0xa78dad948fc179c9) /* 112 */, U64_C(0x8f1f98b72911e50d) /* 113 */,
|
||||
U64_C(0x61e48eae27121a91) /* 114 */, U64_C(0x4d62f7ad31859808) /* 115 */,
|
||||
U64_C(0xeceba345ef5ceaeb) /* 116 */, U64_C(0xf5ceb25ebc9684ce) /* 117 */,
|
||||
U64_C(0xf633e20cb7f76221) /* 118 */, U64_C(0xa32cdf06ab8293e4) /* 119 */,
|
||||
U64_C(0x985a202ca5ee2ca4) /* 120 */, U64_C(0xcf0b8447cc8a8fb1) /* 121 */,
|
||||
U64_C(0x9f765244979859a3) /* 122 */, U64_C(0xa8d516b1a1240017) /* 123 */,
|
||||
U64_C(0x0bd7ba3ebb5dc726) /* 124 */, U64_C(0xe54bca55b86adb39) /* 125 */,
|
||||
U64_C(0x1d7a3afd6c478063) /* 126 */, U64_C(0x519ec608e7669edd) /* 127 */,
|
||||
U64_C(0x0e5715a2d149aa23) /* 128 */, U64_C(0x177d4571848ff194) /* 129 */,
|
||||
U64_C(0xeeb55f3241014c22) /* 130 */, U64_C(0x0f5e5ca13a6e2ec2) /* 131 */,
|
||||
U64_C(0x8029927b75f5c361) /* 132 */, U64_C(0xad139fabc3d6e436) /* 133 */,
|
||||
U64_C(0x0d5df1a94ccf402f) /* 134 */, U64_C(0x3e8bd948bea5dfc8) /* 135 */,
|
||||
U64_C(0xa5a0d357bd3ff77e) /* 136 */, U64_C(0xa2d12e251f74f645) /* 137 */,
|
||||
U64_C(0x66fd9e525e81a082) /* 138 */, U64_C(0x2e0c90ce7f687a49) /* 139 */,
|
||||
U64_C(0xc2e8bcbeba973bc5) /* 140 */, U64_C(0x000001bce509745f) /* 141 */,
|
||||
U64_C(0x423777bbe6dab3d6) /* 142 */, U64_C(0xd1661c7eaef06eb5) /* 143 */,
|
||||
U64_C(0xa1781f354daacfd8) /* 144 */, U64_C(0x2d11284a2b16affc) /* 145 */,
|
||||
U64_C(0xf1fc4f67fa891d1f) /* 146 */, U64_C(0x73ecc25dcb920ada) /* 147 */,
|
||||
U64_C(0xae610c22c2a12651) /* 148 */, U64_C(0x96e0a810d356b78a) /* 149 */,
|
||||
U64_C(0x5a9a381f2fe7870f) /* 150 */, U64_C(0xd5ad62ede94e5530) /* 151 */,
|
||||
U64_C(0xd225e5e8368d1427) /* 152 */, U64_C(0x65977b70c7af4631) /* 153 */,
|
||||
U64_C(0x99f889b2de39d74f) /* 154 */, U64_C(0x233f30bf54e1d143) /* 155 */,
|
||||
U64_C(0x9a9675d3d9a63c97) /* 156 */, U64_C(0x5470554ff334f9a8) /* 157 */,
|
||||
U64_C(0x166acb744a4f5688) /* 158 */, U64_C(0x70c74caab2e4aead) /* 159 */,
|
||||
U64_C(0xf0d091646f294d12) /* 160 */, U64_C(0x57b82a89684031d1) /* 161 */,
|
||||
U64_C(0xefd95a5a61be0b6b) /* 162 */, U64_C(0x2fbd12e969f2f29a) /* 163 */,
|
||||
U64_C(0x9bd37013feff9fe8) /* 164 */, U64_C(0x3f9b0404d6085a06) /* 165 */,
|
||||
U64_C(0x4940c1f3166cfe15) /* 166 */, U64_C(0x09542c4dcdf3defb) /* 167 */,
|
||||
U64_C(0xb4c5218385cd5ce3) /* 168 */, U64_C(0xc935b7dc4462a641) /* 169 */,
|
||||
U64_C(0x3417f8a68ed3b63f) /* 170 */, U64_C(0xb80959295b215b40) /* 171 */,
|
||||
U64_C(0xf99cdaef3b8c8572) /* 172 */, U64_C(0x018c0614f8fcb95d) /* 173 */,
|
||||
U64_C(0x1b14accd1a3acdf3) /* 174 */, U64_C(0x84d471f200bb732d) /* 175 */,
|
||||
U64_C(0xc1a3110e95e8da16) /* 176 */, U64_C(0x430a7220bf1a82b8) /* 177 */,
|
||||
U64_C(0xb77e090d39df210e) /* 178 */, U64_C(0x5ef4bd9f3cd05e9d) /* 179 */,
|
||||
U64_C(0x9d4ff6da7e57a444) /* 180 */, U64_C(0xda1d60e183d4a5f8) /* 181 */,
|
||||
U64_C(0xb287c38417998e47) /* 182 */, U64_C(0xfe3edc121bb31886) /* 183 */,
|
||||
U64_C(0xc7fe3ccc980ccbef) /* 184 */, U64_C(0xe46fb590189bfd03) /* 185 */,
|
||||
U64_C(0x3732fd469a4c57dc) /* 186 */, U64_C(0x7ef700a07cf1ad65) /* 187 */,
|
||||
U64_C(0x59c64468a31d8859) /* 188 */, U64_C(0x762fb0b4d45b61f6) /* 189 */,
|
||||
U64_C(0x155baed099047718) /* 190 */, U64_C(0x68755e4c3d50baa6) /* 191 */,
|
||||
U64_C(0xe9214e7f22d8b4df) /* 192 */, U64_C(0x2addbf532eac95f4) /* 193 */,
|
||||
U64_C(0x32ae3909b4bd0109) /* 194 */, U64_C(0x834df537b08e3450) /* 195 */,
|
||||
U64_C(0xfa209da84220728d) /* 196 */, U64_C(0x9e691d9b9efe23f7) /* 197 */,
|
||||
U64_C(0x0446d288c4ae8d7f) /* 198 */, U64_C(0x7b4cc524e169785b) /* 199 */,
|
||||
U64_C(0x21d87f0135ca1385) /* 200 */, U64_C(0xcebb400f137b8aa5) /* 201 */,
|
||||
U64_C(0x272e2b66580796be) /* 202 */, U64_C(0x3612264125c2b0de) /* 203 */,
|
||||
U64_C(0x057702bdad1efbb2) /* 204 */, U64_C(0xd4babb8eacf84be9) /* 205 */,
|
||||
U64_C(0x91583139641bc67b) /* 206 */, U64_C(0x8bdc2de08036e024) /* 207 */,
|
||||
U64_C(0x603c8156f49f68ed) /* 208 */, U64_C(0xf7d236f7dbef5111) /* 209 */,
|
||||
U64_C(0x9727c4598ad21e80) /* 210 */, U64_C(0xa08a0896670a5fd7) /* 211 */,
|
||||
U64_C(0xcb4a8f4309eba9cb) /* 212 */, U64_C(0x81af564b0f7036a1) /* 213 */,
|
||||
U64_C(0xc0b99aa778199abd) /* 214 */, U64_C(0x959f1ec83fc8e952) /* 215 */,
|
||||
U64_C(0x8c505077794a81b9) /* 216 */, U64_C(0x3acaaf8f056338f0) /* 217 */,
|
||||
U64_C(0x07b43f50627a6778) /* 218 */, U64_C(0x4a44ab49f5eccc77) /* 219 */,
|
||||
U64_C(0x3bc3d6e4b679ee98) /* 220 */, U64_C(0x9cc0d4d1cf14108c) /* 221 */,
|
||||
U64_C(0x4406c00b206bc8a0) /* 222 */, U64_C(0x82a18854c8d72d89) /* 223 */,
|
||||
U64_C(0x67e366b35c3c432c) /* 224 */, U64_C(0xb923dd61102b37f2) /* 225 */,
|
||||
U64_C(0x56ab2779d884271d) /* 226 */, U64_C(0xbe83e1b0ff1525af) /* 227 */,
|
||||
U64_C(0xfb7c65d4217e49a9) /* 228 */, U64_C(0x6bdbe0e76d48e7d4) /* 229 */,
|
||||
U64_C(0x08df828745d9179e) /* 230 */, U64_C(0x22ea6a9add53bd34) /* 231 */,
|
||||
U64_C(0xe36e141c5622200a) /* 232 */, U64_C(0x7f805d1b8cb750ee) /* 233 */,
|
||||
U64_C(0xafe5c7a59f58e837) /* 234 */, U64_C(0xe27f996a4fb1c23c) /* 235 */,
|
||||
U64_C(0xd3867dfb0775f0d0) /* 236 */, U64_C(0xd0e673de6e88891a) /* 237 */,
|
||||
U64_C(0x123aeb9eafb86c25) /* 238 */, U64_C(0x30f1d5d5c145b895) /* 239 */,
|
||||
U64_C(0xbb434a2dee7269e7) /* 240 */, U64_C(0x78cb67ecf931fa38) /* 241 */,
|
||||
U64_C(0xf33b0372323bbf9c) /* 242 */, U64_C(0x52d66336fb279c74) /* 243 */,
|
||||
U64_C(0x505f33ac0afb4eaa) /* 244 */, U64_C(0xe8a5cd99a2cce187) /* 245 */,
|
||||
U64_C(0x534974801e2d30bb) /* 246 */, U64_C(0x8d2d5711d5876d90) /* 247 */,
|
||||
U64_C(0x1f1a412891bc038e) /* 248 */, U64_C(0xd6e2e71d82e56648) /* 249 */,
|
||||
U64_C(0x74036c3a497732b7) /* 250 */, U64_C(0x89b67ed96361f5ab) /* 251 */,
|
||||
U64_C(0xffed95d8f1ea02a2) /* 252 */, U64_C(0xe72b3bd61464d43d) /* 253 */,
|
||||
U64_C(0xa6300f170bdc4820) /* 254 */, U64_C(0xebc18760ed78a77a) /* 255 */
|
||||
};
|
||||
static u64 sbox2[256] = {
|
||||
U64_C(0xe6a6be5a05a12138) /* 256 */, U64_C(0xb5a122a5b4f87c98) /* 257 */,
|
||||
U64_C(0x563c6089140b6990) /* 258 */, U64_C(0x4c46cb2e391f5dd5) /* 259 */,
|
||||
U64_C(0xd932addbc9b79434) /* 260 */, U64_C(0x08ea70e42015aff5) /* 261 */,
|
||||
U64_C(0xd765a6673e478cf1) /* 262 */, U64_C(0xc4fb757eab278d99) /* 263 */,
|
||||
U64_C(0xdf11c6862d6e0692) /* 264 */, U64_C(0xddeb84f10d7f3b16) /* 265 */,
|
||||
U64_C(0x6f2ef604a665ea04) /* 266 */, U64_C(0x4a8e0f0ff0e0dfb3) /* 267 */,
|
||||
U64_C(0xa5edeef83dbcba51) /* 268 */, U64_C(0xfc4f0a2a0ea4371e) /* 269 */,
|
||||
U64_C(0xe83e1da85cb38429) /* 270 */, U64_C(0xdc8ff882ba1b1ce2) /* 271 */,
|
||||
U64_C(0xcd45505e8353e80d) /* 272 */, U64_C(0x18d19a00d4db0717) /* 273 */,
|
||||
U64_C(0x34a0cfeda5f38101) /* 274 */, U64_C(0x0be77e518887caf2) /* 275 */,
|
||||
U64_C(0x1e341438b3c45136) /* 276 */, U64_C(0xe05797f49089ccf9) /* 277 */,
|
||||
U64_C(0xffd23f9df2591d14) /* 278 */, U64_C(0x543dda228595c5cd) /* 279 */,
|
||||
U64_C(0x661f81fd99052a33) /* 280 */, U64_C(0x8736e641db0f7b76) /* 281 */,
|
||||
U64_C(0x15227725418e5307) /* 282 */, U64_C(0xe25f7f46162eb2fa) /* 283 */,
|
||||
U64_C(0x48a8b2126c13d9fe) /* 284 */, U64_C(0xafdc541792e76eea) /* 285 */,
|
||||
U64_C(0x03d912bfc6d1898f) /* 286 */, U64_C(0x31b1aafa1b83f51b) /* 287 */,
|
||||
U64_C(0xf1ac2796e42ab7d9) /* 288 */, U64_C(0x40a3a7d7fcd2ebac) /* 289 */,
|
||||
U64_C(0x1056136d0afbbcc5) /* 290 */, U64_C(0x7889e1dd9a6d0c85) /* 291 */,
|
||||
U64_C(0xd33525782a7974aa) /* 292 */, U64_C(0xa7e25d09078ac09b) /* 293 */,
|
||||
U64_C(0xbd4138b3eac6edd0) /* 294 */, U64_C(0x920abfbe71eb9e70) /* 295 */,
|
||||
U64_C(0xa2a5d0f54fc2625c) /* 296 */, U64_C(0xc054e36b0b1290a3) /* 297 */,
|
||||
U64_C(0xf6dd59ff62fe932b) /* 298 */, U64_C(0x3537354511a8ac7d) /* 299 */,
|
||||
U64_C(0xca845e9172fadcd4) /* 300 */, U64_C(0x84f82b60329d20dc) /* 301 */,
|
||||
U64_C(0x79c62ce1cd672f18) /* 302 */, U64_C(0x8b09a2add124642c) /* 303 */,
|
||||
U64_C(0xd0c1e96a19d9e726) /* 304 */, U64_C(0x5a786a9b4ba9500c) /* 305 */,
|
||||
U64_C(0x0e020336634c43f3) /* 306 */, U64_C(0xc17b474aeb66d822) /* 307 */,
|
||||
U64_C(0x6a731ae3ec9baac2) /* 308 */, U64_C(0x8226667ae0840258) /* 309 */,
|
||||
U64_C(0x67d4567691caeca5) /* 310 */, U64_C(0x1d94155c4875adb5) /* 311 */,
|
||||
U64_C(0x6d00fd985b813fdf) /* 312 */, U64_C(0x51286efcb774cd06) /* 313 */,
|
||||
U64_C(0x5e8834471fa744af) /* 314 */, U64_C(0xf72ca0aee761ae2e) /* 315 */,
|
||||
U64_C(0xbe40e4cdaee8e09a) /* 316 */, U64_C(0xe9970bbb5118f665) /* 317 */,
|
||||
U64_C(0x726e4beb33df1964) /* 318 */, U64_C(0x703b000729199762) /* 319 */,
|
||||
U64_C(0x4631d816f5ef30a7) /* 320 */, U64_C(0xb880b5b51504a6be) /* 321 */,
|
||||
U64_C(0x641793c37ed84b6c) /* 322 */, U64_C(0x7b21ed77f6e97d96) /* 323 */,
|
||||
U64_C(0x776306312ef96b73) /* 324 */, U64_C(0xae528948e86ff3f4) /* 325 */,
|
||||
U64_C(0x53dbd7f286a3f8f8) /* 326 */, U64_C(0x16cadce74cfc1063) /* 327 */,
|
||||
U64_C(0x005c19bdfa52c6dd) /* 328 */, U64_C(0x68868f5d64d46ad3) /* 329 */,
|
||||
U64_C(0x3a9d512ccf1e186a) /* 330 */, U64_C(0x367e62c2385660ae) /* 331 */,
|
||||
U64_C(0xe359e7ea77dcb1d7) /* 332 */, U64_C(0x526c0773749abe6e) /* 333 */,
|
||||
U64_C(0x735ae5f9d09f734b) /* 334 */, U64_C(0x493fc7cc8a558ba8) /* 335 */,
|
||||
U64_C(0xb0b9c1533041ab45) /* 336 */, U64_C(0x321958ba470a59bd) /* 337 */,
|
||||
U64_C(0x852db00b5f46c393) /* 338 */, U64_C(0x91209b2bd336b0e5) /* 339 */,
|
||||
U64_C(0x6e604f7d659ef19f) /* 340 */, U64_C(0xb99a8ae2782ccb24) /* 341 */,
|
||||
U64_C(0xccf52ab6c814c4c7) /* 342 */, U64_C(0x4727d9afbe11727b) /* 343 */,
|
||||
U64_C(0x7e950d0c0121b34d) /* 344 */, U64_C(0x756f435670ad471f) /* 345 */,
|
||||
U64_C(0xf5add442615a6849) /* 346 */, U64_C(0x4e87e09980b9957a) /* 347 */,
|
||||
U64_C(0x2acfa1df50aee355) /* 348 */, U64_C(0xd898263afd2fd556) /* 349 */,
|
||||
U64_C(0xc8f4924dd80c8fd6) /* 350 */, U64_C(0xcf99ca3d754a173a) /* 351 */,
|
||||
U64_C(0xfe477bacaf91bf3c) /* 352 */, U64_C(0xed5371f6d690c12d) /* 353 */,
|
||||
U64_C(0x831a5c285e687094) /* 354 */, U64_C(0xc5d3c90a3708a0a4) /* 355 */,
|
||||
U64_C(0x0f7f903717d06580) /* 356 */, U64_C(0x19f9bb13b8fdf27f) /* 357 */,
|
||||
U64_C(0xb1bd6f1b4d502843) /* 358 */, U64_C(0x1c761ba38fff4012) /* 359 */,
|
||||
U64_C(0x0d1530c4e2e21f3b) /* 360 */, U64_C(0x8943ce69a7372c8a) /* 361 */,
|
||||
U64_C(0xe5184e11feb5ce66) /* 362 */, U64_C(0x618bdb80bd736621) /* 363 */,
|
||||
U64_C(0x7d29bad68b574d0b) /* 364 */, U64_C(0x81bb613e25e6fe5b) /* 365 */,
|
||||
U64_C(0x071c9c10bc07913f) /* 366 */, U64_C(0xc7beeb7909ac2d97) /* 367 */,
|
||||
U64_C(0xc3e58d353bc5d757) /* 368 */, U64_C(0xeb017892f38f61e8) /* 369 */,
|
||||
U64_C(0xd4effb9c9b1cc21a) /* 370 */, U64_C(0x99727d26f494f7ab) /* 371 */,
|
||||
U64_C(0xa3e063a2956b3e03) /* 372 */, U64_C(0x9d4a8b9a4aa09c30) /* 373 */,
|
||||
U64_C(0x3f6ab7d500090fb4) /* 374 */, U64_C(0x9cc0f2a057268ac0) /* 375 */,
|
||||
U64_C(0x3dee9d2dedbf42d1) /* 376 */, U64_C(0x330f49c87960a972) /* 377 */,
|
||||
U64_C(0xc6b2720287421b41) /* 378 */, U64_C(0x0ac59ec07c00369c) /* 379 */,
|
||||
U64_C(0xef4eac49cb353425) /* 380 */, U64_C(0xf450244eef0129d8) /* 381 */,
|
||||
U64_C(0x8acc46e5caf4deb6) /* 382 */, U64_C(0x2ffeab63989263f7) /* 383 */,
|
||||
U64_C(0x8f7cb9fe5d7a4578) /* 384 */, U64_C(0x5bd8f7644e634635) /* 385 */,
|
||||
U64_C(0x427a7315bf2dc900) /* 386 */, U64_C(0x17d0c4aa2125261c) /* 387 */,
|
||||
U64_C(0x3992486c93518e50) /* 388 */, U64_C(0xb4cbfee0a2d7d4c3) /* 389 */,
|
||||
U64_C(0x7c75d6202c5ddd8d) /* 390 */, U64_C(0xdbc295d8e35b6c61) /* 391 */,
|
||||
U64_C(0x60b369d302032b19) /* 392 */, U64_C(0xce42685fdce44132) /* 393 */,
|
||||
U64_C(0x06f3ddb9ddf65610) /* 394 */, U64_C(0x8ea4d21db5e148f0) /* 395 */,
|
||||
U64_C(0x20b0fce62fcd496f) /* 396 */, U64_C(0x2c1b912358b0ee31) /* 397 */,
|
||||
U64_C(0xb28317b818f5a308) /* 398 */, U64_C(0xa89c1e189ca6d2cf) /* 399 */,
|
||||
U64_C(0x0c6b18576aaadbc8) /* 400 */, U64_C(0xb65deaa91299fae3) /* 401 */,
|
||||
U64_C(0xfb2b794b7f1027e7) /* 402 */, U64_C(0x04e4317f443b5beb) /* 403 */,
|
||||
U64_C(0x4b852d325939d0a6) /* 404 */, U64_C(0xd5ae6beefb207ffc) /* 405 */,
|
||||
U64_C(0x309682b281c7d374) /* 406 */, U64_C(0xbae309a194c3b475) /* 407 */,
|
||||
U64_C(0x8cc3f97b13b49f05) /* 408 */, U64_C(0x98a9422ff8293967) /* 409 */,
|
||||
U64_C(0x244b16b01076ff7c) /* 410 */, U64_C(0xf8bf571c663d67ee) /* 411 */,
|
||||
U64_C(0x1f0d6758eee30da1) /* 412 */, U64_C(0xc9b611d97adeb9b7) /* 413 */,
|
||||
U64_C(0xb7afd5887b6c57a2) /* 414 */, U64_C(0x6290ae846b984fe1) /* 415 */,
|
||||
U64_C(0x94df4cdeacc1a5fd) /* 416 */, U64_C(0x058a5bd1c5483aff) /* 417 */,
|
||||
U64_C(0x63166cc142ba3c37) /* 418 */, U64_C(0x8db8526eb2f76f40) /* 419 */,
|
||||
U64_C(0xe10880036f0d6d4e) /* 420 */, U64_C(0x9e0523c9971d311d) /* 421 */,
|
||||
U64_C(0x45ec2824cc7cd691) /* 422 */, U64_C(0x575b8359e62382c9) /* 423 */,
|
||||
U64_C(0xfa9e400dc4889995) /* 424 */, U64_C(0xd1823ecb45721568) /* 425 */,
|
||||
U64_C(0xdafd983b8206082f) /* 426 */, U64_C(0xaa7d29082386a8cb) /* 427 */,
|
||||
U64_C(0x269fcd4403b87588) /* 428 */, U64_C(0x1b91f5f728bdd1e0) /* 429 */,
|
||||
U64_C(0xe4669f39040201f6) /* 430 */, U64_C(0x7a1d7c218cf04ade) /* 431 */,
|
||||
U64_C(0x65623c29d79ce5ce) /* 432 */, U64_C(0x2368449096c00bb1) /* 433 */,
|
||||
U64_C(0xab9bf1879da503ba) /* 434 */, U64_C(0xbc23ecb1a458058e) /* 435 */,
|
||||
U64_C(0x9a58df01bb401ecc) /* 436 */, U64_C(0xa070e868a85f143d) /* 437 */,
|
||||
U64_C(0x4ff188307df2239e) /* 438 */, U64_C(0x14d565b41a641183) /* 439 */,
|
||||
U64_C(0xee13337452701602) /* 440 */, U64_C(0x950e3dcf3f285e09) /* 441 */,
|
||||
U64_C(0x59930254b9c80953) /* 442 */, U64_C(0x3bf299408930da6d) /* 443 */,
|
||||
U64_C(0xa955943f53691387) /* 444 */, U64_C(0xa15edecaa9cb8784) /* 445 */,
|
||||
U64_C(0x29142127352be9a0) /* 446 */, U64_C(0x76f0371fff4e7afb) /* 447 */,
|
||||
U64_C(0x0239f450274f2228) /* 448 */, U64_C(0xbb073af01d5e868b) /* 449 */,
|
||||
U64_C(0xbfc80571c10e96c1) /* 450 */, U64_C(0xd267088568222e23) /* 451 */,
|
||||
U64_C(0x9671a3d48e80b5b0) /* 452 */, U64_C(0x55b5d38ae193bb81) /* 453 */,
|
||||
U64_C(0x693ae2d0a18b04b8) /* 454 */, U64_C(0x5c48b4ecadd5335f) /* 455 */,
|
||||
U64_C(0xfd743b194916a1ca) /* 456 */, U64_C(0x2577018134be98c4) /* 457 */,
|
||||
U64_C(0xe77987e83c54a4ad) /* 458 */, U64_C(0x28e11014da33e1b9) /* 459 */,
|
||||
U64_C(0x270cc59e226aa213) /* 460 */, U64_C(0x71495f756d1a5f60) /* 461 */,
|
||||
U64_C(0x9be853fb60afef77) /* 462 */, U64_C(0xadc786a7f7443dbf) /* 463 */,
|
||||
U64_C(0x0904456173b29a82) /* 464 */, U64_C(0x58bc7a66c232bd5e) /* 465 */,
|
||||
U64_C(0xf306558c673ac8b2) /* 466 */, U64_C(0x41f639c6b6c9772a) /* 467 */,
|
||||
U64_C(0x216defe99fda35da) /* 468 */, U64_C(0x11640cc71c7be615) /* 469 */,
|
||||
U64_C(0x93c43694565c5527) /* 470 */, U64_C(0xea038e6246777839) /* 471 */,
|
||||
U64_C(0xf9abf3ce5a3e2469) /* 472 */, U64_C(0x741e768d0fd312d2) /* 473 */,
|
||||
U64_C(0x0144b883ced652c6) /* 474 */, U64_C(0xc20b5a5ba33f8552) /* 475 */,
|
||||
U64_C(0x1ae69633c3435a9d) /* 476 */, U64_C(0x97a28ca4088cfdec) /* 477 */,
|
||||
U64_C(0x8824a43c1e96f420) /* 478 */, U64_C(0x37612fa66eeea746) /* 479 */,
|
||||
U64_C(0x6b4cb165f9cf0e5a) /* 480 */, U64_C(0x43aa1c06a0abfb4a) /* 481 */,
|
||||
U64_C(0x7f4dc26ff162796b) /* 482 */, U64_C(0x6cbacc8e54ed9b0f) /* 483 */,
|
||||
U64_C(0xa6b7ffefd2bb253e) /* 484 */, U64_C(0x2e25bc95b0a29d4f) /* 485 */,
|
||||
U64_C(0x86d6a58bdef1388c) /* 486 */, U64_C(0xded74ac576b6f054) /* 487 */,
|
||||
U64_C(0x8030bdbc2b45805d) /* 488 */, U64_C(0x3c81af70e94d9289) /* 489 */,
|
||||
U64_C(0x3eff6dda9e3100db) /* 490 */, U64_C(0xb38dc39fdfcc8847) /* 491 */,
|
||||
U64_C(0x123885528d17b87e) /* 492 */, U64_C(0xf2da0ed240b1b642) /* 493 */,
|
||||
U64_C(0x44cefadcd54bf9a9) /* 494 */, U64_C(0x1312200e433c7ee6) /* 495 */,
|
||||
U64_C(0x9ffcc84f3a78c748) /* 496 */, U64_C(0xf0cd1f72248576bb) /* 497 */,
|
||||
U64_C(0xec6974053638cfe4) /* 498 */, U64_C(0x2ba7b67c0cec4e4c) /* 499 */,
|
||||
U64_C(0xac2f4df3e5ce32ed) /* 500 */, U64_C(0xcb33d14326ea4c11) /* 501 */,
|
||||
U64_C(0xa4e9044cc77e58bc) /* 502 */, U64_C(0x5f513293d934fcef) /* 503 */,
|
||||
U64_C(0x5dc9645506e55444) /* 504 */, U64_C(0x50de418f317de40a) /* 505 */,
|
||||
U64_C(0x388cb31a69dde259) /* 506 */, U64_C(0x2db4a83455820a86) /* 507 */,
|
||||
U64_C(0x9010a91e84711ae9) /* 508 */, U64_C(0x4df7f0b7b1498371) /* 509 */,
|
||||
U64_C(0xd62a2eabc0977179) /* 510 */, U64_C(0x22fac097aa8d5c0e) /* 511 */
|
||||
};
|
||||
static u64 sbox3[256] = {
|
||||
U64_C(0xf49fcc2ff1daf39b) /* 512 */, U64_C(0x487fd5c66ff29281) /* 513 */,
|
||||
U64_C(0xe8a30667fcdca83f) /* 514 */, U64_C(0x2c9b4be3d2fcce63) /* 515 */,
|
||||
U64_C(0xda3ff74b93fbbbc2) /* 516 */, U64_C(0x2fa165d2fe70ba66) /* 517 */,
|
||||
U64_C(0xa103e279970e93d4) /* 518 */, U64_C(0xbecdec77b0e45e71) /* 519 */,
|
||||
U64_C(0xcfb41e723985e497) /* 520 */, U64_C(0xb70aaa025ef75017) /* 521 */,
|
||||
U64_C(0xd42309f03840b8e0) /* 522 */, U64_C(0x8efc1ad035898579) /* 523 */,
|
||||
U64_C(0x96c6920be2b2abc5) /* 524 */, U64_C(0x66af4163375a9172) /* 525 */,
|
||||
U64_C(0x2174abdcca7127fb) /* 526 */, U64_C(0xb33ccea64a72ff41) /* 527 */,
|
||||
U64_C(0xf04a4933083066a5) /* 528 */, U64_C(0x8d970acdd7289af5) /* 529 */,
|
||||
U64_C(0x8f96e8e031c8c25e) /* 530 */, U64_C(0xf3fec02276875d47) /* 531 */,
|
||||
U64_C(0xec7bf310056190dd) /* 532 */, U64_C(0xf5adb0aebb0f1491) /* 533 */,
|
||||
U64_C(0x9b50f8850fd58892) /* 534 */, U64_C(0x4975488358b74de8) /* 535 */,
|
||||
U64_C(0xa3354ff691531c61) /* 536 */, U64_C(0x0702bbe481d2c6ee) /* 537 */,
|
||||
U64_C(0x89fb24057deded98) /* 538 */, U64_C(0xac3075138596e902) /* 539 */,
|
||||
U64_C(0x1d2d3580172772ed) /* 540 */, U64_C(0xeb738fc28e6bc30d) /* 541 */,
|
||||
U64_C(0x5854ef8f63044326) /* 542 */, U64_C(0x9e5c52325add3bbe) /* 543 */,
|
||||
U64_C(0x90aa53cf325c4623) /* 544 */, U64_C(0xc1d24d51349dd067) /* 545 */,
|
||||
U64_C(0x2051cfeea69ea624) /* 546 */, U64_C(0x13220f0a862e7e4f) /* 547 */,
|
||||
U64_C(0xce39399404e04864) /* 548 */, U64_C(0xd9c42ca47086fcb7) /* 549 */,
|
||||
U64_C(0x685ad2238a03e7cc) /* 550 */, U64_C(0x066484b2ab2ff1db) /* 551 */,
|
||||
U64_C(0xfe9d5d70efbf79ec) /* 552 */, U64_C(0x5b13b9dd9c481854) /* 553 */,
|
||||
U64_C(0x15f0d475ed1509ad) /* 554 */, U64_C(0x0bebcd060ec79851) /* 555 */,
|
||||
U64_C(0xd58c6791183ab7f8) /* 556 */, U64_C(0xd1187c5052f3eee4) /* 557 */,
|
||||
U64_C(0xc95d1192e54e82ff) /* 558 */, U64_C(0x86eea14cb9ac6ca2) /* 559 */,
|
||||
U64_C(0x3485beb153677d5d) /* 560 */, U64_C(0xdd191d781f8c492a) /* 561 */,
|
||||
U64_C(0xf60866baa784ebf9) /* 562 */, U64_C(0x518f643ba2d08c74) /* 563 */,
|
||||
U64_C(0x8852e956e1087c22) /* 564 */, U64_C(0xa768cb8dc410ae8d) /* 565 */,
|
||||
U64_C(0x38047726bfec8e1a) /* 566 */, U64_C(0xa67738b4cd3b45aa) /* 567 */,
|
||||
U64_C(0xad16691cec0dde19) /* 568 */, U64_C(0xc6d4319380462e07) /* 569 */,
|
||||
U64_C(0xc5a5876d0ba61938) /* 570 */, U64_C(0x16b9fa1fa58fd840) /* 571 */,
|
||||
U64_C(0x188ab1173ca74f18) /* 572 */, U64_C(0xabda2f98c99c021f) /* 573 */,
|
||||
U64_C(0x3e0580ab134ae816) /* 574 */, U64_C(0x5f3b05b773645abb) /* 575 */,
|
||||
U64_C(0x2501a2be5575f2f6) /* 576 */, U64_C(0x1b2f74004e7e8ba9) /* 577 */,
|
||||
U64_C(0x1cd7580371e8d953) /* 578 */, U64_C(0x7f6ed89562764e30) /* 579 */,
|
||||
U64_C(0xb15926ff596f003d) /* 580 */, U64_C(0x9f65293da8c5d6b9) /* 581 */,
|
||||
U64_C(0x6ecef04dd690f84c) /* 582 */, U64_C(0x4782275fff33af88) /* 583 */,
|
||||
U64_C(0xe41433083f820801) /* 584 */, U64_C(0xfd0dfe409a1af9b5) /* 585 */,
|
||||
U64_C(0x4325a3342cdb396b) /* 586 */, U64_C(0x8ae77e62b301b252) /* 587 */,
|
||||
U64_C(0xc36f9e9f6655615a) /* 588 */, U64_C(0x85455a2d92d32c09) /* 589 */,
|
||||
U64_C(0xf2c7dea949477485) /* 590 */, U64_C(0x63cfb4c133a39eba) /* 591 */,
|
||||
U64_C(0x83b040cc6ebc5462) /* 592 */, U64_C(0x3b9454c8fdb326b0) /* 593 */,
|
||||
U64_C(0x56f56a9e87ffd78c) /* 594 */, U64_C(0x2dc2940d99f42bc6) /* 595 */,
|
||||
U64_C(0x98f7df096b096e2d) /* 596 */, U64_C(0x19a6e01e3ad852bf) /* 597 */,
|
||||
U64_C(0x42a99ccbdbd4b40b) /* 598 */, U64_C(0xa59998af45e9c559) /* 599 */,
|
||||
U64_C(0x366295e807d93186) /* 600 */, U64_C(0x6b48181bfaa1f773) /* 601 */,
|
||||
U64_C(0x1fec57e2157a0a1d) /* 602 */, U64_C(0x4667446af6201ad5) /* 603 */,
|
||||
U64_C(0xe615ebcacfb0f075) /* 604 */, U64_C(0xb8f31f4f68290778) /* 605 */,
|
||||
U64_C(0x22713ed6ce22d11e) /* 606 */, U64_C(0x3057c1a72ec3c93b) /* 607 */,
|
||||
U64_C(0xcb46acc37c3f1f2f) /* 608 */, U64_C(0xdbb893fd02aaf50e) /* 609 */,
|
||||
U64_C(0x331fd92e600b9fcf) /* 610 */, U64_C(0xa498f96148ea3ad6) /* 611 */,
|
||||
U64_C(0xa8d8426e8b6a83ea) /* 612 */, U64_C(0xa089b274b7735cdc) /* 613 */,
|
||||
U64_C(0x87f6b3731e524a11) /* 614 */, U64_C(0x118808e5cbc96749) /* 615 */,
|
||||
U64_C(0x9906e4c7b19bd394) /* 616 */, U64_C(0xafed7f7e9b24a20c) /* 617 */,
|
||||
U64_C(0x6509eadeeb3644a7) /* 618 */, U64_C(0x6c1ef1d3e8ef0ede) /* 619 */,
|
||||
U64_C(0xb9c97d43e9798fb4) /* 620 */, U64_C(0xa2f2d784740c28a3) /* 621 */,
|
||||
U64_C(0x7b8496476197566f) /* 622 */, U64_C(0x7a5be3e6b65f069d) /* 623 */,
|
||||
U64_C(0xf96330ed78be6f10) /* 624 */, U64_C(0xeee60de77a076a15) /* 625 */,
|
||||
U64_C(0x2b4bee4aa08b9bd0) /* 626 */, U64_C(0x6a56a63ec7b8894e) /* 627 */,
|
||||
U64_C(0x02121359ba34fef4) /* 628 */, U64_C(0x4cbf99f8283703fc) /* 629 */,
|
||||
U64_C(0x398071350caf30c8) /* 630 */, U64_C(0xd0a77a89f017687a) /* 631 */,
|
||||
U64_C(0xf1c1a9eb9e423569) /* 632 */, U64_C(0x8c7976282dee8199) /* 633 */,
|
||||
U64_C(0x5d1737a5dd1f7abd) /* 634 */, U64_C(0x4f53433c09a9fa80) /* 635 */,
|
||||
U64_C(0xfa8b0c53df7ca1d9) /* 636 */, U64_C(0x3fd9dcbc886ccb77) /* 637 */,
|
||||
U64_C(0xc040917ca91b4720) /* 638 */, U64_C(0x7dd00142f9d1dcdf) /* 639 */,
|
||||
U64_C(0x8476fc1d4f387b58) /* 640 */, U64_C(0x23f8e7c5f3316503) /* 641 */,
|
||||
U64_C(0x032a2244e7e37339) /* 642 */, U64_C(0x5c87a5d750f5a74b) /* 643 */,
|
||||
U64_C(0x082b4cc43698992e) /* 644 */, U64_C(0xdf917becb858f63c) /* 645 */,
|
||||
U64_C(0x3270b8fc5bf86dda) /* 646 */, U64_C(0x10ae72bb29b5dd76) /* 647 */,
|
||||
U64_C(0x576ac94e7700362b) /* 648 */, U64_C(0x1ad112dac61efb8f) /* 649 */,
|
||||
U64_C(0x691bc30ec5faa427) /* 650 */, U64_C(0xff246311cc327143) /* 651 */,
|
||||
U64_C(0x3142368e30e53206) /* 652 */, U64_C(0x71380e31e02ca396) /* 653 */,
|
||||
U64_C(0x958d5c960aad76f1) /* 654 */, U64_C(0xf8d6f430c16da536) /* 655 */,
|
||||
U64_C(0xc8ffd13f1be7e1d2) /* 656 */, U64_C(0x7578ae66004ddbe1) /* 657 */,
|
||||
U64_C(0x05833f01067be646) /* 658 */, U64_C(0xbb34b5ad3bfe586d) /* 659 */,
|
||||
U64_C(0x095f34c9a12b97f0) /* 660 */, U64_C(0x247ab64525d60ca8) /* 661 */,
|
||||
U64_C(0xdcdbc6f3017477d1) /* 662 */, U64_C(0x4a2e14d4decad24d) /* 663 */,
|
||||
U64_C(0xbdb5e6d9be0a1eeb) /* 664 */, U64_C(0x2a7e70f7794301ab) /* 665 */,
|
||||
U64_C(0xdef42d8a270540fd) /* 666 */, U64_C(0x01078ec0a34c22c1) /* 667 */,
|
||||
U64_C(0xe5de511af4c16387) /* 668 */, U64_C(0x7ebb3a52bd9a330a) /* 669 */,
|
||||
U64_C(0x77697857aa7d6435) /* 670 */, U64_C(0x004e831603ae4c32) /* 671 */,
|
||||
U64_C(0xe7a21020ad78e312) /* 672 */, U64_C(0x9d41a70c6ab420f2) /* 673 */,
|
||||
U64_C(0x28e06c18ea1141e6) /* 674 */, U64_C(0xd2b28cbd984f6b28) /* 675 */,
|
||||
U64_C(0x26b75f6c446e9d83) /* 676 */, U64_C(0xba47568c4d418d7f) /* 677 */,
|
||||
U64_C(0xd80badbfe6183d8e) /* 678 */, U64_C(0x0e206d7f5f166044) /* 679 */,
|
||||
U64_C(0xe258a43911cbca3e) /* 680 */, U64_C(0x723a1746b21dc0bc) /* 681 */,
|
||||
U64_C(0xc7caa854f5d7cdd3) /* 682 */, U64_C(0x7cac32883d261d9c) /* 683 */,
|
||||
U64_C(0x7690c26423ba942c) /* 684 */, U64_C(0x17e55524478042b8) /* 685 */,
|
||||
U64_C(0xe0be477656a2389f) /* 686 */, U64_C(0x4d289b5e67ab2da0) /* 687 */,
|
||||
U64_C(0x44862b9c8fbbfd31) /* 688 */, U64_C(0xb47cc8049d141365) /* 689 */,
|
||||
U64_C(0x822c1b362b91c793) /* 690 */, U64_C(0x4eb14655fb13dfd8) /* 691 */,
|
||||
U64_C(0x1ecbba0714e2a97b) /* 692 */, U64_C(0x6143459d5cde5f14) /* 693 */,
|
||||
U64_C(0x53a8fbf1d5f0ac89) /* 694 */, U64_C(0x97ea04d81c5e5b00) /* 695 */,
|
||||
U64_C(0x622181a8d4fdb3f3) /* 696 */, U64_C(0xe9bcd341572a1208) /* 697 */,
|
||||
U64_C(0x1411258643cce58a) /* 698 */, U64_C(0x9144c5fea4c6e0a4) /* 699 */,
|
||||
U64_C(0x0d33d06565cf620f) /* 700 */, U64_C(0x54a48d489f219ca1) /* 701 */,
|
||||
U64_C(0xc43e5eac6d63c821) /* 702 */, U64_C(0xa9728b3a72770daf) /* 703 */,
|
||||
U64_C(0xd7934e7b20df87ef) /* 704 */, U64_C(0xe35503b61a3e86e5) /* 705 */,
|
||||
U64_C(0xcae321fbc819d504) /* 706 */, U64_C(0x129a50b3ac60bfa6) /* 707 */,
|
||||
U64_C(0xcd5e68ea7e9fb6c3) /* 708 */, U64_C(0xb01c90199483b1c7) /* 709 */,
|
||||
U64_C(0x3de93cd5c295376c) /* 710 */, U64_C(0xaed52edf2ab9ad13) /* 711 */,
|
||||
U64_C(0x2e60f512c0a07884) /* 712 */, U64_C(0xbc3d86a3e36210c9) /* 713 */,
|
||||
U64_C(0x35269d9b163951ce) /* 714 */, U64_C(0x0c7d6e2ad0cdb5fa) /* 715 */,
|
||||
U64_C(0x59e86297d87f5733) /* 716 */, U64_C(0x298ef221898db0e7) /* 717 */,
|
||||
U64_C(0x55000029d1a5aa7e) /* 718 */, U64_C(0x8bc08ae1b5061b45) /* 719 */,
|
||||
U64_C(0xc2c31c2b6c92703a) /* 720 */, U64_C(0x94cc596baf25ef42) /* 721 */,
|
||||
U64_C(0x0a1d73db22540456) /* 722 */, U64_C(0x04b6a0f9d9c4179a) /* 723 */,
|
||||
U64_C(0xeffdafa2ae3d3c60) /* 724 */, U64_C(0xf7c8075bb49496c4) /* 725 */,
|
||||
U64_C(0x9cc5c7141d1cd4e3) /* 726 */, U64_C(0x78bd1638218e5534) /* 727 */,
|
||||
U64_C(0xb2f11568f850246a) /* 728 */, U64_C(0xedfabcfa9502bc29) /* 729 */,
|
||||
U64_C(0x796ce5f2da23051b) /* 730 */, U64_C(0xaae128b0dc93537c) /* 731 */,
|
||||
U64_C(0x3a493da0ee4b29ae) /* 732 */, U64_C(0xb5df6b2c416895d7) /* 733 */,
|
||||
U64_C(0xfcabbd25122d7f37) /* 734 */, U64_C(0x70810b58105dc4b1) /* 735 */,
|
||||
U64_C(0xe10fdd37f7882a90) /* 736 */, U64_C(0x524dcab5518a3f5c) /* 737 */,
|
||||
U64_C(0x3c9e85878451255b) /* 738 */, U64_C(0x4029828119bd34e2) /* 739 */,
|
||||
U64_C(0x74a05b6f5d3ceccb) /* 740 */, U64_C(0xb610021542e13eca) /* 741 */,
|
||||
U64_C(0x0ff979d12f59e2ac) /* 742 */, U64_C(0x6037da27e4f9cc50) /* 743 */,
|
||||
U64_C(0x5e92975a0df1847d) /* 744 */, U64_C(0xd66de190d3e623fe) /* 745 */,
|
||||
U64_C(0x5032d6b87b568048) /* 746 */, U64_C(0x9a36b7ce8235216e) /* 747 */,
|
||||
U64_C(0x80272a7a24f64b4a) /* 748 */, U64_C(0x93efed8b8c6916f7) /* 749 */,
|
||||
U64_C(0x37ddbff44cce1555) /* 750 */, U64_C(0x4b95db5d4b99bd25) /* 751 */,
|
||||
U64_C(0x92d3fda169812fc0) /* 752 */, U64_C(0xfb1a4a9a90660bb6) /* 753 */,
|
||||
U64_C(0x730c196946a4b9b2) /* 754 */, U64_C(0x81e289aa7f49da68) /* 755 */,
|
||||
U64_C(0x64669a0f83b1a05f) /* 756 */, U64_C(0x27b3ff7d9644f48b) /* 757 */,
|
||||
U64_C(0xcc6b615c8db675b3) /* 758 */, U64_C(0x674f20b9bcebbe95) /* 759 */,
|
||||
U64_C(0x6f31238275655982) /* 760 */, U64_C(0x5ae488713e45cf05) /* 761 */,
|
||||
U64_C(0xbf619f9954c21157) /* 762 */, U64_C(0xeabac46040a8eae9) /* 763 */,
|
||||
U64_C(0x454c6fe9f2c0c1cd) /* 764 */, U64_C(0x419cf6496412691c) /* 765 */,
|
||||
U64_C(0xd3dc3bef265b0f70) /* 766 */, U64_C(0x6d0e60f5c3578a9e) /* 767 */
|
||||
};
|
||||
static u64 sbox4[256] = {
|
||||
U64_C(0x5b0e608526323c55) /* 768 */, U64_C(0x1a46c1a9fa1b59f5) /* 769 */,
|
||||
U64_C(0xa9e245a17c4c8ffa) /* 770 */, U64_C(0x65ca5159db2955d7) /* 771 */,
|
||||
U64_C(0x05db0a76ce35afc2) /* 772 */, U64_C(0x81eac77ea9113d45) /* 773 */,
|
||||
U64_C(0x528ef88ab6ac0a0d) /* 774 */, U64_C(0xa09ea253597be3ff) /* 775 */,
|
||||
U64_C(0x430ddfb3ac48cd56) /* 776 */, U64_C(0xc4b3a67af45ce46f) /* 777 */,
|
||||
U64_C(0x4ececfd8fbe2d05e) /* 778 */, U64_C(0x3ef56f10b39935f0) /* 779 */,
|
||||
U64_C(0x0b22d6829cd619c6) /* 780 */, U64_C(0x17fd460a74df2069) /* 781 */,
|
||||
U64_C(0x6cf8cc8e8510ed40) /* 782 */, U64_C(0xd6c824bf3a6ecaa7) /* 783 */,
|
||||
U64_C(0x61243d581a817049) /* 784 */, U64_C(0x048bacb6bbc163a2) /* 785 */,
|
||||
U64_C(0xd9a38ac27d44cc32) /* 786 */, U64_C(0x7fddff5baaf410ab) /* 787 */,
|
||||
U64_C(0xad6d495aa804824b) /* 788 */, U64_C(0xe1a6a74f2d8c9f94) /* 789 */,
|
||||
U64_C(0xd4f7851235dee8e3) /* 790 */, U64_C(0xfd4b7f886540d893) /* 791 */,
|
||||
U64_C(0x247c20042aa4bfda) /* 792 */, U64_C(0x096ea1c517d1327c) /* 793 */,
|
||||
U64_C(0xd56966b4361a6685) /* 794 */, U64_C(0x277da5c31221057d) /* 795 */,
|
||||
U64_C(0x94d59893a43acff7) /* 796 */, U64_C(0x64f0c51ccdc02281) /* 797 */,
|
||||
U64_C(0x3d33bcc4ff6189db) /* 798 */, U64_C(0xe005cb184ce66af1) /* 799 */,
|
||||
U64_C(0xff5ccd1d1db99bea) /* 800 */, U64_C(0xb0b854a7fe42980f) /* 801 */,
|
||||
U64_C(0x7bd46a6a718d4b9f) /* 802 */, U64_C(0xd10fa8cc22a5fd8c) /* 803 */,
|
||||
U64_C(0xd31484952be4bd31) /* 804 */, U64_C(0xc7fa975fcb243847) /* 805 */,
|
||||
U64_C(0x4886ed1e5846c407) /* 806 */, U64_C(0x28cddb791eb70b04) /* 807 */,
|
||||
U64_C(0xc2b00be2f573417f) /* 808 */, U64_C(0x5c9590452180f877) /* 809 */,
|
||||
U64_C(0x7a6bddfff370eb00) /* 810 */, U64_C(0xce509e38d6d9d6a4) /* 811 */,
|
||||
U64_C(0xebeb0f00647fa702) /* 812 */, U64_C(0x1dcc06cf76606f06) /* 813 */,
|
||||
U64_C(0xe4d9f28ba286ff0a) /* 814 */, U64_C(0xd85a305dc918c262) /* 815 */,
|
||||
U64_C(0x475b1d8732225f54) /* 816 */, U64_C(0x2d4fb51668ccb5fe) /* 817 */,
|
||||
U64_C(0xa679b9d9d72bba20) /* 818 */, U64_C(0x53841c0d912d43a5) /* 819 */,
|
||||
U64_C(0x3b7eaa48bf12a4e8) /* 820 */, U64_C(0x781e0e47f22f1ddf) /* 821 */,
|
||||
U64_C(0xeff20ce60ab50973) /* 822 */, U64_C(0x20d261d19dffb742) /* 823 */,
|
||||
U64_C(0x16a12b03062a2e39) /* 824 */, U64_C(0x1960eb2239650495) /* 825 */,
|
||||
U64_C(0x251c16fed50eb8b8) /* 826 */, U64_C(0x9ac0c330f826016e) /* 827 */,
|
||||
U64_C(0xed152665953e7671) /* 828 */, U64_C(0x02d63194a6369570) /* 829 */,
|
||||
U64_C(0x5074f08394b1c987) /* 830 */, U64_C(0x70ba598c90b25ce1) /* 831 */,
|
||||
U64_C(0x794a15810b9742f6) /* 832 */, U64_C(0x0d5925e9fcaf8c6c) /* 833 */,
|
||||
U64_C(0x3067716cd868744e) /* 834 */, U64_C(0x910ab077e8d7731b) /* 835 */,
|
||||
U64_C(0x6a61bbdb5ac42f61) /* 836 */, U64_C(0x93513efbf0851567) /* 837 */,
|
||||
U64_C(0xf494724b9e83e9d5) /* 838 */, U64_C(0xe887e1985c09648d) /* 839 */,
|
||||
U64_C(0x34b1d3c675370cfd) /* 840 */, U64_C(0xdc35e433bc0d255d) /* 841 */,
|
||||
U64_C(0xd0aab84234131be0) /* 842 */, U64_C(0x08042a50b48b7eaf) /* 843 */,
|
||||
U64_C(0x9997c4ee44a3ab35) /* 844 */, U64_C(0x829a7b49201799d0) /* 845 */,
|
||||
U64_C(0x263b8307b7c54441) /* 846 */, U64_C(0x752f95f4fd6a6ca6) /* 847 */,
|
||||
U64_C(0x927217402c08c6e5) /* 848 */, U64_C(0x2a8ab754a795d9ee) /* 849 */,
|
||||
U64_C(0xa442f7552f72943d) /* 850 */, U64_C(0x2c31334e19781208) /* 851 */,
|
||||
U64_C(0x4fa98d7ceaee6291) /* 852 */, U64_C(0x55c3862f665db309) /* 853 */,
|
||||
U64_C(0xbd0610175d53b1f3) /* 854 */, U64_C(0x46fe6cb840413f27) /* 855 */,
|
||||
U64_C(0x3fe03792df0cfa59) /* 856 */, U64_C(0xcfe700372eb85e8f) /* 857 */,
|
||||
U64_C(0xa7be29e7adbce118) /* 858 */, U64_C(0xe544ee5cde8431dd) /* 859 */,
|
||||
U64_C(0x8a781b1b41f1873e) /* 860 */, U64_C(0xa5c94c78a0d2f0e7) /* 861 */,
|
||||
U64_C(0x39412e2877b60728) /* 862 */, U64_C(0xa1265ef3afc9a62c) /* 863 */,
|
||||
U64_C(0xbcc2770c6a2506c5) /* 864 */, U64_C(0x3ab66dd5dce1ce12) /* 865 */,
|
||||
U64_C(0xe65499d04a675b37) /* 866 */, U64_C(0x7d8f523481bfd216) /* 867 */,
|
||||
U64_C(0x0f6f64fcec15f389) /* 868 */, U64_C(0x74efbe618b5b13c8) /* 869 */,
|
||||
U64_C(0xacdc82b714273e1d) /* 870 */, U64_C(0xdd40bfe003199d17) /* 871 */,
|
||||
U64_C(0x37e99257e7e061f8) /* 872 */, U64_C(0xfa52626904775aaa) /* 873 */,
|
||||
U64_C(0x8bbbf63a463d56f9) /* 874 */, U64_C(0xf0013f1543a26e64) /* 875 */,
|
||||
U64_C(0xa8307e9f879ec898) /* 876 */, U64_C(0xcc4c27a4150177cc) /* 877 */,
|
||||
U64_C(0x1b432f2cca1d3348) /* 878 */, U64_C(0xde1d1f8f9f6fa013) /* 879 */,
|
||||
U64_C(0x606602a047a7ddd6) /* 880 */, U64_C(0xd237ab64cc1cb2c7) /* 881 */,
|
||||
U64_C(0x9b938e7225fcd1d3) /* 882 */, U64_C(0xec4e03708e0ff476) /* 883 */,
|
||||
U64_C(0xfeb2fbda3d03c12d) /* 884 */, U64_C(0xae0bced2ee43889a) /* 885 */,
|
||||
U64_C(0x22cb8923ebfb4f43) /* 886 */, U64_C(0x69360d013cf7396d) /* 887 */,
|
||||
U64_C(0x855e3602d2d4e022) /* 888 */, U64_C(0x073805bad01f784c) /* 889 */,
|
||||
U64_C(0x33e17a133852f546) /* 890 */, U64_C(0xdf4874058ac7b638) /* 891 */,
|
||||
U64_C(0xba92b29c678aa14a) /* 892 */, U64_C(0x0ce89fc76cfaadcd) /* 893 */,
|
||||
U64_C(0x5f9d4e0908339e34) /* 894 */, U64_C(0xf1afe9291f5923b9) /* 895 */,
|
||||
U64_C(0x6e3480f60f4a265f) /* 896 */, U64_C(0xeebf3a2ab29b841c) /* 897 */,
|
||||
U64_C(0xe21938a88f91b4ad) /* 898 */, U64_C(0x57dfeff845c6d3c3) /* 899 */,
|
||||
U64_C(0x2f006b0bf62caaf2) /* 900 */, U64_C(0x62f479ef6f75ee78) /* 901 */,
|
||||
U64_C(0x11a55ad41c8916a9) /* 902 */, U64_C(0xf229d29084fed453) /* 903 */,
|
||||
U64_C(0x42f1c27b16b000e6) /* 904 */, U64_C(0x2b1f76749823c074) /* 905 */,
|
||||
U64_C(0x4b76eca3c2745360) /* 906 */, U64_C(0x8c98f463b91691bd) /* 907 */,
|
||||
U64_C(0x14bcc93cf1ade66a) /* 908 */, U64_C(0x8885213e6d458397) /* 909 */,
|
||||
U64_C(0x8e177df0274d4711) /* 910 */, U64_C(0xb49b73b5503f2951) /* 911 */,
|
||||
U64_C(0x10168168c3f96b6b) /* 912 */, U64_C(0x0e3d963b63cab0ae) /* 913 */,
|
||||
U64_C(0x8dfc4b5655a1db14) /* 914 */, U64_C(0xf789f1356e14de5c) /* 915 */,
|
||||
U64_C(0x683e68af4e51dac1) /* 916 */, U64_C(0xc9a84f9d8d4b0fd9) /* 917 */,
|
||||
U64_C(0x3691e03f52a0f9d1) /* 918 */, U64_C(0x5ed86e46e1878e80) /* 919 */,
|
||||
U64_C(0x3c711a0e99d07150) /* 920 */, U64_C(0x5a0865b20c4e9310) /* 921 */,
|
||||
U64_C(0x56fbfc1fe4f0682e) /* 922 */, U64_C(0xea8d5de3105edf9b) /* 923 */,
|
||||
U64_C(0x71abfdb12379187a) /* 924 */, U64_C(0x2eb99de1bee77b9c) /* 925 */,
|
||||
U64_C(0x21ecc0ea33cf4523) /* 926 */, U64_C(0x59a4d7521805c7a1) /* 927 */,
|
||||
U64_C(0x3896f5eb56ae7c72) /* 928 */, U64_C(0xaa638f3db18f75dc) /* 929 */,
|
||||
U64_C(0x9f39358dabe9808e) /* 930 */, U64_C(0xb7defa91c00b72ac) /* 931 */,
|
||||
U64_C(0x6b5541fd62492d92) /* 932 */, U64_C(0x6dc6dee8f92e4d5b) /* 933 */,
|
||||
U64_C(0x353f57abc4beea7e) /* 934 */, U64_C(0x735769d6da5690ce) /* 935 */,
|
||||
U64_C(0x0a234aa642391484) /* 936 */, U64_C(0xf6f9508028f80d9d) /* 937 */,
|
||||
U64_C(0xb8e319a27ab3f215) /* 938 */, U64_C(0x31ad9c1151341a4d) /* 939 */,
|
||||
U64_C(0x773c22a57bef5805) /* 940 */, U64_C(0x45c7561a07968633) /* 941 */,
|
||||
U64_C(0xf913da9e249dbe36) /* 942 */, U64_C(0xda652d9b78a64c68) /* 943 */,
|
||||
U64_C(0x4c27a97f3bc334ef) /* 944 */, U64_C(0x76621220e66b17f4) /* 945 */,
|
||||
U64_C(0x967743899acd7d0b) /* 946 */, U64_C(0xf3ee5bcae0ed6782) /* 947 */,
|
||||
U64_C(0x409f753600c879fc) /* 948 */, U64_C(0x06d09a39b5926db6) /* 949 */,
|
||||
U64_C(0x6f83aeb0317ac588) /* 950 */, U64_C(0x01e6ca4a86381f21) /* 951 */,
|
||||
U64_C(0x66ff3462d19f3025) /* 952 */, U64_C(0x72207c24ddfd3bfb) /* 953 */,
|
||||
U64_C(0x4af6b6d3e2ece2eb) /* 954 */, U64_C(0x9c994dbec7ea08de) /* 955 */,
|
||||
U64_C(0x49ace597b09a8bc4) /* 956 */, U64_C(0xb38c4766cf0797ba) /* 957 */,
|
||||
U64_C(0x131b9373c57c2a75) /* 958 */, U64_C(0xb1822cce61931e58) /* 959 */,
|
||||
U64_C(0x9d7555b909ba1c0c) /* 960 */, U64_C(0x127fafdd937d11d2) /* 961 */,
|
||||
U64_C(0x29da3badc66d92e4) /* 962 */, U64_C(0xa2c1d57154c2ecbc) /* 963 */,
|
||||
U64_C(0x58c5134d82f6fe24) /* 964 */, U64_C(0x1c3ae3515b62274f) /* 965 */,
|
||||
U64_C(0xe907c82e01cb8126) /* 966 */, U64_C(0xf8ed091913e37fcb) /* 967 */,
|
||||
U64_C(0x3249d8f9c80046c9) /* 968 */, U64_C(0x80cf9bede388fb63) /* 969 */,
|
||||
U64_C(0x1881539a116cf19e) /* 970 */, U64_C(0x5103f3f76bd52457) /* 971 */,
|
||||
U64_C(0x15b7e6f5ae47f7a8) /* 972 */, U64_C(0xdbd7c6ded47e9ccf) /* 973 */,
|
||||
U64_C(0x44e55c410228bb1a) /* 974 */, U64_C(0xb647d4255edb4e99) /* 975 */,
|
||||
U64_C(0x5d11882bb8aafc30) /* 976 */, U64_C(0xf5098bbb29d3212a) /* 977 */,
|
||||
U64_C(0x8fb5ea14e90296b3) /* 978 */, U64_C(0x677b942157dd025a) /* 979 */,
|
||||
U64_C(0xfb58e7c0a390acb5) /* 980 */, U64_C(0x89d3674c83bd4a01) /* 981 */,
|
||||
U64_C(0x9e2da4df4bf3b93b) /* 982 */, U64_C(0xfcc41e328cab4829) /* 983 */,
|
||||
U64_C(0x03f38c96ba582c52) /* 984 */, U64_C(0xcad1bdbd7fd85db2) /* 985 */,
|
||||
U64_C(0xbbb442c16082ae83) /* 986 */, U64_C(0xb95fe86ba5da9ab0) /* 987 */,
|
||||
U64_C(0xb22e04673771a93f) /* 988 */, U64_C(0x845358c9493152d8) /* 989 */,
|
||||
U64_C(0xbe2a488697b4541e) /* 990 */, U64_C(0x95a2dc2dd38e6966) /* 991 */,
|
||||
U64_C(0xc02c11ac923c852b) /* 992 */, U64_C(0x2388b1990df2a87b) /* 993 */,
|
||||
U64_C(0x7c8008fa1b4f37be) /* 994 */, U64_C(0x1f70d0c84d54e503) /* 995 */,
|
||||
U64_C(0x5490adec7ece57d4) /* 996 */, U64_C(0x002b3c27d9063a3a) /* 997 */,
|
||||
U64_C(0x7eaea3848030a2bf) /* 998 */, U64_C(0xc602326ded2003c0) /* 999 */,
|
||||
U64_C(0x83a7287d69a94086) /* 1000 */, U64_C(0xc57a5fcb30f57a8a) /* 1001 */,
|
||||
U64_C(0xb56844e479ebe779) /* 1002 */, U64_C(0xa373b40f05dcbce9) /* 1003 */,
|
||||
U64_C(0xd71a786e88570ee2) /* 1004 */, U64_C(0x879cbacdbde8f6a0) /* 1005 */,
|
||||
U64_C(0x976ad1bcc164a32f) /* 1006 */, U64_C(0xab21e25e9666d78b) /* 1007 */,
|
||||
U64_C(0x901063aae5e5c33c) /* 1008 */, U64_C(0x9818b34448698d90) /* 1009 */,
|
||||
U64_C(0xe36487ae3e1e8abb) /* 1010 */, U64_C(0xafbdf931893bdcb4) /* 1011 */,
|
||||
U64_C(0x6345a0dc5fbbd519) /* 1012 */, U64_C(0x8628fe269b9465ca) /* 1013 */,
|
||||
U64_C(0x1e5d01603f9c51ec) /* 1014 */, U64_C(0x4de44006a15049b7) /* 1015 */,
|
||||
U64_C(0xbf6c70e5f776cbb1) /* 1016 */, U64_C(0x411218f2ef552bed) /* 1017 */,
|
||||
U64_C(0xcb0c0708705a36a3) /* 1018 */, U64_C(0xe74d14754f986044) /* 1019 */,
|
||||
U64_C(0xcd56d9430ea8280e) /* 1020 */, U64_C(0xc12591d7535f5065) /* 1021 */,
|
||||
U64_C(0xc83223f1720aef96) /* 1022 */, U64_C(0xc3a0396f7363a51f) /* 1023 */
|
||||
};
|
||||
|
||||
static void
|
||||
tiger_init( void *context )
|
||||
{
|
||||
TIGER_CONTEXT *hd = context;
|
||||
|
||||
hd->a = 0x0123456789abcdefLL;
|
||||
hd->b = 0xfedcba9876543210LL;
|
||||
hd->c = 0xf096a5b4c3b2e187LL;
|
||||
hd->nblocks = 0;
|
||||
hd->count = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
tiger_round( u64 *ra, u64 *rb, u64 *rc, u64 x, int mul )
|
||||
{
|
||||
u64 a = *ra;
|
||||
u64 b = *rb;
|
||||
u64 c = *rc;
|
||||
|
||||
c ^= x;
|
||||
a -= ( sbox1[ c & 0xff ] ^ sbox2[ (c >> 16) & 0xff ]
|
||||
^ sbox3[ (c >> 32) & 0xff ] ^ sbox4[ (c >> 48) & 0xff ]);
|
||||
b += ( sbox4[ (c >> 8) & 0xff ] ^ sbox3[ (c >> 24) & 0xff ]
|
||||
^ sbox2[ (c >> 40) & 0xff ] ^ sbox1[ (c >> 56) & 0xff ]);
|
||||
b *= mul;
|
||||
|
||||
*ra = a;
|
||||
*rb = b;
|
||||
*rc = c;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
pass( u64 *ra, u64 *rb, u64 *rc, u64 *x, int mul )
|
||||
{
|
||||
u64 a = *ra;
|
||||
u64 b = *rb;
|
||||
u64 c = *rc;
|
||||
|
||||
tiger_round( &a, &b, &c, x[0], mul );
|
||||
tiger_round( &b, &c, &a, x[1], mul );
|
||||
tiger_round( &c, &a, &b, x[2], mul );
|
||||
tiger_round( &a, &b, &c, x[3], mul );
|
||||
tiger_round( &b, &c, &a, x[4], mul );
|
||||
tiger_round( &c, &a, &b, x[5], mul );
|
||||
tiger_round( &a, &b, &c, x[6], mul );
|
||||
tiger_round( &b, &c, &a, x[7], mul );
|
||||
|
||||
*ra = a;
|
||||
*rb = b;
|
||||
*rc = c;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
key_schedule( u64 *x )
|
||||
{
|
||||
x[0] -= x[7] ^ 0xa5a5a5a5a5a5a5a5LL;
|
||||
x[1] ^= x[0];
|
||||
x[2] += x[1];
|
||||
x[3] -= x[2] ^ ((~x[1]) << 19 );
|
||||
x[4] ^= x[3];
|
||||
x[5] += x[4];
|
||||
x[6] -= x[5] ^ ((~x[4]) >> 23 );
|
||||
x[7] ^= x[6];
|
||||
x[0] += x[7];
|
||||
x[1] -= x[0] ^ ((~x[7]) << 19 );
|
||||
x[2] ^= x[1];
|
||||
x[3] += x[2];
|
||||
x[4] -= x[3] ^ ((~x[2]) >> 23 );
|
||||
x[5] ^= x[4];
|
||||
x[6] += x[5];
|
||||
x[7] -= x[6] ^ 0x0123456789abcdefLL;
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Transform the message DATA which consists of 512 bytes (8 words)
|
||||
*/
|
||||
static void
|
||||
transform ( TIGER_CONTEXT *hd, const unsigned char *data )
|
||||
{
|
||||
u64 a,b,c,aa,bb,cc;
|
||||
u64 x[8];
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#define MKWORD(d,n) \
|
||||
( ((u64)(d)[8*(n)+7]) << 56 | ((u64)(d)[8*(n)+6]) << 48 \
|
||||
| ((u64)(d)[8*(n)+5]) << 40 | ((u64)(d)[8*(n)+4]) << 32 \
|
||||
| ((u64)(d)[8*(n)+3]) << 24 | ((u64)(d)[8*(n)+2]) << 16 \
|
||||
| ((u64)(d)[8*(n)+1]) << 8 | ((u64)(d)[8*(n) ]) )
|
||||
x[0] = MKWORD(data, 0);
|
||||
x[1] = MKWORD(data, 1);
|
||||
x[2] = MKWORD(data, 2);
|
||||
x[3] = MKWORD(data, 3);
|
||||
x[4] = MKWORD(data, 4);
|
||||
x[5] = MKWORD(data, 5);
|
||||
x[6] = MKWORD(data, 6);
|
||||
x[7] = MKWORD(data, 7);
|
||||
#undef MKWORD
|
||||
#else
|
||||
memcpy( &x[0], data, 64 );
|
||||
#endif
|
||||
|
||||
/* save */
|
||||
a = aa = hd->a;
|
||||
b = bb = hd->b;
|
||||
c = cc = hd->c;
|
||||
|
||||
pass( &a, &b, &c, x, 5);
|
||||
key_schedule( x );
|
||||
pass( &c, &a, &b, x, 7);
|
||||
key_schedule( x );
|
||||
pass( &b, &c, &a, x, 9);
|
||||
|
||||
/* feedforward */
|
||||
a ^= aa;
|
||||
b -= bb;
|
||||
c += cc;
|
||||
/* store */
|
||||
hd->a = a;
|
||||
hd->b = b;
|
||||
hd->c = c;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Update the message digest with the contents
|
||||
* of INBUF with length INLEN.
|
||||
*/
|
||||
static void
|
||||
tiger_write ( void *context, const void *inbuf_arg, size_t inlen)
|
||||
{
|
||||
const unsigned char *inbuf = inbuf_arg;
|
||||
TIGER_CONTEXT *hd = context;
|
||||
|
||||
if( hd->count == 64 ) /* flush the buffer */
|
||||
{
|
||||
transform( hd, hd->buf );
|
||||
_gcry_burn_stack (21*8+11*sizeof(void*));
|
||||
hd->count = 0;
|
||||
hd->nblocks++;
|
||||
}
|
||||
if( !inbuf )
|
||||
return;
|
||||
if( hd->count )
|
||||
{
|
||||
for( ; inlen && hd->count < 64; inlen-- )
|
||||
hd->buf[hd->count++] = *inbuf++;
|
||||
tiger_write( hd, NULL, 0 );
|
||||
if( !inlen )
|
||||
return;
|
||||
}
|
||||
|
||||
while( inlen >= 64 )
|
||||
{
|
||||
transform( hd, inbuf );
|
||||
hd->count = 0;
|
||||
hd->nblocks++;
|
||||
inlen -= 64;
|
||||
inbuf += 64;
|
||||
}
|
||||
_gcry_burn_stack (21*8+11*sizeof(void*));
|
||||
for( ; inlen && hd->count < 64; inlen-- )
|
||||
hd->buf[hd->count++] = *inbuf++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* The routine terminates the computation
|
||||
*/
|
||||
static void
|
||||
tiger_final( void *context )
|
||||
{
|
||||
TIGER_CONTEXT *hd = context;
|
||||
u32 t, msb, lsb;
|
||||
byte *p;
|
||||
|
||||
tiger_write(hd, NULL, 0); /* flush */;
|
||||
|
||||
t = hd->nblocks;
|
||||
/* multiply by 64 to make a byte count */
|
||||
lsb = t << 6;
|
||||
msb = t >> 26;
|
||||
/* add the count */
|
||||
t = lsb;
|
||||
if( (lsb += hd->count) < t )
|
||||
msb++;
|
||||
/* multiply by 8 to make a bit count */
|
||||
t = lsb;
|
||||
lsb <<= 3;
|
||||
msb <<= 3;
|
||||
msb |= t >> 29;
|
||||
|
||||
if( hd->count < 56 ) /* enough room */
|
||||
{
|
||||
hd->buf[hd->count++] = 0x01; /* pad */
|
||||
while( hd->count < 56 )
|
||||
hd->buf[hd->count++] = 0; /* pad */
|
||||
}
|
||||
else /* need one extra block */
|
||||
{
|
||||
hd->buf[hd->count++] = 0x01; /* pad character */
|
||||
while( hd->count < 64 )
|
||||
hd->buf[hd->count++] = 0;
|
||||
tiger_write(hd, NULL, 0); /* flush */;
|
||||
memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
|
||||
}
|
||||
/* append the 64 bit count */
|
||||
hd->buf[56] = lsb ;
|
||||
hd->buf[57] = lsb >> 8;
|
||||
hd->buf[58] = lsb >> 16;
|
||||
hd->buf[59] = lsb >> 24;
|
||||
hd->buf[60] = msb ;
|
||||
hd->buf[61] = msb >> 8;
|
||||
hd->buf[62] = msb >> 16;
|
||||
hd->buf[63] = msb >> 24;
|
||||
transform( hd, hd->buf );
|
||||
_gcry_burn_stack (21*8+11*sizeof(void*));
|
||||
|
||||
p = hd->buf;
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#define X(a) do { *(u64*)p = hd->a ; p += 8; } while(0)
|
||||
#else /* little endian */
|
||||
#define X(a) do { *p++ = hd->a >> 56; *p++ = hd->a >> 48; \
|
||||
*p++ = hd->a >> 40; *p++ = hd->a >> 32; \
|
||||
*p++ = hd->a >> 24; *p++ = hd->a >> 16; \
|
||||
*p++ = hd->a >> 8; *p++ = hd->a; } while(0)
|
||||
#endif
|
||||
X(a);
|
||||
X(b);
|
||||
X(c);
|
||||
#undef X
|
||||
}
|
||||
|
||||
static byte *
|
||||
tiger_read( void *context )
|
||||
{
|
||||
TIGER_CONTEXT *hd = context;
|
||||
|
||||
return hd->buf;
|
||||
}
|
||||
|
||||
static byte asn[19] = /* Object ID is 1.3.6.1.4.1.11591.12.2 */
|
||||
{ 0x30, 0x29, 0x30, 0x0d, 0x06, 0x09, 0x2b, 0x06,
|
||||
0x01, 0x04, 0x01, 0xda, 0x47, 0x0c, 0x02,
|
||||
0x05, 0x00, 0x04, 0x18 };
|
||||
|
||||
static gcry_md_oid_spec_t oid_spec_tiger[] =
|
||||
{
|
||||
/* GNU.digestAlgorithm TIGER */
|
||||
{ "1.3.6.1.4.1.11591.12.2" },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
gcry_md_spec_t _gcry_digest_spec_tiger =
|
||||
{
|
||||
"TIGER192", asn, DIM (asn), oid_spec_tiger, 24,
|
||||
tiger_init, tiger_write, tiger_final, tiger_read,
|
||||
sizeof (TIGER_CONTEXT)
|
||||
};
|
||||
|
||||
#endif /* HAVE_U64_TYPEDEF */
|
1040
lib/libgcrypt/cipher/twofish.c
Normal file
1040
lib/libgcrypt/cipher/twofish.c
Normal file
File diff suppressed because it is too large
Load diff
1406
lib/libgcrypt/cipher/whirlpool.c
Normal file
1406
lib/libgcrypt/cipher/whirlpool.c
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue