utils: Add (partial) libtomcrypt.

Add the parts of libtomcrypt that we're about to use.

Change-Id: I0adc1d7d1f4833e7bb3ed53b9a4d9a85977cfb8b
This commit is contained in:
Dominik Riebeling 2020-08-08 18:45:07 +02:00
parent 7603533f7f
commit caa9d9c1c5
29 changed files with 8417 additions and 0 deletions

View file

@ -738,3 +738,4 @@ The Quake team
The Pocket Quake team (Dan East and others)
The bzip2 team
The bsdiff team
The libtomcrypt team

29
utils/tomcrypt/LICENSE Normal file
View file

@ -0,0 +1,29 @@
LibTomCrypt is licensed under DUAL licensing terms.
Choose and use the license of your needs.
[LICENSE #1]
LibTomCrypt is public domain. As should all quality software be.
Tom St Denis
[/LICENSE #1]
[LICENSE #2]
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
[/LICENSE #2]

View file

@ -0,0 +1,7 @@
This folder contains the source from libtomcrypt.
Only the source files that are actually used have been added. If more
functionality is needed add the missing files.
The source tree has last been synced with libtomcrypt 1.18.2 on 2020-08-08.

View file

@ -0,0 +1,743 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/* AES implementation by Tom St Denis
*
* Derived from the Public Domain source code by
---
* rijndael-alg-fst.c
*
* @version 3.0 (December 2000)
*
* Optimised ANSI C code for the Rijndael cipher (now AES)
*
* @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
* @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
* @author Paulo Barreto <paulo.barreto@terra.com.br>
---
*/
/**
@file aes.c
Implementation of AES
*/
#include "tomcrypt.h"
#ifdef LTC_RIJNDAEL
#ifndef ENCRYPT_ONLY
#define SETUP rijndael_setup
#define ECB_ENC rijndael_ecb_encrypt
#define ECB_DEC rijndael_ecb_decrypt
#define ECB_DONE rijndael_done
#define ECB_TEST rijndael_test
#define ECB_KS rijndael_keysize
const struct ltc_cipher_descriptor rijndael_desc =
{
"rijndael",
6,
16, 32, 16, 10,
SETUP, ECB_ENC, ECB_DEC, ECB_TEST, ECB_DONE, ECB_KS,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
const struct ltc_cipher_descriptor aes_desc =
{
"aes",
6,
16, 32, 16, 10,
SETUP, ECB_ENC, ECB_DEC, ECB_TEST, ECB_DONE, ECB_KS,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
#else
#define SETUP rijndael_enc_setup
#define ECB_ENC rijndael_enc_ecb_encrypt
#define ECB_KS rijndael_enc_keysize
#define ECB_DONE rijndael_enc_done
const struct ltc_cipher_descriptor rijndael_enc_desc =
{
"rijndael",
6,
16, 32, 16, 10,
SETUP, ECB_ENC, NULL, NULL, ECB_DONE, ECB_KS,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
const struct ltc_cipher_descriptor aes_enc_desc =
{
"aes",
6,
16, 32, 16, 10,
SETUP, ECB_ENC, NULL, NULL, ECB_DONE, ECB_KS,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
#endif
#define __LTC_AES_TAB_C__
#include "aes_tab.c"
static ulong32 setup_mix(ulong32 temp)
{
return (Te4_3[byte(temp, 2)]) ^
(Te4_2[byte(temp, 1)]) ^
(Te4_1[byte(temp, 0)]) ^
(Te4_0[byte(temp, 3)]);
}
#ifndef ENCRYPT_ONLY
#ifdef LTC_SMALL_CODE
static ulong32 setup_mix2(ulong32 temp)
{
return Td0(255 & Te4[byte(temp, 3)]) ^
Td1(255 & Te4[byte(temp, 2)]) ^
Td2(255 & Te4[byte(temp, 1)]) ^
Td3(255 & Te4[byte(temp, 0)]);
}
#endif
#endif
/**
Initialize the AES (Rijndael) block cipher
@param key The symmetric key you wish to pass
@param keylen The key length in bytes
@param num_rounds The number of rounds desired (0 for default)
@param skey The key in as scheduled by this function.
@return CRYPT_OK if successful
*/
int SETUP(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
{
int i;
ulong32 temp, *rk;
#ifndef ENCRYPT_ONLY
ulong32 *rrk;
#endif
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(skey != NULL);
if (keylen != 16 && keylen != 24 && keylen != 32) {
return CRYPT_INVALID_KEYSIZE;
}
if (num_rounds != 0 && num_rounds != (10 + ((keylen/8)-2)*2)) {
return CRYPT_INVALID_ROUNDS;
}
skey->rijndael.Nr = 10 + ((keylen/8)-2)*2;
/* setup the forward key */
i = 0;
rk = skey->rijndael.eK;
LOAD32H(rk[0], key );
LOAD32H(rk[1], key + 4);
LOAD32H(rk[2], key + 8);
LOAD32H(rk[3], key + 12);
if (keylen == 16) {
for (;;) {
temp = rk[3];
rk[4] = rk[0] ^ setup_mix(temp) ^ rcon[i];
rk[5] = rk[1] ^ rk[4];
rk[6] = rk[2] ^ rk[5];
rk[7] = rk[3] ^ rk[6];
if (++i == 10) {
break;
}
rk += 4;
}
} else if (keylen == 24) {
LOAD32H(rk[4], key + 16);
LOAD32H(rk[5], key + 20);
for (;;) {
#ifdef _MSC_VER
temp = skey->rijndael.eK[rk - skey->rijndael.eK + 5];
#else
temp = rk[5];
#endif
rk[ 6] = rk[ 0] ^ setup_mix(temp) ^ rcon[i];
rk[ 7] = rk[ 1] ^ rk[ 6];
rk[ 8] = rk[ 2] ^ rk[ 7];
rk[ 9] = rk[ 3] ^ rk[ 8];
if (++i == 8) {
break;
}
rk[10] = rk[ 4] ^ rk[ 9];
rk[11] = rk[ 5] ^ rk[10];
rk += 6;
}
} else if (keylen == 32) {
LOAD32H(rk[4], key + 16);
LOAD32H(rk[5], key + 20);
LOAD32H(rk[6], key + 24);
LOAD32H(rk[7], key + 28);
for (;;) {
#ifdef _MSC_VER
temp = skey->rijndael.eK[rk - skey->rijndael.eK + 7];
#else
temp = rk[7];
#endif
rk[ 8] = rk[ 0] ^ setup_mix(temp) ^ rcon[i];
rk[ 9] = rk[ 1] ^ rk[ 8];
rk[10] = rk[ 2] ^ rk[ 9];
rk[11] = rk[ 3] ^ rk[10];
if (++i == 7) {
break;
}
temp = rk[11];
rk[12] = rk[ 4] ^ setup_mix(RORc(temp, 8));
rk[13] = rk[ 5] ^ rk[12];
rk[14] = rk[ 6] ^ rk[13];
rk[15] = rk[ 7] ^ rk[14];
rk += 8;
}
} else {
/* this can't happen */
/* coverity[dead_error_line] */
return CRYPT_ERROR;
}
#ifndef ENCRYPT_ONLY
/* setup the inverse key now */
rk = skey->rijndael.dK;
rrk = skey->rijndael.eK + (28 + keylen) - 4;
/* apply the inverse MixColumn transform to all round keys but the first and the last: */
/* copy first */
*rk++ = *rrk++;
*rk++ = *rrk++;
*rk++ = *rrk++;
*rk = *rrk;
rk -= 3; rrk -= 3;
for (i = 1; i < skey->rijndael.Nr; i++) {
rrk -= 4;
rk += 4;
#ifdef LTC_SMALL_CODE
temp = rrk[0];
rk[0] = setup_mix2(temp);
temp = rrk[1];
rk[1] = setup_mix2(temp);
temp = rrk[2];
rk[2] = setup_mix2(temp);
temp = rrk[3];
rk[3] = setup_mix2(temp);
#else
temp = rrk[0];
rk[0] =
Tks0[byte(temp, 3)] ^
Tks1[byte(temp, 2)] ^
Tks2[byte(temp, 1)] ^
Tks3[byte(temp, 0)];
temp = rrk[1];
rk[1] =
Tks0[byte(temp, 3)] ^
Tks1[byte(temp, 2)] ^
Tks2[byte(temp, 1)] ^
Tks3[byte(temp, 0)];
temp = rrk[2];
rk[2] =
Tks0[byte(temp, 3)] ^
Tks1[byte(temp, 2)] ^
Tks2[byte(temp, 1)] ^
Tks3[byte(temp, 0)];
temp = rrk[3];
rk[3] =
Tks0[byte(temp, 3)] ^
Tks1[byte(temp, 2)] ^
Tks2[byte(temp, 1)] ^
Tks3[byte(temp, 0)];
#endif
}
/* copy last */
rrk -= 4;
rk += 4;
*rk++ = *rrk++;
*rk++ = *rrk++;
*rk++ = *rrk++;
*rk = *rrk;
#endif /* ENCRYPT_ONLY */
return CRYPT_OK;
}
/**
Encrypts a block of text with AES
@param pt The input plaintext (16 bytes)
@param ct The output ciphertext (16 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
#ifdef LTC_CLEAN_STACK
static int _rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#else
int ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#endif
{
ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk;
int Nr, r;
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(skey != NULL);
Nr = skey->rijndael.Nr;
rk = skey->rijndael.eK;
/*
* map byte array block to cipher state
* and add initial round key:
*/
LOAD32H(s0, pt ); s0 ^= rk[0];
LOAD32H(s1, pt + 4); s1 ^= rk[1];
LOAD32H(s2, pt + 8); s2 ^= rk[2];
LOAD32H(s3, pt + 12); s3 ^= rk[3];
#ifdef LTC_SMALL_CODE
for (r = 0; ; r++) {
rk += 4;
t0 =
Te0(byte(s0, 3)) ^
Te1(byte(s1, 2)) ^
Te2(byte(s2, 1)) ^
Te3(byte(s3, 0)) ^
rk[0];
t1 =
Te0(byte(s1, 3)) ^
Te1(byte(s2, 2)) ^
Te2(byte(s3, 1)) ^
Te3(byte(s0, 0)) ^
rk[1];
t2 =
Te0(byte(s2, 3)) ^
Te1(byte(s3, 2)) ^
Te2(byte(s0, 1)) ^
Te3(byte(s1, 0)) ^
rk[2];
t3 =
Te0(byte(s3, 3)) ^
Te1(byte(s0, 2)) ^
Te2(byte(s1, 1)) ^
Te3(byte(s2, 0)) ^
rk[3];
if (r == Nr-2) {
break;
}
s0 = t0; s1 = t1; s2 = t2; s3 = t3;
}
rk += 4;
#else
/*
* Nr - 1 full rounds:
*/
r = Nr >> 1;
for (;;) {
t0 =
Te0(byte(s0, 3)) ^
Te1(byte(s1, 2)) ^
Te2(byte(s2, 1)) ^
Te3(byte(s3, 0)) ^
rk[4];
t1 =
Te0(byte(s1, 3)) ^
Te1(byte(s2, 2)) ^
Te2(byte(s3, 1)) ^
Te3(byte(s0, 0)) ^
rk[5];
t2 =
Te0(byte(s2, 3)) ^
Te1(byte(s3, 2)) ^
Te2(byte(s0, 1)) ^
Te3(byte(s1, 0)) ^
rk[6];
t3 =
Te0(byte(s3, 3)) ^
Te1(byte(s0, 2)) ^
Te2(byte(s1, 1)) ^
Te3(byte(s2, 0)) ^
rk[7];
rk += 8;
if (--r == 0) {
break;
}
s0 =
Te0(byte(t0, 3)) ^
Te1(byte(t1, 2)) ^
Te2(byte(t2, 1)) ^
Te3(byte(t3, 0)) ^
rk[0];
s1 =
Te0(byte(t1, 3)) ^
Te1(byte(t2, 2)) ^
Te2(byte(t3, 1)) ^
Te3(byte(t0, 0)) ^
rk[1];
s2 =
Te0(byte(t2, 3)) ^
Te1(byte(t3, 2)) ^
Te2(byte(t0, 1)) ^
Te3(byte(t1, 0)) ^
rk[2];
s3 =
Te0(byte(t3, 3)) ^
Te1(byte(t0, 2)) ^
Te2(byte(t1, 1)) ^
Te3(byte(t2, 0)) ^
rk[3];
}
#endif
/*
* apply last round and
* map cipher state to byte array block:
*/
s0 =
(Te4_3[byte(t0, 3)]) ^
(Te4_2[byte(t1, 2)]) ^
(Te4_1[byte(t2, 1)]) ^
(Te4_0[byte(t3, 0)]) ^
rk[0];
STORE32H(s0, ct);
s1 =
(Te4_3[byte(t1, 3)]) ^
(Te4_2[byte(t2, 2)]) ^
(Te4_1[byte(t3, 1)]) ^
(Te4_0[byte(t0, 0)]) ^
rk[1];
STORE32H(s1, ct+4);
s2 =
(Te4_3[byte(t2, 3)]) ^
(Te4_2[byte(t3, 2)]) ^
(Te4_1[byte(t0, 1)]) ^
(Te4_0[byte(t1, 0)]) ^
rk[2];
STORE32H(s2, ct+8);
s3 =
(Te4_3[byte(t3, 3)]) ^
(Te4_2[byte(t0, 2)]) ^
(Te4_1[byte(t1, 1)]) ^
(Te4_0[byte(t2, 0)]) ^
rk[3];
STORE32H(s3, ct+12);
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
int ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
{
int err = _rijndael_ecb_encrypt(pt, ct, skey);
burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2);
return err;
}
#endif
#ifndef ENCRYPT_ONLY
/**
Decrypts a block of text with AES
@param ct The input ciphertext (16 bytes)
@param pt The output plaintext (16 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
#ifdef LTC_CLEAN_STACK
static int _rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#else
int ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#endif
{
ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk;
int Nr, r;
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(skey != NULL);
Nr = skey->rijndael.Nr;
rk = skey->rijndael.dK;
/*
* map byte array block to cipher state
* and add initial round key:
*/
LOAD32H(s0, ct ); s0 ^= rk[0];
LOAD32H(s1, ct + 4); s1 ^= rk[1];
LOAD32H(s2, ct + 8); s2 ^= rk[2];
LOAD32H(s3, ct + 12); s3 ^= rk[3];
#ifdef LTC_SMALL_CODE
for (r = 0; ; r++) {
rk += 4;
t0 =
Td0(byte(s0, 3)) ^
Td1(byte(s3, 2)) ^
Td2(byte(s2, 1)) ^
Td3(byte(s1, 0)) ^
rk[0];
t1 =
Td0(byte(s1, 3)) ^
Td1(byte(s0, 2)) ^
Td2(byte(s3, 1)) ^
Td3(byte(s2, 0)) ^
rk[1];
t2 =
Td0(byte(s2, 3)) ^
Td1(byte(s1, 2)) ^
Td2(byte(s0, 1)) ^
Td3(byte(s3, 0)) ^
rk[2];
t3 =
Td0(byte(s3, 3)) ^
Td1(byte(s2, 2)) ^
Td2(byte(s1, 1)) ^
Td3(byte(s0, 0)) ^
rk[3];
if (r == Nr-2) {
break;
}
s0 = t0; s1 = t1; s2 = t2; s3 = t3;
}
rk += 4;
#else
/*
* Nr - 1 full rounds:
*/
r = Nr >> 1;
for (;;) {
t0 =
Td0(byte(s0, 3)) ^
Td1(byte(s3, 2)) ^
Td2(byte(s2, 1)) ^
Td3(byte(s1, 0)) ^
rk[4];
t1 =
Td0(byte(s1, 3)) ^
Td1(byte(s0, 2)) ^
Td2(byte(s3, 1)) ^
Td3(byte(s2, 0)) ^
rk[5];
t2 =
Td0(byte(s2, 3)) ^
Td1(byte(s1, 2)) ^
Td2(byte(s0, 1)) ^
Td3(byte(s3, 0)) ^
rk[6];
t3 =
Td0(byte(s3, 3)) ^
Td1(byte(s2, 2)) ^
Td2(byte(s1, 1)) ^
Td3(byte(s0, 0)) ^
rk[7];
rk += 8;
if (--r == 0) {
break;
}
s0 =
Td0(byte(t0, 3)) ^
Td1(byte(t3, 2)) ^
Td2(byte(t2, 1)) ^
Td3(byte(t1, 0)) ^
rk[0];
s1 =
Td0(byte(t1, 3)) ^
Td1(byte(t0, 2)) ^
Td2(byte(t3, 1)) ^
Td3(byte(t2, 0)) ^
rk[1];
s2 =
Td0(byte(t2, 3)) ^
Td1(byte(t1, 2)) ^
Td2(byte(t0, 1)) ^
Td3(byte(t3, 0)) ^
rk[2];
s3 =
Td0(byte(t3, 3)) ^
Td1(byte(t2, 2)) ^
Td2(byte(t1, 1)) ^
Td3(byte(t0, 0)) ^
rk[3];
}
#endif
/*
* apply last round and
* map cipher state to byte array block:
*/
s0 =
(Td4[byte(t0, 3)] & 0xff000000) ^
(Td4[byte(t3, 2)] & 0x00ff0000) ^
(Td4[byte(t2, 1)] & 0x0000ff00) ^
(Td4[byte(t1, 0)] & 0x000000ff) ^
rk[0];
STORE32H(s0, pt);
s1 =
(Td4[byte(t1, 3)] & 0xff000000) ^
(Td4[byte(t0, 2)] & 0x00ff0000) ^
(Td4[byte(t3, 1)] & 0x0000ff00) ^
(Td4[byte(t2, 0)] & 0x000000ff) ^
rk[1];
STORE32H(s1, pt+4);
s2 =
(Td4[byte(t2, 3)] & 0xff000000) ^
(Td4[byte(t1, 2)] & 0x00ff0000) ^
(Td4[byte(t0, 1)] & 0x0000ff00) ^
(Td4[byte(t3, 0)] & 0x000000ff) ^
rk[2];
STORE32H(s2, pt+8);
s3 =
(Td4[byte(t3, 3)] & 0xff000000) ^
(Td4[byte(t2, 2)] & 0x00ff0000) ^
(Td4[byte(t1, 1)] & 0x0000ff00) ^
(Td4[byte(t0, 0)] & 0x000000ff) ^
rk[3];
STORE32H(s3, pt+12);
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
int ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
{
int err = _rijndael_ecb_decrypt(ct, pt, skey);
burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2);
return err;
}
#endif
/**
Performs a self-test of the AES block cipher
@return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
*/
int ECB_TEST(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
int err;
static const struct {
int keylen;
unsigned char key[32], pt[16], ct[16];
} tests[] = {
{ 16,
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
{ 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30,
0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a }
}, {
24,
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 },
{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
{ 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0,
0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91 }
}, {
32,
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
{ 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf,
0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 }
}
};
symmetric_key key;
unsigned char tmp[2][16];
int i, y;
for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
zeromem(&key, sizeof(key));
if ((err = rijndael_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) {
return err;
}
rijndael_ecb_encrypt(tests[i].pt, tmp[0], &key);
rijndael_ecb_decrypt(tmp[0], tmp[1], &key);
if (compare_testvector(tmp[0], 16, tests[i].ct, 16, "AES Encrypt", i) ||
compare_testvector(tmp[1], 16, tests[i].pt, 16, "AES Decrypt", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
/* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
for (y = 0; y < 16; y++) tmp[0][y] = 0;
for (y = 0; y < 1000; y++) rijndael_ecb_encrypt(tmp[0], tmp[0], &key);
for (y = 0; y < 1000; y++) rijndael_ecb_decrypt(tmp[0], tmp[0], &key);
for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
}
return CRYPT_OK;
#endif
}
#endif /* ENCRYPT_ONLY */
/** Terminate the context
@param skey The scheduled key
*/
void ECB_DONE(symmetric_key *skey)
{
LTC_UNUSED_PARAM(skey);
}
/**
Gets suitable key size
@param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
@return CRYPT_OK if the input key size is acceptable.
*/
int ECB_KS(int *keysize)
{
LTC_ARGCHK(keysize != NULL);
if (*keysize < 16)
return CRYPT_INVALID_KEYSIZE;
if (*keysize < 24) {
*keysize = 16;
return CRYPT_OK;
} else if (*keysize < 32) {
*keysize = 24;
return CRYPT_OK;
} else {
*keysize = 32;
return CRYPT_OK;
}
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,286 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
/**
@file sha1.c
LTC_SHA1 code by Tom St Denis
*/
#ifdef LTC_SHA1
const struct ltc_hash_descriptor sha1_desc =
{
"sha1",
2,
20,
64,
/* OID */
{ 1, 3, 14, 3, 2, 26, },
6,
&sha1_init,
&sha1_process,
&sha1_done,
&sha1_test,
NULL
};
#define F0(x,y,z) (z ^ (x & (y ^ z)))
#define F1(x,y,z) (x ^ y ^ z)
#define F2(x,y,z) ((x & y) | (z & (x | y)))
#define F3(x,y,z) (x ^ y ^ z)
#ifdef LTC_CLEAN_STACK
static int _sha1_compress(hash_state *md, unsigned char *buf)
#else
static int sha1_compress(hash_state *md, unsigned char *buf)
#endif
{
ulong32 a,b,c,d,e,W[80],i;
#ifdef LTC_SMALL_CODE
ulong32 t;
#endif
/* copy the state into 512-bits into W[0..15] */
for (i = 0; i < 16; i++) {
LOAD32H(W[i], buf + (4*i));
}
/* copy state */
a = md->sha1.state[0];
b = md->sha1.state[1];
c = md->sha1.state[2];
d = md->sha1.state[3];
e = md->sha1.state[4];
/* expand it */
for (i = 16; i < 80; i++) {
W[i] = ROL(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1);
}
/* compress */
/* round one */
#define FF0(a,b,c,d,e,i) e = (ROLc(a, 5) + F0(b,c,d) + e + W[i] + 0x5a827999UL); b = ROLc(b, 30);
#define FF1(a,b,c,d,e,i) e = (ROLc(a, 5) + F1(b,c,d) + e + W[i] + 0x6ed9eba1UL); b = ROLc(b, 30);
#define FF2(a,b,c,d,e,i) e = (ROLc(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = ROLc(b, 30);
#define FF3(a,b,c,d,e,i) e = (ROLc(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = ROLc(b, 30);
#ifdef LTC_SMALL_CODE
for (i = 0; i < 20; ) {
FF0(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
}
for (; i < 40; ) {
FF1(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
}
for (; i < 60; ) {
FF2(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
}
for (; i < 80; ) {
FF3(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
}
#else
for (i = 0; i < 20; ) {
FF0(a,b,c,d,e,i++);
FF0(e,a,b,c,d,i++);
FF0(d,e,a,b,c,i++);
FF0(c,d,e,a,b,i++);
FF0(b,c,d,e,a,i++);
}
/* round two */
for (; i < 40; ) {
FF1(a,b,c,d,e,i++);
FF1(e,a,b,c,d,i++);
FF1(d,e,a,b,c,i++);
FF1(c,d,e,a,b,i++);
FF1(b,c,d,e,a,i++);
}
/* round three */
for (; i < 60; ) {
FF2(a,b,c,d,e,i++);
FF2(e,a,b,c,d,i++);
FF2(d,e,a,b,c,i++);
FF2(c,d,e,a,b,i++);
FF2(b,c,d,e,a,i++);
}
/* round four */
for (; i < 80; ) {
FF3(a,b,c,d,e,i++);
FF3(e,a,b,c,d,i++);
FF3(d,e,a,b,c,i++);
FF3(c,d,e,a,b,i++);
FF3(b,c,d,e,a,i++);
}
#endif
#undef FF0
#undef FF1
#undef FF2
#undef FF3
/* store */
md->sha1.state[0] = md->sha1.state[0] + a;
md->sha1.state[1] = md->sha1.state[1] + b;
md->sha1.state[2] = md->sha1.state[2] + c;
md->sha1.state[3] = md->sha1.state[3] + d;
md->sha1.state[4] = md->sha1.state[4] + e;
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
static int sha1_compress(hash_state *md, unsigned char *buf)
{
int err;
err = _sha1_compress(md, buf);
burn_stack(sizeof(ulong32) * 87);
return err;
}
#endif
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int sha1_init(hash_state * md)
{
LTC_ARGCHK(md != NULL);
md->sha1.state[0] = 0x67452301UL;
md->sha1.state[1] = 0xefcdab89UL;
md->sha1.state[2] = 0x98badcfeUL;
md->sha1.state[3] = 0x10325476UL;
md->sha1.state[4] = 0xc3d2e1f0UL;
md->sha1.curlen = 0;
md->sha1.length = 0;
return CRYPT_OK;
}
/**
Process a block of memory though the hash
@param md The hash state
@param in The data to hash
@param inlen The length of the data (octets)
@return CRYPT_OK if successful
*/
HASH_PROCESS(sha1_process, sha1_compress, sha1, 64)
/**
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (20 bytes)
@return CRYPT_OK if successful
*/
int sha1_done(hash_state * md, unsigned char *out)
{
int i;
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(out != NULL);
if (md->sha1.curlen >= sizeof(md->sha1.buf)) {
return CRYPT_INVALID_ARG;
}
/* increase the length of the message */
md->sha1.length += md->sha1.curlen * 8;
/* append the '1' bit */
md->sha1.buf[md->sha1.curlen++] = (unsigned char)0x80;
/* if the length is currently above 56 bytes we append zeros
* then compress. Then we can fall back to padding zeros and length
* encoding like normal.
*/
if (md->sha1.curlen > 56) {
while (md->sha1.curlen < 64) {
md->sha1.buf[md->sha1.curlen++] = (unsigned char)0;
}
sha1_compress(md, md->sha1.buf);
md->sha1.curlen = 0;
}
/* pad upto 56 bytes of zeroes */
while (md->sha1.curlen < 56) {
md->sha1.buf[md->sha1.curlen++] = (unsigned char)0;
}
/* store length */
STORE64H(md->sha1.length, md->sha1.buf+56);
sha1_compress(md, md->sha1.buf);
/* copy output */
for (i = 0; i < 5; i++) {
STORE32H(md->sha1.state[i], out+(4*i));
}
#ifdef LTC_CLEAN_STACK
zeromem(md, sizeof(hash_state));
#endif
return CRYPT_OK;
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int sha1_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[20];
} tests[] = {
{ "abc",
{ 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a,
0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c,
0x9c, 0xd0, 0xd8, 0x9d }
},
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
{ 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E,
0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5,
0xE5, 0x46, 0x70, 0xF1 }
}
};
int i;
unsigned char tmp[20];
hash_state md;
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
sha1_init(&md);
sha1_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg));
sha1_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "SHA1", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View file

@ -0,0 +1,105 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#ifndef TOMCRYPT_H_
#define TOMCRYPT_H_
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include <time.h>
#include <ctype.h>
#include <limits.h>
/* use configuration data */
#include <tomcrypt_custom.h>
#ifdef __cplusplus
extern "C" {
#endif
/* version */
#define CRYPT 0x0118
#define SCRYPT "1.18.2"
/* max size of either a cipher/hash block or symmetric key [largest of the two] */
#define MAXBLOCKSIZE 128
#ifndef TAB_SIZE
/* descriptor table size */
#define TAB_SIZE 32
#endif
/* error codes [will be expanded in future releases] */
enum {
CRYPT_OK=0, /* Result OK */
CRYPT_ERROR, /* Generic Error */
CRYPT_NOP, /* Not a failure but no operation was performed */
CRYPT_INVALID_KEYSIZE, /* Invalid key size given */
CRYPT_INVALID_ROUNDS, /* Invalid number of rounds */
CRYPT_FAIL_TESTVECTOR, /* Algorithm failed test vectors */
CRYPT_BUFFER_OVERFLOW, /* Not enough space for output */
CRYPT_INVALID_PACKET, /* Invalid input packet given */
CRYPT_INVALID_PRNGSIZE, /* Invalid number of bits for a PRNG */
CRYPT_ERROR_READPRNG, /* Could not read enough from PRNG */
CRYPT_INVALID_CIPHER, /* Invalid cipher specified */
CRYPT_INVALID_HASH, /* Invalid hash specified */
CRYPT_INVALID_PRNG, /* Invalid PRNG specified */
CRYPT_MEM, /* Out of memory */
CRYPT_PK_TYPE_MISMATCH, /* Not equivalent types of PK keys */
CRYPT_PK_NOT_PRIVATE, /* Requires a private PK key */
CRYPT_INVALID_ARG, /* Generic invalid argument */
CRYPT_FILE_NOTFOUND, /* File Not Found */
CRYPT_PK_INVALID_TYPE, /* Invalid type of PK key */
CRYPT_OVERFLOW, /* An overflow of a value was detected/prevented */
CRYPT_UNUSED1, /* UNUSED1 */
CRYPT_INPUT_TOO_LONG, /* The input was longer than expected. */
CRYPT_PK_INVALID_SIZE, /* Invalid size input for PK parameters */
CRYPT_INVALID_PRIME_SIZE,/* Invalid size of prime requested */
CRYPT_PK_INVALID_PADDING, /* Invalid padding on input */
CRYPT_HASH_OVERFLOW /* Hash applied to too many bits */
};
#include <tomcrypt_cfg.h>
#include <tomcrypt_macros.h>
#include <tomcrypt_cipher.h>
#include <tomcrypt_hash.h>
#include <tomcrypt_mac.h>
#include <tomcrypt_prng.h>
#include <tomcrypt_pk.h>
#include <tomcrypt_math.h>
#include <tomcrypt_misc.h>
#include <tomcrypt_argchk.h>
#include <tomcrypt_pkcs.h>
#ifdef __cplusplus
}
#endif
#endif /* TOMCRYPT_H_ */
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View file

@ -0,0 +1,53 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/* Defines the LTC_ARGCHK macro used within the library */
/* ARGTYPE is defined in tomcrypt_cfg.h */
#if ARGTYPE == 0
#include <signal.h>
/* this is the default LibTomCrypt macro */
#if defined(__clang__) || defined(__GNUC_MINOR__)
#define NORETURN __attribute__ ((noreturn))
#else
#define NORETURN
#endif
void crypt_argchk(const char *v, const char *s, int d) NORETURN;
#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
#define LTC_ARGCHKVD(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0)
#elif ARGTYPE == 1
/* fatal type of error */
#define LTC_ARGCHK(x) assert((x))
#define LTC_ARGCHKVD(x) LTC_ARGCHK(x)
#elif ARGTYPE == 2
#define LTC_ARGCHK(x) if (!(x)) { fprintf(stderr, "\nwarning: ARGCHK failed at %s:%d\n", __FILE__, __LINE__); }
#define LTC_ARGCHKVD(x) LTC_ARGCHK(x)
#elif ARGTYPE == 3
#define LTC_ARGCHK(x)
#define LTC_ARGCHKVD(x) LTC_ARGCHK(x)
#elif ARGTYPE == 4
#define LTC_ARGCHK(x) if (!(x)) return CRYPT_INVALID_ARG;
#define LTC_ARGCHKVD(x) if (!(x)) return;
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View file

@ -0,0 +1,283 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/* This is the build config file.
*
* With this you can setup what to inlcude/exclude automatically during any build. Just comment
* out the line that #define's the word for the thing you want to remove. phew!
*/
#ifndef TOMCRYPT_CFG_H
#define TOMCRYPT_CFG_H
#if defined(_WIN32) || defined(_MSC_VER)
#define LTC_CALL __cdecl
#elif !defined(LTC_CALL)
#define LTC_CALL
#endif
#ifndef LTC_EXPORT
#define LTC_EXPORT
#endif
/* certain platforms use macros for these, making the prototypes broken */
#ifndef LTC_NO_PROTOTYPES
/* you can change how memory allocation works ... */
LTC_EXPORT void * LTC_CALL XMALLOC(size_t n);
LTC_EXPORT void * LTC_CALL XREALLOC(void *p, size_t n);
LTC_EXPORT void * LTC_CALL XCALLOC(size_t n, size_t s);
LTC_EXPORT void LTC_CALL XFREE(void *p);
LTC_EXPORT void LTC_CALL XQSORT(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *));
/* change the clock function too */
LTC_EXPORT clock_t LTC_CALL XCLOCK(void);
/* various other functions */
LTC_EXPORT void * LTC_CALL XMEMCPY(void *dest, const void *src, size_t n);
LTC_EXPORT int LTC_CALL XMEMCMP(const void *s1, const void *s2, size_t n);
LTC_EXPORT void * LTC_CALL XMEMSET(void *s, int c, size_t n);
LTC_EXPORT int LTC_CALL XSTRCMP(const char *s1, const char *s2);
#endif
/* some compilers do not like "inline" (or maybe "static inline"), namely: HP cc, IBM xlc */
#if defined(__HP_cc) || defined(__xlc__)
#define LTC_INLINE
#elif defined(_MSC_VER)
#define LTC_INLINE __inline
#else
#define LTC_INLINE inline
#endif
/* type of argument checking, 0=default, 1=fatal and 2=error+continue, 3=nothing */
#ifndef ARGTYPE
#define ARGTYPE 0
#endif
#undef LTC_ENCRYPT
#define LTC_ENCRYPT 0
#undef LTC_DECRYPT
#define LTC_DECRYPT 1
/* Controls endianess and size of registers. Leave uncommented to get platform neutral [slower] code
*
* Note: in order to use the optimized macros your platform must support unaligned 32 and 64 bit read/writes.
* The x86 platforms allow this but some others [ARM for instance] do not. On those platforms you **MUST**
* use the portable [slower] macros.
*/
/* detect x86/i386 32bit */
#if defined(__i386__) || defined(__i386) || defined(_M_IX86)
#define ENDIAN_LITTLE
#define ENDIAN_32BITWORD
#define LTC_FAST
#endif
/* detect amd64/x64 */
#if defined(__x86_64__) || defined(_M_X64) || defined(_M_AMD64)
#define ENDIAN_LITTLE
#define ENDIAN_64BITWORD
#define LTC_FAST
#endif
/* detect PPC32 */
#if defined(LTC_PPC32)
#define ENDIAN_BIG
#define ENDIAN_32BITWORD
#define LTC_FAST
#endif
/* detects MIPS R5900 processors (PS2) */
#if (defined(__R5900) || defined(R5900) || defined(__R5900__)) && (defined(_mips) || defined(__mips__) || defined(mips))
#define ENDIAN_64BITWORD
#if defined(_MIPSEB) || defined(__MIPSEB) || defined(__MIPSEB__)
#define ENDIAN_BIG
#endif
#define ENDIAN_LITTLE
#endif
#endif
/* detect AIX */
#if defined(_AIX) && defined(_BIG_ENDIAN)
#define ENDIAN_BIG
#if defined(__LP64__) || defined(_ARCH_PPC64)
#define ENDIAN_64BITWORD
#else
#define ENDIAN_32BITWORD
#endif
#endif
/* detect HP-UX */
#if defined(__hpux) || defined(__hpux__)
#define ENDIAN_BIG
#if defined(__ia64) || defined(__ia64__) || defined(__LP64__)
#define ENDIAN_64BITWORD
#else
#define ENDIAN_32BITWORD
#endif
#endif
/* detect Apple OS X */
#if defined(__APPLE__) && defined(__MACH__)
#if defined(__LITTLE_ENDIAN__) || defined(__x86_64__)
#define ENDIAN_LITTLE
#else
#define ENDIAN_BIG
#endif
#if defined(__LP64__) || defined(__x86_64__)
#define ENDIAN_64BITWORD
#else
#define ENDIAN_32BITWORD
#endif
#endif
/* detect SPARC and SPARC64 */
#if defined(__sparc__) || defined(__sparc)
#define ENDIAN_BIG
#if defined(__arch64__) || defined(__sparcv9) || defined(__sparc_v9__)
#define ENDIAN_64BITWORD
#else
#define ENDIAN_32BITWORD
#endif
#endif
/* detect IBM S390(x) */
#if defined(__s390x__) || defined(__s390__)
#define ENDIAN_BIG
#if defined(__s390x__)
#define ENDIAN_64BITWORD
#else
#define ENDIAN_32BITWORD
#endif
#endif
/* detect PPC64 */
#if defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__)
#define ENDIAN_64BITWORD
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
#define ENDIAN_BIG
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#define ENDIAN_LITTLE
#endif
#define LTC_FAST
#endif
/* endianness fallback */
#if !defined(ENDIAN_BIG) && !defined(ENDIAN_LITTLE)
#if defined(_BYTE_ORDER) && _BYTE_ORDER == _BIG_ENDIAN || \
defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN || \
defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ || \
defined(__BIG_ENDIAN__) || \
defined(__ARMEB__) || defined(__THUMBEB__) || defined(__AARCH64EB__) || \
defined(_MIPSEB) || defined(__MIPSEB) || defined(__MIPSEB__)
#define ENDIAN_BIG
#elif defined(_BYTE_ORDER) && _BYTE_ORDER == _LITTLE_ENDIAN || \
defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN || \
defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ || \
defined(__LITTLE_ENDIAN__) || \
defined(__ARMEL__) || defined(__THUMBEL__) || defined(__AARCH64EL__) || \
defined(_MIPSEL) || defined(__MIPSEL) || defined(__MIPSEL__)
#define ENDIAN_LITTLE
#else
#error Cannot detect endianness
#endif
#endif
/* ulong64: 64-bit data type */
#ifdef _MSC_VER
#define CONST64(n) n ## ui64
typedef unsigned __int64 ulong64;
#else
#define CONST64(n) n ## ULL
typedef unsigned long long ulong64;
#endif
/* ulong32: "32-bit at least" data type */
#if defined(__x86_64__) || defined(_M_X64) || defined(_M_AMD64) || \
defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__) || \
defined(__s390x__) || defined(__arch64__) || defined(__aarch64__) || \
defined(__sparcv9) || defined(__sparc_v9__) || defined(__sparc64__) || \
defined(__ia64) || defined(__ia64__) || defined(__itanium__) || defined(_M_IA64) || \
defined(__LP64__) || defined(_LP64) || defined(__64BIT__)
typedef unsigned ulong32;
#if !defined(ENDIAN_64BITWORD) && !defined(ENDIAN_32BITWORD)
#define ENDIAN_64BITWORD
#endif
#else
typedef unsigned long ulong32;
#if !defined(ENDIAN_64BITWORD) && !defined(ENDIAN_32BITWORD)
#define ENDIAN_32BITWORD
#endif
#endif
#if defined(ENDIAN_64BITWORD) && !defined(_MSC_VER)
typedef unsigned long long ltc_mp_digit;
#else
typedef unsigned long ltc_mp_digit;
#endif
/* No asm is a quick way to disable anything "not portable" */
#ifdef LTC_NO_ASM
#define ENDIAN_NEUTRAL
#undef ENDIAN_32BITWORD
#undef ENDIAN_64BITWORD
#undef LTC_FAST
#define LTC_NO_ROLC
#define LTC_NO_BSWAP
#endif
/* No LTC_FAST if: explicitly disabled OR non-gcc/non-clang compiler OR old gcc OR using -ansi -std=c99 */
#if defined(LTC_NO_FAST) || (__GNUC__ < 4) || defined(__STRICT_ANSI__)
#undef LTC_FAST
#endif
#ifdef LTC_FAST
#define LTC_FAST_TYPE_PTR_CAST(x) ((LTC_FAST_TYPE*)(void*)(x))
#ifdef ENDIAN_64BITWORD
typedef ulong64 __attribute__((__may_alias__)) LTC_FAST_TYPE;
#else
typedef ulong32 __attribute__((__may_alias__)) LTC_FAST_TYPE;
#endif
#endif
#if !defined(ENDIAN_NEUTRAL) && (defined(ENDIAN_BIG) || defined(ENDIAN_LITTLE)) && !(defined(ENDIAN_32BITWORD) || defined(ENDIAN_64BITWORD))
#error You must specify a word size as well as endianess in tomcrypt_cfg.h
#endif
#if !(defined(ENDIAN_BIG) || defined(ENDIAN_LITTLE))
#define ENDIAN_NEUTRAL
#endif
#if (defined(ENDIAN_32BITWORD) && defined(ENDIAN_64BITWORD))
#error Cannot be 32 and 64 bit words...
#endif
/* gcc 4.3 and up has a bswap builtin; detect it by gcc version.
* clang also supports the bswap builtin, and although clang pretends
* to be gcc (macro-wise, anyway), clang pretends to be a version
* prior to gcc 4.3, so we can't detect bswap that way. Instead,
* clang has a __has_builtin mechanism that can be used to check
* for builtins:
* http://clang.llvm.org/docs/LanguageExtensions.html#feature_check */
#ifndef __has_builtin
#define __has_builtin(x) 0
#endif
#if !defined(LTC_NO_BSWAP) && defined(__GNUC__) && \
((__GNUC__ * 100 + __GNUC_MINOR__ >= 403) || \
(__has_builtin(__builtin_bswap32) && __has_builtin(__builtin_bswap64)))
#define LTC_HAVE_BSWAP_BUILTIN
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,590 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#ifndef TOMCRYPT_CUSTOM_H_
#define TOMCRYPT_CUSTOM_H_
/* macros for various libc functions you can change for embedded targets */
#ifndef XMALLOC
#define XMALLOC malloc
#endif
#ifndef XREALLOC
#define XREALLOC realloc
#endif
#ifndef XCALLOC
#define XCALLOC calloc
#endif
#ifndef XFREE
#define XFREE free
#endif
#ifndef XMEMSET
#define XMEMSET memset
#endif
#ifndef XMEMCPY
#define XMEMCPY memcpy
#endif
#ifndef XMEMMOVE
#define XMEMMOVE memmove
#endif
#ifndef XMEMCMP
#define XMEMCMP memcmp
#endif
/* A memory compare function that has to run in constant time,
* c.f. mem_neq() API summary.
*/
#ifndef XMEM_NEQ
#define XMEM_NEQ mem_neq
#endif
#ifndef XSTRCMP
#define XSTRCMP strcmp
#endif
#ifndef XCLOCK
#define XCLOCK clock
#endif
#ifndef XQSORT
#define XQSORT qsort
#endif
#if ( defined(malloc) || defined(realloc) || defined(calloc) || defined(free) || \
defined(memset) || defined(memcpy) || defined(memcmp) || defined(strcmp) || \
defined(clock) || defined(qsort) ) && !defined(LTC_NO_PROTOTYPES)
#define LTC_NO_PROTOTYPES
#endif
/* shortcut to disable automatic inclusion */
#if defined LTC_NOTHING && !defined LTC_EASY
#define LTC_NO_CIPHERS
#define LTC_NO_MODES
#define LTC_NO_HASHES
#define LTC_NO_MACS
#define LTC_NO_PRNGS
#define LTC_NO_PK
#define LTC_NO_PKCS
#define LTC_NO_MISC
#endif /* LTC_NOTHING */
/* Easy button? */
#ifdef LTC_EASY
#define LTC_NO_CIPHERS
#define LTC_RIJNDAEL
#define LTC_BLOWFISH
#define LTC_DES
#define LTC_CAST5
#define LTC_NO_MODES
#define LTC_ECB_MODE
#define LTC_CBC_MODE
#define LTC_CTR_MODE
#define LTC_NO_HASHES
#define LTC_SHA1
#define LTC_SHA3
#define LTC_SHA512
#define LTC_SHA384
#define LTC_SHA256
#define LTC_SHA224
#define LTC_HASH_HELPERS
#define LTC_NO_MACS
#define LTC_HMAC
#define LTC_OMAC
#define LTC_CCM_MODE
#define LTC_NO_PRNGS
#define LTC_SPRNG
#define LTC_YARROW
#define LTC_DEVRANDOM
#define LTC_TRY_URANDOM_FIRST
#define LTC_RNG_GET_BYTES
#define LTC_RNG_MAKE_PRNG
#define LTC_NO_PK
#define LTC_MRSA
#define LTC_MECC
#define LTC_NO_MISC
#define LTC_BASE64
#endif
/* The minimal set of functionality to run the tests */
#ifdef LTC_MINIMAL
#define LTC_RIJNDAEL
#define LTC_SHA256
#define LTC_YARROW
#define LTC_CTR_MODE
#define LTC_RNG_MAKE_PRNG
#define LTC_RNG_GET_BYTES
#define LTC_DEVRANDOM
#define LTC_TRY_URANDOM_FIRST
#undef LTC_NO_FILE
#endif
/* Enable self-test test vector checking */
#ifndef LTC_NO_TEST
#define LTC_TEST
#endif
/* Enable extended self-tests */
/* #define LTC_TEST_EXT */
/* Use small code where possible */
/* #define LTC_SMALL_CODE */
/* clean the stack of functions which put private information on stack */
/* #define LTC_CLEAN_STACK */
/* disable all file related functions */
/* #define LTC_NO_FILE */
/* disable all forms of ASM */
/* #define LTC_NO_ASM */
/* disable FAST mode */
/* #define LTC_NO_FAST */
/* disable BSWAP on x86 */
/* #define LTC_NO_BSWAP */
/* ---> math provider? <--- */
#ifndef LTC_NO_MATH
/* LibTomMath */
/* #define LTM_DESC */
/* TomsFastMath */
/* #define TFM_DESC */
/* GNU Multiple Precision Arithmetic Library */
/* #define GMP_DESC */
#endif /* LTC_NO_MATH */
/* ---> Symmetric Block Ciphers <--- */
#ifndef LTC_NO_CIPHERS
#define LTC_BLOWFISH
#define LTC_RC2
#define LTC_RC5
#define LTC_RC6
#define LTC_SAFERP
#define LTC_RIJNDAEL
#define LTC_XTEA
/* _TABLES tells it to use tables during setup, _SMALL means to use the smaller scheduled key format
* (saves 4KB of ram), _ALL_TABLES enables all tables during setup */
#define LTC_TWOFISH
#ifndef LTC_NO_TABLES
#define LTC_TWOFISH_TABLES
/* #define LTC_TWOFISH_ALL_TABLES */
#else
#define LTC_TWOFISH_SMALL
#endif
/* #define LTC_TWOFISH_SMALL */
/* LTC_DES includes EDE triple-DES */
#define LTC_DES
#define LTC_CAST5
#define LTC_NOEKEON
#define LTC_SKIPJACK
#define LTC_SAFER
#define LTC_KHAZAD
#define LTC_ANUBIS
#define LTC_ANUBIS_TWEAK
#define LTC_KSEED
#define LTC_KASUMI
#define LTC_MULTI2
#define LTC_CAMELLIA
/* stream ciphers */
#define LTC_CHACHA
#define LTC_RC4_STREAM
#define LTC_SOBER128_STREAM
#endif /* LTC_NO_CIPHERS */
/* ---> Block Cipher Modes of Operation <--- */
#ifndef LTC_NO_MODES
#define LTC_CFB_MODE
#define LTC_OFB_MODE
#define LTC_ECB_MODE
#define LTC_CBC_MODE
#define LTC_CTR_MODE
/* F8 chaining mode */
#define LTC_F8_MODE
/* LRW mode */
#define LTC_LRW_MODE
#ifndef LTC_NO_TABLES
/* like GCM mode this will enable 16 8x128 tables [64KB] that make
* seeking very fast.
*/
#define LTC_LRW_TABLES
#endif
/* XTS mode */
#define LTC_XTS_MODE
#endif /* LTC_NO_MODES */
/* ---> One-Way Hash Functions <--- */
#ifndef LTC_NO_HASHES
#define LTC_CHC_HASH
#define LTC_WHIRLPOOL
#define LTC_SHA3
#define LTC_SHA512
#define LTC_SHA512_256
#define LTC_SHA512_224
#define LTC_SHA384
#define LTC_SHA256
#define LTC_SHA224
#define LTC_TIGER
#define LTC_SHA1
#define LTC_MD5
#define LTC_MD4
#define LTC_MD2
#define LTC_RIPEMD128
#define LTC_RIPEMD160
#define LTC_RIPEMD256
#define LTC_RIPEMD320
#define LTC_BLAKE2S
#define LTC_BLAKE2B
#define LTC_HASH_HELPERS
#endif /* LTC_NO_HASHES */
/* ---> MAC functions <--- */
#ifndef LTC_NO_MACS
#define LTC_HMAC
#define LTC_OMAC
#define LTC_PMAC
#define LTC_XCBC
#define LTC_F9_MODE
#define LTC_PELICAN
#define LTC_POLY1305
#define LTC_BLAKE2SMAC
#define LTC_BLAKE2BMAC
/* ---> Encrypt + Authenticate Modes <--- */
#define LTC_EAX_MODE
#define LTC_OCB_MODE
#define LTC_OCB3_MODE
#define LTC_CCM_MODE
#define LTC_GCM_MODE
#define LTC_CHACHA20POLY1305_MODE
/* Use 64KiB tables */
#ifndef LTC_NO_TABLES
#define LTC_GCM_TABLES
#endif
/* USE SSE2? requires GCC works on x86_32 and x86_64*/
#ifdef LTC_GCM_TABLES
/* #define LTC_GCM_TABLES_SSE2 */
#endif
#endif /* LTC_NO_MACS */
/* --> Pseudo Random Number Generators <--- */
#ifndef LTC_NO_PRNGS
/* Yarrow */
#define LTC_YARROW
/* a PRNG that simply reads from an available system source */
#define LTC_SPRNG
/* The RC4 stream cipher based PRNG */
#define LTC_RC4
/* The ChaCha20 stream cipher based PRNG */
#define LTC_CHACHA20_PRNG
/* Fortuna PRNG */
#define LTC_FORTUNA
/* Greg's SOBER128 stream cipher based PRNG */
#define LTC_SOBER128
/* the *nix style /dev/random device */
#define LTC_DEVRANDOM
/* try /dev/urandom before trying /dev/random
* are you sure you want to disable this? http://www.2uo.de/myths-about-urandom/ */
#define LTC_TRY_URANDOM_FIRST
/* rng_get_bytes() */
#define LTC_RNG_GET_BYTES
/* rng_make_prng() */
#define LTC_RNG_MAKE_PRNG
/* enable the ltc_rng hook to integrate e.g. embedded hardware RNG's easily */
/* #define LTC_PRNG_ENABLE_LTC_RNG */
#endif /* LTC_NO_PRNGS */
#ifdef LTC_YARROW
/* which descriptor of AES to use? */
/* 0 = rijndael_enc 1 = aes_enc, 2 = rijndael [full], 3 = aes [full] */
#ifdef ENCRYPT_ONLY
#define LTC_YARROW_AES 0
#else
#define LTC_YARROW_AES 2
#endif
#endif
#ifdef LTC_FORTUNA
#ifndef LTC_FORTUNA_WD
/* reseed every N calls to the read function */
#define LTC_FORTUNA_WD 10
#endif
#ifndef LTC_FORTUNA_POOLS
/* number of pools (4..32) can save a bit of ram by lowering the count */
#define LTC_FORTUNA_POOLS 32
#endif
#endif /* LTC_FORTUNA */
/* ---> Public Key Crypto <--- */
#ifndef LTC_NO_PK
/* Include RSA support */
#define LTC_MRSA
/* Include Diffie-Hellman support */
/* is_prime fails for GMP */
#define LTC_MDH
/* Supported Key Sizes */
#define LTC_DH768
#define LTC_DH1024
#define LTC_DH1536
#define LTC_DH2048
#ifndef TFM_DESC
/* tfm has a problem in fp_isprime for larger key sizes */
#define LTC_DH3072
#define LTC_DH4096
#define LTC_DH6144
#define LTC_DH8192
#endif
/* Include Katja (a Rabin variant like RSA) */
/* #define LTC_MKAT */
/* Digital Signature Algorithm */
#define LTC_MDSA
/* ECC */
#define LTC_MECC
/* use Shamir's trick for point mul (speeds up signature verification) */
#define LTC_ECC_SHAMIR
#if defined(TFM_DESC) && defined(LTC_MECC)
#define LTC_MECC_ACCEL
#endif
/* do we want fixed point ECC */
/* #define LTC_MECC_FP */
#endif /* LTC_NO_PK */
#if defined(LTC_MRSA) && !defined(LTC_NO_RSA_BLINDING)
/* Enable RSA blinding when doing private key operations by default */
#define LTC_RSA_BLINDING
#endif /* LTC_NO_RSA_BLINDING */
#if defined(LTC_MRSA) && !defined(LTC_NO_RSA_CRT_HARDENING)
/* Enable RSA CRT hardening when doing private key operations by default */
#define LTC_RSA_CRT_HARDENING
#endif /* LTC_NO_RSA_CRT_HARDENING */
#if defined(LTC_MECC) && !defined(LTC_NO_ECC_TIMING_RESISTANT)
/* Enable ECC timing resistant version by default */
#define LTC_ECC_TIMING_RESISTANT
#endif
/* PKCS #1 (RSA) and #5 (Password Handling) stuff */
#ifndef LTC_NO_PKCS
#define LTC_PKCS_1
#define LTC_PKCS_5
/* Include ASN.1 DER (required by DSA/RSA) */
#define LTC_DER
#endif /* LTC_NO_PKCS */
/* misc stuff */
#ifndef LTC_NO_MISC
/* Various tidbits of modern neatoness */
#define LTC_BASE64
/* ... and it's URL safe version */
#define LTC_BASE64_URL
/* Keep LTC_NO_HKDF for compatibility reasons
* superseeded by LTC_NO_MISC*/
#ifndef LTC_NO_HKDF
/* HKDF Key Derivation/Expansion stuff */
#define LTC_HKDF
#endif /* LTC_NO_HKDF */
#define LTC_ADLER32
#define LTC_CRC32
#endif /* LTC_NO_MISC */
/* cleanup */
#ifdef LTC_MECC
/* Supported ECC Key Sizes */
#ifndef LTC_NO_CURVES
#define LTC_ECC112
#define LTC_ECC128
#define LTC_ECC160
#define LTC_ECC192
#define LTC_ECC224
#define LTC_ECC256
#define LTC_ECC384
#define LTC_ECC521
#endif
#endif
#if defined(LTC_DER)
#ifndef LTC_DER_MAX_RECURSION
/* Maximum recursion limit when processing nested ASN.1 types. */
#define LTC_DER_MAX_RECURSION 30
#endif
#endif
#if defined(LTC_MECC) || defined(LTC_MRSA) || defined(LTC_MDSA) || defined(LTC_MKAT)
/* Include the MPI functionality? (required by the PK algorithms) */
#define LTC_MPI
#ifndef LTC_PK_MAX_RETRIES
/* iterations limit for retry-loops */
#define LTC_PK_MAX_RETRIES 20
#endif
#endif
#ifdef LTC_MRSA
#define LTC_PKCS_1
#endif
#if defined(LTC_PELICAN) && !defined(LTC_RIJNDAEL)
#error Pelican-MAC requires LTC_RIJNDAEL
#endif
#if defined(LTC_EAX_MODE) && !(defined(LTC_CTR_MODE) && defined(LTC_OMAC))
#error LTC_EAX_MODE requires CTR and LTC_OMAC mode
#endif
#if defined(LTC_YARROW) && !defined(LTC_CTR_MODE)
#error LTC_YARROW requires LTC_CTR_MODE chaining mode to be defined!
#endif
#if defined(LTC_DER) && !defined(LTC_MPI)
#error ASN.1 DER requires MPI functionality
#endif
#if (defined(LTC_MDSA) || defined(LTC_MRSA) || defined(LTC_MECC) || defined(LTC_MKAT)) && !defined(LTC_DER)
#error PK requires ASN.1 DER functionality, make sure LTC_DER is enabled
#endif
#if defined(LTC_CHACHA20POLY1305_MODE) && (!defined(LTC_CHACHA) || !defined(LTC_POLY1305))
#error LTC_CHACHA20POLY1305_MODE requires LTC_CHACHA + LTC_POLY1305
#endif
#if defined(LTC_CHACHA20_PRNG) && !defined(LTC_CHACHA)
#error LTC_CHACHA20_PRNG requires LTC_CHACHA
#endif
#if defined(LTC_RC4) && !defined(LTC_RC4_STREAM)
#error LTC_RC4 requires LTC_RC4_STREAM
#endif
#if defined(LTC_SOBER128) && !defined(LTC_SOBER128_STREAM)
#error LTC_SOBER128 requires LTC_SOBER128_STREAM
#endif
#if defined(LTC_BLAKE2SMAC) && !defined(LTC_BLAKE2S)
#error LTC_BLAKE2SMAC requires LTC_BLAKE2S
#endif
#if defined(LTC_BLAKE2BMAC) && !defined(LTC_BLAKE2B)
#error LTC_BLAKE2BMAC requires LTC_BLAKE2B
#endif
#if defined(LTC_SPRNG) && !defined(LTC_RNG_GET_BYTES)
#error LTC_SPRNG requires LTC_RNG_GET_BYTES
#endif
#if defined(LTC_NO_MATH) && (defined(LTM_DESC) || defined(TFM_DESC) || defined(GMP_DESC))
#error LTC_NO_MATH defined, but also a math descriptor
#endif
/* THREAD management */
#ifdef LTC_PTHREAD
#include <pthread.h>
#define LTC_MUTEX_GLOBAL(x) pthread_mutex_t x = PTHREAD_MUTEX_INITIALIZER;
#define LTC_MUTEX_PROTO(x) extern pthread_mutex_t x;
#define LTC_MUTEX_TYPE(x) pthread_mutex_t x;
#define LTC_MUTEX_INIT(x) LTC_ARGCHK(pthread_mutex_init(x, NULL) == 0);
#define LTC_MUTEX_LOCK(x) LTC_ARGCHK(pthread_mutex_lock(x) == 0);
#define LTC_MUTEX_UNLOCK(x) LTC_ARGCHK(pthread_mutex_unlock(x) == 0);
#define LTC_MUTEX_DESTROY(x) LTC_ARGCHK(pthread_mutex_destroy(x) == 0);
#else
/* default no functions */
#define LTC_MUTEX_GLOBAL(x)
#define LTC_MUTEX_PROTO(x)
#define LTC_MUTEX_TYPE(x)
#define LTC_MUTEX_INIT(x)
#define LTC_MUTEX_LOCK(x)
#define LTC_MUTEX_UNLOCK(x)
#define LTC_MUTEX_DESTROY(x)
#endif
/* Debuggers */
/* define this if you use Valgrind, note: it CHANGES the way SOBER-128 and RC4 work (see the code) */
/* #define LTC_VALGRIND */
#endif
#ifndef LTC_NO_FILE
/* buffer size for reading from a file via fread(..) */
#ifndef LTC_FILE_READ_BUFSIZE
#define LTC_FILE_READ_BUFSIZE 8192
#endif
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View file

@ -0,0 +1,531 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/* ---- HASH FUNCTIONS ---- */
#ifdef LTC_SHA3
struct sha3_state {
ulong64 saved; /* the portion of the input message that we didn't consume yet */
ulong64 s[25];
unsigned char sb[25 * 8]; /* used for storing `ulong64 s[25]` as little-endian bytes */
unsigned short byte_index; /* 0..7--the next byte after the set one (starts from 0; 0--none are buffered) */
unsigned short word_index; /* 0..24--the next word to integrate input (starts from 0) */
unsigned short capacity_words; /* the double size of the hash output in words (e.g. 16 for Keccak 512) */
unsigned short xof_flag;
};
#endif
#ifdef LTC_SHA512
struct sha512_state {
ulong64 length, state[8];
unsigned long curlen;
unsigned char buf[128];
};
#endif
#ifdef LTC_SHA256
struct sha256_state {
ulong64 length;
ulong32 state[8], curlen;
unsigned char buf[64];
};
#endif
#ifdef LTC_SHA1
struct sha1_state {
ulong64 length;
ulong32 state[5], curlen;
unsigned char buf[64];
};
#endif
#ifdef LTC_MD5
struct md5_state {
ulong64 length;
ulong32 state[4], curlen;
unsigned char buf[64];
};
#endif
#ifdef LTC_MD4
struct md4_state {
ulong64 length;
ulong32 state[4], curlen;
unsigned char buf[64];
};
#endif
#ifdef LTC_TIGER
struct tiger_state {
ulong64 state[3], length;
unsigned long curlen;
unsigned char buf[64];
};
#endif
#ifdef LTC_MD2
struct md2_state {
unsigned char chksum[16], X[48], buf[16];
unsigned long curlen;
};
#endif
#ifdef LTC_RIPEMD128
struct rmd128_state {
ulong64 length;
unsigned char buf[64];
ulong32 curlen, state[4];
};
#endif
#ifdef LTC_RIPEMD160
struct rmd160_state {
ulong64 length;
unsigned char buf[64];
ulong32 curlen, state[5];
};
#endif
#ifdef LTC_RIPEMD256
struct rmd256_state {
ulong64 length;
unsigned char buf[64];
ulong32 curlen, state[8];
};
#endif
#ifdef LTC_RIPEMD320
struct rmd320_state {
ulong64 length;
unsigned char buf[64];
ulong32 curlen, state[10];
};
#endif
#ifdef LTC_WHIRLPOOL
struct whirlpool_state {
ulong64 length, state[8];
unsigned char buf[64];
ulong32 curlen;
};
#endif
#ifdef LTC_CHC_HASH
struct chc_state {
ulong64 length;
unsigned char state[MAXBLOCKSIZE], buf[MAXBLOCKSIZE];
ulong32 curlen;
};
#endif
#ifdef LTC_BLAKE2S
struct blake2s_state {
ulong32 h[8];
ulong32 t[2];
ulong32 f[2];
unsigned char buf[64];
unsigned long curlen;
unsigned long outlen;
unsigned char last_node;
};
#endif
#ifdef LTC_BLAKE2B
struct blake2b_state {
ulong64 h[8];
ulong64 t[2];
ulong64 f[2];
unsigned char buf[128];
unsigned long curlen;
unsigned long outlen;
unsigned char last_node;
};
#endif
typedef union Hash_state {
char dummy[1];
#ifdef LTC_CHC_HASH
struct chc_state chc;
#endif
#ifdef LTC_WHIRLPOOL
struct whirlpool_state whirlpool;
#endif
#ifdef LTC_SHA3
struct sha3_state sha3;
#endif
#ifdef LTC_SHA512
struct sha512_state sha512;
#endif
#ifdef LTC_SHA256
struct sha256_state sha256;
#endif
#ifdef LTC_SHA1
struct sha1_state sha1;
#endif
#ifdef LTC_MD5
struct md5_state md5;
#endif
#ifdef LTC_MD4
struct md4_state md4;
#endif
#ifdef LTC_MD2
struct md2_state md2;
#endif
#ifdef LTC_TIGER
struct tiger_state tiger;
#endif
#ifdef LTC_RIPEMD128
struct rmd128_state rmd128;
#endif
#ifdef LTC_RIPEMD160
struct rmd160_state rmd160;
#endif
#ifdef LTC_RIPEMD256
struct rmd256_state rmd256;
#endif
#ifdef LTC_RIPEMD320
struct rmd320_state rmd320;
#endif
#ifdef LTC_BLAKE2S
struct blake2s_state blake2s;
#endif
#ifdef LTC_BLAKE2B
struct blake2b_state blake2b;
#endif
void *data;
} hash_state;
/** hash descriptor */
extern struct ltc_hash_descriptor {
/** name of hash */
const char *name;
/** internal ID */
unsigned char ID;
/** Size of digest in octets */
unsigned long hashsize;
/** Input block size in octets */
unsigned long blocksize;
/** ASN.1 OID */
unsigned long OID[16];
/** Length of DER encoding */
unsigned long OIDlen;
/** Init a hash state
@param hash The hash to initialize
@return CRYPT_OK if successful
*/
int (*init)(hash_state *hash);
/** Process a block of data
@param hash The hash state
@param in The data to hash
@param inlen The length of the data (octets)
@return CRYPT_OK if successful
*/
int (*process)(hash_state *hash, const unsigned char *in, unsigned long inlen);
/** Produce the digest and store it
@param hash The hash state
@param out [out] The destination of the digest
@return CRYPT_OK if successful
*/
int (*done)(hash_state *hash, unsigned char *out);
/** Self-test
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int (*test)(void);
/* accelerated hmac callback: if you need to-do multiple packets just use the generic hmac_memory and provide a hash callback */
int (*hmac_block)(const unsigned char *key, unsigned long keylen,
const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
} hash_descriptor[];
#ifdef LTC_CHC_HASH
int chc_register(int cipher);
int chc_init(hash_state * md);
int chc_process(hash_state * md, const unsigned char *in, unsigned long inlen);
int chc_done(hash_state * md, unsigned char *hash);
int chc_test(void);
extern const struct ltc_hash_descriptor chc_desc;
#endif
#ifdef LTC_WHIRLPOOL
int whirlpool_init(hash_state * md);
int whirlpool_process(hash_state * md, const unsigned char *in, unsigned long inlen);
int whirlpool_done(hash_state * md, unsigned char *hash);
int whirlpool_test(void);
extern const struct ltc_hash_descriptor whirlpool_desc;
#endif
#ifdef LTC_SHA3
int sha3_512_init(hash_state * md);
int sha3_512_test(void);
extern const struct ltc_hash_descriptor sha3_512_desc;
int sha3_384_init(hash_state * md);
int sha3_384_test(void);
extern const struct ltc_hash_descriptor sha3_384_desc;
int sha3_256_init(hash_state * md);
int sha3_256_test(void);
extern const struct ltc_hash_descriptor sha3_256_desc;
int sha3_224_init(hash_state * md);
int sha3_224_test(void);
extern const struct ltc_hash_descriptor sha3_224_desc;
/* process + done are the same for all variants */
int sha3_process(hash_state * md, const unsigned char *in, unsigned long inlen);
int sha3_done(hash_state *md, unsigned char *hash);
/* SHAKE128 + SHAKE256 */
int sha3_shake_init(hash_state *md, int num);
#define sha3_shake_process(a,b,c) sha3_process(a,b,c)
int sha3_shake_done(hash_state *md, unsigned char *out, unsigned long outlen);
int sha3_shake_test(void);
int sha3_shake_memory(int num, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen);
#endif
#ifdef LTC_SHA512
int sha512_init(hash_state * md);
int sha512_process(hash_state * md, const unsigned char *in, unsigned long inlen);
int sha512_done(hash_state * md, unsigned char *hash);
int sha512_test(void);
extern const struct ltc_hash_descriptor sha512_desc;
#endif
#ifdef LTC_SHA384
#ifndef LTC_SHA512
#error LTC_SHA512 is required for LTC_SHA384
#endif
int sha384_init(hash_state * md);
#define sha384_process sha512_process
int sha384_done(hash_state * md, unsigned char *hash);
int sha384_test(void);
extern const struct ltc_hash_descriptor sha384_desc;
#endif
#ifdef LTC_SHA512_256
#ifndef LTC_SHA512
#error LTC_SHA512 is required for LTC_SHA512_256
#endif
int sha512_256_init(hash_state * md);
#define sha512_256_process sha512_process
int sha512_256_done(hash_state * md, unsigned char *hash);
int sha512_256_test(void);
extern const struct ltc_hash_descriptor sha512_256_desc;
#endif
#ifdef LTC_SHA512_224
#ifndef LTC_SHA512
#error LTC_SHA512 is required for LTC_SHA512_224
#endif
int sha512_224_init(hash_state * md);
#define sha512_224_process sha512_process
int sha512_224_done(hash_state * md, unsigned char *hash);
int sha512_224_test(void);
extern const struct ltc_hash_descriptor sha512_224_desc;
#endif
#ifdef LTC_SHA256
int sha256_init(hash_state * md);
int sha256_process(hash_state * md, const unsigned char *in, unsigned long inlen);
int sha256_done(hash_state * md, unsigned char *hash);
int sha256_test(void);
extern const struct ltc_hash_descriptor sha256_desc;
#ifdef LTC_SHA224
#ifndef LTC_SHA256
#error LTC_SHA256 is required for LTC_SHA224
#endif
int sha224_init(hash_state * md);
#define sha224_process sha256_process
int sha224_done(hash_state * md, unsigned char *hash);
int sha224_test(void);
extern const struct ltc_hash_descriptor sha224_desc;
#endif
#endif
#ifdef LTC_SHA1
int sha1_init(hash_state * md);
int sha1_process(hash_state * md, const unsigned char *in, unsigned long inlen);
int sha1_done(hash_state * md, unsigned char *hash);
int sha1_test(void);
extern const struct ltc_hash_descriptor sha1_desc;
#endif
#ifdef LTC_BLAKE2S
extern const struct ltc_hash_descriptor blake2s_256_desc;
int blake2s_256_init(hash_state * md);
int blake2s_256_test(void);
extern const struct ltc_hash_descriptor blake2s_224_desc;
int blake2s_224_init(hash_state * md);
int blake2s_224_test(void);
extern const struct ltc_hash_descriptor blake2s_160_desc;
int blake2s_160_init(hash_state * md);
int blake2s_160_test(void);
extern const struct ltc_hash_descriptor blake2s_128_desc;
int blake2s_128_init(hash_state * md);
int blake2s_128_test(void);
int blake2s_init(hash_state * md, unsigned long outlen, const unsigned char *key, unsigned long keylen);
int blake2s_process(hash_state * md, const unsigned char *in, unsigned long inlen);
int blake2s_done(hash_state * md, unsigned char *hash);
#endif
#ifdef LTC_BLAKE2B
extern const struct ltc_hash_descriptor blake2b_512_desc;
int blake2b_512_init(hash_state * md);
int blake2b_512_test(void);
extern const struct ltc_hash_descriptor blake2b_384_desc;
int blake2b_384_init(hash_state * md);
int blake2b_384_test(void);
extern const struct ltc_hash_descriptor blake2b_256_desc;
int blake2b_256_init(hash_state * md);
int blake2b_256_test(void);
extern const struct ltc_hash_descriptor blake2b_160_desc;
int blake2b_160_init(hash_state * md);
int blake2b_160_test(void);
int blake2b_init(hash_state * md, unsigned long outlen, const unsigned char *key, unsigned long keylen);
int blake2b_process(hash_state * md, const unsigned char *in, unsigned long inlen);
int blake2b_done(hash_state * md, unsigned char *hash);
#endif
#ifdef LTC_MD5
int md5_init(hash_state * md);
int md5_process(hash_state * md, const unsigned char *in, unsigned long inlen);
int md5_done(hash_state * md, unsigned char *hash);
int md5_test(void);
extern const struct ltc_hash_descriptor md5_desc;
#endif
#ifdef LTC_MD4
int md4_init(hash_state * md);
int md4_process(hash_state * md, const unsigned char *in, unsigned long inlen);
int md4_done(hash_state * md, unsigned char *hash);
int md4_test(void);
extern const struct ltc_hash_descriptor md4_desc;
#endif
#ifdef LTC_MD2
int md2_init(hash_state * md);
int md2_process(hash_state * md, const unsigned char *in, unsigned long inlen);
int md2_done(hash_state * md, unsigned char *hash);
int md2_test(void);
extern const struct ltc_hash_descriptor md2_desc;
#endif
#ifdef LTC_TIGER
int tiger_init(hash_state * md);
int tiger_process(hash_state * md, const unsigned char *in, unsigned long inlen);
int tiger_done(hash_state * md, unsigned char *hash);
int tiger_test(void);
extern const struct ltc_hash_descriptor tiger_desc;
#endif
#ifdef LTC_RIPEMD128
int rmd128_init(hash_state * md);
int rmd128_process(hash_state * md, const unsigned char *in, unsigned long inlen);
int rmd128_done(hash_state * md, unsigned char *hash);
int rmd128_test(void);
extern const struct ltc_hash_descriptor rmd128_desc;
#endif
#ifdef LTC_RIPEMD160
int rmd160_init(hash_state * md);
int rmd160_process(hash_state * md, const unsigned char *in, unsigned long inlen);
int rmd160_done(hash_state * md, unsigned char *hash);
int rmd160_test(void);
extern const struct ltc_hash_descriptor rmd160_desc;
#endif
#ifdef LTC_RIPEMD256
int rmd256_init(hash_state * md);
int rmd256_process(hash_state * md, const unsigned char *in, unsigned long inlen);
int rmd256_done(hash_state * md, unsigned char *hash);
int rmd256_test(void);
extern const struct ltc_hash_descriptor rmd256_desc;
#endif
#ifdef LTC_RIPEMD320
int rmd320_init(hash_state * md);
int rmd320_process(hash_state * md, const unsigned char *in, unsigned long inlen);
int rmd320_done(hash_state * md, unsigned char *hash);
int rmd320_test(void);
extern const struct ltc_hash_descriptor rmd320_desc;
#endif
int find_hash(const char *name);
int find_hash_id(unsigned char ID);
int find_hash_oid(const unsigned long *ID, unsigned long IDlen);
int find_hash_any(const char *name, int digestlen);
int register_hash(const struct ltc_hash_descriptor *hash);
int unregister_hash(const struct ltc_hash_descriptor *hash);
int register_all_hashes(void);
int hash_is_valid(int idx);
LTC_MUTEX_PROTO(ltc_hash_mutex)
int hash_memory(int hash,
const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
int hash_memory_multi(int hash, unsigned char *out, unsigned long *outlen,
const unsigned char *in, unsigned long inlen, ...);
#ifndef LTC_NO_FILE
int hash_filehandle(int hash, FILE *in, unsigned char *out, unsigned long *outlen);
int hash_file(int hash, const char *fname, unsigned char *out, unsigned long *outlen);
#endif
/* a simple macro for making hash "process" functions */
#define HASH_PROCESS(func_name, compress_name, state_var, block_size) \
int func_name (hash_state * md, const unsigned char *in, unsigned long inlen) \
{ \
unsigned long n; \
int err; \
LTC_ARGCHK(md != NULL); \
LTC_ARGCHK(in != NULL); \
if (md-> state_var .curlen > sizeof(md-> state_var .buf)) { \
return CRYPT_INVALID_ARG; \
} \
if ((md-> state_var .length + inlen) < md-> state_var .length) { \
return CRYPT_HASH_OVERFLOW; \
} \
while (inlen > 0) { \
if (md-> state_var .curlen == 0 && inlen >= block_size) { \
if ((err = compress_name (md, (unsigned char *)in)) != CRYPT_OK) { \
return err; \
} \
md-> state_var .length += block_size * 8; \
in += block_size; \
inlen -= block_size; \
} else { \
n = MIN(inlen, (block_size - md-> state_var .curlen)); \
XMEMCPY(md-> state_var .buf + md-> state_var.curlen, in, (size_t)n); \
md-> state_var .curlen += n; \
in += n; \
inlen -= n; \
if (md-> state_var .curlen == block_size) { \
if ((err = compress_name (md, md-> state_var .buf)) != CRYPT_OK) { \
return err; \
} \
md-> state_var .length += 8*block_size; \
md-> state_var .curlen = 0; \
} \
} \
} \
return CRYPT_OK; \
}
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View file

@ -0,0 +1,565 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#ifdef LTC_HMAC
typedef struct Hmac_state {
hash_state md;
int hash;
hash_state hashstate;
unsigned char *key;
} hmac_state;
int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned long keylen);
int hmac_process(hmac_state *hmac, const unsigned char *in, unsigned long inlen);
int hmac_done(hmac_state *hmac, unsigned char *out, unsigned long *outlen);
int hmac_test(void);
int hmac_memory(int hash,
const unsigned char *key, unsigned long keylen,
const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
int hmac_memory_multi(int hash,
const unsigned char *key, unsigned long keylen,
unsigned char *out, unsigned long *outlen,
const unsigned char *in, unsigned long inlen, ...);
int hmac_file(int hash, const char *fname, const unsigned char *key,
unsigned long keylen,
unsigned char *dst, unsigned long *dstlen);
#endif
#ifdef LTC_OMAC
typedef struct {
int cipher_idx,
buflen,
blklen;
unsigned char block[MAXBLOCKSIZE],
prev[MAXBLOCKSIZE],
Lu[2][MAXBLOCKSIZE];
symmetric_key key;
} omac_state;
int omac_init(omac_state *omac, int cipher, const unsigned char *key, unsigned long keylen);
int omac_process(omac_state *omac, const unsigned char *in, unsigned long inlen);
int omac_done(omac_state *omac, unsigned char *out, unsigned long *outlen);
int omac_memory(int cipher,
const unsigned char *key, unsigned long keylen,
const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
int omac_memory_multi(int cipher,
const unsigned char *key, unsigned long keylen,
unsigned char *out, unsigned long *outlen,
const unsigned char *in, unsigned long inlen, ...);
int omac_file(int cipher,
const unsigned char *key, unsigned long keylen,
const char *filename,
unsigned char *out, unsigned long *outlen);
int omac_test(void);
#endif /* LTC_OMAC */
#ifdef LTC_PMAC
typedef struct {
unsigned char Ls[32][MAXBLOCKSIZE], /* L shifted by i bits to the left */
Li[MAXBLOCKSIZE], /* value of Li [current value, we calc from previous recall] */
Lr[MAXBLOCKSIZE], /* L * x^-1 */
block[MAXBLOCKSIZE], /* currently accumulated block */
checksum[MAXBLOCKSIZE]; /* current checksum */
symmetric_key key; /* scheduled key for cipher */
unsigned long block_index; /* index # for current block */
int cipher_idx, /* cipher idx */
block_len, /* length of block */
buflen; /* number of bytes in the buffer */
} pmac_state;
int pmac_init(pmac_state *pmac, int cipher, const unsigned char *key, unsigned long keylen);
int pmac_process(pmac_state *pmac, const unsigned char *in, unsigned long inlen);
int pmac_done(pmac_state *pmac, unsigned char *out, unsigned long *outlen);
int pmac_memory(int cipher,
const unsigned char *key, unsigned long keylen,
const unsigned char *msg, unsigned long msglen,
unsigned char *out, unsigned long *outlen);
int pmac_memory_multi(int cipher,
const unsigned char *key, unsigned long keylen,
unsigned char *out, unsigned long *outlen,
const unsigned char *in, unsigned long inlen, ...);
int pmac_file(int cipher,
const unsigned char *key, unsigned long keylen,
const char *filename,
unsigned char *out, unsigned long *outlen);
int pmac_test(void);
/* internal functions */
int pmac_ntz(unsigned long x);
void pmac_shift_xor(pmac_state *pmac);
#endif /* PMAC */
#ifdef LTC_POLY1305
typedef struct {
ulong32 r[5];
ulong32 h[5];
ulong32 pad[4];
unsigned long leftover;
unsigned char buffer[16];
int final;
} poly1305_state;
int poly1305_init(poly1305_state *st, const unsigned char *key, unsigned long keylen);
int poly1305_process(poly1305_state *st, const unsigned char *in, unsigned long inlen);
int poly1305_done(poly1305_state *st, unsigned char *mac, unsigned long *maclen);
int poly1305_memory(const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *mac, unsigned long *maclen);
int poly1305_memory_multi(const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen, const unsigned char *in, unsigned long inlen, ...);
int poly1305_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen);
int poly1305_test(void);
#endif /* LTC_POLY1305 */
#ifdef LTC_BLAKE2SMAC
typedef hash_state blake2smac_state;
int blake2smac_init(blake2smac_state *st, unsigned long outlen, const unsigned char *key, unsigned long keylen);
int blake2smac_process(blake2smac_state *st, const unsigned char *in, unsigned long inlen);
int blake2smac_done(blake2smac_state *st, unsigned char *mac, unsigned long *maclen);
int blake2smac_memory(const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *mac, unsigned long *maclen);
int blake2smac_memory_multi(const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen, const unsigned char *in, unsigned long inlen, ...);
int blake2smac_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen);
int blake2smac_test(void);
#endif /* LTC_BLAKE2SMAC */
#ifdef LTC_BLAKE2BMAC
typedef hash_state blake2bmac_state;
int blake2bmac_init(blake2bmac_state *st, unsigned long outlen, const unsigned char *key, unsigned long keylen);
int blake2bmac_process(blake2bmac_state *st, const unsigned char *in, unsigned long inlen);
int blake2bmac_done(blake2bmac_state *st, unsigned char *mac, unsigned long *maclen);
int blake2bmac_memory(const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *mac, unsigned long *maclen);
int blake2bmac_memory_multi(const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen, const unsigned char *in, unsigned long inlen, ...);
int blake2bmac_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen);
int blake2bmac_test(void);
#endif /* LTC_BLAKE2BMAC */
#ifdef LTC_EAX_MODE
#if !(defined(LTC_OMAC) && defined(LTC_CTR_MODE))
#error LTC_EAX_MODE requires LTC_OMAC and CTR
#endif
typedef struct {
unsigned char N[MAXBLOCKSIZE];
symmetric_CTR ctr;
omac_state headeromac, ctomac;
} eax_state;
int eax_init(eax_state *eax, int cipher, const unsigned char *key, unsigned long keylen,
const unsigned char *nonce, unsigned long noncelen,
const unsigned char *header, unsigned long headerlen);
int eax_encrypt(eax_state *eax, const unsigned char *pt, unsigned char *ct, unsigned long length);
int eax_decrypt(eax_state *eax, const unsigned char *ct, unsigned char *pt, unsigned long length);
int eax_addheader(eax_state *eax, const unsigned char *header, unsigned long length);
int eax_done(eax_state *eax, unsigned char *tag, unsigned long *taglen);
int eax_encrypt_authenticate_memory(int cipher,
const unsigned char *key, unsigned long keylen,
const unsigned char *nonce, unsigned long noncelen,
const unsigned char *header, unsigned long headerlen,
const unsigned char *pt, unsigned long ptlen,
unsigned char *ct,
unsigned char *tag, unsigned long *taglen);
int eax_decrypt_verify_memory(int cipher,
const unsigned char *key, unsigned long keylen,
const unsigned char *nonce, unsigned long noncelen,
const unsigned char *header, unsigned long headerlen,
const unsigned char *ct, unsigned long ctlen,
unsigned char *pt,
unsigned char *tag, unsigned long taglen,
int *stat);
int eax_test(void);
#endif /* EAX MODE */
#ifdef LTC_OCB_MODE
typedef struct {
unsigned char L[MAXBLOCKSIZE], /* L value */
Ls[32][MAXBLOCKSIZE], /* L shifted by i bits to the left */
Li[MAXBLOCKSIZE], /* value of Li [current value, we calc from previous recall] */
Lr[MAXBLOCKSIZE], /* L * x^-1 */
R[MAXBLOCKSIZE], /* R value */
checksum[MAXBLOCKSIZE]; /* current checksum */
symmetric_key key; /* scheduled key for cipher */
unsigned long block_index; /* index # for current block */
int cipher, /* cipher idx */
block_len; /* length of block */
} ocb_state;
int ocb_init(ocb_state *ocb, int cipher,
const unsigned char *key, unsigned long keylen, const unsigned char *nonce);
int ocb_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned char *ct);
int ocb_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned char *pt);
int ocb_done_encrypt(ocb_state *ocb,
const unsigned char *pt, unsigned long ptlen,
unsigned char *ct,
unsigned char *tag, unsigned long *taglen);
int ocb_done_decrypt(ocb_state *ocb,
const unsigned char *ct, unsigned long ctlen,
unsigned char *pt,
const unsigned char *tag, unsigned long taglen, int *stat);
int ocb_encrypt_authenticate_memory(int cipher,
const unsigned char *key, unsigned long keylen,
const unsigned char *nonce,
const unsigned char *pt, unsigned long ptlen,
unsigned char *ct,
unsigned char *tag, unsigned long *taglen);
int ocb_decrypt_verify_memory(int cipher,
const unsigned char *key, unsigned long keylen,
const unsigned char *nonce,
const unsigned char *ct, unsigned long ctlen,
unsigned char *pt,
const unsigned char *tag, unsigned long taglen,
int *stat);
int ocb_test(void);
/* internal functions */
void ocb_shift_xor(ocb_state *ocb, unsigned char *Z);
int ocb_ntz(unsigned long x);
int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen,
unsigned char *ct, unsigned char *tag, unsigned long *taglen, int mode);
#endif /* LTC_OCB_MODE */
#ifdef LTC_OCB3_MODE
typedef struct {
unsigned char Offset_0[MAXBLOCKSIZE], /* Offset_0 value */
Offset_current[MAXBLOCKSIZE], /* Offset_{current_block_index} value */
L_dollar[MAXBLOCKSIZE], /* L_$ value */
L_star[MAXBLOCKSIZE], /* L_* value */
L_[32][MAXBLOCKSIZE], /* L_{i} values */
tag_part[MAXBLOCKSIZE], /* intermediate result of tag calculation */
checksum[MAXBLOCKSIZE]; /* current checksum */
/* AAD related members */
unsigned char aSum_current[MAXBLOCKSIZE], /* AAD related helper variable */
aOffset_current[MAXBLOCKSIZE], /* AAD related helper variable */
adata_buffer[MAXBLOCKSIZE]; /* AAD buffer */
int adata_buffer_bytes; /* bytes in AAD buffer */
unsigned long ablock_index; /* index # for current adata (AAD) block */
symmetric_key key; /* scheduled key for cipher */
unsigned long block_index; /* index # for current data block */
int cipher, /* cipher idx */
tag_len, /* length of tag */
block_len; /* length of block */
} ocb3_state;
int ocb3_init(ocb3_state *ocb, int cipher,
const unsigned char *key, unsigned long keylen,
const unsigned char *nonce, unsigned long noncelen,
unsigned long taglen);
int ocb3_encrypt(ocb3_state *ocb, const unsigned char *pt, unsigned long ptlen, unsigned char *ct);
int ocb3_decrypt(ocb3_state *ocb, const unsigned char *ct, unsigned long ctlen, unsigned char *pt);
int ocb3_encrypt_last(ocb3_state *ocb, const unsigned char *pt, unsigned long ptlen, unsigned char *ct);
int ocb3_decrypt_last(ocb3_state *ocb, const unsigned char *ct, unsigned long ctlen, unsigned char *pt);
int ocb3_add_aad(ocb3_state *ocb, const unsigned char *aad, unsigned long aadlen);
int ocb3_done(ocb3_state *ocb, unsigned char *tag, unsigned long *taglen);
int ocb3_encrypt_authenticate_memory(int cipher,
const unsigned char *key, unsigned long keylen,
const unsigned char *nonce, unsigned long noncelen,
const unsigned char *adata, unsigned long adatalen,
const unsigned char *pt, unsigned long ptlen,
unsigned char *ct,
unsigned char *tag, unsigned long *taglen);
int ocb3_decrypt_verify_memory(int cipher,
const unsigned char *key, unsigned long keylen,
const unsigned char *nonce, unsigned long noncelen,
const unsigned char *adata, unsigned long adatalen,
const unsigned char *ct, unsigned long ctlen,
unsigned char *pt,
const unsigned char *tag, unsigned long taglen,
int *stat);
int ocb3_test(void);
#ifdef LTC_SOURCE
/* internal helper functions */
int ocb3_int_ntz(unsigned long x);
void ocb3_int_xor_blocks(unsigned char *out, const unsigned char *block_a, const unsigned char *block_b, unsigned long block_len);
#endif /* LTC_SOURCE */
#endif /* LTC_OCB3_MODE */
#ifdef LTC_CCM_MODE
#define CCM_ENCRYPT LTC_ENCRYPT
#define CCM_DECRYPT LTC_DECRYPT
typedef struct {
symmetric_key K;
int cipher, /* which cipher */
taglen, /* length of the tag */
x; /* index in PAD */
unsigned long L, /* L value */
ptlen, /* length that will be enc / dec */
current_ptlen, /* current processed length */
aadlen, /* length of the aad */
current_aadlen, /* length of the currently provided add */
noncelen; /* length of the nonce */
unsigned char PAD[16],
ctr[16],
CTRPAD[16],
CTRlen;
} ccm_state;
int ccm_init(ccm_state *ccm, int cipher,
const unsigned char *key, int keylen, int ptlen, int taglen, int aad_len);
int ccm_reset(ccm_state *ccm);
int ccm_add_nonce(ccm_state *ccm,
const unsigned char *nonce, unsigned long noncelen);
int ccm_add_aad(ccm_state *ccm,
const unsigned char *adata, unsigned long adatalen);
int ccm_process(ccm_state *ccm,
unsigned char *pt, unsigned long ptlen,
unsigned char *ct,
int direction);
int ccm_done(ccm_state *ccm,
unsigned char *tag, unsigned long *taglen);
int ccm_memory(int cipher,
const unsigned char *key, unsigned long keylen,
symmetric_key *uskey,
const unsigned char *nonce, unsigned long noncelen,
const unsigned char *header, unsigned long headerlen,
unsigned char *pt, unsigned long ptlen,
unsigned char *ct,
unsigned char *tag, unsigned long *taglen,
int direction);
int ccm_test(void);
#endif /* LTC_CCM_MODE */
#if defined(LRW_MODE) || defined(LTC_GCM_MODE)
void gcm_gf_mult(const unsigned char *a, const unsigned char *b, unsigned char *c);
#endif
/* table shared between GCM and LRW */
#if defined(LTC_GCM_TABLES) || defined(LTC_LRW_TABLES) || ((defined(LTC_GCM_MODE) || defined(LTC_GCM_MODE)) && defined(LTC_FAST))
extern const unsigned char gcm_shift_table[];
#endif
#ifdef LTC_GCM_MODE
#define GCM_ENCRYPT LTC_ENCRYPT
#define GCM_DECRYPT LTC_DECRYPT
#define LTC_GCM_MODE_IV 0
#define LTC_GCM_MODE_AAD 1
#define LTC_GCM_MODE_TEXT 2
typedef struct {
symmetric_key K;
unsigned char H[16], /* multiplier */
X[16], /* accumulator */
Y[16], /* counter */
Y_0[16], /* initial counter */
buf[16]; /* buffer for stuff */
int cipher, /* which cipher */
ivmode, /* Which mode is the IV in? */
mode, /* mode the GCM code is in */
buflen; /* length of data in buf */
ulong64 totlen, /* 64-bit counter used for IV and AAD */
pttotlen; /* 64-bit counter for the PT */
#ifdef LTC_GCM_TABLES
unsigned char PC[16][256][16] /* 16 tables of 8x128 */
#ifdef LTC_GCM_TABLES_SSE2
__attribute__ ((aligned (16)))
#endif
;
#endif
} gcm_state;
void gcm_mult_h(gcm_state *gcm, unsigned char *I);
int gcm_init(gcm_state *gcm, int cipher,
const unsigned char *key, int keylen);
int gcm_reset(gcm_state *gcm);
int gcm_add_iv(gcm_state *gcm,
const unsigned char *IV, unsigned long IVlen);
int gcm_add_aad(gcm_state *gcm,
const unsigned char *adata, unsigned long adatalen);
int gcm_process(gcm_state *gcm,
unsigned char *pt, unsigned long ptlen,
unsigned char *ct,
int direction);
int gcm_done(gcm_state *gcm,
unsigned char *tag, unsigned long *taglen);
int gcm_memory( int cipher,
const unsigned char *key, unsigned long keylen,
const unsigned char *IV, unsigned long IVlen,
const unsigned char *adata, unsigned long adatalen,
unsigned char *pt, unsigned long ptlen,
unsigned char *ct,
unsigned char *tag, unsigned long *taglen,
int direction);
int gcm_test(void);
#endif /* LTC_GCM_MODE */
#ifdef LTC_PELICAN
typedef struct pelican_state
{
symmetric_key K;
unsigned char state[16];
int buflen;
} pelican_state;
int pelican_init(pelican_state *pelmac, const unsigned char *key, unsigned long keylen);
int pelican_process(pelican_state *pelmac, const unsigned char *in, unsigned long inlen);
int pelican_done(pelican_state *pelmac, unsigned char *out);
int pelican_test(void);
int pelican_memory(const unsigned char *key, unsigned long keylen,
const unsigned char *in, unsigned long inlen,
unsigned char *out);
#endif
#ifdef LTC_XCBC
/* add this to "keylen" to xcbc_init to use a pure three-key XCBC MAC */
#define LTC_XCBC_PURE 0x8000UL
typedef struct {
unsigned char K[3][MAXBLOCKSIZE],
IV[MAXBLOCKSIZE];
symmetric_key key;
int cipher,
buflen,
blocksize;
} xcbc_state;
int xcbc_init(xcbc_state *xcbc, int cipher, const unsigned char *key, unsigned long keylen);
int xcbc_process(xcbc_state *xcbc, const unsigned char *in, unsigned long inlen);
int xcbc_done(xcbc_state *xcbc, unsigned char *out, unsigned long *outlen);
int xcbc_memory(int cipher,
const unsigned char *key, unsigned long keylen,
const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
int xcbc_memory_multi(int cipher,
const unsigned char *key, unsigned long keylen,
unsigned char *out, unsigned long *outlen,
const unsigned char *in, unsigned long inlen, ...);
int xcbc_file(int cipher,
const unsigned char *key, unsigned long keylen,
const char *filename,
unsigned char *out, unsigned long *outlen);
int xcbc_test(void);
#endif
#ifdef LTC_F9_MODE
typedef struct {
unsigned char akey[MAXBLOCKSIZE],
ACC[MAXBLOCKSIZE],
IV[MAXBLOCKSIZE];
symmetric_key key;
int cipher,
buflen,
keylen,
blocksize;
} f9_state;
int f9_init(f9_state *f9, int cipher, const unsigned char *key, unsigned long keylen);
int f9_process(f9_state *f9, const unsigned char *in, unsigned long inlen);
int f9_done(f9_state *f9, unsigned char *out, unsigned long *outlen);
int f9_memory(int cipher,
const unsigned char *key, unsigned long keylen,
const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
int f9_memory_multi(int cipher,
const unsigned char *key, unsigned long keylen,
unsigned char *out, unsigned long *outlen,
const unsigned char *in, unsigned long inlen, ...);
int f9_file(int cipher,
const unsigned char *key, unsigned long keylen,
const char *filename,
unsigned char *out, unsigned long *outlen);
int f9_test(void);
#endif
#ifdef LTC_CHACHA20POLY1305_MODE
typedef struct {
poly1305_state poly;
chacha_state chacha;
ulong64 aadlen;
ulong64 ctlen;
int aadflg;
} chacha20poly1305_state;
#define CHACHA20POLY1305_ENCRYPT LTC_ENCRYPT
#define CHACHA20POLY1305_DECRYPT LTC_DECRYPT
int chacha20poly1305_init(chacha20poly1305_state *st, const unsigned char *key, unsigned long keylen);
int chacha20poly1305_setiv(chacha20poly1305_state *st, const unsigned char *iv, unsigned long ivlen);
int chacha20poly1305_setiv_rfc7905(chacha20poly1305_state *st, const unsigned char *iv, unsigned long ivlen, ulong64 sequence_number);
int chacha20poly1305_add_aad(chacha20poly1305_state *st, const unsigned char *in, unsigned long inlen);
int chacha20poly1305_encrypt(chacha20poly1305_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out);
int chacha20poly1305_decrypt(chacha20poly1305_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out);
int chacha20poly1305_done(chacha20poly1305_state *st, unsigned char *tag, unsigned long *taglen);
int chacha20poly1305_memory(const unsigned char *key, unsigned long keylen,
const unsigned char *iv, unsigned long ivlen,
const unsigned char *aad, unsigned long aadlen,
const unsigned char *in, unsigned long inlen,
unsigned char *out,
unsigned char *tag, unsigned long *taglen,
int direction);
int chacha20poly1305_test(void);
#endif /* LTC_CHACHA20POLY1305_MODE */
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View file

@ -0,0 +1,446 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/* ---- HELPER MACROS ---- */
#ifdef ENDIAN_NEUTRAL
#define STORE32L(x, y) \
do { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
(y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } while(0)
#define LOAD32L(x, y) \
do { x = ((ulong32)((y)[3] & 255)<<24) | \
((ulong32)((y)[2] & 255)<<16) | \
((ulong32)((y)[1] & 255)<<8) | \
((ulong32)((y)[0] & 255)); } while(0)
#define STORE64L(x, y) \
do { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \
(y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \
(y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
(y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } while(0)
#define LOAD64L(x, y) \
do { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \
(((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \
(((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \
(((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } while(0)
#define STORE32H(x, y) \
do { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \
(y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); } while(0)
#define LOAD32H(x, y) \
do { x = ((ulong32)((y)[0] & 255)<<24) | \
((ulong32)((y)[1] & 255)<<16) | \
((ulong32)((y)[2] & 255)<<8) | \
((ulong32)((y)[3] & 255)); } while(0)
#define STORE64H(x, y) \
do { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \
(y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \
(y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \
(y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } while(0)
#define LOAD64H(x, y) \
do { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \
(((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \
(((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \
(((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); } while(0)
#elif defined(ENDIAN_LITTLE)
#ifdef LTC_HAVE_BSWAP_BUILTIN
#define STORE32H(x, y) \
do { ulong32 __t = __builtin_bswap32 ((x)); \
XMEMCPY ((y), &__t, 4); } while(0)
#define LOAD32H(x, y) \
do { XMEMCPY (&(x), (y), 4); \
(x) = __builtin_bswap32 ((x)); } while(0)
#elif !defined(LTC_NO_BSWAP) && (defined(INTEL_CC) || (defined(__GNUC__) && (defined(__DJGPP__) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__i386__) || defined(__x86_64__))))
#define STORE32H(x, y) \
asm __volatile__ ( \
"bswapl %0 \n\t" \
"movl %0,(%1)\n\t" \
"bswapl %0 \n\t" \
::"r"(x), "r"(y));
#define LOAD32H(x, y) \
asm __volatile__ ( \
"movl (%1),%0\n\t" \
"bswapl %0\n\t" \
:"=r"(x): "r"(y));
#else
#define STORE32H(x, y) \
do { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \
(y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); } while(0)
#define LOAD32H(x, y) \
do { x = ((ulong32)((y)[0] & 255)<<24) | \
((ulong32)((y)[1] & 255)<<16) | \
((ulong32)((y)[2] & 255)<<8) | \
((ulong32)((y)[3] & 255)); } while(0)
#endif
#ifdef LTC_HAVE_BSWAP_BUILTIN
#define STORE64H(x, y) \
do { ulong64 __t = __builtin_bswap64 ((x)); \
XMEMCPY ((y), &__t, 8); } while(0)
#define LOAD64H(x, y) \
do { XMEMCPY (&(x), (y), 8); \
(x) = __builtin_bswap64 ((x)); } while(0)
/* x86_64 processor */
#elif !defined(LTC_NO_BSWAP) && (defined(__GNUC__) && defined(__x86_64__))
#define STORE64H(x, y) \
asm __volatile__ ( \
"bswapq %0 \n\t" \
"movq %0,(%1)\n\t" \
"bswapq %0 \n\t" \
::"r"(x), "r"(y): "memory");
#define LOAD64H(x, y) \
asm __volatile__ ( \
"movq (%1),%0\n\t" \
"bswapq %0\n\t" \
:"=r"(x): "r"(y): "memory");
#else
#define STORE64H(x, y) \
do { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \
(y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \
(y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \
(y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } while(0)
#define LOAD64H(x, y) \
do { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \
(((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \
(((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \
(((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); } while(0)
#endif
#ifdef ENDIAN_32BITWORD
#define STORE32L(x, y) \
do { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } while(0)
#define LOAD32L(x, y) \
do { XMEMCPY(&(x), y, 4); } while(0)
#define STORE64L(x, y) \
do { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \
(y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \
(y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
(y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } while(0)
#define LOAD64L(x, y) \
do { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \
(((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \
(((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \
(((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } while(0)
#else /* 64-bit words then */
#define STORE32L(x, y) \
do { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } while(0)
#define LOAD32L(x, y) \
do { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } while(0)
#define STORE64L(x, y) \
do { ulong64 __t = (x); XMEMCPY(y, &__t, 8); } while(0)
#define LOAD64L(x, y) \
do { XMEMCPY(&(x), y, 8); } while(0)
#endif /* ENDIAN_64BITWORD */
#elif defined(ENDIAN_BIG)
#define STORE32L(x, y) \
do { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
(y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } while(0)
#define LOAD32L(x, y) \
do { x = ((ulong32)((y)[3] & 255)<<24) | \
((ulong32)((y)[2] & 255)<<16) | \
((ulong32)((y)[1] & 255)<<8) | \
((ulong32)((y)[0] & 255)); } while(0)
#define STORE64L(x, y) \
do { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \
(y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \
(y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
(y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } while(0)
#define LOAD64L(x, y) \
do { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48) | \
(((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32) | \
(((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16) | \
(((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } while(0)
#ifdef ENDIAN_32BITWORD
#define STORE32H(x, y) \
do { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } while(0)
#define LOAD32H(x, y) \
do { XMEMCPY(&(x), y, 4); } while(0)
#define STORE64H(x, y) \
do { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \
(y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \
(y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \
(y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } while(0)
#define LOAD64H(x, y) \
do { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48)| \
(((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32)| \
(((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16)| \
(((ulong64)((y)[6] & 255))<<8)| (((ulong64)((y)[7] & 255))); } while(0)
#else /* 64-bit words then */
#define STORE32H(x, y) \
do { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } while(0)
#define LOAD32H(x, y) \
do { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } while(0)
#define STORE64H(x, y) \
do { ulong64 __t = (x); XMEMCPY(y, &__t, 8); } while(0)
#define LOAD64H(x, y) \
do { XMEMCPY(&(x), y, 8); } while(0)
#endif /* ENDIAN_64BITWORD */
#endif /* ENDIAN_BIG */
#define BSWAP(x) ( ((x>>24)&0x000000FFUL) | ((x<<24)&0xFF000000UL) | \
((x>>8)&0x0000FF00UL) | ((x<<8)&0x00FF0000UL) )
/* 32-bit Rotates */
#if defined(_MSC_VER)
#define LTC_ROx_ASM
/* instrinsic rotate */
#include <stdlib.h>
#pragma intrinsic(_lrotr,_lrotl)
#define ROR(x,n) _lrotr(x,n)
#define ROL(x,n) _lrotl(x,n)
#define RORc(x,n) _lrotr(x,n)
#define ROLc(x,n) _lrotl(x,n)
#elif !defined(__STRICT_ANSI__) && defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && !defined(INTEL_CC) && !defined(LTC_NO_ASM)
#define LTC_ROx_ASM
static inline ulong32 ROL(ulong32 word, int i)
{
asm ("roll %%cl,%0"
:"=r" (word)
:"0" (word),"c" (i));
return word;
}
static inline ulong32 ROR(ulong32 word, int i)
{
asm ("rorl %%cl,%0"
:"=r" (word)
:"0" (word),"c" (i));
return word;
}
#ifndef LTC_NO_ROLC
#define ROLc(word,i) ({ \
ulong32 __ROLc_tmp = (word); \
__asm__ ("roll %2, %0" : \
"=r" (__ROLc_tmp) : \
"0" (__ROLc_tmp), \
"I" (i)); \
__ROLc_tmp; \
})
#define RORc(word,i) ({ \
ulong32 __RORc_tmp = (word); \
__asm__ ("rorl %2, %0" : \
"=r" (__RORc_tmp) : \
"0" (__RORc_tmp), \
"I" (i)); \
__RORc_tmp; \
})
#else
#define ROLc ROL
#define RORc ROR
#endif
#elif !defined(__STRICT_ANSI__) && defined(LTC_PPC32)
#define LTC_ROx_ASM
static inline ulong32 ROL(ulong32 word, int i)
{
asm ("rotlw %0,%0,%2"
:"=r" (word)
:"0" (word),"r" (i));
return word;
}
static inline ulong32 ROR(ulong32 word, int i)
{
asm ("rotlw %0,%0,%2"
:"=r" (word)
:"0" (word),"r" (32-i));
return word;
}
#ifndef LTC_NO_ROLC
static inline ulong32 ROLc(ulong32 word, const int i)
{
asm ("rotlwi %0,%0,%2"
:"=r" (word)
:"0" (word),"I" (i));
return word;
}
static inline ulong32 RORc(ulong32 word, const int i)
{
asm ("rotrwi %0,%0,%2"
:"=r" (word)
:"0" (word),"I" (i));
return word;
}
#else
#define ROLc ROL
#define RORc ROR
#endif
#else
/* rotates the hard way */
#define ROL(x, y) ( (((ulong32)(x)<<(ulong32)((y)&31)) | (((ulong32)(x)&0xFFFFFFFFUL)>>(ulong32)((32-((y)&31))&31))) & 0xFFFFFFFFUL)
#define ROR(x, y) ( ((((ulong32)(x)&0xFFFFFFFFUL)>>(ulong32)((y)&31)) | ((ulong32)(x)<<(ulong32)((32-((y)&31))&31))) & 0xFFFFFFFFUL)
#define ROLc(x, y) ( (((ulong32)(x)<<(ulong32)((y)&31)) | (((ulong32)(x)&0xFFFFFFFFUL)>>(ulong32)((32-((y)&31))&31))) & 0xFFFFFFFFUL)
#define RORc(x, y) ( ((((ulong32)(x)&0xFFFFFFFFUL)>>(ulong32)((y)&31)) | ((ulong32)(x)<<(ulong32)((32-((y)&31))&31))) & 0xFFFFFFFFUL)
#endif
/* 64-bit Rotates */
#if !defined(__STRICT_ANSI__) && defined(__GNUC__) && defined(__x86_64__) && !defined(_WIN64) && !defined(LTC_NO_ASM)
static inline ulong64 ROL64(ulong64 word, int i)
{
asm("rolq %%cl,%0"
:"=r" (word)
:"0" (word),"c" (i));
return word;
}
static inline ulong64 ROR64(ulong64 word, int i)
{
asm("rorq %%cl,%0"
:"=r" (word)
:"0" (word),"c" (i));
return word;
}
#ifndef LTC_NO_ROLC
#define ROL64c(word,i) ({ \
ulong64 __ROL64c_tmp = word; \
__asm__ ("rolq %2, %0" : \
"=r" (__ROL64c_tmp) : \
"0" (__ROL64c_tmp), \
"J" (i)); \
__ROL64c_tmp; \
})
#define ROR64c(word,i) ({ \
ulong64 __ROR64c_tmp = word; \
__asm__ ("rorq %2, %0" : \
"=r" (__ROR64c_tmp) : \
"0" (__ROR64c_tmp), \
"J" (i)); \
__ROR64c_tmp; \
})
#else /* LTC_NO_ROLC */
#define ROL64c ROL64
#define ROR64c ROR64
#endif
#else /* Not x86_64 */
#define ROL64(x, y) \
( (((x)<<((ulong64)(y)&63)) | \
(((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>(((ulong64)64-((y)&63))&63))) & CONST64(0xFFFFFFFFFFFFFFFF))
#define ROR64(x, y) \
( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \
((x)<<(((ulong64)64-((y)&63))&63))) & CONST64(0xFFFFFFFFFFFFFFFF))
#define ROL64c(x, y) \
( (((x)<<((ulong64)(y)&63)) | \
(((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>(((ulong64)64-((y)&63))&63))) & CONST64(0xFFFFFFFFFFFFFFFF))
#define ROR64c(x, y) \
( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \
((x)<<(((ulong64)64-((y)&63))&63))) & CONST64(0xFFFFFFFFFFFFFFFF))
#endif
#ifndef MAX
#define MAX(x, y) ( ((x)>(y))?(x):(y) )
#endif
#ifndef MIN
#define MIN(x, y) ( ((x)<(y))?(x):(y) )
#endif
#ifndef LTC_UNUSED_PARAM
#define LTC_UNUSED_PARAM(x) (void)(x)
#endif
/* extract a byte portably */
#ifdef _MSC_VER
#define byte(x, n) ((unsigned char)((x) >> (8 * (n))))
#else
#define byte(x, n) (((x) >> (8 * (n))) & 255)
#endif
/* there is no snprintf before Visual C++ 2015 */
#if defined(_MSC_VER) && _MSC_VER < 1900
#define snprintf _snprintf
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View file

@ -0,0 +1,583 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/** math functions **/
#define LTC_MP_LT -1
#define LTC_MP_EQ 0
#define LTC_MP_GT 1
#define LTC_MP_NO 0
#define LTC_MP_YES 1
#ifndef LTC_MECC
typedef void ecc_point;
#endif
#ifndef LTC_MRSA
typedef void rsa_key;
#endif
#ifndef LTC_MILLER_RABIN_REPS
/* Number of rounds of the Miller-Rabin test
* "Reasonable values of reps are between 15 and 50." c.f. gmp doc of mpz_probab_prime_p()
* As of https://security.stackexchange.com/a/4546 we should use 40 rounds */
#define LTC_MILLER_RABIN_REPS 40
#endif
int radix_to_bin(const void *in, int radix, void *out, unsigned long *len);
/** math descriptor */
typedef struct {
/** Name of the math provider */
const char *name;
/** Bits per digit, amount of bits must fit in an unsigned long */
int bits_per_digit;
/* ---- init/deinit functions ---- */
/** initialize a bignum
@param a The number to initialize
@return CRYPT_OK on success
*/
int (*init)(void **a);
/** init copy
@param dst The number to initialize and write to
@param src The number to copy from
@return CRYPT_OK on success
*/
int (*init_copy)(void **dst, void *src);
/** deinit
@param a The number to free
@return CRYPT_OK on success
*/
void (*deinit)(void *a);
/* ---- data movement ---- */
/** negate
@param src The number to negate
@param dst The destination
@return CRYPT_OK on success
*/
int (*neg)(void *src, void *dst);
/** copy
@param src The number to copy from
@param dst The number to write to
@return CRYPT_OK on success
*/
int (*copy)(void *src, void *dst);
/* ---- trivial low level functions ---- */
/** set small constant
@param a Number to write to
@param n Source upto bits_per_digit (actually meant for very small constants)
@return CRYPT_OK on success
*/
int (*set_int)(void *a, ltc_mp_digit n);
/** get small constant
@param a Small number to read,
only fetches up to bits_per_digit from the number
@return The lower bits_per_digit of the integer (unsigned)
*/
unsigned long (*get_int)(void *a);
/** get digit n
@param a The number to read from
@param n The number of the digit to fetch
@return The bits_per_digit sized n'th digit of a
*/
ltc_mp_digit (*get_digit)(void *a, int n);
/** Get the number of digits that represent the number
@param a The number to count
@return The number of digits used to represent the number
*/
int (*get_digit_count)(void *a);
/** compare two integers
@param a The left side integer
@param b The right side integer
@return LTC_MP_LT if a < b,
LTC_MP_GT if a > b and
LTC_MP_EQ otherwise. (signed comparison)
*/
int (*compare)(void *a, void *b);
/** compare against int
@param a The left side integer
@param b The right side integer (upto bits_per_digit)
@return LTC_MP_LT if a < b,
LTC_MP_GT if a > b and
LTC_MP_EQ otherwise. (signed comparison)
*/
int (*compare_d)(void *a, ltc_mp_digit n);
/** Count the number of bits used to represent the integer
@param a The integer to count
@return The number of bits required to represent the integer
*/
int (*count_bits)(void * a);
/** Count the number of LSB bits which are zero
@param a The integer to count
@return The number of contiguous zero LSB bits
*/
int (*count_lsb_bits)(void *a);
/** Compute a power of two
@param a The integer to store the power in
@param n The power of two you want to store (a = 2^n)
@return CRYPT_OK on success
*/
int (*twoexpt)(void *a , int n);
/* ---- radix conversions ---- */
/** read ascii string
@param a The integer to store into
@param str The string to read
@param radix The radix the integer has been represented in (2-64)
@return CRYPT_OK on success
*/
int (*read_radix)(void *a, const char *str, int radix);
/** write number to string
@param a The integer to store
@param str The destination for the string
@param radix The radix the integer is to be represented in (2-64)
@return CRYPT_OK on success
*/
int (*write_radix)(void *a, char *str, int radix);
/** get size as unsigned char string
@param a The integer to get the size (when stored in array of octets)
@return The length of the integer in octets
*/
unsigned long (*unsigned_size)(void *a);
/** store an integer as an array of octets
@param src The integer to store
@param dst The buffer to store the integer in
@return CRYPT_OK on success
*/
int (*unsigned_write)(void *src, unsigned char *dst);
/** read an array of octets and store as integer
@param dst The integer to load
@param src The array of octets
@param len The number of octets
@return CRYPT_OK on success
*/
int (*unsigned_read)( void *dst,
unsigned char *src,
unsigned long len);
/* ---- basic math ---- */
/** add two integers
@param a The first source integer
@param b The second source integer
@param c The destination of "a + b"
@return CRYPT_OK on success
*/
int (*add)(void *a, void *b, void *c);
/** add two integers
@param a The first source integer
@param b The second source integer
(single digit of upto bits_per_digit in length)
@param c The destination of "a + b"
@return CRYPT_OK on success
*/
int (*addi)(void *a, ltc_mp_digit b, void *c);
/** subtract two integers
@param a The first source integer
@param b The second source integer
@param c The destination of "a - b"
@return CRYPT_OK on success
*/
int (*sub)(void *a, void *b, void *c);
/** subtract two integers
@param a The first source integer
@param b The second source integer
(single digit of upto bits_per_digit in length)
@param c The destination of "a - b"
@return CRYPT_OK on success
*/
int (*subi)(void *a, ltc_mp_digit b, void *c);
/** multiply two integers
@param a The first source integer
@param b The second source integer
(single digit of upto bits_per_digit in length)
@param c The destination of "a * b"
@return CRYPT_OK on success
*/
int (*mul)(void *a, void *b, void *c);
/** multiply two integers
@param a The first source integer
@param b The second source integer
(single digit of upto bits_per_digit in length)
@param c The destination of "a * b"
@return CRYPT_OK on success
*/
int (*muli)(void *a, ltc_mp_digit b, void *c);
/** Square an integer
@param a The integer to square
@param b The destination
@return CRYPT_OK on success
*/
int (*sqr)(void *a, void *b);
/** Divide an integer
@param a The dividend
@param b The divisor
@param c The quotient (can be NULL to signify don't care)
@param d The remainder (can be NULL to signify don't care)
@return CRYPT_OK on success
*/
int (*mpdiv)(void *a, void *b, void *c, void *d);
/** divide by two
@param a The integer to divide (shift right)
@param b The destination
@return CRYPT_OK on success
*/
int (*div_2)(void *a, void *b);
/** Get remainder (small value)
@param a The integer to reduce
@param b The modulus (upto bits_per_digit in length)
@param c The destination for the residue
@return CRYPT_OK on success
*/
int (*modi)(void *a, ltc_mp_digit b, ltc_mp_digit *c);
/** gcd
@param a The first integer
@param b The second integer
@param c The destination for (a, b)
@return CRYPT_OK on success
*/
int (*gcd)(void *a, void *b, void *c);
/** lcm
@param a The first integer
@param b The second integer
@param c The destination for [a, b]
@return CRYPT_OK on success
*/
int (*lcm)(void *a, void *b, void *c);
/** Modular multiplication
@param a The first source
@param b The second source
@param c The modulus
@param d The destination (a*b mod c)
@return CRYPT_OK on success
*/
int (*mulmod)(void *a, void *b, void *c, void *d);
/** Modular squaring
@param a The first source
@param b The modulus
@param c The destination (a*a mod b)
@return CRYPT_OK on success
*/
int (*sqrmod)(void *a, void *b, void *c);
/** Modular inversion
@param a The value to invert
@param b The modulus
@param c The destination (1/a mod b)
@return CRYPT_OK on success
*/
int (*invmod)(void *, void *, void *);
/* ---- reduction ---- */
/** setup Montgomery
@param a The modulus
@param b The destination for the reduction digit
@return CRYPT_OK on success
*/
int (*montgomery_setup)(void *a, void **b);
/** get normalization value
@param a The destination for the normalization value
@param b The modulus
@return CRYPT_OK on success
*/
int (*montgomery_normalization)(void *a, void *b);
/** reduce a number
@param a The number [and dest] to reduce
@param b The modulus
@param c The value "b" from montgomery_setup()
@return CRYPT_OK on success
*/
int (*montgomery_reduce)(void *a, void *b, void *c);
/** clean up (frees memory)
@param a The value "b" from montgomery_setup()
@return CRYPT_OK on success
*/
void (*montgomery_deinit)(void *a);
/* ---- exponentiation ---- */
/** Modular exponentiation
@param a The base integer
@param b The power (can be negative) integer
@param c The modulus integer
@param d The destination
@return CRYPT_OK on success
*/
int (*exptmod)(void *a, void *b, void *c, void *d);
/** Primality testing
@param a The integer to test
@param b The number of Miller-Rabin tests that shall be executed
@param c The destination of the result (FP_YES if prime)
@return CRYPT_OK on success
*/
int (*isprime)(void *a, int b, int *c);
/* ---- (optional) ecc point math ---- */
/** ECC GF(p) point multiplication (from the NIST curves)
@param k The integer to multiply the point by
@param G The point to multiply
@param R The destination for kG
@param modulus The modulus for the field
@param map Boolean indicated whether to map back to affine or not
(can be ignored if you work in affine only)
@return CRYPT_OK on success
*/
int (*ecc_ptmul)( void *k,
ecc_point *G,
ecc_point *R,
void *modulus,
int map);
/** ECC GF(p) point addition
@param P The first point
@param Q The second point
@param R The destination of P + Q
@param modulus The modulus
@param mp The "b" value from montgomery_setup()
@return CRYPT_OK on success
*/
int (*ecc_ptadd)(ecc_point *P,
ecc_point *Q,
ecc_point *R,
void *modulus,
void *mp);
/** ECC GF(p) point double
@param P The first point
@param R The destination of 2P
@param modulus The modulus
@param mp The "b" value from montgomery_setup()
@return CRYPT_OK on success
*/
int (*ecc_ptdbl)(ecc_point *P,
ecc_point *R,
void *modulus,
void *mp);
/** ECC mapping from projective to affine,
currently uses (x,y,z) => (x/z^2, y/z^3, 1)
@param P The point to map
@param modulus The modulus
@param mp The "b" value from montgomery_setup()
@return CRYPT_OK on success
@remark The mapping can be different but keep in mind a
ecc_point only has three integers (x,y,z) so if
you use a different mapping you have to make it fit.
*/
int (*ecc_map)(ecc_point *P, void *modulus, void *mp);
/** Computes kA*A + kB*B = C using Shamir's Trick
@param A First point to multiply
@param kA What to multiple A by
@param B Second point to multiply
@param kB What to multiple B by
@param C [out] Destination point (can overlap with A or B)
@param modulus Modulus for curve
@return CRYPT_OK on success
*/
int (*ecc_mul2add)(ecc_point *A, void *kA,
ecc_point *B, void *kB,
ecc_point *C,
void *modulus);
/* ---- (optional) rsa optimized math (for internal CRT) ---- */
/** RSA Key Generation
@param prng An active PRNG state
@param wprng The index of the PRNG desired
@param size The size of the key in octets
@param e The "e" value (public key).
e==65537 is a good choice
@param key [out] Destination of a newly created private key pair
@return CRYPT_OK if successful, upon error all allocated ram is freed
*/
int (*rsa_keygen)(prng_state *prng,
int wprng,
int size,
long e,
rsa_key *key);
/** RSA exponentiation
@param in The octet array representing the base
@param inlen The length of the input
@param out The destination (to be stored in an octet array format)
@param outlen The length of the output buffer and the resulting size
(zero padded to the size of the modulus)
@param which PK_PUBLIC for public RSA and PK_PRIVATE for private RSA
@param key The RSA key to use
@return CRYPT_OK on success
*/
int (*rsa_me)(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen, int which,
rsa_key *key);
/* ---- basic math continued ---- */
/** Modular addition
@param a The first source
@param b The second source
@param c The modulus
@param d The destination (a + b mod c)
@return CRYPT_OK on success
*/
int (*addmod)(void *a, void *b, void *c, void *d);
/** Modular substraction
@param a The first source
@param b The second source
@param c The modulus
@param d The destination (a - b mod c)
@return CRYPT_OK on success
*/
int (*submod)(void *a, void *b, void *c, void *d);
/* ---- misc stuff ---- */
/** Make a pseudo-random mpi
@param a The mpi to make random
@param size The desired length
@return CRYPT_OK on success
*/
int (*rand)(void *a, int size);
} ltc_math_descriptor;
extern ltc_math_descriptor ltc_mp;
int ltc_init_multi(void **a, ...);
void ltc_deinit_multi(void *a, ...);
void ltc_cleanup_multi(void **a, ...);
#ifdef LTM_DESC
extern const ltc_math_descriptor ltm_desc;
#endif
#ifdef TFM_DESC
extern const ltc_math_descriptor tfm_desc;
#endif
#ifdef GMP_DESC
extern const ltc_math_descriptor gmp_desc;
#endif
#if !defined(DESC_DEF_ONLY) && defined(LTC_SOURCE)
#define MP_DIGIT_BIT ltc_mp.bits_per_digit
/* some handy macros */
#define mp_init(a) ltc_mp.init(a)
#define mp_init_multi ltc_init_multi
#define mp_clear(a) ltc_mp.deinit(a)
#define mp_clear_multi ltc_deinit_multi
#define mp_cleanup_multi ltc_cleanup_multi
#define mp_init_copy(a, b) ltc_mp.init_copy(a, b)
#define mp_neg(a, b) ltc_mp.neg(a, b)
#define mp_copy(a, b) ltc_mp.copy(a, b)
#define mp_set(a, b) ltc_mp.set_int(a, b)
#define mp_set_int(a, b) ltc_mp.set_int(a, b)
#define mp_get_int(a) ltc_mp.get_int(a)
#define mp_get_digit(a, n) ltc_mp.get_digit(a, n)
#define mp_get_digit_count(a) ltc_mp.get_digit_count(a)
#define mp_cmp(a, b) ltc_mp.compare(a, b)
#define mp_cmp_d(a, b) ltc_mp.compare_d(a, b)
#define mp_count_bits(a) ltc_mp.count_bits(a)
#define mp_cnt_lsb(a) ltc_mp.count_lsb_bits(a)
#define mp_2expt(a, b) ltc_mp.twoexpt(a, b)
#define mp_read_radix(a, b, c) ltc_mp.read_radix(a, b, c)
#define mp_toradix(a, b, c) ltc_mp.write_radix(a, b, c)
#define mp_unsigned_bin_size(a) ltc_mp.unsigned_size(a)
#define mp_to_unsigned_bin(a, b) ltc_mp.unsigned_write(a, b)
#define mp_read_unsigned_bin(a, b, c) ltc_mp.unsigned_read(a, b, c)
#define mp_add(a, b, c) ltc_mp.add(a, b, c)
#define mp_add_d(a, b, c) ltc_mp.addi(a, b, c)
#define mp_sub(a, b, c) ltc_mp.sub(a, b, c)
#define mp_sub_d(a, b, c) ltc_mp.subi(a, b, c)
#define mp_mul(a, b, c) ltc_mp.mul(a, b, c)
#define mp_mul_d(a, b, c) ltc_mp.muli(a, b, c)
#define mp_sqr(a, b) ltc_mp.sqr(a, b)
#define mp_div(a, b, c, d) ltc_mp.mpdiv(a, b, c, d)
#define mp_div_2(a, b) ltc_mp.div_2(a, b)
#define mp_mod(a, b, c) ltc_mp.mpdiv(a, b, NULL, c)
#define mp_mod_d(a, b, c) ltc_mp.modi(a, b, c)
#define mp_gcd(a, b, c) ltc_mp.gcd(a, b, c)
#define mp_lcm(a, b, c) ltc_mp.lcm(a, b, c)
#define mp_addmod(a, b, c, d) ltc_mp.addmod(a, b, c, d)
#define mp_submod(a, b, c, d) ltc_mp.submod(a, b, c, d)
#define mp_mulmod(a, b, c, d) ltc_mp.mulmod(a, b, c, d)
#define mp_sqrmod(a, b, c) ltc_mp.sqrmod(a, b, c)
#define mp_invmod(a, b, c) ltc_mp.invmod(a, b, c)
#define mp_montgomery_setup(a, b) ltc_mp.montgomery_setup(a, b)
#define mp_montgomery_normalization(a, b) ltc_mp.montgomery_normalization(a, b)
#define mp_montgomery_reduce(a, b, c) ltc_mp.montgomery_reduce(a, b, c)
#define mp_montgomery_free(a) ltc_mp.montgomery_deinit(a)
#define mp_exptmod(a,b,c,d) ltc_mp.exptmod(a,b,c,d)
#define mp_prime_is_prime(a, b, c) ltc_mp.isprime(a, b, c)
#define mp_iszero(a) (mp_cmp_d(a, 0) == LTC_MP_EQ ? LTC_MP_YES : LTC_MP_NO)
#define mp_isodd(a) (mp_get_digit_count(a) > 0 ? (mp_get_digit(a, 0) & 1 ? LTC_MP_YES : LTC_MP_NO) : LTC_MP_NO)
#define mp_exch(a, b) do { void *ABC__tmp = a; a = b; b = ABC__tmp; } while(0)
#define mp_tohex(a, b) mp_toradix(a, b, 16)
#define mp_rand(a, b) ltc_mp.rand(a, b)
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View file

@ -0,0 +1,113 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/* ---- LTC_BASE64 Routines ---- */
#ifdef LTC_BASE64
int base64_encode(const unsigned char *in, unsigned long len,
unsigned char *out, unsigned long *outlen);
int base64_decode(const unsigned char *in, unsigned long len,
unsigned char *out, unsigned long *outlen);
int base64_strict_decode(const unsigned char *in, unsigned long len,
unsigned char *out, unsigned long *outlen);
#endif
#ifdef LTC_BASE64_URL
int base64url_encode(const unsigned char *in, unsigned long len,
unsigned char *out, unsigned long *outlen);
int base64url_strict_encode(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
int base64url_decode(const unsigned char *in, unsigned long len,
unsigned char *out, unsigned long *outlen);
int base64url_strict_decode(const unsigned char *in, unsigned long len,
unsigned char *out, unsigned long *outlen);
#endif
/* ===> LTC_HKDF -- RFC5869 HMAC-based Key Derivation Function <=== */
#ifdef LTC_HKDF
int hkdf_test(void);
int hkdf_extract(int hash_idx,
const unsigned char *salt, unsigned long saltlen,
const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
int hkdf_expand(int hash_idx,
const unsigned char *info, unsigned long infolen,
const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long outlen);
int hkdf(int hash_idx,
const unsigned char *salt, unsigned long saltlen,
const unsigned char *info, unsigned long infolen,
const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long outlen);
#endif /* LTC_HKDF */
/* ---- MEM routines ---- */
int mem_neq(const void *a, const void *b, size_t len);
void zeromem(volatile void *dst, size_t len);
void burn_stack(unsigned long len);
const char *error_to_string(int err);
extern const char *crypt_build_settings;
/* ---- HMM ---- */
int crypt_fsa(void *mp, ...);
/* ---- Dynamic language support ---- */
int crypt_get_constant(const char* namein, int *valueout);
int crypt_list_all_constants(char *names_list, unsigned int *names_list_size);
int crypt_get_size(const char* namein, unsigned int *sizeout);
int crypt_list_all_sizes(char *names_list, unsigned int *names_list_size);
#ifdef LTM_DESC
void init_LTM(void);
#endif
#ifdef TFM_DESC
void init_TFM(void);
#endif
#ifdef GMP_DESC
void init_GMP(void);
#endif
#ifdef LTC_ADLER32
typedef struct adler32_state_s
{
unsigned short s[2];
} adler32_state;
void adler32_init(adler32_state *ctx);
void adler32_update(adler32_state *ctx, const unsigned char *input, unsigned long length);
void adler32_finish(adler32_state *ctx, void *hash, unsigned long size);
int adler32_test(void);
#endif
#ifdef LTC_CRC32
typedef struct crc32_state_s
{
ulong32 crc;
} crc32_state;
void crc32_init(crc32_state *ctx);
void crc32_update(crc32_state *ctx, const unsigned char *input, unsigned long length);
void crc32_finish(crc32_state *ctx, void *hash, unsigned long size);
int crc32_test(void);
#endif
int compare_testvector(const void* is, const unsigned long is_len, const void* should, const unsigned long should_len, const char* what, int which);
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View file

@ -0,0 +1,747 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/* ---- NUMBER THEORY ---- */
enum {
PK_PUBLIC=0,
PK_PRIVATE=1
};
/* Indicates standard output formats that can be read e.g. by OpenSSL or GnuTLS */
#define PK_STD 0x1000
int rand_prime(void *N, long len, prng_state *prng, int wprng);
#ifdef LTC_SOURCE
/* internal helper functions */
int rand_bn_bits(void *N, int bits, prng_state *prng, int wprng);
int rand_bn_upto(void *N, void *limit, prng_state *prng, int wprng);
enum public_key_algorithms {
PKA_RSA,
PKA_DSA
};
typedef struct Oid {
unsigned long OID[16];
/** Number of OID digits in use */
unsigned long OIDlen;
} oid_st;
int pk_get_oid(int pk, oid_st *st);
#endif /* LTC_SOURCE */
/* ---- RSA ---- */
#ifdef LTC_MRSA
/** RSA PKCS style key */
typedef struct Rsa_key {
/** Type of key, PK_PRIVATE or PK_PUBLIC */
int type;
/** The public exponent */
void *e;
/** The private exponent */
void *d;
/** The modulus */
void *N;
/** The p factor of N */
void *p;
/** The q factor of N */
void *q;
/** The 1/q mod p CRT param */
void *qP;
/** The d mod (p - 1) CRT param */
void *dP;
/** The d mod (q - 1) CRT param */
void *dQ;
} rsa_key;
int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key);
int rsa_get_size(rsa_key *key);
int rsa_exptmod(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen, int which,
rsa_key *key);
void rsa_free(rsa_key *key);
/* These use PKCS #1 v2.0 padding */
#define rsa_encrypt_key(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _prng, _prng_idx, _hash_idx, _key) \
rsa_encrypt_key_ex(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _prng, _prng_idx, _hash_idx, LTC_PKCS_1_OAEP, _key)
#define rsa_decrypt_key(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _hash_idx, _stat, _key) \
rsa_decrypt_key_ex(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _hash_idx, LTC_PKCS_1_OAEP, _stat, _key)
#define rsa_sign_hash(_in, _inlen, _out, _outlen, _prng, _prng_idx, _hash_idx, _saltlen, _key) \
rsa_sign_hash_ex(_in, _inlen, _out, _outlen, LTC_PKCS_1_PSS, _prng, _prng_idx, _hash_idx, _saltlen, _key)
#define rsa_verify_hash(_sig, _siglen, _hash, _hashlen, _hash_idx, _saltlen, _stat, _key) \
rsa_verify_hash_ex(_sig, _siglen, _hash, _hashlen, LTC_PKCS_1_PSS, _hash_idx, _saltlen, _stat, _key)
#define rsa_sign_saltlen_get_max(_hash_idx, _key) \
rsa_sign_saltlen_get_max_ex(LTC_PKCS_1_PSS, _hash_idx, _key)
/* These can be switched between PKCS #1 v2.x and PKCS #1 v1.5 paddings */
int rsa_encrypt_key_ex(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
const unsigned char *lparam, unsigned long lparamlen,
prng_state *prng, int prng_idx, int hash_idx, int padding, rsa_key *key);
int rsa_decrypt_key_ex(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
const unsigned char *lparam, unsigned long lparamlen,
int hash_idx, int padding,
int *stat, rsa_key *key);
int rsa_sign_hash_ex(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
int padding,
prng_state *prng, int prng_idx,
int hash_idx, unsigned long saltlen,
rsa_key *key);
int rsa_verify_hash_ex(const unsigned char *sig, unsigned long siglen,
const unsigned char *hash, unsigned long hashlen,
int padding,
int hash_idx, unsigned long saltlen,
int *stat, rsa_key *key);
int rsa_sign_saltlen_get_max_ex(int padding, int hash_idx, rsa_key *key);
/* PKCS #1 import/export */
int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key);
int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key);
int rsa_import_x509(const unsigned char *in, unsigned long inlen, rsa_key *key);
int rsa_import_pkcs8(const unsigned char *in, unsigned long inlen,
const void *passwd, unsigned long passwdlen, rsa_key *key);
int rsa_set_key(const unsigned char *N, unsigned long Nlen,
const unsigned char *e, unsigned long elen,
const unsigned char *d, unsigned long dlen,
rsa_key *key);
int rsa_set_factors(const unsigned char *p, unsigned long plen,
const unsigned char *q, unsigned long qlen,
rsa_key *key);
int rsa_set_crt_params(const unsigned char *dP, unsigned long dPlen,
const unsigned char *dQ, unsigned long dQlen,
const unsigned char *qP, unsigned long qPlen,
rsa_key *key);
#endif
/* ---- Katja ---- */
#ifdef LTC_MKAT
/* Min and Max KAT key sizes (in bits) */
#define MIN_KAT_SIZE 1024
#define MAX_KAT_SIZE 4096
/** Katja PKCS style key */
typedef struct KAT_key {
/** Type of key, PK_PRIVATE or PK_PUBLIC */
int type;
/** The private exponent */
void *d;
/** The modulus */
void *N;
/** The p factor of N */
void *p;
/** The q factor of N */
void *q;
/** The 1/q mod p CRT param */
void *qP;
/** The d mod (p - 1) CRT param */
void *dP;
/** The d mod (q - 1) CRT param */
void *dQ;
/** The pq param */
void *pq;
} katja_key;
int katja_make_key(prng_state *prng, int wprng, int size, katja_key *key);
int katja_exptmod(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen, int which,
katja_key *key);
void katja_free(katja_key *key);
/* These use PKCS #1 v2.0 padding */
int katja_encrypt_key(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
const unsigned char *lparam, unsigned long lparamlen,
prng_state *prng, int prng_idx, int hash_idx, katja_key *key);
int katja_decrypt_key(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
const unsigned char *lparam, unsigned long lparamlen,
int hash_idx, int *stat,
katja_key *key);
/* PKCS #1 import/export */
int katja_export(unsigned char *out, unsigned long *outlen, int type, katja_key *key);
int katja_import(const unsigned char *in, unsigned long inlen, katja_key *key);
#endif
/* ---- DH Routines ---- */
#ifdef LTC_MDH
typedef struct {
int type;
void *x;
void *y;
void *base;
void *prime;
} dh_key;
int dh_get_groupsize(dh_key *key);
int dh_export(unsigned char *out, unsigned long *outlen, int type, dh_key *key);
int dh_import(const unsigned char *in, unsigned long inlen, dh_key *key);
int dh_set_pg(const unsigned char *p, unsigned long plen,
const unsigned char *g, unsigned long glen,
dh_key *key);
int dh_set_pg_dhparam(const unsigned char *dhparam, unsigned long dhparamlen, dh_key *key);
int dh_set_pg_groupsize(int groupsize, dh_key *key);
int dh_set_key(const unsigned char *in, unsigned long inlen, int type, dh_key *key);
int dh_generate_key(prng_state *prng, int wprng, dh_key *key);
int dh_shared_secret(dh_key *private_key, dh_key *public_key,
unsigned char *out, unsigned long *outlen);
void dh_free(dh_key *key);
int dh_export_key(void *out, unsigned long *outlen, int type, dh_key *key);
#ifdef LTC_SOURCE
typedef struct {
int size;
const char *name, *base, *prime;
} ltc_dh_set_type;
extern const ltc_dh_set_type ltc_dh_sets[];
/* internal helper functions */
int dh_check_pubkey(dh_key *key);
#endif
#endif /* LTC_MDH */
/* ---- ECC Routines ---- */
#ifdef LTC_MECC
/* size of our temp buffers for exported keys */
#define ECC_BUF_SIZE 256
/* max private key size */
#define ECC_MAXSIZE 66
/** Structure defines a NIST GF(p) curve */
typedef struct {
/** The size of the curve in octets */
int size;
/** name of curve */
const char *name;
/** The prime that defines the field the curve is in (encoded in hex) */
const char *prime;
/** The fields B param (hex) */
const char *B;
/** The order of the curve (hex) */
const char *order;
/** The x co-ordinate of the base point on the curve (hex) */
const char *Gx;
/** The y co-ordinate of the base point on the curve (hex) */
const char *Gy;
} ltc_ecc_set_type;
/** A point on a ECC curve, stored in Jacbobian format such that (x,y,z) => (x/z^2, y/z^3, 1) when interpretted as affine */
typedef struct {
/** The x co-ordinate */
void *x;
/** The y co-ordinate */
void *y;
/** The z co-ordinate */
void *z;
} ecc_point;
/** An ECC key */
typedef struct {
/** Type of key, PK_PRIVATE or PK_PUBLIC */
int type;
/** Index into the ltc_ecc_sets[] for the parameters of this curve; if -1, then this key is using user supplied curve in dp */
int idx;
/** pointer to domain parameters; either points to NIST curves (identified by idx >= 0) or user supplied curve */
const ltc_ecc_set_type *dp;
/** The public key */
ecc_point pubkey;
/** The private key */
void *k;
} ecc_key;
/** the ECC params provided */
extern const ltc_ecc_set_type ltc_ecc_sets[];
int ecc_test(void);
void ecc_sizes(int *low, int *high);
int ecc_get_size(ecc_key *key);
int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key);
int ecc_make_key_ex(prng_state *prng, int wprng, ecc_key *key, const ltc_ecc_set_type *dp);
void ecc_free(ecc_key *key);
int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key);
int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key);
int ecc_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_set_type *dp);
int ecc_ansi_x963_export(ecc_key *key, unsigned char *out, unsigned long *outlen);
int ecc_ansi_x963_import(const unsigned char *in, unsigned long inlen, ecc_key *key);
int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp);
int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key,
unsigned char *out, unsigned long *outlen);
int ecc_encrypt_key(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
prng_state *prng, int wprng, int hash,
ecc_key *key);
int ecc_decrypt_key(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
ecc_key *key);
int ecc_sign_hash_rfc7518(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
prng_state *prng, int wprng, ecc_key *key);
int ecc_sign_hash(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
prng_state *prng, int wprng, ecc_key *key);
int ecc_verify_hash_rfc7518(const unsigned char *sig, unsigned long siglen,
const unsigned char *hash, unsigned long hashlen,
int *stat, ecc_key *key);
int ecc_verify_hash(const unsigned char *sig, unsigned long siglen,
const unsigned char *hash, unsigned long hashlen,
int *stat, ecc_key *key);
/* low level functions */
ecc_point *ltc_ecc_new_point(void);
void ltc_ecc_del_point(ecc_point *p);
int ltc_ecc_is_valid_idx(int n);
/* point ops (mp == montgomery digit) */
#if !defined(LTC_MECC_ACCEL) || defined(LTM_DESC) || defined(GMP_DESC)
/* R = 2P */
int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *mp);
/* R = P + Q */
int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp);
#endif
#if defined(LTC_MECC_FP)
/* optimized point multiplication using fixed point cache (HAC algorithm 14.117) */
int ltc_ecc_fp_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map);
/* functions for saving/loading/freeing/adding to fixed point cache */
int ltc_ecc_fp_save_state(unsigned char **out, unsigned long *outlen);
int ltc_ecc_fp_restore_state(unsigned char *in, unsigned long inlen);
void ltc_ecc_fp_free(void);
int ltc_ecc_fp_add_point(ecc_point *g, void *modulus, int lock);
/* lock/unlock all points currently in fixed point cache */
void ltc_ecc_fp_tablelock(int lock);
#endif
/* R = kG */
int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map);
#ifdef LTC_ECC_SHAMIR
/* kA*A + kB*B = C */
int ltc_ecc_mul2add(ecc_point *A, void *kA,
ecc_point *B, void *kB,
ecc_point *C,
void *modulus);
#ifdef LTC_MECC_FP
/* Shamir's trick with optimized point multiplication using fixed point cache */
int ltc_ecc_fp_mul2add(ecc_point *A, void *kA,
ecc_point *B, void *kB,
ecc_point *C, void *modulus);
#endif
#endif
/* map P to affine from projective */
int ltc_ecc_map(ecc_point *P, void *modulus, void *mp);
#endif
#ifdef LTC_MDSA
/* Max diff between group and modulus size in bytes */
#define LTC_MDSA_DELTA 512
/* Max DSA group size in bytes (default allows 4k-bit groups) */
#define LTC_MDSA_MAX_GROUP 512
/** DSA key structure */
typedef struct {
/** The key type, PK_PRIVATE or PK_PUBLIC */
int type;
/** The order of the sub-group used in octets */
int qord;
/** The generator */
void *g;
/** The prime used to generate the sub-group */
void *q;
/** The large prime that generats the field the contains the sub-group */
void *p;
/** The private key */
void *x;
/** The public key */
void *y;
} dsa_key;
int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key);
int dsa_set_pqg(const unsigned char *p, unsigned long plen,
const unsigned char *q, unsigned long qlen,
const unsigned char *g, unsigned long glen,
dsa_key *key);
int dsa_set_pqg_dsaparam(const unsigned char *dsaparam, unsigned long dsaparamlen, dsa_key *key);
int dsa_generate_pqg(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key);
int dsa_set_key(const unsigned char *in, unsigned long inlen, int type, dsa_key *key);
int dsa_generate_key(prng_state *prng, int wprng, dsa_key *key);
void dsa_free(dsa_key *key);
int dsa_sign_hash_raw(const unsigned char *in, unsigned long inlen,
void *r, void *s,
prng_state *prng, int wprng, dsa_key *key);
int dsa_sign_hash(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
prng_state *prng, int wprng, dsa_key *key);
int dsa_verify_hash_raw( void *r, void *s,
const unsigned char *hash, unsigned long hashlen,
int *stat, dsa_key *key);
int dsa_verify_hash(const unsigned char *sig, unsigned long siglen,
const unsigned char *hash, unsigned long hashlen,
int *stat, dsa_key *key);
int dsa_encrypt_key(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
prng_state *prng, int wprng, int hash,
dsa_key *key);
int dsa_decrypt_key(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
dsa_key *key);
int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key);
int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key);
int dsa_verify_key(dsa_key *key, int *stat);
#ifdef LTC_SOURCE
/* internal helper functions */
int dsa_int_validate_xy(dsa_key *key, int *stat);
int dsa_int_validate_pqg(dsa_key *key, int *stat);
int dsa_int_validate_primes(dsa_key *key, int *stat);
#endif
int dsa_shared_secret(void *private_key, void *base,
dsa_key *public_key,
unsigned char *out, unsigned long *outlen);
#endif
#ifdef LTC_DER
/* DER handling */
typedef enum ltc_asn1_type_ {
/* 0 */
LTC_ASN1_EOL,
LTC_ASN1_BOOLEAN,
LTC_ASN1_INTEGER,
LTC_ASN1_SHORT_INTEGER,
LTC_ASN1_BIT_STRING,
/* 5 */
LTC_ASN1_OCTET_STRING,
LTC_ASN1_NULL,
LTC_ASN1_OBJECT_IDENTIFIER,
LTC_ASN1_IA5_STRING,
LTC_ASN1_PRINTABLE_STRING,
/* 10 */
LTC_ASN1_UTF8_STRING,
LTC_ASN1_UTCTIME,
LTC_ASN1_CHOICE,
LTC_ASN1_SEQUENCE,
LTC_ASN1_SET,
/* 15 */
LTC_ASN1_SETOF,
LTC_ASN1_RAW_BIT_STRING,
LTC_ASN1_TELETEX_STRING,
LTC_ASN1_CONSTRUCTED,
LTC_ASN1_CONTEXT_SPECIFIC,
/* 20 */
LTC_ASN1_GENERALIZEDTIME,
} ltc_asn1_type;
/** A LTC ASN.1 list type */
typedef struct ltc_asn1_list_ {
/** The LTC ASN.1 enumerated type identifier */
ltc_asn1_type type;
/** The data to encode or place for decoding */
void *data;
/** The size of the input or resulting output */
unsigned long size;
/** The used flag, this is used by the CHOICE ASN.1 type to indicate which choice was made */
int used;
/** prev/next entry in the list */
struct ltc_asn1_list_ *prev, *next, *child, *parent;
} ltc_asn1_list;
#define LTC_SET_ASN1(list, index, Type, Data, Size) \
do { \
int LTC_MACRO_temp = (index); \
ltc_asn1_list *LTC_MACRO_list = (list); \
LTC_MACRO_list[LTC_MACRO_temp].type = (Type); \
LTC_MACRO_list[LTC_MACRO_temp].data = (void*)(Data); \
LTC_MACRO_list[LTC_MACRO_temp].size = (Size); \
LTC_MACRO_list[LTC_MACRO_temp].used = 0; \
} while (0)
/* SEQUENCE */
int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen,
unsigned char *out, unsigned long *outlen, int type_of);
#define der_encode_sequence(list, inlen, out, outlen) der_encode_sequence_ex(list, inlen, out, outlen, LTC_ASN1_SEQUENCE)
int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen,
ltc_asn1_list *list, unsigned long outlen, int ordered);
#define der_decode_sequence(in, inlen, list, outlen) der_decode_sequence_ex(in, inlen, list, outlen, 1)
int der_length_sequence(ltc_asn1_list *list, unsigned long inlen,
unsigned long *outlen);
#ifdef LTC_SOURCE
/* internal helper functions */
int der_length_sequence_ex(ltc_asn1_list *list, unsigned long inlen,
unsigned long *outlen, unsigned long *payloadlen);
/* SUBJECT PUBLIC KEY INFO */
int der_encode_subject_public_key_info(unsigned char *out, unsigned long *outlen,
unsigned int algorithm, void* public_key, unsigned long public_key_len,
unsigned long parameters_type, void* parameters, unsigned long parameters_len);
int der_decode_subject_public_key_info(const unsigned char *in, unsigned long inlen,
unsigned int algorithm, void* public_key, unsigned long* public_key_len,
unsigned long parameters_type, ltc_asn1_list* parameters, unsigned long parameters_len);
#endif /* LTC_SOURCE */
/* SET */
#define der_decode_set(in, inlen, list, outlen) der_decode_sequence_ex(in, inlen, list, outlen, 0)
#define der_length_set der_length_sequence
int der_encode_set(ltc_asn1_list *list, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
int der_encode_setof(ltc_asn1_list *list, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
/* VA list handy helpers with triplets of <type, size, data> */
int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...);
int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...);
/* FLEXI DECODER handle unknown list decoder */
int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out);
#define der_free_sequence_flexi der_sequence_free
void der_sequence_free(ltc_asn1_list *in);
void der_sequence_shrink(ltc_asn1_list *in);
/* BOOLEAN */
int der_length_boolean(unsigned long *outlen);
int der_encode_boolean(int in,
unsigned char *out, unsigned long *outlen);
int der_decode_boolean(const unsigned char *in, unsigned long inlen,
int *out);
/* INTEGER */
int der_encode_integer(void *num, unsigned char *out, unsigned long *outlen);
int der_decode_integer(const unsigned char *in, unsigned long inlen, void *num);
int der_length_integer(void *num, unsigned long *len);
/* INTEGER -- handy for 0..2^32-1 values */
int der_decode_short_integer(const unsigned char *in, unsigned long inlen, unsigned long *num);
int der_encode_short_integer(unsigned long num, unsigned char *out, unsigned long *outlen);
int der_length_short_integer(unsigned long num, unsigned long *outlen);
/* BIT STRING */
int der_encode_bit_string(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
int der_decode_bit_string(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
int der_encode_raw_bit_string(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
int der_decode_raw_bit_string(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
int der_length_bit_string(unsigned long nbits, unsigned long *outlen);
/* OCTET STRING */
int der_encode_octet_string(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
int der_decode_octet_string(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
int der_length_octet_string(unsigned long noctets, unsigned long *outlen);
/* OBJECT IDENTIFIER */
int der_encode_object_identifier(unsigned long *words, unsigned long nwords,
unsigned char *out, unsigned long *outlen);
int der_decode_object_identifier(const unsigned char *in, unsigned long inlen,
unsigned long *words, unsigned long *outlen);
int der_length_object_identifier(unsigned long *words, unsigned long nwords, unsigned long *outlen);
unsigned long der_object_identifier_bits(unsigned long x);
/* IA5 STRING */
int der_encode_ia5_string(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
int der_decode_ia5_string(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
int der_length_ia5_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen);
int der_ia5_char_encode(int c);
int der_ia5_value_decode(int v);
/* TELETEX STRING */
int der_decode_teletex_string(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
int der_length_teletex_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen);
#ifdef LTC_SOURCE
/* internal helper functions */
int der_teletex_char_encode(int c);
int der_teletex_value_decode(int v);
#endif /* LTC_SOURCE */
/* PRINTABLE STRING */
int der_encode_printable_string(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
int der_decode_printable_string(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
int der_length_printable_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen);
int der_printable_char_encode(int c);
int der_printable_value_decode(int v);
/* UTF-8 */
#if (defined(SIZE_MAX) || __STDC_VERSION__ >= 199901L || defined(WCHAR_MAX) || defined(__WCHAR_MAX__) || defined(_WCHAR_T) || defined(_WCHAR_T_DEFINED) || defined (__WCHAR_TYPE__)) && !defined(LTC_NO_WCHAR)
#if defined(__WCHAR_MAX__)
#define LTC_WCHAR_MAX __WCHAR_MAX__
#else
#include <wchar.h>
#define LTC_WCHAR_MAX WCHAR_MAX
#endif
/* please note that it might happen that LTC_WCHAR_MAX is undefined */
#else
typedef ulong32 wchar_t;
#define LTC_WCHAR_MAX 0xFFFFFFFF
#endif
int der_encode_utf8_string(const wchar_t *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
int der_decode_utf8_string(const unsigned char *in, unsigned long inlen,
wchar_t *out, unsigned long *outlen);
unsigned long der_utf8_charsize(const wchar_t c);
#ifdef LTC_SOURCE
/* internal helper functions */
int der_utf8_valid_char(const wchar_t c);
#endif /* LTC_SOURCE */
int der_length_utf8_string(const wchar_t *in, unsigned long noctets, unsigned long *outlen);
/* CHOICE */
int der_decode_choice(const unsigned char *in, unsigned long *inlen,
ltc_asn1_list *list, unsigned long outlen);
/* UTCTime */
typedef struct {
unsigned YY, /* year */
MM, /* month */
DD, /* day */
hh, /* hour */
mm, /* minute */
ss, /* second */
off_dir, /* timezone offset direction 0 == +, 1 == - */
off_hh, /* timezone offset hours */
off_mm; /* timezone offset minutes */
} ltc_utctime;
int der_encode_utctime(ltc_utctime *utctime,
unsigned char *out, unsigned long *outlen);
int der_decode_utctime(const unsigned char *in, unsigned long *inlen,
ltc_utctime *out);
int der_length_utctime(ltc_utctime *utctime, unsigned long *outlen);
/* GeneralizedTime */
typedef struct {
unsigned YYYY, /* year */
MM, /* month */
DD, /* day */
hh, /* hour */
mm, /* minute */
ss, /* second */
fs, /* fractional seconds */
off_dir, /* timezone offset direction 0 == +, 1 == - */
off_hh, /* timezone offset hours */
off_mm; /* timezone offset minutes */
} ltc_generalizedtime;
int der_encode_generalizedtime(ltc_generalizedtime *gtime,
unsigned char *out, unsigned long *outlen);
int der_decode_generalizedtime(const unsigned char *in, unsigned long *inlen,
ltc_generalizedtime *out);
int der_length_generalizedtime(ltc_generalizedtime *gtime, unsigned long *outlen);
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View file

@ -0,0 +1,108 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/* PKCS Header Info */
/* ===> PKCS #1 -- RSA Cryptography <=== */
#ifdef LTC_PKCS_1
enum ltc_pkcs_1_v1_5_blocks
{
LTC_PKCS_1_EMSA = 1, /* Block type 1 (PKCS #1 v1.5 signature padding) */
LTC_PKCS_1_EME = 2 /* Block type 2 (PKCS #1 v1.5 encryption padding) */
};
enum ltc_pkcs_1_paddings
{
LTC_PKCS_1_V1_5 = 1, /* PKCS #1 v1.5 padding (\sa ltc_pkcs_1_v1_5_blocks) */
LTC_PKCS_1_OAEP = 2, /* PKCS #1 v2.0 encryption padding */
LTC_PKCS_1_PSS = 3, /* PKCS #1 v2.1 signature padding */
LTC_PKCS_1_V1_5_NA1 = 4 /* PKCS #1 v1.5 padding - No ASN.1 (\sa ltc_pkcs_1_v1_5_blocks) */
};
int pkcs_1_mgf1( int hash_idx,
const unsigned char *seed, unsigned long seedlen,
unsigned char *mask, unsigned long masklen);
int pkcs_1_i2osp(void *n, unsigned long modulus_len, unsigned char *out);
int pkcs_1_os2ip(void *n, unsigned char *in, unsigned long inlen);
/* *** v1.5 padding */
int pkcs_1_v1_5_encode(const unsigned char *msg,
unsigned long msglen,
int block_type,
unsigned long modulus_bitlen,
prng_state *prng,
int prng_idx,
unsigned char *out,
unsigned long *outlen);
int pkcs_1_v1_5_decode(const unsigned char *msg,
unsigned long msglen,
int block_type,
unsigned long modulus_bitlen,
unsigned char *out,
unsigned long *outlen,
int *is_valid);
/* *** v2.1 padding */
int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen,
const unsigned char *lparam, unsigned long lparamlen,
unsigned long modulus_bitlen, prng_state *prng,
int prng_idx, int hash_idx,
unsigned char *out, unsigned long *outlen);
int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen,
const unsigned char *lparam, unsigned long lparamlen,
unsigned long modulus_bitlen, int hash_idx,
unsigned char *out, unsigned long *outlen,
int *res);
int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen,
unsigned long saltlen, prng_state *prng,
int prng_idx, int hash_idx,
unsigned long modulus_bitlen,
unsigned char *out, unsigned long *outlen);
int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen,
const unsigned char *sig, unsigned long siglen,
unsigned long saltlen, int hash_idx,
unsigned long modulus_bitlen, int *res);
#endif /* LTC_PKCS_1 */
/* ===> PKCS #5 -- Password Based Cryptography <=== */
#ifdef LTC_PKCS_5
/* Algorithm #1 (PBKDF1) */
int pkcs_5_alg1(const unsigned char *password, unsigned long password_len,
const unsigned char *salt,
int iteration_count, int hash_idx,
unsigned char *out, unsigned long *outlen);
/* Algorithm #1 (PBKDF1) - OpenSSL-compatible variant for arbitrarily-long keys.
Compatible with EVP_BytesToKey() */
int pkcs_5_alg1_openssl(const unsigned char *password,
unsigned long password_len,
const unsigned char *salt,
int iteration_count, int hash_idx,
unsigned char *out, unsigned long *outlen);
/* Algorithm #2 (PBKDF2) */
int pkcs_5_alg2(const unsigned char *password, unsigned long password_len,
const unsigned char *salt, unsigned long salt_len,
int iteration_count, int hash_idx,
unsigned char *out, unsigned long *outlen);
int pkcs_5_test (void);
#endif /* LTC_PKCS_5 */
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View file

@ -0,0 +1,447 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt.h"
/*
* Internal Macros
*/
#define LTC_PAD_MASK (0xF000U)
/*
* Internal Enums
*/
enum ltc_oid_id {
PKA_RSA,
PKA_DSA,
PKA_EC,
PKA_EC_PRIMEF,
PKA_X25519,
PKA_ED25519,
};
/*
* Internal Types
*/
typedef struct {
int size;
const char *name, *base, *prime;
} ltc_dh_set_type;
typedef int (*fn_kdf_t)(const unsigned char *password, unsigned long password_len,
const unsigned char *salt, unsigned long salt_len,
int iteration_count, int hash_idx,
unsigned char *out, unsigned long *outlen);
typedef struct {
/* KDF */
fn_kdf_t kdf;
/* Hash or HMAC */
const char* h;
/* cipher */
const char* c;
unsigned long keylen;
/* not used for pbkdf2 */
unsigned long blocklen;
} pbes_properties;
typedef struct
{
pbes_properties type;
const void *pwd;
unsigned long pwdlen;
ltc_asn1_list *enc_data;
ltc_asn1_list *salt;
ltc_asn1_list *iv;
unsigned long iterations;
/* only used for RC2 */
unsigned long key_bits;
} pbes_arg;
/*
* Internal functions
*/
/* tomcrypt_cipher.h */
void blowfish_enc(ulong32 *data, unsigned long blocks, const symmetric_key *skey);
int blowfish_expand(const unsigned char *key, int keylen,
const unsigned char *data, int datalen,
symmetric_key *skey);
int blowfish_setup_with_data(const unsigned char *key, int keylen,
const unsigned char *data, int datalen,
symmetric_key *skey);
/* tomcrypt_hash.h */
/* a simple macro for making hash "process" functions */
#define HASH_PROCESS(func_name, compress_name, state_var, block_size) \
int func_name (hash_state * md, const unsigned char *in, unsigned long inlen) \
{ \
unsigned long n; \
int err; \
LTC_ARGCHK(md != NULL); \
LTC_ARGCHK(in != NULL); \
if (md-> state_var .curlen > sizeof(md-> state_var .buf)) { \
return CRYPT_INVALID_ARG; \
} \
if ((md-> state_var .length + inlen) < md-> state_var .length) { \
return CRYPT_HASH_OVERFLOW; \
} \
while (inlen > 0) { \
if (md-> state_var .curlen == 0 && inlen >= block_size) { \
if ((err = compress_name (md, in)) != CRYPT_OK) { \
return err; \
} \
md-> state_var .length += block_size * 8; \
in += block_size; \
inlen -= block_size; \
} else { \
n = MIN(inlen, (block_size - md-> state_var .curlen)); \
XMEMCPY(md-> state_var .buf + md-> state_var.curlen, in, (size_t)n); \
md-> state_var .curlen += n; \
in += n; \
inlen -= n; \
if (md-> state_var .curlen == block_size) { \
if ((err = compress_name (md, md-> state_var .buf)) != CRYPT_OK) { \
return err; \
} \
md-> state_var .length += 8*block_size; \
md-> state_var .curlen = 0; \
} \
} \
} \
return CRYPT_OK; \
}
/* tomcrypt_mac.h */
int ocb3_int_ntz(unsigned long x);
void ocb3_int_xor_blocks(unsigned char *out, const unsigned char *block_a, const unsigned char *block_b, unsigned long block_len);
/* tomcrypt_math.h */
#if !defined(DESC_DEF_ONLY)
#define MP_DIGIT_BIT ltc_mp.bits_per_digit
/* some handy macros */
#define mp_init(a) ltc_mp.init(a)
#define mp_init_multi ltc_init_multi
#define mp_clear(a) ltc_mp.deinit(a)
#define mp_clear_multi ltc_deinit_multi
#define mp_cleanup_multi ltc_cleanup_multi
#define mp_init_copy(a, b) ltc_mp.init_copy(a, b)
#define mp_neg(a, b) ltc_mp.neg(a, b)
#define mp_copy(a, b) ltc_mp.copy(a, b)
#define mp_set(a, b) ltc_mp.set_int(a, b)
#define mp_set_int(a, b) ltc_mp.set_int(a, b)
#define mp_get_int(a) ltc_mp.get_int(a)
#define mp_get_digit(a, n) ltc_mp.get_digit(a, n)
#define mp_get_digit_count(a) ltc_mp.get_digit_count(a)
#define mp_cmp(a, b) ltc_mp.compare(a, b)
#define mp_cmp_d(a, b) ltc_mp.compare_d(a, b)
#define mp_count_bits(a) ltc_mp.count_bits(a)
#define mp_cnt_lsb(a) ltc_mp.count_lsb_bits(a)
#define mp_2expt(a, b) ltc_mp.twoexpt(a, b)
#define mp_read_radix(a, b, c) ltc_mp.read_radix(a, b, c)
#define mp_toradix(a, b, c) ltc_mp.write_radix(a, b, c)
#define mp_unsigned_bin_size(a) ltc_mp.unsigned_size(a)
#define mp_to_unsigned_bin(a, b) ltc_mp.unsigned_write(a, b)
#define mp_read_unsigned_bin(a, b, c) ltc_mp.unsigned_read(a, b, c)
#define mp_add(a, b, c) ltc_mp.add(a, b, c)
#define mp_add_d(a, b, c) ltc_mp.addi(a, b, c)
#define mp_sub(a, b, c) ltc_mp.sub(a, b, c)
#define mp_sub_d(a, b, c) ltc_mp.subi(a, b, c)
#define mp_mul(a, b, c) ltc_mp.mul(a, b, c)
#define mp_mul_d(a, b, c) ltc_mp.muli(a, b, c)
#define mp_sqr(a, b) ltc_mp.sqr(a, b)
#define mp_sqrtmod_prime(a, b, c) ltc_mp.sqrtmod_prime(a, b, c)
#define mp_div(a, b, c, d) ltc_mp.mpdiv(a, b, c, d)
#define mp_div_2(a, b) ltc_mp.div_2(a, b)
#define mp_mod(a, b, c) ltc_mp.mpdiv(a, b, NULL, c)
#define mp_mod_d(a, b, c) ltc_mp.modi(a, b, c)
#define mp_gcd(a, b, c) ltc_mp.gcd(a, b, c)
#define mp_lcm(a, b, c) ltc_mp.lcm(a, b, c)
#define mp_addmod(a, b, c, d) ltc_mp.addmod(a, b, c, d)
#define mp_submod(a, b, c, d) ltc_mp.submod(a, b, c, d)
#define mp_mulmod(a, b, c, d) ltc_mp.mulmod(a, b, c, d)
#define mp_sqrmod(a, b, c) ltc_mp.sqrmod(a, b, c)
#define mp_invmod(a, b, c) ltc_mp.invmod(a, b, c)
#define mp_montgomery_setup(a, b) ltc_mp.montgomery_setup(a, b)
#define mp_montgomery_normalization(a, b) ltc_mp.montgomery_normalization(a, b)
#define mp_montgomery_reduce(a, b, c) ltc_mp.montgomery_reduce(a, b, c)
#define mp_montgomery_free(a) ltc_mp.montgomery_deinit(a)
#define mp_exptmod(a,b,c,d) ltc_mp.exptmod(a,b,c,d)
#define mp_prime_is_prime(a, b, c) ltc_mp.isprime(a, b, c)
#define mp_iszero(a) (mp_cmp_d(a, 0) == LTC_MP_EQ ? LTC_MP_YES : LTC_MP_NO)
#define mp_isodd(a) (mp_get_digit_count(a) > 0 ? (mp_get_digit(a, 0) & 1 ? LTC_MP_YES : LTC_MP_NO) : LTC_MP_NO)
#define mp_exch(a, b) do { void *ABC__tmp = a; a = b; b = ABC__tmp; } while(0)
#define mp_tohex(a, b) mp_toradix(a, b, 16)
#define mp_rand(a, b) ltc_mp.rand(a, b)
#endif
/* tomcrypt_misc.h */
void copy_or_zeromem(const unsigned char* src, unsigned char* dest, unsigned long len, int coz);
int pbes_decrypt(const pbes_arg *arg, unsigned char *dec_data, unsigned long *dec_size);
int pbes1_extract(const ltc_asn1_list *s, pbes_arg *res);
int pbes2_extract(const ltc_asn1_list *s, pbes_arg *res);
/* tomcrypt_pk.h */
int rand_bn_bits(void *N, int bits, prng_state *prng, int wprng);
int rand_bn_upto(void *N, void *limit, prng_state *prng, int wprng);
int pk_get_oid(enum ltc_oid_id id, const char **st);
int pk_oid_str_to_num(const char *OID, unsigned long *oid, unsigned long *oidlen);
int pk_oid_num_to_str(const unsigned long *oid, unsigned long oidlen, char *OID, unsigned long *outlen);
/* ---- DH Routines ---- */
#ifdef LTC_MRSA
int rsa_init(rsa_key *key);
void rsa_shrink_key(rsa_key *key);
#endif /* LTC_MRSA */
/* ---- DH Routines ---- */
#ifdef LTC_MDH
extern const ltc_dh_set_type ltc_dh_sets[];
int dh_check_pubkey(const dh_key *key);
#endif /* LTC_MDH */
/* ---- ECC Routines ---- */
#ifdef LTC_MECC
int ecc_set_curve_from_mpis(void *a, void *b, void *prime, void *order, void *gx, void *gy, unsigned long cofactor, ecc_key *key);
int ecc_copy_curve(const ecc_key *srckey, ecc_key *key);
int ecc_set_curve_by_size(int size, ecc_key *key);
int ecc_import_subject_public_key_info(const unsigned char *in, unsigned long inlen, ecc_key *key);
#ifdef LTC_SSH
int ecc_ssh_ecdsa_encode_name(char *buffer, unsigned long *buflen, const ecc_key *key);
#endif
/* low level functions */
ecc_point *ltc_ecc_new_point(void);
void ltc_ecc_del_point(ecc_point *p);
int ltc_ecc_set_point_xyz(ltc_mp_digit x, ltc_mp_digit y, ltc_mp_digit z, ecc_point *p);
int ltc_ecc_copy_point(const ecc_point *src, ecc_point *dst);
int ltc_ecc_is_point(const ltc_ecc_dp *dp, void *x, void *y);
int ltc_ecc_is_point_at_infinity(const ecc_point *P, void *modulus, int *retval);
int ltc_ecc_import_point(const unsigned char *in, unsigned long inlen, void *prime, void *a, void *b, void *x, void *y);
int ltc_ecc_export_point(unsigned char *out, unsigned long *outlen, void *x, void *y, unsigned long size, int compressed);
int ltc_ecc_verify_key(const ecc_key *key);
/* point ops (mp == montgomery digit) */
#if !defined(LTC_MECC_ACCEL) || defined(LTM_DESC) || defined(GMP_DESC)
/* R = 2P */
int ltc_ecc_projective_dbl_point(const ecc_point *P, ecc_point *R, void *ma, void *modulus, void *mp);
/* R = P + Q */
int ltc_ecc_projective_add_point(const ecc_point *P, const ecc_point *Q, ecc_point *R, void *ma, void *modulus, void *mp);
#endif
#if defined(LTC_MECC_FP)
/* optimized point multiplication using fixed point cache (HAC algorithm 14.117) */
int ltc_ecc_fp_mulmod(void *k, ecc_point *G, ecc_point *R, void *a, void *modulus, int map);
/* functions for saving/loading/freeing/adding to fixed point cache */
int ltc_ecc_fp_save_state(unsigned char **out, unsigned long *outlen);
int ltc_ecc_fp_restore_state(unsigned char *in, unsigned long inlen);
void ltc_ecc_fp_free(void);
int ltc_ecc_fp_add_point(ecc_point *g, void *modulus, int lock);
/* lock/unlock all points currently in fixed point cache */
void ltc_ecc_fp_tablelock(int lock);
#endif
/* R = kG */
int ltc_ecc_mulmod(void *k, const ecc_point *G, ecc_point *R, void *a, void *modulus, int map);
#ifdef LTC_ECC_SHAMIR
/* kA*A + kB*B = C */
int ltc_ecc_mul2add(const ecc_point *A, void *kA,
const ecc_point *B, void *kB,
ecc_point *C,
void *ma,
void *modulus);
#ifdef LTC_MECC_FP
/* Shamir's trick with optimized point multiplication using fixed point cache */
int ltc_ecc_fp_mul2add(const ecc_point *A, void *kA,
const ecc_point *B, void *kB,
ecc_point *C,
void *ma,
void *modulus);
#endif
#endif
/* map P to affine from projective */
int ltc_ecc_map(ecc_point *P, void *modulus, void *mp);
#endif /* LTC_MECC */
#ifdef LTC_MDSA
int dsa_int_validate_xy(const dsa_key *key, int *stat);
int dsa_int_validate_pqg(const dsa_key *key, int *stat);
int dsa_int_validate_primes(const dsa_key *key, int *stat);
#endif /* LTC_MDSA */
#ifdef LTC_CURVE25519
int tweetnacl_crypto_sign(
unsigned char *sm,unsigned long long *smlen,
const unsigned char *m,unsigned long long mlen,
const unsigned char *sk, const unsigned char *pk);
int tweetnacl_crypto_sign_open(
int *stat,
unsigned char *m,unsigned long long *mlen,
const unsigned char *sm,unsigned long long smlen,
const unsigned char *pk);
int tweetnacl_crypto_sign_keypair(prng_state *prng, int wprng, unsigned char *pk,unsigned char *sk);
int tweetnacl_crypto_sk_to_pk(unsigned char *pk, const unsigned char *sk);
int tweetnacl_crypto_scalarmult(unsigned char *q, const unsigned char *n, const unsigned char *p);
int tweetnacl_crypto_scalarmult_base(unsigned char *q,const unsigned char *n);
typedef int (*sk_to_pk)(unsigned char *pk ,const unsigned char *sk);
int ec25519_import_pkcs8(const unsigned char *in, unsigned long inlen,
const void *pwd, unsigned long pwdlen,
enum ltc_oid_id id, sk_to_pk fp,
curve25519_key *key);
int ec25519_export( unsigned char *out, unsigned long *outlen,
int which,
const curve25519_key *key);
#endif /* LTC_CURVE25519 */
#ifdef LTC_DER
#define LTC_ASN1_IS_TYPE(e, t) (((e) != NULL) && ((e)->type == (t)))
/* DER handling */
int der_decode_custom_type_ex(const unsigned char *in, unsigned long inlen,
ltc_asn1_list *root,
ltc_asn1_list *list, unsigned long outlen, unsigned int flags);
int der_encode_asn1_identifier(const ltc_asn1_list *id, unsigned char *out, unsigned long *outlen);
int der_decode_asn1_identifier(const unsigned char *in, unsigned long *inlen, ltc_asn1_list *id);
int der_length_asn1_identifier(const ltc_asn1_list *id, unsigned long *idlen);
int der_encode_asn1_length(unsigned long len, unsigned char* out, unsigned long* outlen);
int der_decode_asn1_length(const unsigned char *in, unsigned long *inlen, unsigned long *outlen);
int der_length_asn1_length(unsigned long len, unsigned long *outlen);
int der_length_sequence_ex(const ltc_asn1_list *list, unsigned long inlen,
unsigned long *outlen, unsigned long *payloadlen);
extern const ltc_asn1_type der_asn1_tag_to_type_map[];
extern const unsigned long der_asn1_tag_to_type_map_sz;
extern const int der_asn1_type_to_identifier_map[];
extern const unsigned long der_asn1_type_to_identifier_map_sz;
int der_decode_sequence_multi_ex(const unsigned char *in, unsigned long inlen, unsigned int flags, ...);
int der_teletex_char_encode(int c);
int der_teletex_value_decode(int v);
int der_utf8_valid_char(const wchar_t c);
typedef int (*public_key_decode_cb)(const unsigned char *in, unsigned long inlen, void *ctx);
int x509_decode_public_key_from_certificate(const unsigned char *in, unsigned long inlen,
enum ltc_oid_id algorithm, ltc_asn1_type param_type,
ltc_asn1_list* parameters, unsigned long *parameters_len,
public_key_decode_cb callback, void *ctx);
/* SUBJECT PUBLIC KEY INFO */
int x509_encode_subject_public_key_info(unsigned char *out, unsigned long *outlen,
unsigned int algorithm, const void* public_key, unsigned long public_key_len,
ltc_asn1_type parameters_type, ltc_asn1_list* parameters, unsigned long parameters_len);
int x509_decode_subject_public_key_info(const unsigned char *in, unsigned long inlen,
unsigned int algorithm, void* public_key, unsigned long* public_key_len,
ltc_asn1_type parameters_type, ltc_asn1_list* parameters, unsigned long *parameters_len);
int pk_oid_cmp_with_ulong(const char *o1, const unsigned long *o2, unsigned long o2size);
int pk_oid_cmp_with_asn1(const char *o1, const ltc_asn1_list *o2);
#endif /* LTC_DER */
/* tomcrypt_pkcs.h */
#ifdef LTC_PKCS_8
int pkcs8_decode_flexi(const unsigned char *in, unsigned long inlen,
const void *pwd, unsigned long pwdlen,
ltc_asn1_list **decoded_list);
#endif /* LTC_PKCS_8 */
#ifdef LTC_PKCS_12
int pkcs12_utf8_to_utf16(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
int pkcs12_kdf( int hash_id,
const unsigned char *pw, unsigned long pwlen,
const unsigned char *salt, unsigned long saltlen,
unsigned int iterations, unsigned char purpose,
unsigned char *out, unsigned long outlen);
#endif /* LTC_PKCS_12 */
/* tomcrypt_prng.h */
#define LTC_PRNG_EXPORT(which) \
int which ## _export(unsigned char *out, unsigned long *outlen, prng_state *prng) \
{ \
unsigned long len = which ## _desc.export_size; \
\
LTC_ARGCHK(prng != NULL); \
LTC_ARGCHK(out != NULL); \
LTC_ARGCHK(outlen != NULL); \
\
if (*outlen < len) { \
*outlen = len; \
return CRYPT_BUFFER_OVERFLOW; \
} \
\
if (which ## _read(out, len, prng) != len) { \
return CRYPT_ERROR_READPRNG; \
} \
\
*outlen = len; \
return CRYPT_OK; \
}
/* extract a byte portably */
#ifdef _MSC_VER
#define LTC_BYTE(x, n) ((unsigned char)((x) >> (8 * (n))))
#else
#define LTC_BYTE(x, n) (((x) >> (8 * (n))) & 255)
#endif

View file

@ -0,0 +1,232 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/* ---- PRNG Stuff ---- */
#ifdef LTC_YARROW
struct yarrow_prng {
int cipher, hash;
unsigned char pool[MAXBLOCKSIZE];
symmetric_CTR ctr;
};
#endif
#ifdef LTC_RC4
struct rc4_prng {
rc4_state s;
};
#endif
#ifdef LTC_CHACHA20_PRNG
struct chacha20_prng {
chacha_state s; /* chacha state */
unsigned char ent[40]; /* entropy buffer */
unsigned long idx; /* entropy counter */
};
#endif
#ifdef LTC_FORTUNA
struct fortuna_prng {
hash_state pool[LTC_FORTUNA_POOLS]; /* the pools */
symmetric_key skey;
unsigned char K[32], /* the current key */
IV[16]; /* IV for CTR mode */
unsigned long pool_idx, /* current pool we will add to */
pool0_len, /* length of 0'th pool */
wd;
ulong64 reset_cnt; /* number of times we have reset */
};
#endif
#ifdef LTC_SOBER128
struct sober128_prng {
sober128_state s; /* sober128 state */
unsigned char ent[40]; /* entropy buffer */
unsigned long idx; /* entropy counter */
};
#endif
typedef struct {
union {
char dummy[1];
#ifdef LTC_YARROW
struct yarrow_prng yarrow;
#endif
#ifdef LTC_RC4
struct rc4_prng rc4;
#endif
#ifdef LTC_CHACHA20_PRNG
struct chacha20_prng chacha;
#endif
#ifdef LTC_FORTUNA
struct fortuna_prng fortuna;
#endif
#ifdef LTC_SOBER128
struct sober128_prng sober128;
#endif
};
short ready; /* ready flag 0-1 */
LTC_MUTEX_TYPE(lock) /* lock */
} prng_state;
/** PRNG descriptor */
extern struct ltc_prng_descriptor {
/** Name of the PRNG */
const char *name;
/** size in bytes of exported state */
int export_size;
/** Start a PRNG state
@param prng [out] The state to initialize
@return CRYPT_OK if successful
*/
int (*start)(prng_state *prng);
/** Add entropy to the PRNG
@param in The entropy
@param inlen Length of the entropy (octets)\
@param prng The PRNG state
@return CRYPT_OK if successful
*/
int (*add_entropy)(const unsigned char *in, unsigned long inlen, prng_state *prng);
/** Ready a PRNG state to read from
@param prng The PRNG state to ready
@return CRYPT_OK if successful
*/
int (*ready)(prng_state *prng);
/** Read from the PRNG
@param out [out] Where to store the data
@param outlen Length of data desired (octets)
@param prng The PRNG state to read from
@return Number of octets read
*/
unsigned long (*read)(unsigned char *out, unsigned long outlen, prng_state *prng);
/** Terminate a PRNG state
@param prng The PRNG state to terminate
@return CRYPT_OK if successful
*/
int (*done)(prng_state *prng);
/** Export a PRNG state
@param out [out] The destination for the state
@param outlen [in/out] The max size and resulting size of the PRNG state
@param prng The PRNG to export
@return CRYPT_OK if successful
*/
int (*pexport)(unsigned char *out, unsigned long *outlen, prng_state *prng);
/** Import a PRNG state
@param in The data to import
@param inlen The length of the data to import (octets)
@param prng The PRNG to initialize/import
@return CRYPT_OK if successful
*/
int (*pimport)(const unsigned char *in, unsigned long inlen, prng_state *prng);
/** Self-test the PRNG
@return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled
*/
int (*test)(void);
} prng_descriptor[];
#ifdef LTC_YARROW
int yarrow_start(prng_state *prng);
int yarrow_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng);
int yarrow_ready(prng_state *prng);
unsigned long yarrow_read(unsigned char *out, unsigned long outlen, prng_state *prng);
int yarrow_done(prng_state *prng);
int yarrow_export(unsigned char *out, unsigned long *outlen, prng_state *prng);
int yarrow_import(const unsigned char *in, unsigned long inlen, prng_state *prng);
int yarrow_test(void);
extern const struct ltc_prng_descriptor yarrow_desc;
#endif
#ifdef LTC_FORTUNA
int fortuna_start(prng_state *prng);
int fortuna_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng);
int fortuna_ready(prng_state *prng);
unsigned long fortuna_read(unsigned char *out, unsigned long outlen, prng_state *prng);
int fortuna_done(prng_state *prng);
int fortuna_export(unsigned char *out, unsigned long *outlen, prng_state *prng);
int fortuna_import(const unsigned char *in, unsigned long inlen, prng_state *prng);
int fortuna_test(void);
extern const struct ltc_prng_descriptor fortuna_desc;
#endif
#ifdef LTC_RC4
int rc4_start(prng_state *prng);
int rc4_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng);
int rc4_ready(prng_state *prng);
unsigned long rc4_read(unsigned char *out, unsigned long outlen, prng_state *prng);
int rc4_done(prng_state *prng);
int rc4_export(unsigned char *out, unsigned long *outlen, prng_state *prng);
int rc4_import(const unsigned char *in, unsigned long inlen, prng_state *prng);
int rc4_test(void);
extern const struct ltc_prng_descriptor rc4_desc;
#endif
#ifdef LTC_CHACHA20_PRNG
int chacha20_prng_start(prng_state *prng);
int chacha20_prng_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng);
int chacha20_prng_ready(prng_state *prng);
unsigned long chacha20_prng_read(unsigned char *out, unsigned long outlen, prng_state *prng);
int chacha20_prng_done(prng_state *prng);
int chacha20_prng_export(unsigned char *out, unsigned long *outlen, prng_state *prng);
int chacha20_prng_import(const unsigned char *in, unsigned long inlen, prng_state *prng);
int chacha20_prng_test(void);
extern const struct ltc_prng_descriptor chacha20_prng_desc;
#endif
#ifdef LTC_SPRNG
int sprng_start(prng_state *prng);
int sprng_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng);
int sprng_ready(prng_state *prng);
unsigned long sprng_read(unsigned char *out, unsigned long outlen, prng_state *prng);
int sprng_done(prng_state *prng);
int sprng_export(unsigned char *out, unsigned long *outlen, prng_state *prng);
int sprng_import(const unsigned char *in, unsigned long inlen, prng_state *prng);
int sprng_test(void);
extern const struct ltc_prng_descriptor sprng_desc;
#endif
#ifdef LTC_SOBER128
int sober128_start(prng_state *prng);
int sober128_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng);
int sober128_ready(prng_state *prng);
unsigned long sober128_read(unsigned char *out, unsigned long outlen, prng_state *prng);
int sober128_done(prng_state *prng);
int sober128_export(unsigned char *out, unsigned long *outlen, prng_state *prng);
int sober128_import(const unsigned char *in, unsigned long inlen, prng_state *prng);
int sober128_test(void);
extern const struct ltc_prng_descriptor sober128_desc;
#endif
int find_prng(const char *name);
int register_prng(const struct ltc_prng_descriptor *prng);
int unregister_prng(const struct ltc_prng_descriptor *prng);
int register_all_prngs(void);
int prng_is_valid(int idx);
LTC_MUTEX_PROTO(ltc_prng_mutex)
/* Slow RNG you **might** be able to use to seed a PRNG with. Be careful as this
* might not work on all platforms as planned
*/
unsigned long rng_get_bytes(unsigned char *out,
unsigned long outlen,
void (*callback)(void));
int rng_make_prng(int bits, int wprng, prng_state *prng, void (*callback)(void));
#ifdef LTC_PRNG_ENABLE_LTC_RNG
extern unsigned long (*ltc_rng)(unsigned char *out, unsigned long outlen,
void (*callback)(void));
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View file

@ -0,0 +1,87 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
/**
@file compare_testvector.c
Function to compare two testvectors and print a (detailed) error-message if required, Steffen Jaeckel
*/
#if defined(LTC_TEST) && defined(LTC_TEST_DBG)
static void _print_hex(const char* what, const void* v, const unsigned long l)
{
const unsigned char* p = v;
unsigned long x, y = 0, z;
fprintf(stderr, "%s contents: \n", what);
for (x = 0; x < l; ) {
fprintf(stderr, "%02X ", p[x]);
if (!(++x % 16) || x == l) {
if((x % 16) != 0) {
z = 16 - (x % 16);
if(z >= 8)
fprintf(stderr, " ");
for (; z != 0; --z) {
fprintf(stderr, " ");
}
}
fprintf(stderr, " | ");
for(; y < x; y++) {
if((y % 8) == 0)
fprintf(stderr, " ");
if(isgraph(p[y]))
fprintf(stderr, "%c", p[y]);
else
fprintf(stderr, ".");
}
fprintf(stderr, "\n");
}
else if((x % 8) == 0) {
fprintf(stderr, " ");
}
}
}
#endif
/**
Compare two test-vectors
@param is The data as it is
@param is_len The length of is
@param should The data as it should
@param should_len The length of should
@param what The type of the data
@param which The iteration count
@return 0 on equality, -1 or 1 on difference
*/
int compare_testvector(const void* is, const unsigned long is_len, const void* should, const unsigned long should_len, const char* what, int which)
{
int res = 0;
if(is_len != should_len)
res = is_len > should_len ? -1 : 1;
else
res = XMEMCMP(is, should, is_len);
#if defined(LTC_TEST) && defined(LTC_TEST_DBG)
if (res != 0) {
fprintf(stderr, "Testvector #%i of %s failed:\n", which, what);
_print_hex("SHOULD", should, should_len);
_print_hex("IS ", is, is_len);
}
#else
LTC_UNUSED_PARAM(which);
LTC_UNUSED_PARAM(what);
#endif
return res;
}
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View file

@ -0,0 +1,27 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
/**
@file crypt_argchk.c
Perform argument checking, Tom St Denis
*/
#if (ARGTYPE == 0)
void crypt_argchk(const char *v, const char *s, int d)
{
fprintf(stderr, "LTC_ARGCHK '%s' failure on line %d of file %s\n",
v, d, s);
abort();
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View file

@ -0,0 +1,25 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
/**
@file crypt_cipher_descriptor.c
Stores the cipher descriptor table, Tom St Denis
*/
struct ltc_cipher_descriptor cipher_descriptor[TAB_SIZE] = {
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
};
LTC_MUTEX_GLOBAL(ltc_cipher_mutex)
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View file

@ -0,0 +1,34 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
/**
@file crypt_cipher_is_valid.c
Determine if cipher is valid, Tom St Denis
*/
/*
Test if a cipher index is valid
@param idx The index of the cipher to search for
@return CRYPT_OK if valid
*/
int cipher_is_valid(int idx)
{
LTC_MUTEX_LOCK(&ltc_cipher_mutex);
if (idx < 0 || idx >= TAB_SIZE || cipher_descriptor[idx].name == NULL) {
LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
return CRYPT_INVALID_CIPHER;
}
LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
return CRYPT_OK;
}
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View file

@ -0,0 +1,52 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
/**
@file crypt_register_cipher.c
Register a cipher, Tom St Denis
*/
/**
Register a cipher with the descriptor table
@param cipher The cipher you wish to register
@return value >= 0 if successfully added (or already present), -1 if unsuccessful
*/
int register_cipher(const struct ltc_cipher_descriptor *cipher)
{
int x;
LTC_ARGCHK(cipher != NULL);
/* is it already registered? */
LTC_MUTEX_LOCK(&ltc_cipher_mutex);
for (x = 0; x < TAB_SIZE; x++) {
if (cipher_descriptor[x].name != NULL && cipher_descriptor[x].ID == cipher->ID) {
LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
return x;
}
}
/* find a blank spot */
for (x = 0; x < TAB_SIZE; x++) {
if (cipher_descriptor[x].name == NULL) {
XMEMCPY(&cipher_descriptor[x], cipher, sizeof(struct ltc_cipher_descriptor));
LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
return x;
}
}
/* no spot */
LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
return -1;
}
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View file

@ -0,0 +1,32 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
/**
@file zeromem.c
Zero a block of memory, Tom St Denis
*/
/**
Zero a block of memory
@param out The destination of the area to zero
@param outlen The length of the area to zero (octets)
*/
void zeromem(volatile void *out, size_t outlen)
{
volatile char *mem = out;
LTC_ARGCHKVD(out != NULL);
while (outlen-- > 0) {
*mem++ = '\0';
}
}
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View file

@ -0,0 +1,95 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
/**
@file cbc_decrypt.c
CBC implementation, encrypt block, Tom St Denis
*/
#ifdef LTC_CBC_MODE
/**
CBC decrypt
@param ct Ciphertext
@param pt [out] Plaintext
@param len The number of bytes to process (must be multiple of block length)
@param cbc CBC state
@return CRYPT_OK if successful
*/
int cbc_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CBC *cbc)
{
int x, err;
unsigned char tmp[16];
#ifdef LTC_FAST
LTC_FAST_TYPE tmpy;
#else
unsigned char tmpy;
#endif
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(cbc != NULL);
if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) {
return err;
}
/* is blocklen valid? */
if (cbc->blocklen < 1 || cbc->blocklen > (int)sizeof(cbc->IV) || cbc->blocklen > (int)sizeof(tmp)) {
return CRYPT_INVALID_ARG;
}
if (len % cbc->blocklen) {
return CRYPT_INVALID_ARG;
}
#ifdef LTC_FAST
if (cbc->blocklen % sizeof(LTC_FAST_TYPE)) {
return CRYPT_INVALID_ARG;
}
#endif
if (cipher_descriptor[cbc->cipher].accel_cbc_decrypt != NULL) {
return cipher_descriptor[cbc->cipher].accel_cbc_decrypt(ct, pt, len / cbc->blocklen, cbc->IV, &cbc->key);
} else {
while (len) {
/* decrypt */
if ((err = cipher_descriptor[cbc->cipher].ecb_decrypt(ct, tmp, &cbc->key)) != CRYPT_OK) {
return err;
}
/* xor IV against plaintext */
#if defined(LTC_FAST)
for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) {
tmpy = *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)cbc->IV + x)) ^ *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)tmp + x));
*(LTC_FAST_TYPE_PTR_CAST((unsigned char *)cbc->IV + x)) = *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)ct + x));
*(LTC_FAST_TYPE_PTR_CAST((unsigned char *)pt + x)) = tmpy;
}
#else
for (x = 0; x < cbc->blocklen; x++) {
tmpy = tmp[x] ^ cbc->IV[x];
cbc->IV[x] = ct[x];
pt[x] = tmpy;
}
#endif
ct += cbc->blocklen;
pt += cbc->blocklen;
len -= cbc->blocklen;
}
}
return CRYPT_OK;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View file

@ -0,0 +1,96 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
/**
@file cbc_encrypt.c
CBC implementation, encrypt block, Tom St Denis
*/
#ifdef LTC_CBC_MODE
/**
CBC encrypt
@param pt Plaintext
@param ct [out] Ciphertext
@param len The number of bytes to process (must be multiple of block length)
@param cbc CBC state
@return CRYPT_OK if successful
*/
int cbc_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CBC *cbc)
{
int x, err;
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(cbc != NULL);
if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) {
return err;
}
/* is blocklen valid? */
if (cbc->blocklen < 1 || cbc->blocklen > (int)sizeof(cbc->IV)) {
return CRYPT_INVALID_ARG;
}
if (len % cbc->blocklen) {
return CRYPT_INVALID_ARG;
}
#ifdef LTC_FAST
if (cbc->blocklen % sizeof(LTC_FAST_TYPE)) {
return CRYPT_INVALID_ARG;
}
#endif
if (cipher_descriptor[cbc->cipher].accel_cbc_encrypt != NULL) {
return cipher_descriptor[cbc->cipher].accel_cbc_encrypt(pt, ct, len / cbc->blocklen, cbc->IV, &cbc->key);
} else {
while (len) {
/* xor IV against plaintext */
#if defined(LTC_FAST)
for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) {
*(LTC_FAST_TYPE_PTR_CAST((unsigned char *)cbc->IV + x)) ^= *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)pt + x));
}
#else
for (x = 0; x < cbc->blocklen; x++) {
cbc->IV[x] ^= pt[x];
}
#endif
/* encrypt */
if ((err = cipher_descriptor[cbc->cipher].ecb_encrypt(cbc->IV, ct, &cbc->key)) != CRYPT_OK) {
return err;
}
/* store IV [ciphertext] for a future block */
#if defined(LTC_FAST)
for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) {
*(LTC_FAST_TYPE_PTR_CAST((unsigned char *)cbc->IV + x)) = *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)ct + x));
}
#else
for (x = 0; x < cbc->blocklen; x++) {
cbc->IV[x] = ct[x];
}
#endif
ct += cbc->blocklen;
pt += cbc->blocklen;
len -= cbc->blocklen;
}
}
return CRYPT_OK;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View file

@ -0,0 +1,60 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
/**
@file cbc_start.c
CBC implementation, start chain, Tom St Denis
*/
#ifdef LTC_CBC_MODE
/**
Initialize a CBC context
@param cipher The index of the cipher desired
@param IV The initialization vector
@param key The secret key
@param keylen The length of the secret key (octets)
@param num_rounds Number of rounds in the cipher desired (0 for default)
@param cbc The CBC state to initialize
@return CRYPT_OK if successful
*/
int cbc_start(int cipher, const unsigned char *IV, const unsigned char *key,
int keylen, int num_rounds, symmetric_CBC *cbc)
{
int x, err;
LTC_ARGCHK(IV != NULL);
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(cbc != NULL);
/* bad param? */
if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
return err;
}
/* setup cipher */
if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &cbc->key)) != CRYPT_OK) {
return err;
}
/* copy IV */
cbc->blocklen = cipher_descriptor[cipher].block_length;
cbc->cipher = cipher;
for (x = 0; x < cbc->blocklen; x++) {
cbc->IV[x] = IV[x];
}
return CRYPT_OK;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */