chore: update deps

This commit is contained in:
Rim
2025-02-20 06:23:40 -05:00
parent de69a8a5ec
commit 8c7893f668
1045 changed files with 27193 additions and 13903 deletions

View File

@ -34,6 +34,7 @@ const struct ltc_cipher_descriptor aes_desc =
#define AES_SETUP aes_enc_setup
#define AES_ENC aes_enc_ecb_encrypt
#define AES_DONE aes_enc_done
#define AES_TEST aes_enc_test
#define AES_KS aes_enc_keysize
const struct ltc_cipher_descriptor aes_enc_desc =
@ -48,7 +49,7 @@ const struct ltc_cipher_descriptor aes_enc_desc =
#endif
/* Code partially borrowed from https://software.intel.com/content/www/us/en/develop/articles/intel-sha-extensions.html */
#if defined(LTC_HAS_AES_NI)
#if defined(LTC_AES_NI)
static LTC_INLINE int s_aesni_is_supported(void)
{
static int initialized = 0, is_supported = 0;
@ -56,18 +57,18 @@ static LTC_INLINE int s_aesni_is_supported(void)
if (initialized == 0) {
int a, b, c, d;
/* Look for CPUID.1.0.ECX[25]
/* Look for CPUID.1.0.ECX[19] (SSE4.1) and CPUID.1.0.ECX[25] (AES-NI)
* EAX = 1, ECX = 0
*/
a = 1;
c = 0;
asm volatile ("cpuid"
__asm__ volatile ("cpuid"
:"=a"(a), "=b"(b), "=c"(c), "=d"(d)
:"a"(a), "c"(c)
);
is_supported = ((c >> 25) & 1);
is_supported = ((c >> 19) & 1) && ((c >> 25) & 1);
initialized = 1;
}
@ -92,7 +93,7 @@ int aesni_is_supported(void)
*/
int AES_SETUP(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
{
#ifdef LTC_HAS_AES_NI
#ifdef LTC_AES_NI
if (s_aesni_is_supported()) {
return aesni_setup(key, keylen, num_rounds, skey);
}
@ -110,7 +111,7 @@ int AES_SETUP(const unsigned char *key, int keylen, int num_rounds, symmetric_ke
*/
int AES_ENC(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey)
{
#ifdef LTC_HAS_AES_NI
#ifdef LTC_AES_NI
if (s_aesni_is_supported()) {
return aesni_ecb_encrypt(pt, ct, skey);
}
@ -119,6 +120,7 @@ int AES_ENC(const unsigned char *pt, unsigned char *ct, const symmetric_key *ske
}
#ifndef ENCRYPT_ONLY
/**
Decrypts a block of text with AES
@param ct The input ciphertext (16 bytes)
@ -128,13 +130,14 @@ int AES_ENC(const unsigned char *pt, unsigned char *ct, const symmetric_key *ske
*/
int AES_DEC(const unsigned char *ct, unsigned char *pt, const symmetric_key *skey)
{
#ifdef LTC_HAS_AES_NI
#ifdef LTC_AES_NI
if (s_aesni_is_supported()) {
return aesni_ecb_decrypt(ct, pt, skey);
}
#endif
return rijndael_ecb_decrypt(ct, pt, skey);
}
#endif /* ENCRYPT_ONLY */
/**
Performs a self-test of the AES block cipher
@ -181,26 +184,33 @@ int AES_TEST(void)
symmetric_key key;
unsigned char tmp[2][16];
int i, y;
int i;
#ifndef ENCRYPT_ONLY
int y;
#endif
for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
zeromem(&key, sizeof(key));
if ((err = aes_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) {
if ((err = AES_SETUP(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) {
return err;
}
aes_ecb_encrypt(tests[i].pt, tmp[0], &key);
aes_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)) {
AES_ENC(tests[i].pt, tmp[0], &key);
if (compare_testvector(tmp[0], 16, tests[i].ct, 16, "AES Encrypt", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
#ifndef ENCRYPT_ONLY
AES_DEC(tmp[0], tmp[1], &key);
if (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++) aes_ecb_encrypt(tmp[0], tmp[0], &key);
for (y = 0; y < 1000; y++) aes_ecb_decrypt(tmp[0], tmp[0], &key);
for (y = 0; y < 1000; y++) AES_ENC(tmp[0], tmp[0], &key);
for (y = 0; y < 1000; y++) AES_DEC(tmp[0], tmp[0], &key);
for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
#endif
}
return CRYPT_OK;
#endif

View File

@ -9,7 +9,7 @@
#include "tomcrypt_private.h"
#if defined(LTC_HAS_AES_NI)
#if defined(LTC_AES_NI)
const struct ltc_cipher_descriptor aesni_desc =
{
@ -42,6 +42,7 @@ static const ulong32 rcon[] = {
@param skey The key in as scheduled by this function.
@return CRYPT_OK if successful
*/
LTC_ATTRIBUTE((__target__("aes,sse4.1")))
int aesni_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
{
int i;
@ -168,6 +169,7 @@ int aesni_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
LTC_ATTRIBUTE((__target__("aes")))
#ifdef LTC_CLEAN_STACK
static int s_aesni_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey)
#else
@ -219,6 +221,7 @@ int aesni_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetri
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
LTC_ATTRIBUTE((__target__("aes")))
#ifdef LTC_CLEAN_STACK
static int s_aesni_ecb_decrypt(const unsigned char *ct, unsigned char *pt, const symmetric_key *skey)
#else

View File

@ -12,7 +12,7 @@ const struct ltc_cipher_descriptor blowfish_desc =
{
"blowfish",
0,
8, 56, 8, 16,
8, 72, 8, 16,
&blowfish_setup,
&blowfish_ecb_encrypt,
&blowfish_ecb_decrypt,
@ -433,7 +433,7 @@ int blowfish_setup(const unsigned char *key, int keylen, int num_rounds,
symmetric_key *skey)
{
/* check key length */
if (keylen < 8 || keylen > 56) {
if (keylen < 8 || keylen > 72) {
return CRYPT_INVALID_KEYSIZE;
}
/* check rounds */
@ -648,8 +648,8 @@ int blowfish_keysize(int *keysize)
if (*keysize < 8) {
return CRYPT_INVALID_KEYSIZE;
}
if (*keysize > 56) {
*keysize = 56;
if (*keysize > 72) {
*keysize = 72;
}
return CRYPT_OK;
}

View File

@ -40,6 +40,20 @@ const struct ltc_cipher_descriptor des3_desc =
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
const struct ltc_cipher_descriptor desx_desc =
{
"desx",
27,
24, 24, 8, 16,
&desx_setup,
&desx_ecb_encrypt,
&desx_ecb_decrypt,
&desx_test,
&desx_done,
&desx_keysize,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
static const ulong32 bytebit[8] =
{
0200, 0100, 040, 020, 010, 04, 02, 01
@ -1511,7 +1525,7 @@ static void desfunc(ulong32 *block, const ulong32 *keys)
#endif
/**
Initialize the LTC_DES block cipher
Initialize the DES 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)
@ -1538,7 +1552,36 @@ int des_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_ke
}
/**
Initialize the 3LTC_DES-EDE block cipher
Initialize the DES-X 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 desx_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
{
if(num_rounds != 0 && num_rounds != 16) {
return CRYPT_INVALID_ROUNDS;
}
if (keylen != 24) {
return CRYPT_INVALID_KEYSIZE;
}
deskey(key, EN0, skey->desx.ek);
deskey(key, DE1, skey->desx.dk);
LOAD32H(skey->desx.k[0][0], key + 8);
LOAD32H(skey->desx.k[0][1], key + 12);
LOAD32H(skey->desx.k[1][0], key + 16);
LOAD32H(skey->desx.k[1][1], key + 20);
return CRYPT_OK;
}
/**
Initialize the 3DES-EDE 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)
@ -1580,7 +1623,7 @@ int des3_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_k
}
/**
Encrypts a block of text with LTC_DES
Encrypts a block of text with DES
@param pt The input plaintext (8 bytes)
@param ct The output ciphertext (8 bytes)
@param skey The key as scheduled
@ -1601,7 +1644,7 @@ int des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_
}
/**
Decrypts a block of text with LTC_DES
Decrypts a block of text with DES
@param ct The input ciphertext (8 bytes)
@param pt The output plaintext (8 bytes)
@param skey The key as scheduled
@ -1622,7 +1665,57 @@ int des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, const symmetric_
}
/**
Encrypts a block of text with 3LTC_DES-EDE
Encrypts a block of text with DES-X
@param pt The input plaintext (8 bytes)
@param ct The output ciphertext (8 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
int desx_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey)
{
ulong32 work[2];
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(skey != NULL);
LOAD32H(work[0], pt+0);
LOAD32H(work[1], pt+4);
work[0] ^= skey->desx.k[0][0];
work[1] ^= skey->desx.k[0][1];
desfunc(work, skey->desx.ek);
work[0] ^= skey->desx.k[1][0];
work[1] ^= skey->desx.k[1][1];
STORE32H(work[0],ct+0);
STORE32H(work[1],ct+4);
return CRYPT_OK;
}
/**
Decrypts a block of text with DES-X
@param ct The input ciphertext (8 bytes)
@param pt The output plaintext (8 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
int desx_ecb_decrypt(const unsigned char *ct, unsigned char *pt, const symmetric_key *skey)
{
ulong32 work[2];
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(skey != NULL);
LOAD32H(work[0], ct+0);
LOAD32H(work[1], ct+4);
work[0] ^= skey->desx.k[1][0];
work[1] ^= skey->desx.k[1][1];
desfunc(work, skey->des.dk);
work[0] ^= skey->desx.k[0][0];
work[1] ^= skey->desx.k[0][1];
STORE32H(work[0],pt+0);
STORE32H(work[1],pt+4);
return CRYPT_OK;
}
/**
Encrypts a block of text with 3DES-EDE
@param pt The input plaintext (8 bytes)
@param ct The output ciphertext (8 bytes)
@param skey The key as scheduled
@ -1646,7 +1739,7 @@ int des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric
}
/**
Decrypts a block of text with 3LTC_DES-EDE
Decrypts a block of text with 3DES-EDE
@param ct The input ciphertext (8 bytes)
@param pt The output plaintext (8 bytes)
@param skey The key as scheduled
@ -1669,7 +1762,7 @@ int des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, const symmetric
}
/**
Performs a self-test of the LTC_DES block cipher
Performs a self-test of the DES block cipher
@return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
*/
int des_test(void)
@ -1964,6 +2057,39 @@ int des_test(void)
#endif
}
int desx_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
unsigned char key[24], pt[8], tmp[8];
symmetric_key skey;
int i, err;
if ((err = des_test()) != CRYPT_OK) {
return err;
}
/* See if we can encrypt all zero bytes 1000 times, decrypt and come back to where we started */
for (i = 0; i < 24; i++) key[i] = i;
if ((err = desx_setup(key, 24, 0, &skey)) != CRYPT_OK) {
return err;
}
for (i = 0; i < 8; i++) pt[i] = tmp[i] = 0;
for (i = 0; i < 1000; i++) desx_ecb_encrypt(tmp, tmp, &skey);
for (i = 0; i < 1000; i++) desx_ecb_decrypt(tmp, tmp, &skey);
if (compare_testvector(tmp, 8, pt, 8, "DES-X", 0) != 0) {
return CRYPT_FAIL_TESTVECTOR;
}
return CRYPT_OK;
#endif
}
int des3_test(void)
{
#ifndef LTC_TEST
@ -2046,6 +2172,14 @@ void des_done(symmetric_key *skey)
LTC_UNUSED_PARAM(skey);
}
/** Terminate the context
@param skey The scheduled key
*/
void desx_done(symmetric_key *skey)
{
LTC_UNUSED_PARAM(skey);
}
/** Terminate the context
@param skey The scheduled key
*/
@ -2070,6 +2204,21 @@ int des_keysize(int *keysize)
return CRYPT_OK;
}
/**
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 desx_keysize(int *keysize)
{
LTC_ARGCHK(keysize != NULL);
if(*keysize < 24) {
return CRYPT_INVALID_KEYSIZE;
}
*keysize = 24;
return CRYPT_OK;
}
/**
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.

377
deps/libtomcrypt/src/ciphers/sm4.c vendored Normal file
View File

@ -0,0 +1,377 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
/**
@brief SM4 block cipher algorithm
@date Oct 2018
@author Chao Wei
SM4 (formerly SMS4) is a block cipher used in the Chinese National
Standard for Wireless LAN WAPI (Wired Authentication and Privacy
Infrastructure).
--from wikipedia:
https://en.wikipedia.org/wiki/SM4_(cipher)
This implimentation follows Chinese National Standard
GM/T 0002-2012
*/
#include "tomcrypt_private.h"
#ifdef LTC_SM4
/*porting to libtomcrypt*/
/*char always 8bits long*/
typedef unsigned char sm4_u8_t;
typedef ulong32 sm4_u32_t;
/*
* S-box defined in section 6.2
* (1) Nonlinear transformation
*/
static const sm4_u8_t sm4_sbox_table[16][16] = {
{0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7,
0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05},
{0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3,
0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99},
{0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a,
0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62},
{0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95,
0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6},
{0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba,
0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8},
{0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b,
0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35},
{0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2,
0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87},
{0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52,
0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e},
{0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5,
0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1},
{0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55,
0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3},
{0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60,
0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f},
{0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f,
0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51},
{0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f,
0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8},
{0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd,
0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0},
{0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e,
0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84},
{0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20,
0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48},
};
/*
* S-box
* defined in section 2.6 S-box
*/
LTC_INLINE static sm4_u8_t s_sm4_sbox(sm4_u8_t a)
{
return sm4_sbox_table[(a >> 4) & 0x0f][a & 0x0f];
}
/*
* Nonlinear transformation t
* defined in section 6.2 (1) Nonelinear transformation t
*
* Here should be big endian.
* But we just convert a 32bit word byte by byte.
* So it's OK if we don't convert the endian order
*/
LTC_INLINE static sm4_u32_t s_sm4_t(sm4_u32_t A)
{
sm4_u8_t a[4];
sm4_u8_t b[4];
sm4_u32_t B;
STORE32H(A, a);
b[0] = s_sm4_sbox(a[0]);
b[1] = s_sm4_sbox(a[1]);
b[2] = s_sm4_sbox(a[2]);
b[3] = s_sm4_sbox(a[3]);
LOAD32H(B, b);
return B;
}
/*
* defined in section 6.2 (2) Linear transformation L
*/
LTC_INLINE static sm4_u32_t s_sm4_L62(sm4_u32_t B)
{
return B ^ ROLc(B, 2) ^ ROLc(B, 10) ^ ROLc(B, 18) ^ ROLc(B, 24);
}
/*
* defined in section 6.2 Permutation T
*/
LTC_INLINE static sm4_u32_t s_sm4_T62(sm4_u32_t Z)
{
return s_sm4_L62(s_sm4_t(Z));
}
/*
* defined in section 7.3 (2) The system parameter FK
*/
static const sm4_u32_t sm4_FK[4] = {
0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc
};
/*
* defined in section 7.3 (3) The fixed parameter CK
* The fixed parameter CK is used in the key expansion algorithm
*/
static const sm4_u32_t sm4_CK[32] =
{
0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,
0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,
0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,
0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,
0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,
0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,
0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,
0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279,
};
/*
* defined in section 7.3 (1) L'
*/
LTC_INLINE static sm4_u32_t s_sm4_L73(sm4_u32_t B)
{
return B ^ ROLc(B, 13) ^ ROLc(B, 23);
}
/*
* defined in section 7.3 (1) T'
*/
LTC_INLINE static sm4_u32_t s_sm4_T73(sm4_u32_t Z)
{
return s_sm4_L73(s_sm4_t(Z));
}
/*
* defined in section 7.3 Key Expansion
*/
LTC_INLINE static void s_sm4_mk2rk(sm4_u32_t rk[32], sm4_u8_t mk[16])
{
sm4_u32_t MK[4] = { 0 };
sm4_u32_t K[4+32] = { 0 };
int i;
LOAD32H(MK[0], mk );
LOAD32H(MK[1], mk + 4);
LOAD32H(MK[2], mk + 8);
LOAD32H(MK[3], mk + 12);
for (i = 0; i < 4; ++i)
K[i] = MK[i] ^ sm4_FK[i];
for (i = 0; i < 32; ++i)
K[i+4] = K[i] ^ s_sm4_T73(K[i+1] ^ K[i+2] ^ K[i+3] ^ sm4_CK[i]);
for (i = 0; i < 32; ++i)
rk[i] = K[i+4];
}
/*
* defined in section 6 Round Function F
*/
LTC_INLINE static sm4_u32_t s_sm4_F(sm4_u32_t X[4], sm4_u32_t rk)
{
return X[0] ^ s_sm4_T62(X[1] ^ X[2] ^ X[3] ^ rk);
}
/*
* defined in section 7.1 (2) The reverse transformation
*/
LTC_INLINE static void s_sm4_R(sm4_u32_t Y[4], sm4_u32_t X[32+4])
{
Y[0] = X[35];
Y[1] = X[34];
Y[2] = X[33];
Y[3] = X[32];
}
/*
* defined in section 7.1 (En)cryption
*/
LTC_INLINE static void s_sm4_crypt(sm4_u32_t Y[4], sm4_u32_t X[4+32], const sm4_u32_t rk[32])
{
int i;
for (i = 0; i < 32; ++i)
X[i+4] = s_sm4_F(X+i, rk[i]);
s_sm4_R(Y, X);
}
LTC_INLINE static void s_sm4_setkey(struct sm4_key *sm4, const unsigned char *key)
{
int i;
s_sm4_mk2rk(sm4->ek,(void*)key);
/*swap key sequence when decrypt cipher*/
for (i = 0; i < 32; ++i)
sm4->dk[i] = sm4->ek[32 - 1 - i];
}
int sm4_setup(const unsigned char *key, int keylen,
int num_rounds, symmetric_key *skey)
{
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(skey != NULL);
if (num_rounds != 0 && num_rounds != 32)
return CRYPT_INVALID_ROUNDS;
if (keylen != 16)
return CRYPT_INVALID_KEYSIZE;
s_sm4_setkey(&(skey->sm4), key);
return CRYPT_OK;
}
/*
* SM4 encryption.
*/
LTC_INLINE static void s_sm4_do(void *output, const void *input, const sm4_u32_t rk[32])
{
sm4_u32_t Y[4];
sm4_u32_t X[32+4];
LOAD32H(X[0], (sm4_u8_t *)input );
LOAD32H(X[1], (sm4_u8_t *)input + 4);
LOAD32H(X[2], (sm4_u8_t *)input + 8);
LOAD32H(X[3], (sm4_u8_t *)input + 12);
s_sm4_crypt(Y, X, rk);
STORE32H(Y[0], (sm4_u8_t *)output );
STORE32H(Y[1], (sm4_u8_t *)output + 4);
STORE32H(Y[2], (sm4_u8_t *)output + 8);
STORE32H(Y[3], (sm4_u8_t *)output + 12);
}
int sm4_ecb_encrypt(const unsigned char *pt, unsigned char *ct,
const symmetric_key *skey)
{
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(skey != NULL);
s_sm4_do(ct, pt, skey->sm4.ek);
return CRYPT_OK;
}
int sm4_ecb_decrypt(const unsigned char *ct, unsigned char *pt,
const symmetric_key *skey)
{
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(skey != NULL);
s_sm4_do(pt, ct, skey->sm4.dk);
return CRYPT_OK;
}
void sm4_done(symmetric_key *skey)
{
LTC_UNUSED_PARAM(skey);
}
int sm4_keysize(int *keysize)
{
LTC_ARGCHK(keysize != NULL);
if(*keysize < 16) {
return CRYPT_INVALID_KEYSIZE;
}
*keysize = 16;
return CRYPT_OK;
}
/*
* libtomcrypt interface is used
*/
#ifdef LTC_TEST
static int sm4_self_test_ltc(void)
{
int result;
int i;
int keysize;
symmetric_key skey;
sm4_u8_t output[16];
sm4_u8_t plaintext[] = {
0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
};
sm4_u8_t key[] = {
0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
};
sm4_u8_t ciphertext[] = {
0x68, 0x1E, 0xDF, 0x34, 0xD2, 0x06, 0x96, 0x5E,
0x86, 0xB3, 0xE9, 0x4F, 0x53, 0x6E, 0x42, 0x46,
};
sm4_u8_t ciphertext_1000000t[] = {
0x59, 0x52, 0x98, 0xC7, 0xC6, 0xFD, 0x27, 0x1F,
0x04, 0x02, 0xF8, 0x04, 0xC3, 0x3D, 0x3F, 0x66,
};
result = CRYPT_OK; /* Assume the best */
sm4_setup(key, sizeof(key), 32, &skey);
/*A.1 example 1*/
sm4_ecb_encrypt(plaintext, output, &skey);
if (compare_testvector(output, 16, ciphertext, 16, "SM4 single encryption", 0) != 0)
result = CRYPT_ERROR;
sm4_ecb_decrypt(ciphertext, output, &skey);
if (compare_testvector(output, 16, plaintext, 16, "SM4 single decryption", 0) != 0)
result = CRYPT_ERROR;
/*A.2 example 2*/
XMEMCPY(output, plaintext, 16);
for (i = 0; i < 1000000; ++i)
sm4_ecb_encrypt(output, output, &skey);
if (compare_testvector(output, 16, ciphertext_1000000t, 16, "SM4 1000000 times encryption", 0) != 0)
result = CRYPT_ERROR;
XMEMCPY(output, ciphertext_1000000t, 16);
for (i = 0; i < 1000000; ++i)
sm4_ecb_decrypt(output, output, &skey);
if (compare_testvector(output, 16, plaintext, 16, "SM4 1000000 times encryption", 0) != 0)
result = CRYPT_ERROR;
keysize = 128;
if (sm4_keysize(&keysize) != CRYPT_OK) {
fprintf(stderr, "Getting the max SM4 keysize failed\n");
result = CRYPT_ERROR;
} else if (keysize != 16) {
fprintf(stderr, "SM4 maximum key size is faulty:\nSHOULD be 16\nIS %d\n", keysize);
result = CRYPT_ERROR;
}
sm4_done(&skey);
return result;
}
#endif
int sm4_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
return sm4_self_test_ltc();
#endif
}
const struct ltc_cipher_descriptor sm4_desc = {
"sm4",
28,
16, 16, 16, 32, /* min_key_len, max_key_len, block_len, default_rounds */
&sm4_setup,
&sm4_ecb_encrypt,
&sm4_ecb_decrypt,
&sm4_test,
&sm4_done,
&sm4_keysize,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
};
#endif /*LTC_SM4*/

View File

@ -58,6 +58,9 @@ int ccm_add_nonce(ccm_state *ccm,
ccm->PAD[x++] = 0;
}
for (; y < ccm->L; y++) {
if (x >= sizeof(ccm->PAD)) {
return CRYPT_INVALID_ARG;
}
ccm->PAD[x++] = (unsigned char)((len >> 24) & 255);
len <<= 8;
}

View File

@ -162,7 +162,8 @@ int ccm_memory(int cipher,
}
for (; y < L; y++) {
if (x >= sizeof(PAD)) {
return CRYPT_INVALID_ARG;
err = CRYPT_INVALID_ARG;
goto error;
}
PAD[x++] = (unsigned char)((len >> 24) & 255);
len <<= 8;

View File

@ -21,13 +21,15 @@ int chacha20poly1305_done(chacha20poly1305_state *st, unsigned char *tag, unsign
LTC_ARGCHK(st != NULL);
padlen = 16 - (unsigned long)(st->ctlen % 16);
if (padlen < 16) {
if ((err = poly1305_process(&st->poly, padzero, padlen)) != CRYPT_OK) return err;
if (!st->openssh_compat) {
padlen = 16 - (unsigned long)(st->ctlen % 16);
if (padlen < 16) {
if ((err = poly1305_process(&st->poly, padzero, padlen)) != CRYPT_OK) return err;
}
STORE64L(st->aadlen, buf);
STORE64L(st->ctlen, buf + 8);
if ((err = poly1305_process(&st->poly, buf, 16)) != CRYPT_OK) return err;
}
STORE64L(st->aadlen, buf);
STORE64L(st->ctlen, buf + 8);
if ((err = poly1305_process(&st->poly, buf, 16)) != CRYPT_OK) return err;
if ((err = poly1305_done(&st->poly, tag, taglen)) != CRYPT_OK) return err;
if ((err = chacha_done(&st->chacha)) != CRYPT_OK) return err;
return CRYPT_OK;

View File

@ -14,6 +14,7 @@
*/
int chacha20poly1305_init(chacha20poly1305_state *st, const unsigned char *key, unsigned long keylen)
{
XMEMSET(st, 0, sizeof(*st));
return chacha_setup(&st->chacha, key, keylen, 20);
}

View File

@ -6,7 +6,7 @@
#ifdef LTC_CHACHA20POLY1305_MODE
/**
Process an entire GCM packet in one call.
Process an entire ChaCha20Poly1305 packet in one call.
@param key The secret key
@param keylen The length of the secret key
@param iv The initialization vector
@ -40,6 +40,10 @@ int chacha20poly1305_memory(const unsigned char *key, unsigned long keylen,
LTC_ARGCHK(taglen != NULL);
if ((err = chacha20poly1305_init(&st, key, keylen)) != CRYPT_OK) { goto LBL_ERR; }
st.openssh_compat = (direction & CHACHA20POLY1305_OPENSSH_COMPAT) ? 1 : 0;
direction &= ~(CHACHA20POLY1305_OPENSSH_COMPAT);
if ((err = chacha20poly1305_setiv(&st, iv, ivlen)) != CRYPT_OK) { goto LBL_ERR; }
if (aad && aadlen > 0) {
if ((err = chacha20poly1305_add_aad(&st, aad, aadlen)) != CRYPT_OK) { goto LBL_ERR; }

View File

@ -48,7 +48,7 @@ const unsigned char gcm_shift_table[256*2] = {
#endif
#if defined(LTC_GCM_MODE) || defined(LRW_MODE)
#if defined(LTC_GCM_MODE) || defined(LTC_LRW_MODE)
#ifndef LTC_FAST
/* right shift */

View File

@ -19,11 +19,11 @@ void gcm_mult_h(const gcm_state *gcm, unsigned char *I)
#ifdef LTC_GCM_TABLES
int x;
#ifdef LTC_GCM_TABLES_SSE2
asm("movdqa (%0),%%xmm0"::"r"(&gcm->PC[0][I[0]][0]));
__asm__("movdqa (%0),%%xmm0"::"r"(&gcm->PC[0][I[0]][0]));
for (x = 1; x < 16; x++) {
asm("pxor (%0),%%xmm0"::"r"(&gcm->PC[x][I[x]][0]));
__asm__("pxor (%0),%%xmm0"::"r"(&gcm->PC[x][I[x]][0]));
}
asm("movdqa %%xmm0,(%0)"::"r"(&T));
__asm__("movdqa %%xmm0,(%0)"::"r"(&T));
#else
int y;
XMEMCPY(T, &gcm->PC[0][I[0]][0], 16);

746
deps/libtomcrypt/src/encauth/siv/siv.c vendored Normal file
View File

@ -0,0 +1,746 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@file siv.c
RFC 5297 SIV - Synthetic Initialization Vector, Steffen Jaeckel
*/
#ifdef LTC_SIV_MODE
/* RFC 5297 - Chapter 7 - Security Considerations
*
* [...] S2V must not be
* passed more than 127 components. Since SIV includes the plaintext as
* a component to S2V, that limits the number of components of
* associated data that can be safely passed to SIV to 126.
*/
static const unsigned long s_siv_max_aad_components = 126;
static LTC_INLINE void s_siv_dbl(unsigned char *inout)
{
int y, mask, msb, len;
/* setup the system */
mask = 0x87;
len = 16;
/* if msb(L * u^(x+1)) = 0 then just shift, otherwise shift and xor constant mask */
msb = inout[0] >> 7;
/* shift left */
for (y = 0; y < (len - 1); y++) {
inout[y] = ((inout[y] << 1) | (inout[y + 1] >> 7)) & 255;
}
inout[len - 1] = ((inout[len - 1] << 1) ^ (msb ? mask : 0)) & 255;
}
static LTC_INLINE int s_siv_S2V_one(int cipher,
const unsigned char *key, unsigned long keylen,
unsigned char *V, unsigned long *Vlen)
{
/* if n = 0 then
* return V = AES-CMAC(K, <one>)
*/
unsigned char zero_or_one[16] = {0};
zero_or_one[0] = 1;
return omac_memory(cipher, key, keylen, zero_or_one, sizeof(zero_or_one), V, Vlen);
}
typedef struct siv_omac_ctx_t {
omac_state omac;
int cipher;
} siv_omac_ctx_t;
static LTC_INLINE int s_siv_ctx_init(int cipher,
const unsigned char *key, unsigned long keylen,
siv_omac_ctx_t *ctx)
{
ctx->cipher = cipher;
return omac_init(&ctx->omac, cipher, key, keylen);
}
static LTC_INLINE int s_siv_omac_memory(siv_omac_ctx_t *ctx,
const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen)
{
int err;
omac_state omac = ctx->omac;
if ((err = omac_process(&omac, in, inlen)) != CRYPT_OK) {
return err;
}
err = omac_done(&omac, out, outlen);
zeromem(&omac, sizeof(omac));
return err;
}
static LTC_INLINE int s_siv_S2V_zero(siv_omac_ctx_t *ctx,
unsigned char *D, unsigned long *Dlen)
{
/* D = AES-CMAC(K, <zero>) */
const unsigned char zero_or_one[16] = {0};
return s_siv_omac_memory(ctx, zero_or_one, sizeof(zero_or_one), D, Dlen);
}
static LTC_INLINE int s_siv_S2V_dbl_xor_cmac(siv_omac_ctx_t *ctx,
const unsigned char *aad, unsigned long aadlen,
unsigned char *D, unsigned long Dlen)
{
/* for i = 1 to n-1 do
* D = dbl(D) xor AES-CMAC(K, Si)
* done
*/
int err;
unsigned char TMP[16];
unsigned long i, TMPlen = sizeof(TMP);
s_siv_dbl(D);
if ((err = s_siv_omac_memory(ctx, aad, aadlen, TMP, &TMPlen)) != CRYPT_OK) {
return err;
}
for (i = 0; i < Dlen; ++i) {
D[i] ^= TMP[i];
}
return err;
}
static LTC_INLINE int s_siv_omac_memory_multi(siv_omac_ctx_t *ctx,
unsigned char *out, unsigned long *outlen,
const unsigned char *in, unsigned long inlen,
...)
{
int err;
va_list args;
omac_state omac = ctx->omac;
va_start(args, inlen);
if ((err = omac_vprocess(&omac, in, inlen, args)) != CRYPT_OK) {
return err;
}
err = omac_done(&omac, out, outlen);
zeromem(&omac, sizeof(omac));
return err;
}
static LTC_INLINE int s_siv_S2V_T(siv_omac_ctx_t *ctx,
const unsigned char *in, unsigned long inlen,
unsigned char *D,
unsigned char *V, unsigned long *Vlen)
{
int err;
unsigned long i;
unsigned char T[16];
/* if len(Sn) >= 128 then
* T = Sn xorend D
* else
* T = dbl(D) xor pad(Sn)
* fi
*/
if (inlen >= 16) {
XMEMCPY(T, &in[inlen - 16], 16);
for(i = 0; i < 16; ++i) {
T[i] ^= D[i];
}
err = s_siv_omac_memory_multi(ctx, V, Vlen, in, inlen - 16, T, 16uL, NULL);
} else {
s_siv_dbl(D);
XMEMCPY(T, in, inlen);
T[inlen] = 0x80;
for (i = inlen + 1; i < 16; ++i) {
T[i] = 0x0;
}
for(i = 0; i < 16; ++i) {
T[i] ^= D[i];
}
err = s_siv_omac_memory(ctx, T, 16, V, Vlen);
}
return err;
}
static int s_siv_S2V(int cipher,
const unsigned char *key, unsigned long keylen,
const unsigned char **ad, unsigned long *adlen,
const unsigned char *in, unsigned long inlen,
unsigned char *V, unsigned long *Vlen)
{
int err;
unsigned char D[16];
unsigned long Dlen = sizeof(D), n = 0;
siv_omac_ctx_t ctx;
if(ad == NULL || adlen == NULL || ad[0] == NULL || adlen[0] == 0) {
err = s_siv_S2V_one(cipher, key, keylen, V, Vlen);
} else {
if ((err = s_siv_ctx_init(cipher, key, keylen, &ctx)) != CRYPT_OK) {
return err;
}
Dlen = sizeof(D);
if ((err = s_siv_S2V_zero(&ctx, D, &Dlen)) != CRYPT_OK) {
return err;
}
while(ad[n] != NULL && adlen[n] != 0) {
if (n >= s_siv_max_aad_components) {
return CRYPT_INPUT_TOO_LONG;
}
if ((err = s_siv_S2V_dbl_xor_cmac(&ctx, ad[n], adlen[n], D, Dlen)) != CRYPT_OK) {
return err;
}
n++;
}
err = s_siv_S2V_T(&ctx, in, inlen, D, V, Vlen);
}
return err;
}
static LTC_INLINE void s_siv_bitand(const unsigned char* V, unsigned char* Q)
{
int n;
XMEMSET(Q, 0xff, 16);
Q[8] = Q[12] = 0x7f;
for (n = 0; n < 16; ++n) {
Q[n] &= V[n];
}
}
static LTC_INLINE int s_ctr_crypt_memory(int cipher,
const unsigned char *IV,
const unsigned char *key, int keylen,
const unsigned char *in,
unsigned char *out, unsigned long len)
{
int err;
symmetric_CTR ctr;
if ((err = ctr_start(cipher, IV, key, keylen, 0, CTR_COUNTER_BIG_ENDIAN | 16, &ctr)) != CRYPT_OK) {
goto out;
}
if ((err = ctr_encrypt(in, out, len, &ctr)) != CRYPT_OK) {
goto out;
}
if ((err = ctr_done(&ctr)) != CRYPT_OK) {
goto out;
}
out:
zeromem(&ctr, sizeof(ctr));
return err;
}
typedef struct {
unsigned char Q[16], V[16];
} siv_state;
/**
SIV encrypt
@param cipher The index of the cipher desired
@param key The secret key to use
@param keylen The length of the secret key (octets)
@param ad An array of Associated Data pointers (must be NULL terminated)
@param adlen An array with the lengths of the Associated Data
@param pt The plaintext
@param ptlen The length of the plaintext
@param ct The ciphertext
@param ctlen [in/out] The length of the ciphertext
@return CRYPT_OK if successful
*/
int siv_encrypt_memory( int cipher,
const unsigned char *key, unsigned long keylen,
const unsigned char *ad[], unsigned long adlen[],
const unsigned char *pt, unsigned long ptlen,
unsigned char *ct, unsigned long *ctlen)
{
int err;
const unsigned char *K1, *K2;
unsigned long Vlen;
siv_state siv;
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(ad != NULL);
LTC_ARGCHK(adlen != NULL);
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(ctlen != NULL);
if (ptlen + 16 < ptlen) {
return CRYPT_OVERFLOW;
}
if (*ctlen < ptlen + 16) {
*ctlen = ptlen + 16;
return CRYPT_BUFFER_OVERFLOW;
}
if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
return err;
}
K1 = key;
K2 = &key[keylen/2];
Vlen = sizeof(siv.V);
err = s_siv_S2V(cipher, K1, keylen/2, ad, adlen, pt, ptlen, siv.V, &Vlen);
#ifdef LTC_CLEAN_STACK
burn_stack(3 * 16 + 7 * sizeof(unsigned long) + 1 * sizeof(void*));
#endif
if (err != CRYPT_OK) {
return err;
}
s_siv_bitand(siv.V, siv.Q);
XMEMCPY(ct, siv.V, 16);
ct += 16;
if ((err = s_ctr_crypt_memory(cipher, siv.Q, K2, keylen/2, pt, ct, ptlen)) != CRYPT_OK) {
zeromem(ct, ptlen + 16);
goto out;
}
*ctlen = ptlen + 16;
out:
#ifdef LTC_CLEAN_STACK
zeromem(&siv, sizeof(siv));
#endif
return err;
}
/**
SIV decrypt
@param cipher The index of the cipher desired
@param key The secret key to use
@param keylen The length of the secret key (octets)
@param ad An array of Associated Data pointers (must be NULL terminated)
@param adlen An array with the lengths of the Associated Data
@param ct The ciphertext
@param ctlen The length of the ciphertext
@param pt The plaintext
@param ptlen [in/out] The length of the plaintext
@return CRYPT_OK if successful
*/
int siv_decrypt_memory( int cipher,
const unsigned char *key, unsigned long keylen,
const unsigned char *ad[], unsigned long adlen[],
const unsigned char *ct, unsigned long ctlen,
unsigned char *pt, unsigned long *ptlen)
{
int err;
unsigned char *pt_work;
const unsigned char *K1, *K2, *ct_work;
unsigned long Vlen;
siv_state siv;
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(ad != NULL);
LTC_ARGCHK(adlen != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ptlen != NULL);
if (ctlen < 16) {
return CRYPT_INVALID_ARG;
}
if (*ptlen < (ctlen - 16)) {
*ptlen = ctlen - 16;
return CRYPT_BUFFER_OVERFLOW;
}
if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
return err;
}
*ptlen = ctlen - 16;
pt_work = XMALLOC(*ptlen);
if (pt_work == NULL) {
return CRYPT_MEM;
}
K1 = key;
K2 = &key[keylen/2];
ct_work = ct;
s_siv_bitand(ct_work, siv.Q);
ct_work += 16;
if ((err = s_ctr_crypt_memory(cipher, siv.Q, K2, keylen/2, ct_work, pt_work, *ptlen)) != CRYPT_OK) {
goto out;
}
Vlen = sizeof(siv.V);
if ((err = s_siv_S2V(cipher, K1, keylen/2, ad, adlen, pt_work, *ptlen, siv.V, &Vlen)) != CRYPT_OK) {
goto out;
}
err = XMEM_NEQ(siv.V, ct, Vlen);
copy_or_zeromem(pt_work, pt, *ptlen, err);
out:
#ifdef LTC_CLEAN_STACK
zeromem(&siv, sizeof(siv));
#endif
zeromem(pt_work, *ptlen);
XFREE(pt_work);
return err;
}
/**
Process an entire SIV packet in one call.
@param cipher The index of the cipher desired
@param direction Encrypt or Decrypt mode (LTC_ENCRYPT or LTC_DECRYPT)
@param key The secret key to use
@param keylen The length of the secret key (octets)
@param in The input
@param inlen The length of the input
@param out The output
@param outlen [in/out] The max size and resulting size of the output
@remark <...> is of the form <pointer, length> (void*, unsigned long) and contains the Associated Data
@return CRYPT_OK on success
*/
int siv_memory( int cipher, int direction,
const unsigned char *key, unsigned long keylen,
const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
...)
{
int err;
va_list args;
siv_state siv;
unsigned char D[16], *in_buf = NULL, *out_work;
const unsigned char *aad, *K1, *K2, *in_work;
unsigned long n = 0, aadlen, Dlen = sizeof(D), Vlen = sizeof(siv.V), in_work_len;
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
return err;
}
if (direction == LTC_ENCRYPT && *outlen < inlen + 16) {
*outlen = inlen + 16;
return CRYPT_BUFFER_OVERFLOW;
} else if (direction == LTC_DECRYPT && (inlen < 16 || *outlen < inlen - 16)) {
*outlen = inlen - 16;
return CRYPT_BUFFER_OVERFLOW;
}
K1 = key;
K2 = &key[keylen/2];
in_work = in;
in_work_len = inlen;
out_work = out;
if (direction == LTC_DECRYPT) {
in_work_len -= 16;
in_buf = XMALLOC(in_work_len);
if (in_buf == NULL)
return CRYPT_MEM;
s_siv_bitand(in_work, siv.Q);
in_work += 16;
if ((err = s_ctr_crypt_memory(cipher, siv.Q, K2, keylen/2, in_work, in_buf, in_work_len)) != CRYPT_OK) {
goto err_out;
}
in_work = in_buf;
}
va_start(args, outlen);
aad = va_arg(args, const unsigned char*);
aadlen = aad ? va_arg(args, unsigned long) : 0;
if (aad == NULL || aadlen == 0) {
if ((err = s_siv_S2V_one(cipher, K1, keylen/2, siv.V, &Vlen)) != CRYPT_OK) {
goto err_out;
}
} else {
siv_omac_ctx_t ctx;
if ((err = s_siv_ctx_init(cipher, K1, keylen/2, &ctx)) != CRYPT_OK) {
goto err_out;
}
if ((err = s_siv_S2V_zero(&ctx, D, &Dlen)) != CRYPT_OK) {
goto err_out;
}
do {
if (n >= s_siv_max_aad_components) {
err = CRYPT_INPUT_TOO_LONG;
goto err_out;
}
if ((err = s_siv_S2V_dbl_xor_cmac(&ctx, aad, aadlen, D, Dlen)) != CRYPT_OK) {
goto err_out;
}
aad = va_arg(args, const unsigned char*);
if (aad == NULL)
break;
aadlen = va_arg(args, unsigned long);
n++;
} while (aadlen);
if ((err = s_siv_S2V_T(&ctx, in_work, in_work_len, D, siv.V, &Vlen)) != CRYPT_OK) {
goto err_out;
}
}
if (direction == LTC_DECRYPT) {
err = XMEM_NEQ(siv.V, in, Vlen);
copy_or_zeromem(in_work, out, in_work_len, err);
*outlen = in_work_len;
} else {
s_siv_bitand(siv.V, siv.Q);
XMEMCPY(out_work, siv.V, 16);
out_work += 16;
if ((err = s_ctr_crypt_memory(cipher, siv.Q, K2, keylen/2, in, out_work, inlen)) != CRYPT_OK) {
zeromem(out, inlen + 16);
goto err_out;
}
*outlen = inlen + 16;
}
err_out:
if (in_buf) {
zeromem(in_buf, in_work_len);
XFREE(in_buf);
}
va_end(args);
#ifdef LTC_CLEAN_STACK
zeromem(D, sizeof(D));
zeromem(&siv, sizeof(siv));
#endif
return err;
}
int siv_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
/*
* RFC5297 - A.1. Deterministic Authenticated Encryption Example
*/
const unsigned char Key_A1[] =
{ 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff };
const unsigned char AD_A1[] =
{ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27 };
const unsigned char Plaintext_A1[] =
{ 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee };
const unsigned char output_A1[] =
{ 0x85, 0x63, 0x2d, 0x07, 0xc6, 0xe8, 0xf3, 0x7f,
0x95, 0x0a, 0xcd, 0x32, 0x0a, 0x2e, 0xcc, 0x93,
0x40, 0xc0, 0x2b, 0x96, 0x90, 0xc4, 0xdc, 0x04,
0xda, 0xef, 0x7f, 0x6a, 0xfe, 0x5c };
const unsigned char *ad_A1[] =
{ AD_A1, NULL };
unsigned long adlen_A1[] =
{ sizeof(AD_A1), 0 };
const unsigned char Key_A2[] =
{ 0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x7a, 0x79, 0x78,
0x77, 0x76, 0x75, 0x74, 0x73, 0x72, 0x71, 0x70,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f };
const unsigned char AD1_A2[] =
{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
0xde, 0xad, 0xda, 0xda, 0xde, 0xad, 0xda, 0xda,
0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88,
0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00 };
const unsigned char AD2_A2[] =
{ 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80,
0x90, 0xa0 };
const unsigned char AD3_A2[] =
{ 0x09, 0xf9, 0x11, 0x02, 0x9d, 0x74, 0xe3, 0x5b,
0xd8, 0x41, 0x56, 0xc5, 0x63, 0x56, 0x88, 0xc0 };
const unsigned char Plaintext_A2[] =
{ 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20,
0x73, 0x6f, 0x6d, 0x65, 0x20, 0x70, 0x6c, 0x61,
0x69, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x20, 0x74,
0x6f, 0x20, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70,
0x74, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20,
0x53, 0x49, 0x56, 0x2d, 0x41, 0x45, 0x53 };
const unsigned char output_A2[] =
{ 0x7b, 0xdb, 0x6e, 0x3b, 0x43, 0x26, 0x67, 0xeb,
0x06, 0xf4, 0xd1, 0x4b, 0xff, 0x2f, 0xbd, 0x0f,
0xcb, 0x90, 0x0f, 0x2f, 0xdd, 0xbe, 0x40, 0x43,
0x26, 0x60, 0x19, 0x65, 0xc8, 0x89, 0xbf, 0x17,
0xdb, 0xa7, 0x7c, 0xeb, 0x09, 0x4f, 0xa6, 0x63,
0xb7, 0xa3, 0xf7, 0x48, 0xba, 0x8a, 0xf8, 0x29,
0xea, 0x64, 0xad, 0x54, 0x4a, 0x27, 0x2e, 0x9c,
0x48, 0x5b, 0x62, 0xa3, 0xfd, 0x5c, 0x0d };
const unsigned char *ad_A2[] =
{ AD1_A2, AD2_A2, AD3_A2, NULL };
unsigned long adlen_A2[] =
{ sizeof(AD1_A2), sizeof(AD2_A2), sizeof(AD3_A2), 0 };
#define PL_PAIR(n) n, sizeof(n)
struct {
const unsigned char* Key;
unsigned long Keylen;
const unsigned char* Plaintext;
unsigned long Plaintextlen;
const void* ADs;
void* ADlens;
const unsigned char* output;
unsigned long outputlen;
const char* name;
} siv_tests[] = {
{ PL_PAIR(Key_A1), PL_PAIR(Plaintext_A1), &ad_A1, &adlen_A1, PL_PAIR(output_A1), "RFC5297 - A.1. Deterministic Authenticated Encryption Example" },
{ PL_PAIR(Key_A2), PL_PAIR(Plaintext_A2), &ad_A2, &adlen_A2, PL_PAIR(output_A2), "RFC5297 - A.2. Nonce-Based Authenticated Encryption Example" }
};
#undef PL_PAIR
int err, cipher;
unsigned n;
unsigned long buflen, tmplen;
unsigned char buf[MAX(sizeof(output_A1), sizeof(output_A2))];
const unsigned long niter = 1000;
unsigned char *tmpe, *tmpd;
const unsigned long tmpmax = 16 + niter * 16;
cipher = find_cipher("aes");
for (n = 0; n < sizeof(siv_tests)/sizeof(siv_tests[0]); ++n) {
buflen = sizeof(buf);
if ((err = siv_encrypt_memory(cipher,
siv_tests[n].Key, siv_tests[n].Keylen,
(const unsigned char **)siv_tests[n].ADs, siv_tests[n].ADlens,
siv_tests[n].Plaintext, siv_tests[n].Plaintextlen,
buf, &buflen)) != CRYPT_OK) {
return err;
}
if (compare_testvector(buf, buflen, siv_tests[n].output, siv_tests[n].outputlen, siv_tests[n].name, n) != 0) {
return CRYPT_FAIL_TESTVECTOR;
}
buflen = sizeof(buf);
if ((err = siv_decrypt_memory(cipher,
siv_tests[n].Key, siv_tests[n].Keylen,
(const unsigned char **)siv_tests[n].ADs, siv_tests[n].ADlens,
siv_tests[n].output, siv_tests[n].outputlen,
buf, &buflen)) != CRYPT_OK) {
return err;
}
if (compare_testvector(buf, buflen, siv_tests[n].Plaintext, siv_tests[n].Plaintextlen, siv_tests[n].name, n + 0x1000) != 0) {
return CRYPT_FAIL_TESTVECTOR;
}
}
/* Testcase 0x2 */
buflen = sizeof(buf);
if ((err = siv_memory(cipher, LTC_ENCRYPT,
siv_tests[0].Key, siv_tests[0].Keylen,
siv_tests[0].Plaintext, siv_tests[0].Plaintextlen,
buf, &buflen,
AD_A1, sizeof(AD_A1),
NULL)) != CRYPT_OK) {
return err;
}
if (compare_testvector(buf, buflen, siv_tests[0].output, siv_tests[0].outputlen, siv_tests[0].name, n) != 0) {
return CRYPT_FAIL_TESTVECTOR;
}
/* Testcase 0x1002 */
buflen = sizeof(buf);
if ((err = siv_memory(cipher, LTC_DECRYPT,
siv_tests[0].Key, siv_tests[0].Keylen,
siv_tests[0].output, siv_tests[0].outputlen,
buf, &buflen,
AD_A1, sizeof(AD_A1),
NULL)) != CRYPT_OK) {
return err;
}
if (compare_testvector(buf, buflen, siv_tests[0].Plaintext, siv_tests[0].Plaintextlen, siv_tests[0].name, n + 0x1000) != 0) {
return CRYPT_FAIL_TESTVECTOR;
}
n++;
/* Testcase 0x3 */
buflen = sizeof(buf);
if ((err = siv_memory(cipher, LTC_ENCRYPT,
siv_tests[1].Key, siv_tests[1].Keylen,
siv_tests[1].Plaintext, siv_tests[1].Plaintextlen,
buf, &buflen,
ad_A2[0], adlen_A2[0],
ad_A2[1], adlen_A2[1],
ad_A2[2], adlen_A2[2],
NULL)) != CRYPT_OK) {
return err;
}
if (compare_testvector(buf, buflen, siv_tests[1].output, siv_tests[1].outputlen, siv_tests[1].name, n) != 0) {
return CRYPT_FAIL_TESTVECTOR;
}
/* Testcase 0x1003 */
buflen = sizeof(buf);
if ((err = siv_memory(cipher, LTC_DECRYPT,
siv_tests[1].Key, siv_tests[1].Keylen,
siv_tests[1].output, siv_tests[1].outputlen,
buf, &buflen,
ad_A2[0], adlen_A2[0],
ad_A2[1], adlen_A2[1],
ad_A2[2], adlen_A2[2],
NULL)) != CRYPT_OK) {
return err;
}
if (compare_testvector(buf, buflen, siv_tests[1].Plaintext, siv_tests[1].Plaintextlen, siv_tests[1].name, n + 0x1000) != 0) {
return CRYPT_FAIL_TESTVECTOR;
}
tmpe = XCALLOC(1, tmpmax);
if (tmpe == NULL) {
return CRYPT_MEM;
}
tmpd = XCALLOC(1, tmpmax);
if (tmpd == NULL) {
err = CRYPT_MEM;
goto out_tmpd;
}
tmplen = 16;
for (n = 0; n < niter; ++n) {
buflen = tmpmax;
if ((err = siv_memory(cipher, LTC_ENCRYPT,
siv_tests[0].Key, siv_tests[0].Keylen,
tmpe, tmplen,
tmpe, &buflen,
NULL)) != CRYPT_OK) {
goto out;
}
tmplen = buflen;
}
if (compare_testvector(&buflen, sizeof(buflen), &tmpmax, sizeof(tmpmax), "Multiple encrypt length", -(int)niter)) {
err = CRYPT_FAIL_TESTVECTOR;
goto out;
}
XMEMCPY(tmpd, tmpe, buflen);
for (n = 0; n < niter; ++n) {
buflen = tmpmax;
if ((err = siv_memory(cipher, LTC_DECRYPT,
siv_tests[0].Key, siv_tests[0].Keylen,
tmpd, tmplen,
tmpd, &buflen,
NULL)) != CRYPT_OK) {
goto out;
}
tmplen = buflen;
}
if (compare_testvector(tmpd, tmplen, tmpe, tmplen, "Multi decrypt", niter + 0x2000)) {
err = CRYPT_FAIL_TESTVECTOR;
}
out:
XFREE(tmpd);
out_tmpd:
XFREE(tmpe);
return err;
#endif
}
#endif

View File

@ -1,7 +1,6 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
#include <stdarg.h>
#ifdef LTC_HASH_HELPERS
/**

View File

@ -28,6 +28,24 @@ const struct ltc_hash_descriptor tiger_desc =
NULL
};
const struct ltc_hash_descriptor tiger2_desc =
{
"tiger2",
33,
24,
64,
/* OID ... does not exist */
{ 0 },
0,
&tiger2_init,
&tiger_process,
&tiger_done,
&tiger2_test,
NULL
};
#define t1 (table)
#define t2 (table+256)
#define t3 (table+256*2)
@ -601,7 +619,7 @@ static int ss_tiger_compress(hash_state *md, const unsigned char *buf)
static int s_tiger_compress(hash_state *md, const unsigned char *buf)
#endif
{
ulong64 a, b, c, x[8];
ulong64 a, b, c, x[8], t;
unsigned long i;
/* load words */
@ -617,6 +635,11 @@ static int s_tiger_compress(hash_state *md, const unsigned char *buf)
s_pass(&c,&a,&b,x,7);
s_key_schedule(x);
s_pass(&b,&c,&a,x,9);
for (i = 3; i < md->tiger.passes; ++i) {
s_key_schedule(x);
s_pass(&a,&b,&c,x,9);
t = a; a = c; c = b; b = t;
}
/* store state */
md->tiger.state[0] = a ^ md->tiger.state[0];
@ -649,6 +672,57 @@ int tiger_init(hash_state *md)
md->tiger.state[2] = CONST64(0xF096A5B4C3B2E187);
md->tiger.curlen = 0;
md->tiger.length = 0;
md->tiger.passes = 3;
md->tiger.pad = 0x01u;
return CRYPT_OK;
}
/**
Initialize the hash state (extended version)
@param md The hash state you wish to initialize
@param passes The number of passes that should be executed
when the compress function is called.
@return CRYPT_OK if successful
*/
int tiger_init_ex(hash_state *md, unsigned long passes)
{
int err;
if ((err = tiger_init(md) != CRYPT_OK)) {
return err;
}
md->tiger.passes = passes;
return CRYPT_OK;
}
/**
Initialize the hash state (extended version)
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int tiger2_init(hash_state *md)
{
int err;
if ((err = tiger_init(md) != CRYPT_OK)) {
return err;
}
md->tiger.pad = 0x80u;
return CRYPT_OK;
}
/**
Initialize the hash state (extended version)
@param md The hash state you wish to initialize
@param passes The number of passes that should be executed
when the compress function is called.
@return CRYPT_OK if successful
*/
int tiger2_init_ex(hash_state *md, unsigned long passes)
{
int err;
if ((err = tiger2_init(md) != CRYPT_OK)) {
return err;
}
md->tiger.passes = passes;
return CRYPT_OK;
}
@ -679,8 +753,8 @@ int tiger_done(hash_state * md, unsigned char *out)
/* increase the length of the message */
md->tiger.length += md->tiger.curlen * 8;
/* append the '1' bit */
md->tiger.buf[md->tiger.curlen++] = (unsigned char)0x01;
/* append the padding bit */
md->tiger.buf[md->tiger.curlen++] = md->tiger.pad;
/* if the length is currently above 56 bytes we append zeros
* then compress. Then we can fall back to padding zeros and length
@ -717,51 +791,78 @@ int tiger_done(hash_state * md, unsigned char *out)
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int tiger_test(void)
static int s_tiger_test(unsigned int idx)
{
#ifndef LTC_TEST
LTC_UNUSED_PARAM(idx);
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[24];
unsigned char hash[2][24];
} tests[] = {
{ "",
{ 0x32, 0x93, 0xac, 0x63, 0x0c, 0x13, 0xf0, 0x24,
0x5f, 0x92, 0xbb, 0xb1, 0x76, 0x6e, 0x16, 0x16,
0x7a, 0x4e, 0x58, 0x49, 0x2d, 0xde, 0x73, 0xf3 }
{
{ 0x32, 0x93, 0xac, 0x63, 0x0c, 0x13, 0xf0, 0x24,
0x5f, 0x92, 0xbb, 0xb1, 0x76, 0x6e, 0x16, 0x16,
0x7a, 0x4e, 0x58, 0x49, 0x2d, 0xde, 0x73, 0xf3 },
{ 0x44, 0x41, 0xbe, 0x75, 0xf6, 0x01, 0x87, 0x73,
0xc2, 0x06, 0xc2, 0x27, 0x45, 0x37, 0x4b, 0x92,
0x4a, 0xa8, 0x31, 0x3f, 0xef, 0x91, 0x9f, 0x41 },
},
},
{ "abc",
{ 0x2a, 0xab, 0x14, 0x84, 0xe8, 0xc1, 0x58, 0xf2,
0xbf, 0xb8, 0xc5, 0xff, 0x41, 0xb5, 0x7a, 0x52,
0x51, 0x29, 0x13, 0x1c, 0x95, 0x7b, 0x5f, 0x93 }
{
{ 0x2a, 0xab, 0x14, 0x84, 0xe8, 0xc1, 0x58, 0xf2,
0xbf, 0xb8, 0xc5, 0xff, 0x41, 0xb5, 0x7a, 0x52,
0x51, 0x29, 0x13, 0x1c, 0x95, 0x7b, 0x5f, 0x93 },
{ 0xf6, 0x8d, 0x7b, 0xc5, 0xaf, 0x4b, 0x43, 0xa0,
0x6e, 0x04, 0x8d, 0x78, 0x29, 0x56, 0x0d, 0x4a,
0x94, 0x15, 0x65, 0x8b, 0xb0, 0xb1, 0xf3, 0xbf },
},
},
{ "Tiger",
{ 0xdd, 0x00, 0x23, 0x07, 0x99, 0xf5, 0x00, 0x9f,
0xec, 0x6d, 0xeb, 0xc8, 0x38, 0xbb, 0x6a, 0x27,
0xdf, 0x2b, 0x9d, 0x6f, 0x11, 0x0c, 0x79, 0x37 }
{
{ 0xdd, 0x00, 0x23, 0x07, 0x99, 0xf5, 0x00, 0x9f,
0xec, 0x6d, 0xeb, 0xc8, 0x38, 0xbb, 0x6a, 0x27,
0xdf, 0x2b, 0x9d, 0x6f, 0x11, 0x0c, 0x79, 0x37 },
{ 0xfe, 0x40, 0x79, 0x8b, 0x8e, 0xb9, 0x37, 0xfd,
0x97, 0x76, 0x08, 0x93, 0x05, 0x48, 0xd6, 0xa8,
0x94, 0xc2, 0x0b, 0x04, 0xcb, 0xef, 0x7a, 0x42 },
},
},
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-",
{ 0xf7, 0x1c, 0x85, 0x83, 0x90, 0x2a, 0xfb, 0x87,
0x9e, 0xdf, 0xe6, 0x10, 0xf8, 0x2c, 0x0d, 0x47,
0x86, 0xa3, 0xa5, 0x34, 0x50, 0x44, 0x86, 0xb5 }
{
{ 0xf7, 0x1c, 0x85, 0x83, 0x90, 0x2a, 0xfb, 0x87,
0x9e, 0xdf, 0xe6, 0x10, 0xf8, 0x2c, 0x0d, 0x47,
0x86, 0xa3, 0xa5, 0x34, 0x50, 0x44, 0x86, 0xb5 },
{ 0x15, 0x9b, 0x38, 0x0a, 0xb7, 0x92, 0x94, 0xe0,
0xda, 0x19, 0xf1, 0x62, 0x82, 0xce, 0x6d, 0xce,
0x0f, 0x84, 0xd3, 0x4f, 0x72, 0x9d, 0xbe, 0xa3 },
},
},
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-",
{ 0xc5, 0x40, 0x34, 0xe5, 0xb4, 0x3e, 0xb8, 0x00,
0x58, 0x48, 0xa7, 0xe0, 0xae, 0x6a, 0xac, 0x76,
0xe4, 0xff, 0x59, 0x0a, 0xe7, 0x15, 0xfd, 0x25 }
{
{ 0xc5, 0x40, 0x34, 0xe5, 0xb4, 0x3e, 0xb8, 0x00,
0x58, 0x48, 0xa7, 0xe0, 0xae, 0x6a, 0xac, 0x76,
0xe4, 0xff, 0x59, 0x0a, 0xe7, 0x15, 0xfd, 0x25 },
{ 0x01, 0xef, 0x91, 0x0b, 0x9b, 0xb2, 0xcb, 0x4c,
0x6c, 0x47, 0x49, 0x5c, 0x86, 0xb3, 0x64, 0x1a,
0xff, 0x14, 0xfb, 0xf7, 0x79, 0x40, 0x9c, 0x0e },
},
},
};
int (*init[2])(hash_state *hash) = { tiger_init, tiger2_init };
int i;
unsigned char tmp[24];
hash_state md;
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
tiger_init(&md);
init[idx](&md);
tiger_process(&md, (unsigned char *)tests[i].msg, (unsigned long)XSTRLEN(tests[i].msg));
tiger_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "TIGER", i)) {
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash[idx], sizeof(tests[i].hash[idx]), !idx ? "TIGER": "TIGER2", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
@ -769,6 +870,24 @@ int tiger_test(void)
#endif
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int tiger_test(void)
{
return s_tiger_test(0);
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int tiger2_test(void)
{
return s_tiger_test(1);
}
#endif
/*

View File

@ -28,7 +28,7 @@ extern "C" {
#ifndef TAB_SIZE
/* descriptor table size */
#define TAB_SIZE 34
#define TAB_SIZE 48
#endif
/* error codes [will be expanded in future releases] */
@ -69,10 +69,16 @@ enum {
CRYPT_PK_INVALID_SIZE, /* Invalid size input for PK parameters */
CRYPT_INVALID_PRIME_SIZE,/* Invalid size of prime requested */
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 */
CRYPT_HASH_OVERFLOW, /* Hash applied to too many bits */
CRYPT_PW_CTX_MISSING, /* Password context to decrypt key file is missing */
CRYPT_UNKNOWN_PEM, /* The PEM header was not recognized */
/* Here only follows the number of error codes.
* This will never be returned and shall always be at the end of the enum. */
CRYPT_ERR_NUM
};
#include "tomcrypt_cfg.h"

View File

@ -91,10 +91,8 @@ LTC_EXPORT int LTC_CALL XSTRCMP(const char *s1, const char *s2);
#define ENDIAN_LITTLE
#define ENDIAN_64BITWORD
#define LTC_FAST
#if defined(__SSE4_1__)
#if __SSE4_1__ == 1
#define LTC_AMD64_SSE4_1
#endif
#if defined(_ILP32) || defined(__ILP32__)
#define ENDIAN_64BITWORD_X32
#endif
#endif
@ -312,10 +310,6 @@ typedef unsigned long ltc_mp_digit;
# endif
#endif
#if defined(_MSC_VER) && defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0600 && !defined(LTC_WIN32_BCRYPT)
# define LTC_WIN32_BCRYPT
#endif
/* Define `LTC_NO_NULL_TERMINATION_CHECK` in the user code
* before including `tomcrypt.h` to disable this functionality.
*/
@ -341,4 +335,10 @@ typedef unsigned long ltc_mp_digit;
# define LTC_DEPRECATED_PRAGMA(s)
#endif
#if defined(__GNUC__) || defined(__clang__)
# define LTC_ATTRIBUTE(x) __attribute__(x)
#else
# define LTC_ATTRIBUTE(x)
#endif
#endif /* TOMCRYPT_CFG_H */

View File

@ -97,11 +97,22 @@ struct des_key {
ulong32 ek[32], dk[32];
};
struct desx_key {
ulong32 ek[32], dk[32];
ulong32 k[2][2];
};
struct des3_key {
ulong32 ek[3][32], dk[3][32];
};
#endif
#ifdef LTC_SM4
struct sm4_key {
ulong32 ek[32], dk[32];
};
#endif
#ifdef LTC_CAST5
struct cast5_key {
ulong32 K[32], keylen;
@ -176,8 +187,12 @@ struct tea_key {
typedef union Symmetric_key {
#ifdef LTC_DES
struct des_key des;
struct desx_key desx;
struct des3_key des3;
#endif
#ifdef LTC_SM4
struct sm4_key sm4;
#endif
#ifdef LTC_RC2
struct rc2_key rc2;
#endif
@ -269,6 +284,8 @@ typedef struct {
int cipher,
/** The block size of the given cipher */
blocklen,
/** The width of the mode: 1, 8, 64, or 128 */
width,
/** The padding offset */
padlen;
} symmetric_CFB;
@ -699,6 +716,7 @@ void aes_done(symmetric_key *skey);
int aes_keysize(int *keysize);
int aes_enc_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
int aes_enc_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey);
int aes_enc_test(void);
void aes_enc_done(symmetric_key *skey);
int aes_enc_keysize(int *keysize);
extern const struct ltc_cipher_descriptor aes_desc;
@ -718,7 +736,7 @@ extern const struct ltc_cipher_descriptor rijndael_desc;
extern const struct ltc_cipher_descriptor rijndael_enc_desc;
#endif
#if defined(LTC_AES_NI) && defined(LTC_AMD64_SSE4_1)
#if defined(LTC_AES_NI)
int aesni_is_supported(void);
int aesni_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
int aesni_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey);
@ -756,13 +774,29 @@ int des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, const symmetric_
int des_test(void);
void des_done(symmetric_key *skey);
int des_keysize(int *keysize);
int desx_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
int desx_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey);
int desx_ecb_decrypt(const unsigned char *ct, unsigned char *pt, const symmetric_key *skey);
int desx_test(void);
void desx_done(symmetric_key *skey);
int desx_keysize(int *keysize);
int des3_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
int des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey);
int des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, const symmetric_key *skey);
int des3_test(void);
void des3_done(symmetric_key *skey);
int des3_keysize(int *keysize);
extern const struct ltc_cipher_descriptor des_desc, des3_desc;
extern const struct ltc_cipher_descriptor des_desc, desx_desc, des3_desc;
#endif
#ifdef LTC_SM4
int sm4_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
int sm4_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey);
int sm4_ecb_decrypt(const unsigned char *ct, unsigned char *pt, const symmetric_key *skey);
int sm4_test(void);
void sm4_done(symmetric_key *skey);
int sm4_keysize(int *keysize);
extern const struct ltc_cipher_descriptor sm4_desc;
#endif
#ifdef LTC_CAST5
@ -897,6 +931,8 @@ int ecb_done(symmetric_ECB *ecb);
#ifdef LTC_CFB_MODE
int cfb_start(int cipher, const unsigned char *IV, const unsigned char *key,
int keylen, int num_rounds, symmetric_CFB *cfb);
int cfb_start_ex(int cipher, const unsigned char *IV, const unsigned char *key,
int keylen, int num_rounds, int width, symmetric_CFB *cfb);
int cfb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CFB *cfb);
int cfb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CFB *cfb);
int cfb_getiv(unsigned char *IV, unsigned long *len, const symmetric_CFB *cfb);

View File

@ -79,6 +79,7 @@
#define LTC_RIJNDAEL
#define LTC_BLOWFISH
#define LTC_DES
#define LTC_SM4
#define LTC_CAST5
#define LTC_NO_MODES
@ -114,6 +115,8 @@
#define LTC_NO_MISC
#define LTC_BASE64
#define LTC_BASE16
#define LTC_PEM
#endif /* LTC_EASY */
/* The minimal set of functionality to run the tests */
@ -179,9 +182,6 @@
#define LTC_RC6
#define LTC_SAFERP
#define LTC_RIJNDAEL
#ifndef LTC_NO_AES_NI
#define LTC_AES_NI
#endif
#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 */
@ -195,6 +195,7 @@
/* #define LTC_TWOFISH_SMALL */
/* LTC_DES includes EDE triple-DES */
#define LTC_DES
#define LTC_SM4
#define LTC_CAST5
#define LTC_NOEKEON
#define LTC_SKIPJACK
@ -300,6 +301,7 @@
#define LTC_CCM_MODE
#define LTC_GCM_MODE
#define LTC_CHACHA20POLY1305_MODE
#define LTC_SIV_MODE
/* Use 64KiB tables */
#ifndef LTC_NO_TABLES
@ -375,9 +377,9 @@
/* with non-glibc or glibc 2.17+ prefer clock_gettime over gettimeofday */
#if defined(__GLIBC__) && defined(__GLIBC_PREREQ)
#if __GLIBC_PREREQ(2, 17)
#define LTC_CLOCK_GETTIME
#endif
#if __GLIBC_PREREQ(2, 17)
#define LTC_CLOCK_GETTIME
#endif
#elif defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L
#define LTC_CLOCK_GETTIME
#endif
@ -407,6 +409,11 @@
#define LTC_FORTUNA_POOLS 32
#endif
/* at compile time you can decide whether fortuna uses the regular AES APIs
* or whether it will use the 'encrypt_only' variants.
* This is useful for custom builds of libtomcrypt for size-constrained targets. */
/* #define LTC_FORTUNA_USE_ENCRYPT_ONLY */
#endif /* LTC_FORTUNA */
@ -517,6 +524,8 @@
#define LTC_PBES
#define LTC_PEM
#endif /* LTC_NO_MISC */
/* cleanup */
@ -561,6 +570,33 @@
#endif
#endif /* LTC_MECC */
#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
#if defined(LTC_PEM)
/* Size of the line-buffer */
#ifndef LTC_PEM_DECODE_BUFSZ
#define LTC_PEM_DECODE_BUFSZ 80
#elif LTC_PEM_DECODE_BUFSZ < 72
#error "LTC_PEM_DECODE_BUFSZ shall not be < 72 bytes"
#endif
/* Size of the decoded data buffer */
#ifndef LTC_PEM_READ_BUFSIZE
#ifdef LTC_FILE_READ_BUFSIZE
#define LTC_PEM_READ_BUFSIZE LTC_FILE_READ_BUFSIZE
#else
#define LTC_PEM_READ_BUFSIZE 4096
#endif
#endif
#if defined(LTC_SSH)
#define LTC_PEM_SSH
#endif
#endif
#if defined(LTC_DER)
#ifndef LTC_DER_MAX_RECURSION
/* Maximum recursion limit when processing nested ASN.1 types. */
@ -703,13 +739,6 @@
/* define this if you use Valgrind, note: it CHANGES the way SOBER-128 and RC4 work (see the code) */
/* #define LTC_VALGRIND */
#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
/* ECC backwards compatibility */
#if !defined(LTC_ECC_SECP112R1) && defined(LTC_ECC112)
#define LTC_ECC_SECP112R1

View File

@ -57,8 +57,8 @@ struct md4_state {
#ifdef LTC_TIGER
struct tiger_state {
ulong64 state[3], length;
unsigned long curlen;
unsigned char buf[64];
unsigned long curlen, passes;
unsigned char buf[64], pad;
};
#endif
@ -440,10 +440,16 @@ extern const struct ltc_hash_descriptor md2_desc;
#ifdef LTC_TIGER
int tiger_init(hash_state * md);
int tiger_init_ex(hash_state *md, unsigned long passes);
int tiger_process(hash_state * md, const unsigned char *in, unsigned long inlen);
int tiger_done(hash_state * md, unsigned char *out);
int tiger_test(void);
extern const struct ltc_hash_descriptor tiger_desc;
int tiger2_init(hash_state *md);
int tiger2_init_ex(hash_state *md, unsigned long passes);
#define tiger2_process(m, i, l) tiger_process(m, i, l)
#define tiger2_done(m, o) tiger_done(m, o)
int tiger2_test(void);
extern const struct ltc_hash_descriptor tiger_desc, tiger2_desc;
#endif
#ifdef LTC_RIPEMD128

View File

@ -460,7 +460,7 @@ int ccm_test(void);
#endif /* LTC_CCM_MODE */
#if defined(LRW_MODE) || defined(LTC_GCM_MODE)
#if defined(LTC_LRW_MODE) || defined(LTC_GCM_MODE)
void gcm_gf_mult(const unsigned char *a, const unsigned char *b, unsigned char *c);
#endif
@ -541,11 +541,12 @@ typedef struct {
chacha_state chacha;
ulong64 aadlen;
ulong64 ctlen;
int aadflg;
int aadflg, openssh_compat;
} chacha20poly1305_state;
#define CHACHA20POLY1305_ENCRYPT LTC_ENCRYPT
#define CHACHA20POLY1305_DECRYPT LTC_DECRYPT
#define CHACHA20POLY1305_ENCRYPT LTC_ENCRYPT
#define CHACHA20POLY1305_DECRYPT LTC_DECRYPT
#define CHACHA20POLY1305_OPENSSH_COMPAT 2
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);
@ -564,3 +565,24 @@ int chacha20poly1305_memory(const unsigned char *key, unsigned long keylen,
int chacha20poly1305_test(void);
#endif /* LTC_CHACHA20POLY1305_MODE */
#ifdef LTC_SIV_MODE
int siv_encrypt_memory( int cipher,
const unsigned char *key, unsigned long keylen,
const unsigned char *ad[], unsigned long adlen[],
const unsigned char *pt, unsigned long ptlen,
unsigned char *ct, unsigned long *ctlen);
int siv_decrypt_memory( int cipher,
const unsigned char *key, unsigned long keylen,
const unsigned char *ad[], unsigned long adlen[],
const unsigned char *ct, unsigned long ctlen,
unsigned char *pt, unsigned long *ptlen);
int siv_memory( int cipher, int direction,
const unsigned char *key, unsigned long keylen,
const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
...) LTC_NULL_TERMINATED;
int siv_test(void);
#endif

View File

@ -69,14 +69,14 @@ do { XMEMCPY (&(x), (y), 4); \
#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__ ( \
__asm__ volatile ( \
"bswapl %0 \n\t" \
"movl %0,(%1)\n\t" \
"bswapl %0 \n\t" \
::"r"(x), "r"(y): "memory");
#define LOAD32H(x, y) \
asm __volatile__ ( \
__asm__ volatile ( \
"movl (%1),%0\n\t" \
"bswapl %0\n\t" \
:"=r"(x): "r"(y): "memory");
@ -109,14 +109,14 @@ do { XMEMCPY (&(x), (y), 8); \
#elif !defined(LTC_NO_BSWAP) && (defined(__GNUC__) && defined(__x86_64__))
#define STORE64H(x, y) \
asm __volatile__ ( \
__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__ ( \
__asm__ volatile ( \
"movq (%1),%0\n\t" \
"bswapq %0\n\t" \
:"=r"(x): "r"(y): "memory");
@ -263,7 +263,7 @@ do { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48) | \
static inline ulong32 ROL(ulong32 word, int i)
{
asm ("roll %%cl,%0"
__asm__ ("roll %%cl,%0"
:"=r" (word)
:"0" (word),"c" (i));
return word;
@ -271,7 +271,7 @@ static inline ulong32 ROL(ulong32 word, int i)
static inline ulong32 ROR(ulong32 word, int i)
{
asm ("rorl %%cl,%0"
__asm__ ("rorl %%cl,%0"
:"=r" (word)
:"0" (word),"c" (i));
return word;
@ -308,7 +308,7 @@ static inline ulong32 ROR(ulong32 word, int i)
static inline ulong32 ROL(ulong32 word, int i)
{
asm ("rotlw %0,%0,%2"
__asm__ ("rotlw %0,%0,%2"
:"=r" (word)
:"0" (word),"r" (i));
return word;
@ -316,7 +316,7 @@ static inline ulong32 ROL(ulong32 word, int i)
static inline ulong32 ROR(ulong32 word, int i)
{
asm ("rotlw %0,%0,%2"
__asm__ ("rotlw %0,%0,%2"
:"=r" (word)
:"0" (word),"r" (32-i));
return word;
@ -326,7 +326,7 @@ static inline ulong32 ROR(ulong32 word, int i)
static inline ulong32 ROLc(ulong32 word, const int i)
{
asm ("rotlwi %0,%0,%2"
__asm__ ("rotlwi %0,%0,%2"
:"=r" (word)
:"0" (word),"I" (i));
return word;
@ -334,7 +334,7 @@ static inline ulong32 ROLc(ulong32 word, const int i)
static inline ulong32 RORc(ulong32 word, const int i)
{
asm ("rotrwi %0,%0,%2"
__asm__ ("rotrwi %0,%0,%2"
:"=r" (word)
:"0" (word),"I" (i));
return word;
@ -381,7 +381,7 @@ static inline ulong32 RORc(ulong32 word, const int i)
static inline ulong64 ROL64(ulong64 word, int i)
{
asm("rolq %%cl,%0"
__asm__("rolq %%cl,%0"
:"=r" (word)
:"0" (word),"c" (i));
return word;
@ -389,7 +389,7 @@ static inline ulong64 ROL64(ulong64 word, int i)
static inline ulong64 ROR64(ulong64 word, int i)
{
asm("rorq %%cl,%0"
__asm__("rorq %%cl,%0"
:"=r" (word)
:"0" (word),"c" (i));
return word;

View File

@ -48,7 +48,7 @@ typedef struct {
@param src The number to copy from
@return CRYPT_OK on success
*/
int (*init_copy)(void **dst, void *src);
int (*init_copy)(void **dst, const void *src);
/** deinit
@param a The number to free
@ -63,14 +63,14 @@ typedef struct {
@param dst The destination
@return CRYPT_OK on success
*/
int (*neg)(void *src, void *dst);
int (*neg)(const 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);
int (*copy)(const void *src, void *dst);
/* ---- trivial low level functions ---- */
@ -86,20 +86,20 @@ typedef struct {
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);
unsigned long (*get_int)(const 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);
ltc_mp_digit (*get_digit)(const 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);
int (*get_digit_count)(const void *a);
/** compare two integers
@param a The left side integer
@ -108,7 +108,7 @@ typedef struct {
LTC_MP_GT if a > b and
LTC_MP_EQ otherwise. (signed comparison)
*/
int (*compare)(void *a, void *b);
int (*compare)(const void *a, const void *b);
/** compare against int
@param a The left side integer
@ -117,19 +117,19 @@ typedef struct {
LTC_MP_GT if a > b and
LTC_MP_EQ otherwise. (signed comparison)
*/
int (*compare_d)(void *a, ltc_mp_digit n);
int (*compare_d)(const 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);
int (*count_bits)(const 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);
int (*count_lsb_bits)(const void *a);
/** Compute a power of two
@param a The integer to store the power in
@ -154,20 +154,20 @@ typedef struct {
@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);
int (*write_radix)(const 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);
unsigned long (*unsigned_size)(const 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);
int (*unsigned_write)(const void *src, unsigned char *dst);
/** read an array of octets and store as integer
@param dst The integer to load
@ -175,9 +175,9 @@ typedef struct {
@param len The number of octets
@return CRYPT_OK on success
*/
int (*unsigned_read)( void *dst,
unsigned char *src,
unsigned long len);
int (*unsigned_read)( void *dst,
const unsigned char *src,
unsigned long len);
/* ---- basic math ---- */
@ -187,7 +187,7 @@ typedef struct {
@param c The destination of "a + b"
@return CRYPT_OK on success
*/
int (*add)(void *a, void *b, void *c);
int (*add)(const void *a, const void *b, void *c);
/** add two integers
@param a The first source integer
@ -196,7 +196,7 @@ typedef struct {
@param c The destination of "a + b"
@return CRYPT_OK on success
*/
int (*addi)(void *a, ltc_mp_digit b, void *c);
int (*addi)(const void *a, ltc_mp_digit b, void *c);
/** subtract two integers
@param a The first source integer
@ -204,7 +204,7 @@ typedef struct {
@param c The destination of "a - b"
@return CRYPT_OK on success
*/
int (*sub)(void *a, void *b, void *c);
int (*sub)(const void *a, const void *b, void *c);
/** subtract two integers
@param a The first source integer
@ -213,7 +213,7 @@ typedef struct {
@param c The destination of "a - b"
@return CRYPT_OK on success
*/
int (*subi)(void *a, ltc_mp_digit b, void *c);
int (*subi)(const void *a, ltc_mp_digit b, void *c);
/** multiply two integers
@param a The first source integer
@ -222,7 +222,7 @@ typedef struct {
@param c The destination of "a * b"
@return CRYPT_OK on success
*/
int (*mul)(void *a, void *b, void *c);
int (*mul)(const void *a, const void *b, void *c);
/** multiply two integers
@param a The first source integer
@ -231,14 +231,14 @@ typedef struct {
@param c The destination of "a * b"
@return CRYPT_OK on success
*/
int (*muli)(void *a, ltc_mp_digit b, void *c);
int (*muli)(const 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);
int (*sqr)(const void *a, void *b);
/** Square root (mod prime)
@param a The integer to compute square root mod prime from
@ -246,7 +246,7 @@ typedef struct {
@param c The destination
@return CRYPT_OK on success
*/
int (*sqrtmod_prime)(void *a, void *b, void *c);
int (*sqrtmod_prime)(const void *a, const void *b, void *c);
/** Divide an integer
@param a The dividend
@ -255,14 +255,14 @@ typedef struct {
@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);
int (*mpdiv)(const void *a, const 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);
int (*div_2)(const void *a, void *b);
/** Get remainder (small value)
@param a The integer to reduce
@ -270,7 +270,7 @@ typedef struct {
@param c The destination for the residue
@return CRYPT_OK on success
*/
int (*modi)(void *a, ltc_mp_digit b, ltc_mp_digit *c);
int (*modi)(const void *a, ltc_mp_digit b, ltc_mp_digit *c);
/** gcd
@param a The first integer
@ -278,7 +278,7 @@ typedef struct {
@param c The destination for (a, b)
@return CRYPT_OK on success
*/
int (*gcd)(void *a, void *b, void *c);
int (*gcd)(const void *a, const void *b, void *c);
/** lcm
@param a The first integer
@ -286,7 +286,7 @@ typedef struct {
@param c The destination for [a, b]
@return CRYPT_OK on success
*/
int (*lcm)(void *a, void *b, void *c);
int (*lcm)(const void *a, const void *b, void *c);
/** Modular multiplication
@param a The first source
@ -295,7 +295,7 @@ typedef struct {
@param d The destination (a*b mod c)
@return CRYPT_OK on success
*/
int (*mulmod)(void *a, void *b, void *c, void *d);
int (*mulmod)(const void *a, const void *b, const void *c, void *d);
/** Modular squaring
@param a The first source
@ -303,7 +303,7 @@ typedef struct {
@param c The destination (a*a mod b)
@return CRYPT_OK on success
*/
int (*sqrmod)(void *a, void *b, void *c);
int (*sqrmod)(const void *a, const void *b, void *c);
/** Modular inversion
@param a The value to invert
@ -311,7 +311,7 @@ typedef struct {
@param c The destination (1/a mod b)
@return CRYPT_OK on success
*/
int (*invmod)(void *, void *, void *);
int (*invmod)(const void *a, const void *b, void *c);
/* ---- reduction ---- */
@ -320,14 +320,14 @@ typedef struct {
@param b The destination for the reduction digit
@return CRYPT_OK on success
*/
int (*montgomery_setup)(void *a, void **b);
int (*montgomery_setup)(const 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);
int (*montgomery_normalization)(void *a, const void *b);
/** reduce a number
@param a The number [and dest] to reduce
@ -335,7 +335,7 @@ typedef struct {
@param c The value "b" from montgomery_setup()
@return CRYPT_OK on success
*/
int (*montgomery_reduce)(void *a, void *b, void *c);
int (*montgomery_reduce)(void *a, const void *b, void *c);
/** clean up (frees memory)
@param a The value "b" from montgomery_setup()
@ -352,7 +352,7 @@ typedef struct {
@param d The destination
@return CRYPT_OK on success
*/
int (*exptmod)(void *a, void *b, void *c, void *d);
int (*exptmod)(const void *a, const void *b, const void *c, void *d);
/** Primality testing
@param a The integer to test
@ -360,7 +360,7 @@ typedef struct {
@param c The destination of the result (FP_YES if prime)
@return CRYPT_OK on success
*/
int (*isprime)(void *a, int b, int *c);
int (*isprime)(const void *a, int b, int *c);
/* ---- (optional) ecc point math ---- */
@ -374,11 +374,11 @@ typedef struct {
(can be ignored if you work in affine only)
@return CRYPT_OK on success
*/
int (*ecc_ptmul)( void *k,
int (*ecc_ptmul)( const void *k,
const ecc_point *G,
ecc_point *R,
void *a,
void *modulus,
const void *a,
const void *modulus,
int map);
/** ECC GF(p) point addition
@ -393,8 +393,8 @@ typedef struct {
int (*ecc_ptadd)(const ecc_point *P,
const ecc_point *Q,
ecc_point *R,
void *ma,
void *modulus,
const void *ma,
const void *modulus,
void *mp);
/** ECC GF(p) point double
@ -407,8 +407,8 @@ typedef struct {
*/
int (*ecc_ptdbl)(const ecc_point *P,
ecc_point *R,
void *ma,
void *modulus,
const void *ma,
const void *modulus,
void *mp);
/** ECC mapping from projective to affine,
@ -421,7 +421,7 @@ typedef struct {
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);
int (*ecc_map)(ecc_point *P, const void *modulus, void *mp);
/** Computes kA*A + kB*B = C using Shamir's Trick
@param A First point to multiply
@ -436,8 +436,8 @@ typedef struct {
int (*ecc_mul2add)(const ecc_point *A, void *kA,
const ecc_point *B, void *kB,
ecc_point *C,
void *ma,
void *modulus);
const void *ma,
const void *modulus);
/* ---- (optional) rsa optimized math (for internal CRT) ---- */
@ -479,7 +479,7 @@ typedef struct {
@param d The destination (a + b mod c)
@return CRYPT_OK on success
*/
int (*addmod)(void *a, void *b, void *c, void *d);
int (*addmod)(const void *a, const void *b, const void *c, void *d);
/** Modular substraction
@param a The first source
@ -488,7 +488,7 @@ typedef struct {
@param d The destination (a - b mod c)
@return CRYPT_OK on success
*/
int (*submod)(void *a, void *b, void *c, void *d);
int (*submod)(const void *a, const void *b, const void *c, void *d);
/* ---- misc stuff ---- */

View File

@ -159,6 +159,40 @@ int padding_pad(unsigned char *data, unsigned long length, unsigned long* padded
int padding_depad(const unsigned char *data, unsigned long *length, unsigned long mode);
#endif /* LTC_PADDING */
#ifdef LTC_PEM
/* Buffer-based API */
int pem_decode(const void *buf, unsigned long len, ltc_pka_key *k, const password_ctx *pw_ctx);
int pem_decode_pkcs(const void *buf, unsigned long len, ltc_pka_key *k, const password_ctx *pw_ctx);
#ifdef LTC_SSH
/**
Callback function for each key in an `authorized_keys` file.
This function takes ownership of the `k` parameter passed.
`k` must be free'd by calling `pka_key_destroy(&k)`.
@param k Pointer to the PKA key.
@param comment Pointer to a string with the comment.
@param ctx The `ctx` pointer as passed to the read function.
*/
typedef int (*ssh_authorized_key_cb)(ltc_pka_key *k, const char *comment, void *ctx);
int pem_decode_openssh(const void *buf, unsigned long len, ltc_pka_key *k, const password_ctx *pw_ctx);
int ssh_read_authorized_keys(const void *buf, unsigned long len, ssh_authorized_key_cb cb, void *ctx);
#endif /* LTC_SSH */
/* FILE*-based API */
#ifndef LTC_NO_FILE
int pem_decode_filehandle(FILE *f, ltc_pka_key *k, const password_ctx *pw_ctx);
int pem_decode_pkcs_filehandle(FILE *f, ltc_pka_key *k, const password_ctx *pw_ctx);
#ifdef LTC_SSH
int pem_decode_openssh_filehandle(FILE *f, ltc_pka_key *k, const password_ctx *pw_ctx);
int ssh_read_authorized_keys_filehandle(FILE *f, ssh_authorized_key_cb cb, void *ctx);
#endif /* LTC_SSH */
#endif /* LTC_NO_FILE */
#endif /* LTC_PEM */
#ifdef LTC_SSH
typedef enum ssh_data_type_ {
LTC_SSHDATA_EOL,

View File

@ -1,8 +1,48 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
typedef struct password_ctx {
/**
Callback function that is called when a password is required.
Please be aware that the library takes ownership of the pointer that is
returned to the library via `str`.
The data will be zeroed and `free()`'d as soon as it isn't required anymore.
c.f. the documentation of the `free()` function pointer for details.
@param str Pointer to pointer where the password will be stored.
@param len Pointer to the length of the password.
@param userdata `userdata` that was passed in the `password_ctx` struct.
@return CRYPT_OK on success
*/
int (*callback)(void **str, unsigned long *len, void *userdata);
/**
Optional free function to free the allocated buffer.
At the point where the value returned by `callback()` is not required
anymore the library will free it by either calling this `free()` function
or `XFREE()` in case this `free()` function is set to `NULL`.
@param str Pointer to the buffer to be free'd.
*/
void (*free)(void *str);
/** Opaque `userdata` pointer passed when the callback is called */
void *userdata;
} password_ctx;
/* ---- NUMBER THEORY ---- */
enum ltc_pka_id {
LTC_PKA_UNDEF = 0,
LTC_PKA_RSA,
LTC_PKA_DSA,
LTC_PKA_EC,
LTC_PKA_X25519,
LTC_PKA_ED25519,
LTC_PKA_DH,
LTC_PKA_NUM
};
enum public_key_type {
/* Refers to the public key */
PK_PUBLIC = 0x0000,
@ -108,7 +148,7 @@ 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);
const password_ctx *pw_ctx, rsa_key *key);
int rsa_set_key(const unsigned char *N, unsigned long Nlen,
const unsigned char *e, unsigned long elen,
@ -138,6 +178,8 @@ int dh_get_groupsize(const dh_key *key);
int dh_export(unsigned char *out, unsigned long *outlen, int type, const dh_key *key);
int dh_import(const unsigned char *in, unsigned long inlen, dh_key *key);
int dh_import_pkcs8(const unsigned char *in, unsigned long inlen,
const password_ctx *pw_ctx, dh_key *key);
int dh_set_pg(const unsigned char *p, unsigned long plen,
const unsigned char *g, unsigned long glen,
@ -280,7 +322,7 @@ int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen, ecc_ke
int ecc_export_openssl(unsigned char *out, unsigned long *outlen, int type, const ecc_key *key);
int ecc_import_openssl(const unsigned char *in, unsigned long inlen, ecc_key *key);
int ecc_import_pkcs8(const unsigned char *in, unsigned long inlen, const void *pwd, unsigned long pwdlen, ecc_key *key);
int ecc_import_pkcs8(const unsigned char *in, unsigned long inlen, const password_ctx *pw_ctx, ecc_key *key);
int ecc_import_x509(const unsigned char *in, unsigned long inlen, ecc_key *key);
int ecc_shared_secret(const ecc_key *private_key, const ecc_key *public_key,
@ -328,12 +370,8 @@ typedef struct {
/** The key type, PK_PRIVATE or PK_PUBLIC */
enum public_key_type type;
/** The PK-algorithm, PKA_ED25519 or PKA_X25519 */
/** This was supposed to be:
* enum public_key_algorithms algo;
* but that enum is now in tomcrypt_private.h
*/
int algo;
/** The PK-algorithm, LTC_PKA_ED25519 or LTC_PKA_X25519 */
enum ltc_pka_id pka;
/** The private key */
unsigned char priv[32];
@ -353,9 +391,9 @@ int ed25519_export( unsigned char *out, unsigned long *outlen,
int ed25519_import(const unsigned char *in, unsigned long inlen, curve25519_key *key);
int ed25519_import_raw(const unsigned char *in, unsigned long inlen, int which, curve25519_key *key);
int ed25519_import_x509(const unsigned char *in, unsigned long inlen, curve25519_key *key);
int ed25519_import_pkcs8(const unsigned char *in, unsigned long inlen,
const void *pwd, unsigned long pwdlen,
curve25519_key *key);
int ed25519_import_pkcs8(const unsigned char *in, unsigned long inlen,
const password_ctx *pw_ctx,
curve25519_key *key);
int ed25519_sign(const unsigned char *msg, unsigned long msglen,
unsigned char *sig, unsigned long *siglen,
@ -393,9 +431,9 @@ int x25519_export( unsigned char *out, unsigned long *outlen,
int x25519_import(const unsigned char *in, unsigned long inlen, curve25519_key *key);
int x25519_import_raw(const unsigned char *in, unsigned long inlen, int which, curve25519_key *key);
int x25519_import_x509(const unsigned char *in, unsigned long inlen, curve25519_key *key);
int x25519_import_pkcs8(const unsigned char *in, unsigned long inlen,
const void *pwd, unsigned long pwdlen,
curve25519_key *key);
int x25519_import_pkcs8(const unsigned char *in, unsigned long inlen,
const password_ctx *pw_ctx,
curve25519_key *key);
int x25519_shared_secret(const curve25519_key *private_key,
const curve25519_key *public_key,
@ -478,6 +516,9 @@ int dsa_decrypt_key(const unsigned char *in, unsigned long inlen,
const dsa_key *key);
int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key);
int dsa_import_pkcs8(const unsigned char *in, unsigned long inlen,
const password_ctx *pw_ctx,
dsa_key *key);
int dsa_export(unsigned char *out, unsigned long *outlen, int type, const dsa_key *key);
int dsa_verify_key(const dsa_key *key, int *stat);
int dsa_shared_secret(void *private_key, void *base,
@ -485,6 +526,36 @@ int dsa_shared_secret(void *private_key, void *base,
unsigned char *out, unsigned long *outlen);
#endif /* LTC_MDSA */
/*
* LibTomCrypt tagged-union for holding a Public Key
*/
typedef struct {
union {
#ifdef LTC_CURVE25519
curve25519_key x25519;
curve25519_key ed25519;
#endif
#ifdef LTC_MDH
dh_key dh;
#endif
#ifdef LTC_MDSA
dsa_key dsa;
#endif
#ifdef LTC_MECC
ecc_key ecc;
#endif
#ifdef LTC_MRSA
rsa_key rsa;
#endif
char dummy;
} u;
enum ltc_pka_id id;
} ltc_pka_key;
void pka_key_free(ltc_pka_key *key);
void pka_key_destroy(ltc_pka_key **key);
#ifdef LTC_DER
/* DER handling */

View File

@ -2,6 +2,7 @@
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt.h"
#include <stdarg.h>
/*
* Internal Macros
@ -11,7 +12,8 @@
#define LTC_PAD_MASK (0xF000U)
#if defined(ENDIAN_64BITWORD)
/* only real 64bit, not x32 */
#if defined(ENDIAN_64BITWORD) && !defined(ENDIAN_64BITWORD_X32)
#define CONSTPTR(n) CONST64(n)
#else
#define CONSTPTR(n) n ## uL
@ -30,6 +32,8 @@ LTC_STATIC_ASSERT(correct_ltc_uintptr_size, sizeof(ltc_uintptr) == sizeof(void*)
*/
#define LTC_ALIGN_BUF(buf, n) ((void*)((ltc_uintptr)&((unsigned char*)(buf))[n - 1] & (~(CONSTPTR(n) - CONSTPTR(1)))))
#define LTC_OID_MAX_STRLEN 256
/* `NULL` as defined by the standard is not guaranteed to be of a pointer
* type. In order to make sure that in vararg API's a pointer type is used,
* define our own version and use that one internally.
@ -43,12 +47,15 @@ LTC_STATIC_ASSERT(correct_ltc_uintptr_size, sizeof(ltc_uintptr) == sizeof(void*)
*/
enum ltc_oid_id {
LTC_OID_UNDEF,
LTC_OID_RSA,
LTC_OID_DSA,
LTC_OID_EC,
LTC_OID_EC_PRIMEF,
LTC_OID_X25519,
LTC_OID_ED25519,
LTC_OID_DH,
LTC_OID_NUM
};
/*
@ -61,8 +68,16 @@ typedef struct {
} 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,
struct password {
/* usually a `char*` but could also contain binary data
* so use a `void*` + length to be on the safe side.
*/
void *pw;
unsigned long l;
};
typedef int (*fn_kdf_t)(const struct password *pwd,
const unsigned char *salt, unsigned long salt_len,
int iteration_count, int hash_idx,
unsigned char *out, unsigned long *outlen);
@ -81,8 +96,7 @@ typedef struct {
typedef struct
{
pbes_properties type;
const void *pwd;
unsigned long pwdlen;
struct password pw;
ltc_asn1_list *enc_data;
ltc_asn1_list *salt;
ltc_asn1_list *iv;
@ -98,10 +112,6 @@ typedef struct
/* tomcrypt_cipher.h */
#if defined(LTC_AES_NI) && defined(LTC_AMD64_SSE4_1)
#define LTC_HAS_AES_NI
#endif
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,
@ -159,6 +169,7 @@ int func_name (hash_state * md, const unsigned char *in, unsigned long inlen)
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);
int omac_vprocess(omac_state *omac, const unsigned char *in, unsigned long inlen, va_list args);
/* tomcrypt_math.h */
@ -247,13 +258,121 @@ int base64_encode_pem(const unsigned char *in, unsigned long inlen,
char *out, unsigned long *outlen,
unsigned int flags);
/* PEM related */
#ifdef LTC_PEM
enum cipher_mode {
cm_modes = 0x00ff,
cm_flags = 0xff00,
/* Flags */
cm_openssh = 0x0100,
cm_1bit = 0x0200,
cm_8bit = 0x0400,
/* Modes */
cm_none = 0x0000,
cm_cbc = 0x0001,
cm_cfb = 0x0002,
cm_ctr = 0x0003,
cm_ofb = 0x0004,
cm_stream = 0x0005,
cm_gcm = 0x0006,
cm_cfb1 = cm_cfb | cm_1bit,
cm_cfb8 = cm_cfb | cm_8bit,
cm_stream_openssh = cm_stream | cm_openssh,
};
struct blockcipher_info {
const char *name;
const char *algo;
unsigned long keylen;
enum cipher_mode mode;
/* should use `MAXBLOCKSIZE` here, but all supported
* blockciphers require max 16 bytes IV */
char iv[16 * 2 + 1];
};
struct str {
char *p;
unsigned long len;
};
#define SET_STR(n, s) n.p = s, n.len = XSTRLEN(s)
#define SET_CSTR(n, s) n.p = (char*)s, n.len = (sizeof s) - 1
#define COPY_STR(n, s, l) do { XMEMCPY(n.p, s, l); n.len = l; } while(0)
#define RESET_STR(n) do { n.p = NULL; n.len = 0; } while(0)
enum more_headers {
no,
yes,
maybe
};
enum pem_flags {
pf_encrypted = 0x01u,
pf_pkcs8 = 0x02u,
pf_public = 0x04u,
pf_x509 = 0x08u,
pf_encrypted_pkcs8 = pf_encrypted | pf_pkcs8,
};
struct pem_header_id {
struct str start, end;
enum more_headers has_more_headers;
enum pem_flags flags;
enum ltc_pka_id pka;
int (*decrypt)(void *, unsigned long *, void *);
};
struct pem_headers {
const struct pem_header_id *id;
int encrypted;
struct blockcipher_info info;
struct password *pw;
};
struct bufp {
/* `end` points to one byte after the last
* element of the allocated buffer
*/
char *start, *work, *end;
};
#define SET_BUFP(n, d, l) n.start = (char*)d, n.work = (char*)d, n.end = (char*)d + l + 1
struct get_char {
int (*get)(struct get_char*);
union {
#ifndef LTC_NO_FILE
FILE *f;
#endif /* LTC_NO_FILE */
struct bufp buf;
} data;
struct str unget_buf;
char unget_buf_[LTC_PEM_DECODE_BUFSZ];
};
#endif
/* others */
void copy_or_zeromem(const unsigned char* src, unsigned char* dest, unsigned long len, int coz);
void password_free(struct password *pw, const struct password_ctx *ctx);
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);
int pem_decrypt(unsigned char *data, unsigned long *datalen,
unsigned char *key, unsigned long keylen,
unsigned char *iv, unsigned long ivlen,
unsigned char *tag, unsigned long taglen,
const struct blockcipher_info *info,
enum padding_type padding);
#ifndef LTC_NO_FILE
int pem_get_char_from_file(struct get_char *g);
#endif /* LTC_NO_FILE */
int pem_get_char_from_buf(struct get_char *g);
int pem_read(void *pem, unsigned long *w, struct pem_headers *hdr, struct get_char *g);
/* tomcrypt_pk.h */
@ -261,6 +380,9 @@ 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_get_pka_id(enum ltc_oid_id id, enum ltc_pka_id *pka);
int pk_get_oid_id(enum ltc_pka_id pka, enum ltc_oid_id *oid);
int pk_get_oid_from_asn1(const ltc_asn1_list *oid, enum ltc_oid_id *id);
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);
@ -271,13 +393,16 @@ void rsa_shrink_key(rsa_key *key);
int rsa_make_key_bn_e(prng_state *prng, int wprng, int size, void *e,
rsa_key *key); /* used by op-tee */
int rsa_import_pkcs1(const unsigned char *in, unsigned long inlen, rsa_key *key);
int rsa_import_pkcs8_asn1(ltc_asn1_list *alg_id, ltc_asn1_list *priv_key, rsa_key *key);
#endif /* LTC_MRSA */
/* ---- DH Routines ---- */
#ifdef LTC_MDH
extern const ltc_dh_set_type ltc_dh_sets[];
int dh_init(dh_key *key);
int dh_check_pubkey(const dh_key *key);
int dh_import_pkcs8_asn1(ltc_asn1_list *alg_id, ltc_asn1_list *priv_key, dh_key *key);
#endif /* LTC_MDH */
/* ---- ECC Routines ---- */
@ -286,6 +411,9 @@ int ecc_set_curve_from_mpis(void *a, void *b, void *prime, void *order, void *gx
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);
int ecc_import_pkcs8_asn1(ltc_asn1_list *alg_id, ltc_asn1_list *priv_key, ecc_key *key);
int ecc_import_with_curve(const unsigned char *in, unsigned long inlen, int type, ecc_key *key);
int ecc_import_with_oid(const unsigned char *in, unsigned long inlen, unsigned long *oid, unsigned long oid_len, int type, ecc_key *key);
#ifdef LTC_SSH
int ecc_ssh_ecdsa_encode_name(char *buffer, unsigned long *buflen, const ecc_key *key);
@ -297,7 +425,7 @@ 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_is_point_at_infinity(const ecc_point *P, const 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);
@ -305,10 +433,12 @@ 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);
int ltc_ecc_projective_dbl_point(const ecc_point *P, ecc_point *R,
const void *ma, const 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);
int ltc_ecc_projective_add_point(const ecc_point *P, const ecc_point *Q, ecc_point *R,
const void *ma, const void *modulus, void *mp);
#endif
#if defined(LTC_MECC_FP)
@ -326,36 +456,41 @@ 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);
int ltc_ecc_mulmod(const void *k, const ecc_point *G, ecc_point *R,
const void *a, const 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);
const void *ma,
const 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);
const void *ma,
const void *modulus);
#endif
#endif
/* map P to affine from projective */
int ltc_ecc_map(ecc_point *P, void *modulus, void *mp);
int ltc_ecc_map(ecc_point *P, const void *modulus, void *mp);
#endif /* LTC_MECC */
#ifdef LTC_MDSA
int dsa_int_init(dsa_key *key);
int dsa_int_validate(const dsa_key *key, int *stat);
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);
int dsa_import_pkcs1(const unsigned char *in, unsigned long inlen, dsa_key *key);
int dsa_import_pkcs8_asn1(ltc_asn1_list *alg_id, ltc_asn1_list *priv_key, dsa_key *key);
#endif /* LTC_MDSA */
@ -378,11 +513,18 @@ int tweetnacl_crypto_scalarmult(unsigned char *q, const unsigned char *n, const
int tweetnacl_crypto_scalarmult_base(unsigned char *q,const unsigned char *n);
int tweetnacl_crypto_ph(unsigned char *out, const unsigned char *msg, unsigned long long msglen);
typedef int (*sk_to_pk)(unsigned char *pk ,const unsigned char *sk);
int ed25519_import_pkcs8_asn1(ltc_asn1_list *alg_id, ltc_asn1_list *priv_key,
curve25519_key *key);
int x25519_import_pkcs8_asn1(ltc_asn1_list *alg_id, ltc_asn1_list *priv_key,
curve25519_key *key);
int ec25519_import_pkcs8_asn1(ltc_asn1_list *alg_id, ltc_asn1_list *priv_key,
enum ltc_oid_id id,
curve25519_key *key);
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);
const password_ctx *pw_ctx,
enum ltc_oid_id id,
curve25519_key *key);
int ec25519_export( unsigned char *out, unsigned long *outlen,
int which,
const curve25519_key *key);
@ -411,12 +553,27 @@ 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);
typedef struct {
ltc_asn1_type t;
ltc_asn1_list **pp;
} der_flexi_check;
#define LTC_SET_DER_FLEXI_CHECK(list, index, Type, P) \
do { \
int LTC_SDFC_temp##__LINE__ = (index); \
list[LTC_SDFC_temp##__LINE__].t = Type; \
list[LTC_SDFC_temp##__LINE__].pp = P; \
} while (0)
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_flexi_sequence_cmp(const ltc_asn1_list *flexi, der_flexi_check *check);
int der_decode_sequence_multi_ex(const unsigned char *in, unsigned long inlen, unsigned int flags, ...)
LTC_NULL_TERMINATED;
@ -431,14 +588,15 @@ int x509_decode_public_key_from_certificate(const unsigned char *in, unsigned lo
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);
int x509_decode_spki(const unsigned char *in, unsigned long inlen, ltc_asn1_list **out, ltc_asn1_list **spki);
/* 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,
enum ltc_oid_id 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,
enum ltc_oid_id 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);
@ -450,9 +608,35 @@ int pk_oid_cmp_with_asn1(const char *o1, const ltc_asn1_list *o2);
#ifdef LTC_PKCS_8
/* Public-Key Cryptography Standards (PKCS) #8:
* Private-Key Information Syntax Specification Version 1.2
* https://tools.ietf.org/html/rfc5208
*
* PrivateKeyInfo ::= SEQUENCE {
* version Version,
* privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
* privateKey PrivateKey,
* attributes [0] IMPLICIT Attributes OPTIONAL }
* where:
* - Version ::= INTEGER
* - PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
* - PrivateKey ::= OCTET STRING
* - Attributes ::= SET OF Attribute
*
* EncryptedPrivateKeyInfo ::= SEQUENCE {
* encryptionAlgorithm EncryptionAlgorithmIdentifier,
* encryptedData EncryptedData }
* where:
* - EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
* - EncryptedData ::= OCTET STRING
*/
int pkcs8_decode_flexi(const unsigned char *in, unsigned long inlen,
const void *pwd, unsigned long pwdlen,
ltc_asn1_list **decoded_list);
const password_ctx *pw_ctx,
ltc_asn1_list **decoded_list);
int pkcs8_get_children(const ltc_asn1_list *decoded_list, enum ltc_oid_id *pka,
ltc_asn1_list **alg_id, ltc_asn1_list **priv_key);
#endif /* LTC_PKCS_8 */
@ -500,3 +684,14 @@ int which ## _export(unsigned char *out, unsigned long *outlen, prng_state *prng
#else
#define LTC_BYTE(x, n) (((x) >> (8 * (n))) & 255)
#endif
/*
* On Windows, choose whether to use CryptGenRandom() [older Windows versions]
* or BCryptGenRandom() [newer Windows versions].
* If CryptGenRandom() is desired, define LTC_NO_WIN32_BCRYPT when building.
*/
#if defined(_MSC_VER) && defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0600
#if !defined(LTC_NO_WIN32_BCRYPT)
#define LTC_WIN32_BCRYPT
#endif
#endif

View File

@ -2,7 +2,6 @@
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
#include <stdarg.h>
#ifdef LTC_BLAKE2BMAC

View File

@ -2,7 +2,6 @@
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
#include <stdarg.h>
#ifdef LTC_BLAKE2SMAC

View File

@ -1,7 +1,6 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
#include <stdarg.h>
/**
@file f9_memory_multi.c

View File

@ -1,7 +1,6 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
#include <stdarg.h>
/**
@file hmac_memory_multi.c

View File

@ -1,7 +1,6 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
#include <stdarg.h>
/**
@file omac_memory_multi.c
@ -10,6 +9,31 @@
#ifdef LTC_OMAC
static LTC_INLINE int s_omac_vprocess(omac_state *omac, const unsigned char *in, unsigned long inlen, va_list args)
{
const unsigned char * curptr = in;
unsigned long curlen = inlen;
int err;
for (;;) {
/* process buf */
if ((err = omac_process(omac, curptr, curlen)) != CRYPT_OK) {
return err;
}
/* step to next */
curptr = va_arg(args, const unsigned char*);
if (curptr == NULL) {
break;
}
curlen = va_arg(args, unsigned long);
}
return CRYPT_OK;
}
int omac_vprocess(omac_state *omac, const unsigned char *in, unsigned long inlen, va_list args)
{
return s_omac_vprocess(omac, in, inlen, args);
}
/**
OMAC multiple blocks of memory
@param cipher The index of the desired cipher
@ -30,8 +54,6 @@ int omac_memory_multi(int cipher,
int err;
omac_state *omac;
va_list args;
const unsigned char *curptr;
unsigned long curlen;
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(in != NULL);
@ -49,23 +71,10 @@ int omac_memory_multi(int cipher,
goto LBL_ERR;
}
va_start(args, inlen);
curptr = in;
curlen = inlen;
for (;;) {
/* process buf */
if ((err = omac_process(omac, curptr, curlen)) != CRYPT_OK) {
goto LBL_ERR;
}
/* step to next */
curptr = va_arg(args, const unsigned char*);
if (curptr == NULL) {
break;
}
curlen = va_arg(args, unsigned long);
}
if ((err = omac_done(omac, out, outlen)) != CRYPT_OK) {
if ((err = s_omac_vprocess(omac, in, inlen, args)) != CRYPT_OK) {
goto LBL_ERR;
}
err = omac_done(omac, out, outlen);
LBL_ERR:
#ifdef LTC_CLEAN_STACK
zeromem(omac, sizeof(omac_state));

View File

@ -1,7 +1,6 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
#include <stdarg.h>
/**
@file pmac_memory_multi.c

View File

@ -7,7 +7,6 @@
*/
#include "tomcrypt_private.h"
#include <stdarg.h>
#ifdef LTC_POLY1305

View File

@ -1,7 +1,6 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
#include <stdarg.h>
/**
@file xcbc_memory_multi.c

View File

@ -17,7 +17,7 @@ static int init(void **a)
if (*a == NULL) {
return CRYPT_MEM;
}
mpz_init(((__mpz_struct *)*a));
mpz_init(*a);
return CRYPT_OK;
}
@ -28,7 +28,7 @@ static void deinit(void *a)
XFREE(a);
}
static int neg(void *a, void *b)
static int neg(const void *a, void *b)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
@ -36,7 +36,7 @@ static int neg(void *a, void *b)
return CRYPT_OK;
}
static int copy(void *a, void *b)
static int copy(const void *a, void *b)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
@ -44,7 +44,7 @@ static int copy(void *a, void *b)
return CRYPT_OK;
}
static int init_copy(void **a, void *b)
static int init_copy(void **a, const void *b)
{
if (init(a) != CRYPT_OK) {
return CRYPT_MEM;
@ -56,29 +56,29 @@ static int init_copy(void **a, void *b)
static int set_int(void *a, ltc_mp_digit b)
{
LTC_ARGCHK(a != NULL);
mpz_set_ui(((__mpz_struct *)a), b);
mpz_set_ui(a, b);
return CRYPT_OK;
}
static unsigned long get_int(void *a)
static unsigned long get_int(const void *a)
{
LTC_ARGCHK(a != NULL);
return mpz_get_ui(a);
}
static ltc_mp_digit get_digit(void *a, int n)
static ltc_mp_digit get_digit(const void *a, int n)
{
LTC_ARGCHK(a != NULL);
return mpz_getlimbn(a, n);
}
static int get_digit_count(void *a)
static int get_digit_count(const void *a)
{
LTC_ARGCHK(a != NULL);
return mpz_size(a);
}
static int compare(void *a, void *b)
static int compare(const void *a, const void *b)
{
int ret;
LTC_ARGCHK(a != NULL);
@ -93,11 +93,11 @@ static int compare(void *a, void *b)
}
}
static int compare_d(void *a, ltc_mp_digit b)
static int compare_d(const void *a, ltc_mp_digit b)
{
int ret;
LTC_ARGCHK(a != NULL);
ret = mpz_cmp_ui(((__mpz_struct *)a), b);
ret = mpz_cmp_ui((__mpz_struct *)a, b);
if (ret < 0) {
return LTC_MP_LT;
} else if (ret > 0) {
@ -107,13 +107,13 @@ static int compare_d(void *a, ltc_mp_digit b)
}
}
static int count_bits(void *a)
static int count_bits(const void *a)
{
LTC_ARGCHK(a != NULL);
return mpz_sizeinbase(a, 2);
}
static int count_lsb_bits(void *a)
static int count_lsb_bits(const void *a)
{
LTC_ARGCHK(a != NULL);
return mpz_scan1(a, 0);
@ -176,7 +176,7 @@ static int read_radix(void *a, const char *b, int radix)
}
/* write one */
static int write_radix(void *a, char *b, int radix)
static int write_radix(const void *a, char *b, int radix)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
@ -190,26 +190,26 @@ static int write_radix(void *a, char *b, int radix)
}
/* get size as unsigned char string */
static unsigned long unsigned_size(void *a)
static unsigned long unsigned_size(const void *a)
{
unsigned long t;
LTC_ARGCHK(a != NULL);
t = mpz_sizeinbase(a, 2);
if (mpz_cmp_ui(((__mpz_struct *)a), 0) == 0) return 0;
if (mpz_cmp_ui((__mpz_struct *)a, 0) == 0) return 0;
return (t>>3) + ((t&7)?1:0);
}
/* store */
static int unsigned_write(void *a, unsigned char *b)
static int unsigned_write(const void *a, unsigned char *b)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
mpz_export(b, NULL, 1, 1, 1, 0, ((__mpz_struct*)a));
mpz_export(b, NULL, 1, 1, 1, 0, a);
return CRYPT_OK;
}
/* read */
static int unsigned_read(void *a, unsigned char *b, unsigned long len)
static int unsigned_read(void *a, const unsigned char *b, unsigned long len)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
@ -218,7 +218,7 @@ static int unsigned_read(void *a, unsigned char *b, unsigned long len)
}
/* add */
static int add(void *a, void *b, void *c)
static int add(const void *a, const void *b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
@ -227,7 +227,7 @@ static int add(void *a, void *b, void *c)
return CRYPT_OK;
}
static int addi(void *a, ltc_mp_digit b, void *c)
static int addi(const void *a, ltc_mp_digit b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(c != NULL);
@ -236,7 +236,7 @@ static int addi(void *a, ltc_mp_digit b, void *c)
}
/* sub */
static int sub(void *a, void *b, void *c)
static int sub(const void *a, const void *b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
@ -245,7 +245,7 @@ static int sub(void *a, void *b, void *c)
return CRYPT_OK;
}
static int subi(void *a, ltc_mp_digit b, void *c)
static int subi(const void *a, ltc_mp_digit b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(c != NULL);
@ -254,7 +254,7 @@ static int subi(void *a, ltc_mp_digit b, void *c)
}
/* mul */
static int mul(void *a, void *b, void *c)
static int mul(const void *a, const void *b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
@ -263,7 +263,7 @@ static int mul(void *a, void *b, void *c)
return CRYPT_OK;
}
static int muli(void *a, ltc_mp_digit b, void *c)
static int muli(const void *a, ltc_mp_digit b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(c != NULL);
@ -272,7 +272,7 @@ static int muli(void *a, ltc_mp_digit b, void *c)
}
/* sqr */
static int sqr(void *a, void *b)
static int sqr(const void *a, void *b)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
@ -281,7 +281,7 @@ static int sqr(void *a, void *b)
}
/* sqrtmod_prime */
static int sqrtmod_prime(void *n, void *prime, void *ret)
static int sqrtmod_prime(const void *n, const void *prime, void *ret)
{
int res, legendre, i;
mpz_t t1, C, Q, S, Z, M, T, R, two;
@ -291,11 +291,11 @@ static int sqrtmod_prime(void *n, void *prime, void *ret)
LTC_ARGCHK(ret != NULL);
/* first handle the simple cases */
if (mpz_cmp_ui(((__mpz_struct *)n), 0) == 0) {
if (mpz_cmp_ui((__mpz_struct *)n, 0) == 0) {
mpz_set_ui(ret, 0);
return CRYPT_OK;
}
if (mpz_cmp_ui(((__mpz_struct *)prime), 2) == 0) return CRYPT_ERROR; /* prime must be odd */
if (mpz_cmp_ui((__mpz_struct *)prime, 2) == 0) return CRYPT_ERROR; /* prime must be odd */
legendre = mpz_legendre(n, prime);
if (legendre == -1) return CRYPT_ERROR; /* quadratic non-residue mod prime */
@ -358,7 +358,7 @@ static int sqrtmod_prime(void *n, void *prime, void *ret)
mpz_set(t1, T);
i = 0;
while (1) {
if (mpz_cmp_ui(((__mpz_struct *)t1), 1) == 0) break;
if (mpz_cmp_ui(t1, 1) == 0) break;
mpz_powm(t1, t1, two, prime);
i++;
}
@ -394,7 +394,7 @@ cleanup:
}
/* div */
static int divide(void *a, void *b, void *c, void *d)
static int divide(const void *a, const void *b, void *c, void *d)
{
mpz_t tmp;
LTC_ARGCHK(a != NULL);
@ -413,7 +413,7 @@ static int divide(void *a, void *b, void *c, void *d)
return CRYPT_OK;
}
static int div_2(void *a, void *b)
static int div_2(const void *a, void *b)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
@ -422,7 +422,7 @@ static int div_2(void *a, void *b)
}
/* modi */
static int modi(void *a, ltc_mp_digit b, ltc_mp_digit *c)
static int modi(const void *a, ltc_mp_digit b, ltc_mp_digit *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(c != NULL);
@ -432,7 +432,7 @@ static int modi(void *a, ltc_mp_digit b, ltc_mp_digit *c)
}
/* gcd */
static int gcd(void *a, void *b, void *c)
static int gcd(const void *a, const void *b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
@ -442,7 +442,7 @@ static int gcd(void *a, void *b, void *c)
}
/* lcm */
static int lcm(void *a, void *b, void *c)
static int lcm(const void *a, const void *b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
@ -451,7 +451,7 @@ static int lcm(void *a, void *b, void *c)
return CRYPT_OK;
}
static int addmod(void *a, void *b, void *c, void *d)
static int addmod(const void *a, const void *b, const void *c, void *d)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
@ -462,7 +462,7 @@ static int addmod(void *a, void *b, void *c, void *d)
return CRYPT_OK;
}
static int submod(void *a, void *b, void *c, void *d)
static int submod(const void *a, const void *b, const void *c, void *d)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
@ -473,7 +473,7 @@ static int submod(void *a, void *b, void *c, void *d)
return CRYPT_OK;
}
static int mulmod(void *a, void *b, void *c, void *d)
static int mulmod(const void *a, const void *b, const void *c, void *d)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
@ -484,7 +484,7 @@ static int mulmod(void *a, void *b, void *c, void *d)
return CRYPT_OK;
}
static int sqrmod(void *a, void *b, void *c)
static int sqrmod(const void *a, const void *b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
@ -495,7 +495,7 @@ static int sqrmod(void *a, void *b, void *c)
}
/* invmod */
static int invmod(void *a, void *b, void *c)
static int invmod(const void *a, const void *b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
@ -505,7 +505,7 @@ static int invmod(void *a, void *b, void *c)
}
/* setup */
static int montgomery_setup(void *a, void **b)
static int montgomery_setup(const void *a, void **b)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
@ -514,7 +514,7 @@ static int montgomery_setup(void *a, void **b)
}
/* get normalization value */
static int montgomery_normalization(void *a, void *b)
static int montgomery_normalization(void *a, const void *b)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
@ -523,7 +523,7 @@ static int montgomery_normalization(void *a, void *b)
}
/* reduce */
static int montgomery_reduce(void *a, void *b, void *c)
static int montgomery_reduce(void *a, const void *b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
@ -538,7 +538,7 @@ static void montgomery_deinit(void *a)
LTC_UNUSED_PARAM(a);
}
static int exptmod(void *a, void *b, void *c, void *d)
static int exptmod(const void *a, const void *b, const void *c, void *d)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
@ -548,7 +548,7 @@ static int exptmod(void *a, void *b, void *c, void *d)
return CRYPT_OK;
}
static int isprime(void *a, int b, int *c)
static int isprime(const void *a, int b, int *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(c != NULL);

View File

@ -75,21 +75,21 @@ static void deinit(void *a)
XFREE(a);
}
static int neg(void *a, void *b)
static int neg(const void *a, void *b)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
return mpi_to_ltc_error(mp_neg(a, b));
}
static int copy(void *a, void *b)
static int copy(const void *a, void *b)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
return mpi_to_ltc_error(mp_copy(a, b));
}
static int init_copy(void **a, void *b)
static int init_copy(void **a, const void *b)
{
int err;
LTC_ARGCHK(a != NULL);
@ -110,7 +110,7 @@ static int set_int(void *a, ltc_mp_digit b)
#endif
}
static unsigned long get_int(void *a)
static unsigned long get_int(const void *a)
{
LTC_ARGCHK(a != NULL);
#ifdef BN_MP_GET_INT_C
@ -120,23 +120,23 @@ static unsigned long get_int(void *a)
#endif
}
static ltc_mp_digit get_digit(void *a, int n)
static ltc_mp_digit get_digit(const void *a, int n)
{
mp_int *A;
const mp_int *A;
LTC_ARGCHK(a != NULL);
A = a;
return (n >= A->used || n < 0) ? 0 : A->dp[n];
}
static int get_digit_count(void *a)
static int get_digit_count(const void *a)
{
mp_int *A;
const mp_int *A;
LTC_ARGCHK(a != NULL);
A = a;
return A->used;
}
static int compare(void *a, void *b)
static int compare(const void *a, const void *b)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
@ -148,7 +148,7 @@ static int compare(void *a, void *b)
}
}
static int compare_d(void *a, ltc_mp_digit b)
static int compare_d(const void *a, ltc_mp_digit b)
{
LTC_ARGCHK(a != NULL);
switch (mp_cmp_d(a, b)) {
@ -159,13 +159,13 @@ static int compare_d(void *a, ltc_mp_digit b)
}
}
static int count_bits(void *a)
static int count_bits(const void *a)
{
LTC_ARGCHK(a != NULL);
return mp_count_bits(a);
}
static int count_lsb_bits(void *a)
static int count_lsb_bits(const void *a)
{
LTC_ARGCHK(a != NULL);
return mp_cnt_lsb(a);
@ -189,7 +189,7 @@ static int read_radix(void *a, const char *b, int radix)
}
/* write one */
static int write_radix(void *a, char *b, int radix)
static int write_radix(const void *a, char *b, int radix)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
@ -201,7 +201,7 @@ static int write_radix(void *a, char *b, int radix)
}
/* get size as unsigned char string */
static unsigned long unsigned_size(void *a)
static unsigned long unsigned_size(const void *a)
{
LTC_ARGCHK(a != NULL);
#ifdef BN_MP_UNSIGNED_BIN_SIZE_C
@ -212,7 +212,7 @@ static unsigned long unsigned_size(void *a)
}
/* store */
static int unsigned_write(void *a, unsigned char *b)
static int unsigned_write(const void *a, unsigned char *b)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
@ -224,7 +224,7 @@ static int unsigned_write(void *a, unsigned char *b)
}
/* read */
static int unsigned_read(void *a, unsigned char *b, unsigned long len)
static int unsigned_read(void *a, const unsigned char *b, unsigned long len)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
@ -236,7 +236,7 @@ static int unsigned_read(void *a, unsigned char *b, unsigned long len)
}
/* add */
static int add(void *a, void *b, void *c)
static int add(const void *a, const void *b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
@ -244,7 +244,7 @@ static int add(void *a, void *b, void *c)
return mpi_to_ltc_error(mp_add(a, b, c));
}
static int addi(void *a, ltc_mp_digit b, void *c)
static int addi(const void *a, ltc_mp_digit b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(c != NULL);
@ -252,7 +252,7 @@ static int addi(void *a, ltc_mp_digit b, void *c)
}
/* sub */
static int sub(void *a, void *b, void *c)
static int sub(const void *a, const void *b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
@ -260,7 +260,7 @@ static int sub(void *a, void *b, void *c)
return mpi_to_ltc_error(mp_sub(a, b, c));
}
static int subi(void *a, ltc_mp_digit b, void *c)
static int subi(const void *a, ltc_mp_digit b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(c != NULL);
@ -268,7 +268,7 @@ static int subi(void *a, ltc_mp_digit b, void *c)
}
/* mul */
static int mul(void *a, void *b, void *c)
static int mul(const void *a, const void *b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
@ -276,7 +276,7 @@ static int mul(void *a, void *b, void *c)
return mpi_to_ltc_error(mp_mul(a, b, c));
}
static int muli(void *a, ltc_mp_digit b, void *c)
static int muli(const void *a, ltc_mp_digit b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(c != NULL);
@ -284,7 +284,7 @@ static int muli(void *a, ltc_mp_digit b, void *c)
}
/* sqr */
static int sqr(void *a, void *b)
static int sqr(const void *a, void *b)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
@ -292,7 +292,7 @@ static int sqr(void *a, void *b)
}
/* sqrtmod_prime */
static int sqrtmod_prime(void *a, void *b, void *c)
static int sqrtmod_prime(const void *a, const void *b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
@ -301,14 +301,14 @@ static int sqrtmod_prime(void *a, void *b, void *c)
}
/* div */
static int divide(void *a, void *b, void *c, void *d)
static int divide(const void *a, const void *b, void *c, void *d)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
return mpi_to_ltc_error(mp_div(a, b, c, d));
}
static int div_2(void *a, void *b)
static int div_2(const void *a, void *b)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
@ -316,7 +316,7 @@ static int div_2(void *a, void *b)
}
/* modi */
static int modi(void *a, ltc_mp_digit b, ltc_mp_digit *c)
static int modi(const void *a, ltc_mp_digit b, ltc_mp_digit *c)
{
mp_digit tmp;
int err;
@ -332,7 +332,7 @@ static int modi(void *a, ltc_mp_digit b, ltc_mp_digit *c)
}
/* gcd */
static int gcd(void *a, void *b, void *c)
static int gcd(const void *a, const void *b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
@ -341,7 +341,7 @@ static int gcd(void *a, void *b, void *c)
}
/* lcm */
static int lcm(void *a, void *b, void *c)
static int lcm(const void *a, const void *b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
@ -349,7 +349,7 @@ static int lcm(void *a, void *b, void *c)
return mpi_to_ltc_error(mp_lcm(a, b, c));
}
static int addmod(void *a, void *b, void *c, void *d)
static int addmod(const void *a, const void *b, const void *c, void *d)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
@ -358,7 +358,7 @@ static int addmod(void *a, void *b, void *c, void *d)
return mpi_to_ltc_error(mp_addmod(a,b,c,d));
}
static int submod(void *a, void *b, void *c, void *d)
static int submod(const void *a, const void *b, const void *c, void *d)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
@ -367,7 +367,7 @@ static int submod(void *a, void *b, void *c, void *d)
return mpi_to_ltc_error(mp_submod(a,b,c,d));
}
static int mulmod(void *a, void *b, void *c, void *d)
static int mulmod(const void *a, const void *b, const void *c, void *d)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
@ -376,7 +376,7 @@ static int mulmod(void *a, void *b, void *c, void *d)
return mpi_to_ltc_error(mp_mulmod(a,b,c,d));
}
static int sqrmod(void *a, void *b, void *c)
static int sqrmod(const void *a, const void *b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
@ -385,7 +385,7 @@ static int sqrmod(void *a, void *b, void *c)
}
/* invmod */
static int invmod(void *a, void *b, void *c)
static int invmod(const void *a, const void *b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
@ -394,7 +394,7 @@ static int invmod(void *a, void *b, void *c)
}
/* setup */
static int montgomery_setup(void *a, void **b)
static int montgomery_setup(const void *a, void **b)
{
int err;
LTC_ARGCHK(a != NULL);
@ -403,14 +403,14 @@ static int montgomery_setup(void *a, void **b)
if (*b == NULL) {
return CRYPT_MEM;
}
if ((err = mpi_to_ltc_error(mp_montgomery_setup(a, (mp_digit *)*b))) != CRYPT_OK) {
if ((err = mpi_to_ltc_error(mp_montgomery_setup(a, *b))) != CRYPT_OK) {
XFREE(*b);
}
return err;
}
/* get normalization value */
static int montgomery_normalization(void *a, void *b)
static int montgomery_normalization(void *a, const void *b)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
@ -418,7 +418,7 @@ static int montgomery_normalization(void *a, void *b)
}
/* reduce */
static int montgomery_reduce(void *a, void *b, void *c)
static int montgomery_reduce(void *a, const void *b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
@ -432,7 +432,7 @@ static void montgomery_deinit(void *a)
XFREE(a);
}
static int exptmod(void *a, void *b, void *c, void *d)
static int exptmod(const void *a, const void *b, const void *c, void *d)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
@ -441,7 +441,7 @@ static int exptmod(void *a, void *b, void *c, void *d)
return mpi_to_ltc_error(mp_exptmod(a,b,c,d));
}
static int isprime(void *a, int b, int *c)
static int isprime(const void *a, int b, int *c)
{
int err;
#if defined(PRIVATE_MP_WARRAY) || defined(BN_MP_PRIME_IS_PRIME_C)

View File

@ -3,8 +3,6 @@
#include "tomcrypt_private.h"
#ifdef LTC_MPI
#include <stdarg.h>
int ltc_init_multi(void **a, ...)
{
void **cur = a;

View File

@ -8,6 +8,20 @@
#include <tfm.h>
#if !defined(TFM_VERSION_3)
# if 0 /* Enable if desirable */
# warning "pre-constification TFM used (TFM_VERSION_3 undefined)"
# endif
# define TFM_UNCONST(type) (type)
#elif TFM_VERSION <= TFM_VERSION_3(0, 13, 89)
# if 0 /* Enable if desirable */
# warning "pre-constification TFM used (older version detected)"
# endif
# define TFM_UNCONST(type) (type)
#else
# define TFM_UNCONST(type)
#endif
static const struct {
int tfm_code, ltc_code;
} tfm_to_ltc_codes[] = {
@ -51,15 +65,18 @@ static void deinit(void *a)
XFREE(a);
}
static int neg(void *a, void *b)
static int neg(const void *a, void *b)
{
/* fp_neg() is a macro that accesses the internals of the b */
fp_int *tmpb = b;
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
fp_neg(((fp_int*)a), ((fp_int*)b));
fp_neg(a, tmpb);
return CRYPT_OK;
}
static int copy(void *a, void *b)
static int copy(const void *a, void *b)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
@ -67,7 +84,7 @@ static int copy(void *a, void *b)
return CRYPT_OK;
}
static int init_copy(void **a, void *b)
static int init_copy(void **a, const void *b)
{
if (init(a) != CRYPT_OK) {
return CRYPT_MEM;
@ -83,36 +100,36 @@ static int set_int(void *a, ltc_mp_digit b)
return CRYPT_OK;
}
static unsigned long get_int(void *a)
static unsigned long get_int(const void *a)
{
fp_int *A;
const fp_int *A;
LTC_ARGCHK(a != NULL);
A = a;
return A->used > 0 ? A->dp[0] : 0;
}
static ltc_mp_digit get_digit(void *a, int n)
static ltc_mp_digit get_digit(const void *a, int n)
{
fp_int *A;
const fp_int *A;
LTC_ARGCHK(a != NULL);
A = a;
return (n >= A->used || n < 0) ? 0 : A->dp[n];
}
static int get_digit_count(void *a)
static int get_digit_count(const void *a)
{
fp_int *A;
const fp_int *A;
LTC_ARGCHK(a != NULL);
A = a;
return A->used;
}
static int compare(void *a, void *b)
static int compare(const void *a, const void *b)
{
int ret;
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
ret = fp_cmp(a, b);
ret = fp_cmp(TFM_UNCONST(void *)a, TFM_UNCONST(void *)b);
switch (ret) {
case FP_LT: return LTC_MP_LT;
case FP_EQ: return LTC_MP_EQ;
@ -121,11 +138,11 @@ static int compare(void *a, void *b)
return 0;
}
static int compare_d(void *a, ltc_mp_digit b)
static int compare_d(const void *a, ltc_mp_digit b)
{
int ret;
LTC_ARGCHK(a != NULL);
ret = fp_cmp_d(a, b);
ret = fp_cmp_d(TFM_UNCONST(void *)a, b);
switch (ret) {
case FP_LT: return LTC_MP_LT;
case FP_EQ: return LTC_MP_EQ;
@ -134,16 +151,16 @@ static int compare_d(void *a, ltc_mp_digit b)
return 0;
}
static int count_bits(void *a)
static int count_bits(const void *a)
{
LTC_ARGCHK(a != NULL);
return fp_count_bits(a);
return fp_count_bits(TFM_UNCONST(void *)a);
}
static int count_lsb_bits(void *a)
static int count_lsb_bits(const void *a)
{
LTC_ARGCHK(a != NULL);
return fp_cnt_lsb(a);
return fp_cnt_lsb(TFM_UNCONST(void *)a);
}
static int twoexpt(void *a, int n)
@ -160,35 +177,35 @@ static int read_radix(void *a, const char *b, int radix)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
return tfm_to_ltc_error(fp_read_radix(a, (char *)b, radix));
return tfm_to_ltc_error(fp_read_radix(a, b, radix));
}
/* write one */
static int write_radix(void *a, char *b, int radix)
static int write_radix(const void *a, char *b, int radix)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
return tfm_to_ltc_error(fp_toradix(a, b, radix));
return tfm_to_ltc_error(fp_toradix(TFM_UNCONST(void *)a, b, radix));
}
/* get size as unsigned char string */
static unsigned long unsigned_size(void *a)
static unsigned long unsigned_size(const void *a)
{
LTC_ARGCHK(a != NULL);
return fp_unsigned_bin_size(a);
return fp_unsigned_bin_size(TFM_UNCONST(void *)a);
}
/* store */
static int unsigned_write(void *a, unsigned char *b)
static int unsigned_write(const void *a, unsigned char *b)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
fp_to_unsigned_bin(a, b);
fp_to_unsigned_bin(TFM_UNCONST(void *)a, b);
return CRYPT_OK;
}
/* read */
static int unsigned_read(void *a, unsigned char *b, unsigned long len)
static int unsigned_read(void *a, const unsigned char *b, unsigned long len)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
@ -197,88 +214,88 @@ static int unsigned_read(void *a, unsigned char *b, unsigned long len)
}
/* add */
static int add(void *a, void *b, void *c)
static int add(const void *a, const void *b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
LTC_ARGCHK(c != NULL);
fp_add(a, b, c);
fp_add(TFM_UNCONST(void *)a, TFM_UNCONST(void *)b, c);
return CRYPT_OK;
}
static int addi(void *a, ltc_mp_digit b, void *c)
static int addi(const void *a, ltc_mp_digit b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(c != NULL);
fp_add_d(a, b, c);
fp_add_d(TFM_UNCONST(void *)a, b, c);
return CRYPT_OK;
}
/* sub */
static int sub(void *a, void *b, void *c)
static int sub(const void *a, const void *b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
LTC_ARGCHK(c != NULL);
fp_sub(a, b, c);
fp_sub(TFM_UNCONST(void *)a, TFM_UNCONST(void *)b, c);
return CRYPT_OK;
}
static int subi(void *a, ltc_mp_digit b, void *c)
static int subi(const void *a, ltc_mp_digit b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(c != NULL);
fp_sub_d(a, b, c);
fp_sub_d(TFM_UNCONST(void *)a, b, c);
return CRYPT_OK;
}
/* mul */
static int mul(void *a, void *b, void *c)
static int mul(const void *a, const void *b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
LTC_ARGCHK(c != NULL);
fp_mul(a, b, c);
fp_mul(TFM_UNCONST(void *)a, TFM_UNCONST(void *)b, c);
return CRYPT_OK;
}
static int muli(void *a, ltc_mp_digit b, void *c)
static int muli(const void *a, ltc_mp_digit b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(c != NULL);
fp_mul_d(a, b, c);
fp_mul_d(TFM_UNCONST(void *)a, b, c);
return CRYPT_OK;
}
/* sqr */
static int sqr(void *a, void *b)
static int sqr(const void *a, void *b)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
fp_sqr(a, b);
fp_sqr(TFM_UNCONST(void *)a, b);
return CRYPT_OK;
}
/* sqrtmod_prime - NOT SUPPORTED */
/* div */
static int divide(void *a, void *b, void *c, void *d)
static int divide(const void *a, const void *b, void *c, void *d)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
return tfm_to_ltc_error(fp_div(a, b, c, d));
return tfm_to_ltc_error(fp_div(TFM_UNCONST(void *)a, TFM_UNCONST(void *)b, c, d));
}
static int div_2(void *a, void *b)
static int div_2(const void *a, void *b)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
fp_div_2(a, b);
fp_div_2(TFM_UNCONST(void *)a, b);
return CRYPT_OK;
}
/* modi */
static int modi(void *a, ltc_mp_digit b, ltc_mp_digit *c)
static int modi(const void *a, ltc_mp_digit b, ltc_mp_digit *c)
{
fp_digit tmp;
int err;
@ -286,7 +303,7 @@ static int modi(void *a, ltc_mp_digit b, ltc_mp_digit *c)
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(c != NULL);
if ((err = tfm_to_ltc_error(fp_mod_d(a, b, &tmp))) != CRYPT_OK) {
if ((err = tfm_to_ltc_error(fp_mod_d(TFM_UNCONST(void *)a, b, &tmp))) != CRYPT_OK) {
return err;
}
*c = tmp;
@ -294,71 +311,71 @@ static int modi(void *a, ltc_mp_digit b, ltc_mp_digit *c)
}
/* gcd */
static int gcd(void *a, void *b, void *c)
static int gcd(const void *a, const void *b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
LTC_ARGCHK(c != NULL);
fp_gcd(a, b, c);
fp_gcd(TFM_UNCONST(void *)a, TFM_UNCONST(void *)b, c);
return CRYPT_OK;
}
/* lcm */
static int lcm(void *a, void *b, void *c)
static int lcm(const void *a, const void *b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
LTC_ARGCHK(c != NULL);
fp_lcm(a, b, c);
fp_lcm(TFM_UNCONST(void *)a, TFM_UNCONST(void *)b, c);
return CRYPT_OK;
}
static int addmod(void *a, void *b, void *c, void *d)
static int addmod(const void *a, const void *b, const void *c, void *d)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
LTC_ARGCHK(c != NULL);
LTC_ARGCHK(d != NULL);
return tfm_to_ltc_error(fp_addmod(a,b,c,d));
return tfm_to_ltc_error(fp_addmod(TFM_UNCONST(void *)a,TFM_UNCONST(void *)b,TFM_UNCONST(void *)c,d));
}
static int submod(void *a, void *b, void *c, void *d)
static int submod(const void *a, const void *b, const void *c, void *d)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
LTC_ARGCHK(c != NULL);
LTC_ARGCHK(d != NULL);
return tfm_to_ltc_error(fp_submod(a,b,c,d));
return tfm_to_ltc_error(fp_submod(TFM_UNCONST(void *)a,TFM_UNCONST(void *)b,TFM_UNCONST(void *)c,d));
}
static int mulmod(void *a, void *b, void *c, void *d)
static int mulmod(const void *a, const void *b, const void *c, void *d)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
LTC_ARGCHK(c != NULL);
LTC_ARGCHK(d != NULL);
return tfm_to_ltc_error(fp_mulmod(a,b,c,d));
return tfm_to_ltc_error(fp_mulmod(TFM_UNCONST(void *)a,TFM_UNCONST(void *)b,TFM_UNCONST(void *)c,d));
}
static int sqrmod(void *a, void *b, void *c)
static int sqrmod(const void *a, const void *b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
LTC_ARGCHK(c != NULL);
return tfm_to_ltc_error(fp_sqrmod(a,b,c));
return tfm_to_ltc_error(fp_sqrmod(TFM_UNCONST(void *)a,TFM_UNCONST(void *)b,c));
}
/* invmod */
static int invmod(void *a, void *b, void *c)
static int invmod(const void *a, const void *b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
LTC_ARGCHK(c != NULL);
return tfm_to_ltc_error(fp_invmod(a, b, c));
return tfm_to_ltc_error(fp_invmod(TFM_UNCONST(void *)a, TFM_UNCONST(void *)b, c));
}
/* setup */
static int montgomery_setup(void *a, void **b)
static int montgomery_setup(const void *a, void **b)
{
int err;
LTC_ARGCHK(a != NULL);
@ -367,28 +384,29 @@ static int montgomery_setup(void *a, void **b)
if (*b == NULL) {
return CRYPT_MEM;
}
if ((err = tfm_to_ltc_error(fp_montgomery_setup(a, (fp_digit *)*b))) != CRYPT_OK) {
if ((err = tfm_to_ltc_error(fp_montgomery_setup(TFM_UNCONST(void *)a, *b))) != CRYPT_OK) {
XFREE(*b);
}
return err;
}
/* get normalization value */
static int montgomery_normalization(void *a, void *b)
static int montgomery_normalization(void *a, const void *b)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
fp_montgomery_calc_normalization(a, b);
fp_montgomery_calc_normalization(a, TFM_UNCONST(void *)b);
return CRYPT_OK;
}
/* reduce */
static int montgomery_reduce(void *a, void *b, void *c)
static int montgomery_reduce(void *a, const void *b, void *c)
{
fp_digit *tmpc = c;
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
LTC_ARGCHK(c != NULL);
fp_montgomery_reduce(a, b, *((fp_digit *)c));
fp_montgomery_reduce(a, TFM_UNCONST(void *)b, *tmpc);
return CRYPT_OK;
}
@ -398,29 +416,29 @@ static void montgomery_deinit(void *a)
XFREE(a);
}
static int exptmod(void *a, void *b, void *c, void *d)
static int exptmod(const void *a, const void *b, const void *c, void *d)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
LTC_ARGCHK(c != NULL);
LTC_ARGCHK(d != NULL);
return tfm_to_ltc_error(fp_exptmod(a,b,c,d));
return tfm_to_ltc_error(fp_exptmod(TFM_UNCONST(void *)a,TFM_UNCONST(void *)b,TFM_UNCONST(void *)c,d));
}
static int isprime(void *a, int b, int *c)
static int isprime(const void *a, int b, int *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(c != NULL);
if (b == 0) {
b = LTC_MILLER_RABIN_REPS;
} /* if */
*c = (fp_isprime_ex(a, b) == FP_YES) ? LTC_MP_YES : LTC_MP_NO;
*c = (fp_isprime_ex(TFM_UNCONST(void *)a, b) == FP_YES) ? LTC_MP_YES : LTC_MP_NO;
return CRYPT_OK;
}
#if defined(LTC_MECC) && defined(LTC_MECC_ACCEL)
static int tfm_ecc_projective_dbl_point(const ecc_point *P, ecc_point *R, void *ma, void *modulus, void *Mp)
static int tfm_ecc_projective_dbl_point(const ecc_point *P, ecc_point *R, const void *ma, const void *modulus, void *Mp)
{
fp_int t1, t2;
fp_digit mp;
@ -453,114 +471,114 @@ static int tfm_ecc_projective_dbl_point(const ecc_point *P, ecc_point *R, void *
/* t1 = Z * Z */
fp_sqr(R->z, &t1);
fp_montgomery_reduce(&t1, modulus, mp);
fp_montgomery_reduce(&t1, TFM_UNCONST(void *)modulus, mp);
/* Z = Y * Z */
fp_mul(R->z, R->y, R->z);
fp_montgomery_reduce(R->z, modulus, mp);
fp_montgomery_reduce(R->z, TFM_UNCONST(void *)modulus, mp);
/* Z = 2Z */
fp_add(R->z, R->z, R->z);
if (fp_cmp(R->z, modulus) != FP_LT) {
fp_sub(R->z, modulus, R->z);
if (fp_cmp(R->z, TFM_UNCONST(void *)modulus) != FP_LT) {
fp_sub(R->z, TFM_UNCONST(void *)modulus, R->z);
}
if (ma == NULL) { /* special case for curves with a == -3 (10% faster than general case) */
/* T2 = X - T1 */
fp_sub(R->x, &t1, &t2);
if (fp_cmp_d(&t2, 0) == LTC_MP_LT) {
fp_add(&t2, modulus, &t2);
fp_add(&t2, TFM_UNCONST(void *)modulus, &t2);
}
/* T1 = X + T1 */
fp_add(&t1, R->x, &t1);
if (fp_cmp(&t1, modulus) != FP_LT) {
fp_sub(&t1, modulus, &t1);
if (fp_cmp(&t1, TFM_UNCONST(void *)modulus) != FP_LT) {
fp_sub(&t1, TFM_UNCONST(void *)modulus, &t1);
}
/* T2 = T1 * T2 */
fp_mul(&t1, &t2, &t2);
fp_montgomery_reduce(&t2, modulus, mp);
fp_montgomery_reduce(&t2, TFM_UNCONST(void *)modulus, mp);
/* T1 = 2T2 */
fp_add(&t2, &t2, &t1);
if (fp_cmp(&t1, modulus) != FP_LT) {
fp_sub(&t1, modulus, &t1);
if (fp_cmp(&t1, TFM_UNCONST(void *)modulus) != FP_LT) {
fp_sub(&t1, TFM_UNCONST(void *)modulus, &t1);
}
/* T1 = T1 + T2 */
fp_add(&t1, &t2, &t1);
if (fp_cmp(&t1, modulus) != FP_LT) {
fp_sub(&t1, modulus, &t1);
if (fp_cmp(&t1, TFM_UNCONST(void *)modulus) != FP_LT) {
fp_sub(&t1, TFM_UNCONST(void *)modulus, &t1);
}
}
else {
/* T2 = T1 * T1 */
fp_sqr(&t1, &t2);
fp_montgomery_reduce(&t2, modulus, mp);
fp_montgomery_reduce(&t2, TFM_UNCONST(void *)modulus, mp);
/* T1 = T2 * a */
fp_mul(&t2, ma, &t1);
fp_montgomery_reduce(&t1, modulus, mp);
fp_mul(&t2, TFM_UNCONST(void *)ma, &t1);
fp_montgomery_reduce(&t1, TFM_UNCONST(void *)modulus, mp);
/* T2 = X * X */
fp_sqr(R->x, &t2);
fp_montgomery_reduce(&t2, modulus, mp);
fp_montgomery_reduce(&t2, TFM_UNCONST(void *)modulus, mp);
/* T1 = T1 + T2 */
fp_add(&t1, &t2, &t1);
if (fp_cmp(&t1, modulus) != FP_LT) {
fp_sub(&t1, modulus, &t1);
if (fp_cmp(&t1, TFM_UNCONST(void *)modulus) != FP_LT) {
fp_sub(&t1, TFM_UNCONST(void *)modulus, &t1);
}
/* T1 = T1 + T2 */
fp_add(&t1, &t2, &t1);
if (fp_cmp(&t1, modulus) != FP_LT) {
fp_sub(&t1, modulus, &t1);
if (fp_cmp(&t1, TFM_UNCONST(void *)modulus) != FP_LT) {
fp_sub(&t1, TFM_UNCONST(void *)modulus, &t1);
}
/* T1 = T1 + T2 */
fp_add(&t1, &t2, &t1);
if (fp_cmp(&t1, modulus) != FP_LT) {
fp_sub(&t1, modulus, &t1);
if (fp_cmp(&t1, TFM_UNCONST(void *)modulus) != FP_LT) {
fp_sub(&t1, TFM_UNCONST(void *)modulus, &t1);
}
}
/* Y = 2Y */
fp_add(R->y, R->y, R->y);
if (fp_cmp(R->y, modulus) != FP_LT) {
fp_sub(R->y, modulus, R->y);
if (fp_cmp(R->y, TFM_UNCONST(void *)modulus) != FP_LT) {
fp_sub(R->y, TFM_UNCONST(void *)modulus, R->y);
}
/* Y = Y * Y */
fp_sqr(R->y, R->y);
fp_montgomery_reduce(R->y, modulus, mp);
fp_montgomery_reduce(R->y, TFM_UNCONST(void *)modulus, mp);
/* T2 = Y * Y */
fp_sqr(R->y, &t2);
fp_montgomery_reduce(&t2, modulus, mp);
fp_montgomery_reduce(&t2, TFM_UNCONST(void *)modulus, mp);
/* T2 = T2/2 */
if (fp_isodd(&t2)) {
fp_add(&t2, modulus, &t2);
fp_add(&t2, TFM_UNCONST(void *)modulus, &t2);
}
fp_div_2(&t2, &t2);
/* Y = Y * X */
fp_mul(R->y, R->x, R->y);
fp_montgomery_reduce(R->y, modulus, mp);
fp_montgomery_reduce(R->y, TFM_UNCONST(void *)modulus, mp);
/* X = T1 * T1 */
fp_sqr(&t1, R->x);
fp_montgomery_reduce(R->x, modulus, mp);
fp_montgomery_reduce(R->x, TFM_UNCONST(void *)modulus, mp);
/* X = X - Y */
fp_sub(R->x, R->y, R->x);
if (fp_cmp_d(R->x, 0) == FP_LT) {
fp_add(R->x, modulus, R->x);
fp_add(R->x, TFM_UNCONST(void *)modulus, R->x);
}
/* X = X - Y */
fp_sub(R->x, R->y, R->x);
if (fp_cmp_d(R->x, 0) == FP_LT) {
fp_add(R->x, modulus, R->x);
fp_add(R->x, TFM_UNCONST(void *)modulus, R->x);
}
/* Y = Y - X */
fp_sub(R->y, R->x, R->y);
if (fp_cmp_d(R->y, 0) == FP_LT) {
fp_add(R->y, modulus, R->y);
fp_add(R->y, TFM_UNCONST(void *)modulus, R->y);
}
/* Y = Y * T1 */
fp_mul(R->y, &t1, R->y);
fp_montgomery_reduce(R->y, modulus, mp);
fp_montgomery_reduce(R->y, TFM_UNCONST(void *)modulus, mp);
/* Y = Y - T2 */
fp_sub(R->y, &t2, R->y);
if (fp_cmp_d(R->y, 0) == FP_LT) {
fp_add(R->y, modulus, R->y);
fp_add(R->y, TFM_UNCONST(void *)modulus, R->y);
}
return CRYPT_OK;
@ -575,7 +593,7 @@ static int tfm_ecc_projective_dbl_point(const ecc_point *P, ecc_point *R, void *
@param Mp The "b" value from montgomery_setup()
@return CRYPT_OK on success
*/
static int tfm_ecc_projective_add_point(const ecc_point *P, const ecc_point *Q, ecc_point *R, void *ma, void *modulus, void *Mp)
static int tfm_ecc_projective_add_point(const ecc_point *P, const ecc_point *Q, ecc_point *R, const void *ma, const void *modulus, void *Mp)
{
fp_int t1, t2, x, y, z;
fp_digit mp;
@ -614,7 +632,7 @@ static int tfm_ecc_projective_add_point(const ecc_point *P, const ecc_point *Q,
}
/* should we dbl instead? */
fp_sub(modulus, Q->y, &t1);
fp_sub(TFM_UNCONST(void *)modulus, Q->y, &t1);
if ( (fp_cmp(P->x, Q->x) == FP_EQ) &&
(Q->z != NULL && fp_cmp(P->z, Q->z) == FP_EQ) &&
(fp_cmp(P->y, Q->y) == FP_EQ || fp_cmp(P->y, &t1) == FP_EQ)) {
@ -629,116 +647,116 @@ static int tfm_ecc_projective_add_point(const ecc_point *P, const ecc_point *Q,
if (Q->z != NULL) {
/* T1 = Z' * Z' */
fp_sqr(Q->z, &t1);
fp_montgomery_reduce(&t1, modulus, mp);
fp_montgomery_reduce(&t1, TFM_UNCONST(void *)modulus, mp);
/* X = X * T1 */
fp_mul(&t1, &x, &x);
fp_montgomery_reduce(&x, modulus, mp);
fp_montgomery_reduce(&x, TFM_UNCONST(void *)modulus, mp);
/* T1 = Z' * T1 */
fp_mul(Q->z, &t1, &t1);
fp_montgomery_reduce(&t1, modulus, mp);
fp_montgomery_reduce(&t1, TFM_UNCONST(void *)modulus, mp);
/* Y = Y * T1 */
fp_mul(&t1, &y, &y);
fp_montgomery_reduce(&y, modulus, mp);
fp_montgomery_reduce(&y, TFM_UNCONST(void *)modulus, mp);
}
/* T1 = Z*Z */
fp_sqr(&z, &t1);
fp_montgomery_reduce(&t1, modulus, mp);
fp_montgomery_reduce(&t1, TFM_UNCONST(void *)modulus, mp);
/* T2 = X' * T1 */
fp_mul(Q->x, &t1, &t2);
fp_montgomery_reduce(&t2, modulus, mp);
fp_montgomery_reduce(&t2, TFM_UNCONST(void *)modulus, mp);
/* T1 = Z * T1 */
fp_mul(&z, &t1, &t1);
fp_montgomery_reduce(&t1, modulus, mp);
fp_montgomery_reduce(&t1, TFM_UNCONST(void *)modulus, mp);
/* T1 = Y' * T1 */
fp_mul(Q->y, &t1, &t1);
fp_montgomery_reduce(&t1, modulus, mp);
fp_montgomery_reduce(&t1, TFM_UNCONST(void *)modulus, mp);
/* Y = Y - T1 */
fp_sub(&y, &t1, &y);
if (fp_cmp_d(&y, 0) == FP_LT) {
fp_add(&y, modulus, &y);
fp_add(&y, TFM_UNCONST(void *)modulus, &y);
}
/* T1 = 2T1 */
fp_add(&t1, &t1, &t1);
if (fp_cmp(&t1, modulus) != FP_LT) {
fp_sub(&t1, modulus, &t1);
if (fp_cmp(&t1, TFM_UNCONST(void *)modulus) != FP_LT) {
fp_sub(&t1, TFM_UNCONST(void *)modulus, &t1);
}
/* T1 = Y + T1 */
fp_add(&t1, &y, &t1);
if (fp_cmp(&t1, modulus) != FP_LT) {
fp_sub(&t1, modulus, &t1);
if (fp_cmp(&t1, TFM_UNCONST(void *)modulus) != FP_LT) {
fp_sub(&t1, TFM_UNCONST(void *)modulus, &t1);
}
/* X = X - T2 */
fp_sub(&x, &t2, &x);
if (fp_cmp_d(&x, 0) == FP_LT) {
fp_add(&x, modulus, &x);
fp_add(&x, TFM_UNCONST(void *)modulus, &x);
}
/* T2 = 2T2 */
fp_add(&t2, &t2, &t2);
if (fp_cmp(&t2, modulus) != FP_LT) {
fp_sub(&t2, modulus, &t2);
if (fp_cmp(&t2, TFM_UNCONST(void *)modulus) != FP_LT) {
fp_sub(&t2, TFM_UNCONST(void *)modulus, &t2);
}
/* T2 = X + T2 */
fp_add(&t2, &x, &t2);
if (fp_cmp(&t2, modulus) != FP_LT) {
fp_sub(&t2, modulus, &t2);
if (fp_cmp(&t2, TFM_UNCONST(void *)modulus) != FP_LT) {
fp_sub(&t2, TFM_UNCONST(void *)modulus, &t2);
}
/* if Z' != 1 */
if (Q->z != NULL) {
/* Z = Z * Z' */
fp_mul(&z, Q->z, &z);
fp_montgomery_reduce(&z, modulus, mp);
fp_montgomery_reduce(&z, TFM_UNCONST(void *)modulus, mp);
}
/* Z = Z * X */
fp_mul(&z, &x, &z);
fp_montgomery_reduce(&z, modulus, mp);
fp_montgomery_reduce(&z, TFM_UNCONST(void *)modulus, mp);
/* T1 = T1 * X */
fp_mul(&t1, &x, &t1);
fp_montgomery_reduce(&t1, modulus, mp);
fp_montgomery_reduce(&t1, TFM_UNCONST(void *)modulus, mp);
/* X = X * X */
fp_sqr(&x, &x);
fp_montgomery_reduce(&x, modulus, mp);
fp_montgomery_reduce(&x, TFM_UNCONST(void *)modulus, mp);
/* T2 = T2 * x */
fp_mul(&t2, &x, &t2);
fp_montgomery_reduce(&t2, modulus, mp);
fp_montgomery_reduce(&t2, TFM_UNCONST(void *)modulus, mp);
/* T1 = T1 * X */
fp_mul(&t1, &x, &t1);
fp_montgomery_reduce(&t1, modulus, mp);
fp_montgomery_reduce(&t1, TFM_UNCONST(void *)modulus, mp);
/* X = Y*Y */
fp_sqr(&y, &x);
fp_montgomery_reduce(&x, modulus, mp);
fp_montgomery_reduce(&x, TFM_UNCONST(void *)modulus, mp);
/* X = X - T2 */
fp_sub(&x, &t2, &x);
if (fp_cmp_d(&x, 0) == FP_LT) {
fp_add(&x, modulus, &x);
fp_add(&x, TFM_UNCONST(void *)modulus, &x);
}
/* T2 = T2 - X */
fp_sub(&t2, &x, &t2);
if (fp_cmp_d(&t2, 0) == FP_LT) {
fp_add(&t2, modulus, &t2);
fp_add(&t2, TFM_UNCONST(void *)modulus, &t2);
}
/* T2 = T2 - X */
fp_sub(&t2, &x, &t2);
if (fp_cmp_d(&t2, 0) == FP_LT) {
fp_add(&t2, modulus, &t2);
fp_add(&t2, TFM_UNCONST(void *)modulus, &t2);
}
/* T2 = T2 * Y */
fp_mul(&t2, &y, &t2);
fp_montgomery_reduce(&t2, modulus, mp);
fp_montgomery_reduce(&t2, TFM_UNCONST(void *)modulus, mp);
/* Y = T2 - T1 */
fp_sub(&t2, &t1, &y);
if (fp_cmp_d(&y, 0) == FP_LT) {
fp_add(&y, modulus, &y);
fp_add(&y, TFM_UNCONST(void *)modulus, &y);
}
/* Y = Y/2 */
if (fp_isodd(&y)) {
fp_add(&y, modulus, &y);
fp_add(&y, TFM_UNCONST(void *)modulus, &y);
}
fp_div_2(&y, &y);

View File

@ -42,8 +42,8 @@ static const unsigned char map_base64[256] = {
255, 255, 255, 255 };
#endif /* LTC_BASE64 */
static const unsigned char map_base64url[] = {
#if defined(LTC_BASE64_URL)
static const unsigned char map_base64url[] = {
255, 255, 255, 255, 255, 255, 255, 255, 255, 253, 253, 255,
255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 253, 255, 255, 255,
@ -66,8 +66,8 @@ static const unsigned char map_base64url[] = {
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255
#endif /* LTC_BASE64_URL */
};
#endif /* LTC_BASE64_URL */
enum {
insane = 0,
@ -127,7 +127,9 @@ static int s_base64_decode_internal(const char *in, unsigned long inlen,
if (y != 0) {
if (y == 1) return CRYPT_INVALID_PACKET;
if (((y + g) != 4) && (mode == strict) && (map != map_base64url)) return CRYPT_INVALID_PACKET;
#if defined(LTC_BASE64)
if (((y + g) != 4) && (mode == strict) && (map == map_base64)) return CRYPT_INVALID_PACKET;
#endif /* LTC_BASE64 */
t = t << (6 * (4 - y));
if (z + y - 1 > *outlen) return CRYPT_BUFFER_OVERFLOW;
if (y >= 2) out[z++] = (unsigned char) ((t >> 16) & 255);

View File

@ -1,558 +0,0 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@file crypt.c
Build strings, Tom St Denis
*/
#define NAME_VALUE(s) #s"="NAME(s)
#define NAME(s) #s
const char *crypt_build_settings =
"LibTomCrypt " SCRYPT " (www.libtom.net)\n"
"LibTomCrypt is public domain software.\n"
#if defined(INCLUDE_BUILD_DATE)
"Built on " __DATE__ " at " __TIME__ "\n"
#endif
"\n\nEndianness: "
#if defined(ENDIAN_NEUTRAL)
"neutral/"
#endif
#if defined(ENDIAN_LITTLE)
"little"
#elif defined(ENDIAN_BIG)
"big"
#endif
#if defined(ENDIAN_32BITWORD)
" (32-bit words)\n"
#elif defined(ENDIAN_64BITWORD)
" (64-bit words)\n"
#else
" (no wordsize defined)\n"
#endif
"Clean stack: "
#if defined(LTC_CLEAN_STACK)
"enabled\n"
#else
"disabled\n"
#endif
"\nCiphers built-in:\n"
#if defined(LTC_BLOWFISH)
" Blowfish\n"
#endif
#if defined(LTC_RC2)
" RC2\n"
#endif
#if defined(LTC_RC5)
" RC5\n"
#endif
#if defined(LTC_RC6)
" RC6\n"
#endif
#if defined(LTC_SAFERP)
" Safer+\n"
#endif
#if defined(LTC_SAFER)
" Safer\n"
#endif
#if defined(LTC_RIJNDAEL)
" Rijndael\n"
#endif
#if defined(LTC_XTEA)
" XTEA\n"
#endif
#if defined(LTC_TWOFISH)
" Twofish "
#if defined(LTC_TWOFISH_SMALL) && defined(LTC_TWOFISH_TABLES) && defined(LTC_TWOFISH_ALL_TABLES)
"(small, tables, all_tables)\n"
#elif defined(LTC_TWOFISH_SMALL) && defined(LTC_TWOFISH_TABLES)
"(small, tables)\n"
#elif defined(LTC_TWOFISH_SMALL) && defined(LTC_TWOFISH_ALL_TABLES)
"(small, all_tables)\n"
#elif defined(LTC_TWOFISH_TABLES) && defined(LTC_TWOFISH_ALL_TABLES)
"(tables, all_tables)\n"
#elif defined(LTC_TWOFISH_SMALL)
"(small)\n"
#elif defined(LTC_TWOFISH_TABLES)
"(tables)\n"
#elif defined(LTC_TWOFISH_ALL_TABLES)
"(all_tables)\n"
#else
"\n"
#endif
#endif
#if defined(LTC_DES)
" DES\n"
#endif
#if defined(LTC_CAST5)
" CAST5\n"
#endif
#if defined(LTC_NOEKEON)
" Noekeon\n"
#endif
#if defined(LTC_SKIPJACK)
" Skipjack\n"
#endif
#if defined(LTC_KHAZAD)
" Khazad\n"
#endif
#if defined(LTC_ANUBIS)
" Anubis "
#endif
#if defined(LTC_ANUBIS_TWEAK)
" (tweaked)"
#endif
"\n"
#if defined(LTC_KSEED)
" KSEED\n"
#endif
#if defined(LTC_KASUMI)
" KASUMI\n"
#endif
#if defined(LTC_MULTI2)
" MULTI2\n"
#endif
#if defined(LTC_CAMELLIA)
" Camellia\n"
#endif
#if defined(LTC_IDEA)
" IDEA\n"
#endif
#if defined(LTC_SERPENT)
" Serpent\n"
#endif
#if defined(LTC_TEA)
" TEA\n"
#endif
"Stream ciphers built-in:\n"
#if defined(LTC_CHACHA)
" ChaCha\n"
#endif
#if defined(LTC_SALSA20)
" Salsa20\n"
#endif
#if defined(LTC_XSALSA20)
" XSalsa20\n"
#endif
#if defined(LTC_SOSEMANUK)
" Sosemanuk\n"
#endif
#if defined(LTC_RABBIT)
" Rabbit\n"
#endif
#if defined(LTC_RC4_STREAM)
" RC4\n"
#endif
#if defined(LTC_SOBER128_STREAM)
" SOBER128\n"
#endif
"\nHashes built-in:\n"
#if defined(LTC_SHA3)
" SHA3\n"
#endif
#if defined(LTC_KECCAK)
" KECCAK\n"
#endif
#if defined(LTC_SHA512)
" SHA-512\n"
#endif
#if defined(LTC_SHA384)
" SHA-384\n"
#endif
#if defined(LTC_SHA512_256)
" SHA-512/256\n"
#endif
#if defined(LTC_SHA256)
" SHA-256\n"
#endif
#if defined(LTC_SHA512_224)
" SHA-512/224\n"
#endif
#if defined(LTC_SHA224)
" SHA-224\n"
#endif
#if defined(LTC_TIGER)
" TIGER\n"
#endif
#if defined(LTC_SHA1)
" SHA1\n"
#endif
#if defined(LTC_MD5)
" MD5\n"
#endif
#if defined(LTC_MD4)
" MD4\n"
#endif
#if defined(LTC_MD2)
" MD2\n"
#endif
#if defined(LTC_RIPEMD128)
" RIPEMD128\n"
#endif
#if defined(LTC_RIPEMD160)
" RIPEMD160\n"
#endif
#if defined(LTC_RIPEMD256)
" RIPEMD256\n"
#endif
#if defined(LTC_RIPEMD320)
" RIPEMD320\n"
#endif
#if defined(LTC_WHIRLPOOL)
" WHIRLPOOL\n"
#endif
#if defined(LTC_BLAKE2S)
" BLAKE2S\n"
#endif
#if defined(LTC_BLAKE2B)
" BLAKE2B\n"
#endif
#if defined(LTC_CHC_HASH)
" CHC_HASH\n"
#endif
"\nBlock Chaining Modes:\n"
#if defined(LTC_CFB_MODE)
" CFB\n"
#endif
#if defined(LTC_OFB_MODE)
" OFB\n"
#endif
#if defined(LTC_ECB_MODE)
" ECB\n"
#endif
#if defined(LTC_CBC_MODE)
" CBC\n"
#endif
#if defined(LTC_CTR_MODE)
" CTR\n"
#endif
#if defined(LTC_LRW_MODE)
" LRW"
#if defined(LTC_LRW_TABLES)
" (tables) "
#endif
"\n"
#endif
#if defined(LTC_F8_MODE)
" F8\n"
#endif
#if defined(LTC_XTS_MODE)
" XTS\n"
#endif
"\nMACs:\n"
#if defined(LTC_HMAC)
" HMAC\n"
#endif
#if defined(LTC_OMAC)
" OMAC\n"
#endif
#if defined(LTC_PMAC)
" PMAC\n"
#endif
#if defined(LTC_PELICAN)
" PELICAN\n"
#endif
#if defined(LTC_XCBC)
" XCBC\n"
#endif
#if defined(LTC_F9_MODE)
" F9\n"
#endif
#if defined(LTC_POLY1305)
" POLY1305\n"
#endif
#if defined(LTC_BLAKE2SMAC)
" BLAKE2S MAC\n"
#endif
#if defined(LTC_BLAKE2BMAC)
" BLAKE2B MAC\n"
#endif
"\nENC + AUTH modes:\n"
#if defined(LTC_EAX_MODE)
" EAX\n"
#endif
#if defined(LTC_OCB_MODE)
" OCB\n"
#endif
#if defined(LTC_OCB3_MODE)
" OCB3\n"
#endif
#if defined(LTC_CCM_MODE)
" CCM\n"
#endif
#if defined(LTC_GCM_MODE)
" GCM"
#if defined(LTC_GCM_TABLES)
" (tables) "
#endif
#if defined(LTC_GCM_TABLES_SSE2)
" (SSE2) "
#endif
"\n"
#endif
#if defined(LTC_CHACHA20POLY1305_MODE)
" CHACHA20POLY1305\n"
#endif
"\nPRNG:\n"
#if defined(LTC_YARROW)
" Yarrow ("NAME_VALUE(LTC_YARROW_AES)")\n"
#endif
#if defined(LTC_SPRNG)
" SPRNG\n"
#endif
#if defined(LTC_RC4)
" RC4\n"
#endif
#if defined(LTC_CHACHA20_PRNG)
" ChaCha20\n"
#endif
#if defined(LTC_FORTUNA)
" Fortuna (" NAME_VALUE(LTC_FORTUNA_POOLS) ", "
#if defined(LTC_FORTUNA_RESEED_RATELIMIT_TIMED)
"LTC_FORTUNA_RESEED_RATELIMIT_TIMED, "
#else
"LTC_FORTUNA_RESEED_RATELIMIT_STATIC, " NAME_VALUE(LTC_FORTUNA_WD)
#endif
")\n"
#endif
#if defined(LTC_SOBER128)
" SOBER128\n"
#endif
#if defined(LTC_WIN32_BCRYPT)
" WIN32_BCRYPT\n"
#endif
"\nPK Crypto:\n"
#if defined(LTC_MRSA)
" RSA"
#if defined(LTC_RSA_BLINDING) && defined(LTC_RSA_CRT_HARDENING)
" (with blinding and CRT hardening)"
#elif defined(LTC_RSA_BLINDING)
" (with blinding)"
#elif defined(LTC_RSA_CRT_HARDENING)
" (with CRT hardening)"
#endif
"\n"
#endif
#if defined(LTC_MDH)
" DH\n"
#endif
#if defined(LTC_MECC)
" ECC"
#if defined(LTC_ECC_TIMING_RESISTANT)
" (with blinding)"
#endif
"\n"
#endif
#if defined(LTC_MDSA)
" DSA\n"
#endif
#if defined(LTC_CURVE25519)
#if defined(LTC_CURVE25519)
" Ed25519\n"
#endif
#if defined(LTC_CURVE25519)
" X25519\n"
#endif
#endif
#if defined(LTC_PK_MAX_RETRIES)
" "NAME_VALUE(LTC_PK_MAX_RETRIES)"\n"
#endif
"\nMPI (Math):\n"
#if defined(LTC_MPI)
" LTC_MPI\n"
#endif
#if defined(LTM_DESC)
" LTM_DESC\n"
#endif
#if defined(TFM_DESC)
" TFM_DESC\n"
#endif
#if defined(GMP_DESC)
" GMP_DESC\n"
#endif
#if defined(LTC_MILLER_RABIN_REPS)
" "NAME_VALUE(LTC_MILLER_RABIN_REPS)"\n"
#endif
"\nCompiler:\n"
#if defined(_WIN64)
" WIN64 platform detected.\n"
#elif defined(_WIN32)
" WIN32 platform detected.\n"
#endif
#if defined(__CYGWIN__)
" CYGWIN Detected.\n"
#endif
#if defined(__DJGPP__)
" DJGPP Detected.\n"
#endif
#if defined(_MSC_VER)
" MSVC compiler detected.\n"
#endif
#if defined(__clang_version__)
" Clang compiler " __clang_version__ ".\n"
#elif defined(INTEL_CC)
" Intel C Compiler " __VERSION__ ".\n"
#elif defined(__GNUC__) /* clang and icc also define __GNUC__ */
" GCC compiler " __VERSION__ ".\n"
#endif
#if defined(__x86_64__)
" x86-64 detected.\n"
#endif
#if defined(LTC_PPC32)
" PPC32 detected.\n"
#endif
"\nVarious others: "
#if defined(ARGTYPE)
" " NAME_VALUE(ARGTYPE) " "
#endif
#if defined(LTC_ADLER32)
" ADLER32 "
#endif
#if defined(LTC_AES_NI) && defined(LTC_AMD64_SSE4_1)
" AES-NI "
#endif
#if defined(LTC_BASE64)
" BASE64 "
#endif
#if defined(LTC_BASE64_URL)
" BASE64-URL-SAFE "
#endif
#if defined(LTC_BASE32)
" BASE32 "
#endif
#if defined(LTC_BASE16)
" BASE16 "
#endif
#if defined(LTC_BCRYPT)
" BCRYPT "
" " NAME_VALUE(LTC_BCRYPT_DEFAULT_ROUNDS) " "
#endif
#if defined(LTC_CRC32)
" CRC32 "
#endif
#if defined(LTC_DER)
" DER "
" " NAME_VALUE(LTC_DER_MAX_RECURSION) " "
#endif
#if defined(LTC_PKCS_1)
" PKCS#1 "
#endif
#if defined(LTC_PKCS_5)
" PKCS#5 "
#endif
#if defined(LTC_PKCS_8)
" PKCS#8 "
#endif
#if defined(LTC_PKCS_12)
" PKCS#12 "
#endif
#if defined(LTC_PADDING)
" PADDING "
#endif
#if defined(LTC_HKDF)
" HKDF "
#endif
#if defined(LTC_PBES)
" PBES1 "
" PBES2 "
#endif
#if defined(LTC_SSH)
" SSH "
#endif
#if defined(LTC_DEVRANDOM)
" LTC_DEVRANDOM "
#endif
#if defined(LTC_TRY_URANDOM_FIRST)
" LTC_TRY_URANDOM_FIRST "
#endif
#if defined(LTC_RNG_GET_BYTES)
" LTC_RNG_GET_BYTES "
#endif
#if defined(LTC_RNG_MAKE_PRNG)
" LTC_RNG_MAKE_PRNG "
#endif
#if defined(LTC_PRNG_ENABLE_LTC_RNG)
" LTC_PRNG_ENABLE_LTC_RNG "
#endif
#if defined(LTC_HASH_HELPERS)
" LTC_HASH_HELPERS "
#endif
#if defined(LTC_VALGRIND)
" LTC_VALGRIND "
#endif
#if defined(LTC_TEST)
" LTC_TEST "
#endif
#if defined(LTC_TEST_DBG)
" " NAME_VALUE(LTC_TEST_DBG) " "
#endif
#if defined(LTC_TEST_EXT)
" LTC_TEST_EXT "
#endif
#if defined(LTC_SMALL_CODE)
" LTC_SMALL_CODE "
#endif
#if defined(LTC_NO_FILE)
" LTC_NO_FILE "
#endif
#if defined(LTC_FILE_READ_BUFSIZE)
" " NAME_VALUE(LTC_FILE_READ_BUFSIZE) " "
#endif
#if defined(LTC_FAST)
" LTC_FAST "
#endif
#if defined(LTC_NO_FAST)
" LTC_NO_FAST "
#endif
#if defined(LTC_NO_BSWAP)
" LTC_NO_BSWAP "
#endif
#if defined(LTC_NO_ASM)
" LTC_NO_ASM "
#endif
#if defined(LTC_ROx_BUILTIN)
" LTC_ROx_BUILTIN "
#elif defined(LTC_ROx_ASM)
" LTC_ROx_ASM "
#if defined(LTC_NO_ROLC)
" LTC_NO_ROLC "
#endif
#endif
#if defined(LTC_NO_TEST)
" LTC_NO_TEST "
#endif
#if defined(LTC_NO_TABLES)
" LTC_NO_TABLES "
#endif
#if defined(LTC_PTHREAD)
" LTC_PTHREAD "
#endif
#if defined(LTC_EASY)
" LTC_EASY "
#endif
#if defined(LTC_MECC_ACCEL)
" LTC_MECC_ACCEL "
#endif
#if defined(LTC_MECC_FP)
" LTC_MECC_FP "
#endif
#if defined(LTC_ECC_SHAMIR)
" LTC_ECC_SHAMIR "
#endif
#if defined(LTC_CLOCK_GETTIME)
" LTC_CLOCK_GETTIME "
#endif
"\n"
;

View File

@ -1,17 +0,0 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.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

View File

@ -1,15 +0,0 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.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)

View File

@ -1,24 +0,0 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.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;
}

View File

@ -1,290 +0,0 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@file crypt_constants.c
Make various constants available to dynamic languages
like Python - Larry Bugbee, February 2013
LB - Dec 2013 - revised to include compiler define options
LB - Mar 2014 - added endianness and word size
*/
typedef struct {
const char *name;
const int value;
} crypt_constant;
#define C_STRINGIFY(s) { #s, s }
static const crypt_constant s_crypt_constants[] = {
C_STRINGIFY(CRYPT_OK),
C_STRINGIFY(CRYPT_ERROR),
C_STRINGIFY(CRYPT_NOP),
C_STRINGIFY(CRYPT_INVALID_KEYSIZE),
C_STRINGIFY(CRYPT_INVALID_ROUNDS),
C_STRINGIFY(CRYPT_FAIL_TESTVECTOR),
C_STRINGIFY(CRYPT_BUFFER_OVERFLOW),
C_STRINGIFY(CRYPT_INVALID_PACKET),
C_STRINGIFY(CRYPT_INVALID_PRNGSIZE),
C_STRINGIFY(CRYPT_ERROR_READPRNG),
C_STRINGIFY(CRYPT_INVALID_CIPHER),
C_STRINGIFY(CRYPT_INVALID_HASH),
C_STRINGIFY(CRYPT_INVALID_PRNG),
C_STRINGIFY(CRYPT_MEM),
C_STRINGIFY(CRYPT_PK_TYPE_MISMATCH),
C_STRINGIFY(CRYPT_PK_NOT_PRIVATE),
C_STRINGIFY(CRYPT_INVALID_ARG),
C_STRINGIFY(CRYPT_FILE_NOTFOUND),
C_STRINGIFY(CRYPT_PK_INVALID_TYPE),
C_STRINGIFY(CRYPT_OVERFLOW),
C_STRINGIFY(CRYPT_PK_ASN1_ERROR),
C_STRINGIFY(CRYPT_INPUT_TOO_LONG),
C_STRINGIFY(CRYPT_PK_INVALID_SIZE),
C_STRINGIFY(CRYPT_INVALID_PRIME_SIZE),
C_STRINGIFY(CRYPT_PK_INVALID_PADDING),
C_STRINGIFY(CRYPT_HASH_OVERFLOW),
C_STRINGIFY(PK_PUBLIC),
C_STRINGIFY(PK_PRIVATE),
C_STRINGIFY(LTC_ENCRYPT),
C_STRINGIFY(LTC_DECRYPT),
#ifdef LTC_PKCS_1
{"LTC_PKCS_1", 1},
/* Block types */
C_STRINGIFY(LTC_PKCS_1_EMSA),
C_STRINGIFY(LTC_PKCS_1_EME),
/* Padding types */
C_STRINGIFY(LTC_PKCS_1_V1_5),
C_STRINGIFY(LTC_PKCS_1_OAEP),
C_STRINGIFY(LTC_PKCS_1_PSS),
C_STRINGIFY(LTC_PKCS_1_V1_5_NA1),
#else
{"LTC_PKCS_1", 0},
#endif
#ifdef LTC_PADDING
{"LTC_PADDING", 1},
C_STRINGIFY(LTC_PAD_PKCS7),
#ifdef LTC_RNG_GET_BYTES
C_STRINGIFY(LTC_PAD_ISO_10126),
#endif
C_STRINGIFY(LTC_PAD_ANSI_X923),
C_STRINGIFY(LTC_PAD_ONE_AND_ZERO),
C_STRINGIFY(LTC_PAD_ZERO),
C_STRINGIFY(LTC_PAD_ZERO_ALWAYS),
#else
{"LTC_PADDING", 0},
#endif
#ifdef LTC_MRSA
{"LTC_MRSA", 1},
#else
{"LTC_MRSA", 0},
#endif
#ifdef LTC_MECC
{"LTC_MECC", 1},
C_STRINGIFY(ECC_BUF_SIZE),
C_STRINGIFY(ECC_MAXSIZE),
#else
{"LTC_MECC", 0},
#endif
#ifdef LTC_MDSA
{"LTC_MDSA", 1},
C_STRINGIFY(LTC_MDSA_DELTA),
C_STRINGIFY(LTC_MDSA_MAX_GROUP),
C_STRINGIFY(LTC_MDSA_MAX_MODULUS),
#else
{"LTC_MDSA", 0},
#endif
#ifdef LTC_MILLER_RABIN_REPS
C_STRINGIFY(LTC_MILLER_RABIN_REPS),
#endif
#ifdef LTC_DER
/* DER handling */
{"LTC_DER", 1},
C_STRINGIFY(LTC_ASN1_EOL),
C_STRINGIFY(LTC_ASN1_BOOLEAN),
C_STRINGIFY(LTC_ASN1_INTEGER),
C_STRINGIFY(LTC_ASN1_SHORT_INTEGER),
C_STRINGIFY(LTC_ASN1_BIT_STRING),
C_STRINGIFY(LTC_ASN1_OCTET_STRING),
C_STRINGIFY(LTC_ASN1_NULL),
C_STRINGIFY(LTC_ASN1_OBJECT_IDENTIFIER),
C_STRINGIFY(LTC_ASN1_IA5_STRING),
C_STRINGIFY(LTC_ASN1_PRINTABLE_STRING),
C_STRINGIFY(LTC_ASN1_UTF8_STRING),
C_STRINGIFY(LTC_ASN1_UTCTIME),
C_STRINGIFY(LTC_ASN1_CHOICE),
C_STRINGIFY(LTC_ASN1_SEQUENCE),
C_STRINGIFY(LTC_ASN1_SET),
C_STRINGIFY(LTC_ASN1_SETOF),
C_STRINGIFY(LTC_ASN1_RAW_BIT_STRING),
C_STRINGIFY(LTC_ASN1_TELETEX_STRING),
C_STRINGIFY(LTC_ASN1_GENERALIZEDTIME),
C_STRINGIFY(LTC_ASN1_CUSTOM_TYPE),
C_STRINGIFY(LTC_DER_MAX_RECURSION),
#else
{"LTC_DER", 0},
#endif
#ifdef LTC_CTR_MODE
{"LTC_CTR_MODE", 1},
C_STRINGIFY(CTR_COUNTER_LITTLE_ENDIAN),
C_STRINGIFY(CTR_COUNTER_BIG_ENDIAN),
C_STRINGIFY(LTC_CTR_RFC3686),
#else
{"LTC_CTR_MODE", 0},
#endif
#ifdef LTC_GCM_MODE
C_STRINGIFY(LTC_GCM_MODE_IV),
C_STRINGIFY(LTC_GCM_MODE_AAD),
C_STRINGIFY(LTC_GCM_MODE_TEXT),
#endif
C_STRINGIFY(LTC_MP_LT),
C_STRINGIFY(LTC_MP_EQ),
C_STRINGIFY(LTC_MP_GT),
C_STRINGIFY(LTC_MP_NO),
C_STRINGIFY(LTC_MP_YES),
C_STRINGIFY(MAXBLOCKSIZE),
C_STRINGIFY(TAB_SIZE),
C_STRINGIFY(ARGTYPE),
#ifdef LTM_DESC
{"LTM_DESC", 1},
#else
{"LTM_DESC", 0},
#endif
#ifdef TFM_DESC
{"TFM_DESC", 1},
#else
{"TFM_DESC", 0},
#endif
#ifdef GMP_DESC
{"GMP_DESC", 1},
#else
{"GMP_DESC", 0},
#endif
#ifdef LTC_FAST
{"LTC_FAST", 1},
#else
{"LTC_FAST", 0},
#endif
#ifdef LTC_NO_FILE
{"LTC_NO_FILE", 1},
#else
{"LTC_NO_FILE", 0},
#endif
#ifdef ENDIAN_LITTLE
{"ENDIAN_LITTLE", 1},
#else
{"ENDIAN_LITTLE", 0},
#endif
#ifdef ENDIAN_BIG
{"ENDIAN_BIG", 1},
#else
{"ENDIAN_BIG", 0},
#endif
#ifdef ENDIAN_32BITWORD
{"ENDIAN_32BITWORD", 1},
#else
{"ENDIAN_32BITWORD", 0},
#endif
#ifdef ENDIAN_64BITWORD
{"ENDIAN_64BITWORD", 1},
#else
{"ENDIAN_64BITWORD", 0},
#endif
#ifdef ENDIAN_NEUTRAL
{"ENDIAN_NEUTRAL", 1},
#else
{"ENDIAN_NEUTRAL", 0},
#endif
};
/* crypt_get_constant()
* valueout will be the value of the named constant
* return -1 if named item not found
*/
int crypt_get_constant(const char* namein, int *valueout) {
int i;
int count = sizeof(s_crypt_constants) / sizeof(s_crypt_constants[0]);
for (i=0; i<count; i++) {
if (XSTRCMP(s_crypt_constants[i].name, namein) == 0) {
*valueout = s_crypt_constants[i].value;
return 0;
}
}
return 1;
}
/* crypt_list_all_constants()
* if names_list is NULL, names_list_size will be the minimum
* number of bytes needed to receive the complete names_list
* if names_list is NOT NULL, names_list must be the addr of
* sufficient memory allocated into which the names_list
* is to be written. Also, the value in names_list_size
* sets the upper bound of the number of characters to be
* written.
* a -1 return value signifies insufficient space made available
*/
int crypt_list_all_constants(char *names_list, unsigned int *names_list_size) {
int i;
unsigned int total_len = 0;
char *ptr;
int number_len;
int count = sizeof(s_crypt_constants) / sizeof(s_crypt_constants[0]);
/* calculate amount of memory required for the list */
for (i=0; i<count; i++) {
number_len = snprintf(NULL, 0, "%s,%d\n", s_crypt_constants[i].name, s_crypt_constants[i].value);
if (number_len < 0) {
return -1;
}
total_len += number_len;
}
if (names_list == NULL) {
*names_list_size = total_len;
} else {
if (total_len > *names_list_size) {
return -1;
}
/* build the names list */
ptr = names_list;
for (i=0; i<count; i++) {
number_len = snprintf(ptr, total_len, "%s,%d\n", s_crypt_constants[i].name, s_crypt_constants[i].value);
if (number_len < 0) return -1;
if ((unsigned int)number_len > total_len) return -1;
total_len -= number_len;
ptr += number_len;
}
/* to remove the trailing new-line */
ptr -= 1;
*ptr = 0;
}
return 0;
}

View File

@ -1,29 +0,0 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@file crypt_find_cipher.c
Find a cipher in the descriptor tables, Tom St Denis
*/
/**
Find a registered cipher by name
@param name The name of the cipher to look for
@return >= 0 if found, -1 if not present
*/
int find_cipher(const char *name)
{
int x;
LTC_ARGCHK(name != NULL);
LTC_MUTEX_LOCK(&ltc_cipher_mutex);
for (x = 0; x < TAB_SIZE; x++) {
if (cipher_descriptor[x].name != NULL && !XSTRCMP(cipher_descriptor[x].name, name)) {
LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
return x;
}
}
LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
return -1;
}

View File

@ -1,38 +0,0 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@file crypt_find_cipher_any.c
Find a cipher in the descriptor tables, Tom St Denis
*/
/**
Find a cipher flexibly. First by name then if not present by block and key size
@param name The name of the cipher desired
@param blocklen The minimum length of the block cipher desired (octets)
@param keylen The minimum length of the key size desired (octets)
@return >= 0 if found, -1 if not present
*/
int find_cipher_any(const char *name, int blocklen, int keylen)
{
int x;
if(name != NULL) {
x = find_cipher(name);
if (x != -1) return x;
}
LTC_MUTEX_LOCK(&ltc_cipher_mutex);
for (x = 0; x < TAB_SIZE; x++) {
if (cipher_descriptor[x].name == NULL) {
continue;
}
if (blocklen <= (int)cipher_descriptor[x].block_length && keylen <= (int)cipher_descriptor[x].max_key_length) {
LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
return x;
}
}
LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
return -1;
}

View File

@ -1,28 +0,0 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@file crypt_find_cipher_id.c
Find cipher by ID, Tom St Denis
*/
/**
Find a cipher by ID number
@param ID The ID (not same as index) of the cipher to find
@return >= 0 if found, -1 if not present
*/
int find_cipher_id(unsigned char ID)
{
int x;
LTC_MUTEX_LOCK(&ltc_cipher_mutex);
for (x = 0; x < TAB_SIZE; x++) {
if (cipher_descriptor[x].ID == ID) {
x = (cipher_descriptor[x].name == NULL) ? -1 : x;
LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
return x;
}
}
LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
return -1;
}

View File

@ -1,28 +0,0 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@file crypt_find_hash.c
Find a hash, Tom St Denis
*/
/**
Find a registered hash by name
@param name The name of the hash to look for
@return >= 0 if found, -1 if not present
*/
int find_hash(const char *name)
{
int x;
LTC_ARGCHK(name != NULL);
LTC_MUTEX_LOCK(&ltc_hash_mutex);
for (x = 0; x < TAB_SIZE; x++) {
if (hash_descriptor[x].name != NULL && XSTRCMP(hash_descriptor[x].name, name) == 0) {
LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
return x;
}
}
LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
return -1;
}

View File

@ -1,37 +0,0 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@file crypt_find_hash_any.c
Find a hash, Tom St Denis
*/
/**
Find a hash flexibly. First by name then if not present by digest size
@param name The name of the hash desired
@param digestlen The minimum length of the digest size (octets)
@return >= 0 if found, -1 if not present
*/int find_hash_any(const char *name, int digestlen)
{
int x, y, z;
LTC_ARGCHK(name != NULL);
x = find_hash(name);
if (x != -1) return x;
LTC_MUTEX_LOCK(&ltc_hash_mutex);
y = MAXBLOCKSIZE+1;
z = -1;
for (x = 0; x < TAB_SIZE; x++) {
if (hash_descriptor[x].name == NULL) {
continue;
}
if ((int)hash_descriptor[x].hashsize >= digestlen && (int)hash_descriptor[x].hashsize < y) {
z = x;
y = hash_descriptor[x].hashsize;
}
}
LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
return z;
}

View File

@ -1,28 +0,0 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@file crypt_find_hash_id.c
Find hash by ID, Tom St Denis
*/
/**
Find a hash by ID number
@param ID The ID (not same as index) of the hash to find
@return >= 0 if found, -1 if not present
*/
int find_hash_id(unsigned char ID)
{
int x;
LTC_MUTEX_LOCK(&ltc_hash_mutex);
for (x = 0; x < TAB_SIZE; x++) {
if (hash_descriptor[x].ID == ID) {
x = (hash_descriptor[x].name == NULL) ? -1 : x;
LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
return x;
}
}
LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
return -1;
}

View File

@ -1,23 +0,0 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@file crypt_find_hash_oid.c
Find a hash, Tom St Denis
*/
int find_hash_oid(const unsigned long *ID, unsigned long IDlen)
{
int x;
LTC_ARGCHK(ID != NULL);
LTC_MUTEX_LOCK(&ltc_hash_mutex);
for (x = 0; x < TAB_SIZE; x++) {
if (hash_descriptor[x].name != NULL && hash_descriptor[x].OIDlen == IDlen && !XMEMCMP(hash_descriptor[x].OID, ID, sizeof(unsigned long) * IDlen)) {
LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
return x;
}
}
LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
return -1;
}

View File

@ -1,29 +0,0 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@file crypt_find_prng.c
Find a PRNG, Tom St Denis
*/
/**
Find a registered PRNG by name
@param name The name of the PRNG to look for
@return >= 0 if found, -1 if not present
*/
int find_prng(const char *name)
{
int x;
LTC_ARGCHK(name != NULL);
LTC_MUTEX_LOCK(&ltc_prng_mutex);
for (x = 0; x < TAB_SIZE; x++) {
if ((prng_descriptor[x].name != NULL) && XSTRCMP(prng_descriptor[x].name, name) == 0) {
LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
return x;
}
}
LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
return -1;
}

View File

@ -1,46 +0,0 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
#include <stdarg.h>
/**
@file crypt_fsa.c
LibTomCrypt FULL SPEED AHEAD!, Tom St Denis
*/
/* format is ltc_mp, cipher_desc, [cipher_desc], NULL, hash_desc, [hash_desc], NULL, prng_desc, [prng_desc], NULL */
int crypt_fsa(void *mp, ...)
{
va_list args;
void *p;
va_start(args, mp);
if (mp != NULL) {
XMEMCPY(&ltc_mp, mp, sizeof(ltc_mp));
}
while ((p = va_arg(args, void*)) != NULL) {
if (register_cipher(p) == -1) {
va_end(args);
return CRYPT_INVALID_CIPHER;
}
}
while ((p = va_arg(args, void*)) != NULL) {
if (register_hash(p) == -1) {
va_end(args);
return CRYPT_INVALID_HASH;
}
}
while ((p = va_arg(args, void*)) != NULL) {
if (register_prng(p) == -1) {
va_end(args);
return CRYPT_INVALID_PRNG;
}
}
va_end(args);
return CRYPT_OK;
}

View File

@ -1,15 +0,0 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@file crypt_hash_descriptor.c
Stores the hash descriptor table, Tom St Denis
*/
struct ltc_hash_descriptor hash_descriptor[TAB_SIZE] = {
{ NULL, 0, 0, 0, { 0 }, 0, NULL, NULL, NULL, NULL, NULL }
};
LTC_MUTEX_GLOBAL(ltc_hash_mutex)

View File

@ -1,24 +0,0 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@file crypt_hash_is_valid.c
Determine if hash is valid, Tom St Denis
*/
/*
Test if a hash index is valid
@param idx The index of the hash to search for
@return CRYPT_OK if valid
*/
int hash_is_valid(int idx)
{
LTC_MUTEX_LOCK(&ltc_hash_mutex);
if (idx < 0 || idx >= TAB_SIZE || hash_descriptor[idx].name == NULL) {
LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
return CRYPT_INVALID_HASH;
}
LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
return CRYPT_OK;
}

View File

@ -1,81 +0,0 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@file crypt_inits.c
Provide math library functions for dynamic languages
like Python - Larry Bugbee, February 2013
*/
#ifdef LTM_DESC
void init_LTM(void)
{
ltc_mp = ltm_desc;
}
#endif
#ifdef TFM_DESC
void init_TFM(void)
{
ltc_mp = tfm_desc;
}
#endif
#ifdef GMP_DESC
void init_GMP(void)
{
ltc_mp = gmp_desc;
}
#endif
int crypt_mp_init(const char* mpi)
{
if (mpi == NULL) return CRYPT_ERROR;
switch (mpi[0]) {
#ifdef LTM_DESC
case 'l':
case 'L':
ltc_mp = ltm_desc;
return CRYPT_OK;
#endif
#ifdef TFM_DESC
case 't':
case 'T':
ltc_mp = tfm_desc;
return CRYPT_OK;
#endif
#ifdef GMP_DESC
case 'g':
case 'G':
ltc_mp = gmp_desc;
return CRYPT_OK;
#endif
#ifdef EXT_MATH_LIB
case 'e':
case 'E':
{
extern ltc_math_descriptor EXT_MATH_LIB;
ltc_mp = EXT_MATH_LIB;
}
#if defined(LTC_TEST_DBG)
#define NAME_VALUE(s) #s"="NAME(s)
#define NAME(s) #s
printf("EXT_MATH_LIB = %s\n", NAME_VALUE(EXT_MATH_LIB));
#undef NAME_VALUE
#undef NAME
#endif
return CRYPT_OK;
#endif
default:
#if defined(LTC_TEST_DBG)
printf("Unknown/Invalid MPI provider: %s\n", mpi);
#endif
return CRYPT_ERROR;
}
}

View File

@ -1,6 +0,0 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/* Initialize ltc_mp to nulls, to force allocation on all platforms, including macOS. */
ltc_math_descriptor ltc_mp = { 0 };

View File

@ -1,14 +0,0 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@file crypt_prng_descriptor.c
Stores the PRNG descriptors, Tom St Denis
*/
struct ltc_prng_descriptor prng_descriptor[TAB_SIZE] = {
{ NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
};
LTC_MUTEX_GLOBAL(ltc_prng_mutex)

View File

@ -1,24 +0,0 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@file crypt_prng_is_valid.c
Determine if PRNG is valid, Tom St Denis
*/
/*
Test if a PRNG index is valid
@param idx The index of the PRNG to search for
@return CRYPT_OK if valid
*/
int prng_is_valid(int idx)
{
LTC_MUTEX_LOCK(&ltc_prng_mutex);
if (idx < 0 || idx >= TAB_SIZE || prng_descriptor[idx].name == NULL) {
LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
return CRYPT_INVALID_PRNG;
}
LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
return CRYPT_OK;
}

View File

@ -1,7 +0,0 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
#ifdef LTC_PRNG_ENABLE_LTC_RNG
unsigned long (*ltc_rng)(unsigned char *out, unsigned long outlen, void (*callback)(void));
#endif

View File

@ -1,100 +0,0 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@file crypt_register_all_ciphers.c
Steffen Jaeckel
*/
#define REGISTER_CIPHER(h) do {\
LTC_ARGCHK(register_cipher(h) != -1); \
} while(0)
int register_all_ciphers(void)
{
#ifdef LTC_RIJNDAEL
/* `aesni_desc` is explicitely not registered, since it's handled from within the `aes_desc` */
#ifdef ENCRYPT_ONLY
/* alternative would be
* register_cipher(&rijndael_enc_desc);
*/
REGISTER_CIPHER(&aes_enc_desc);
#else
/* alternative would be
* register_cipher(&rijndael_desc);
*/
REGISTER_CIPHER(&aes_desc);
#endif
#endif
#ifdef LTC_BLOWFISH
REGISTER_CIPHER(&blowfish_desc);
#endif
#ifdef LTC_XTEA
REGISTER_CIPHER(&xtea_desc);
#endif
#ifdef LTC_RC5
REGISTER_CIPHER(&rc5_desc);
#endif
#ifdef LTC_RC6
REGISTER_CIPHER(&rc6_desc);
#endif
#ifdef LTC_SAFERP
REGISTER_CIPHER(&saferp_desc);
#endif
#ifdef LTC_TWOFISH
REGISTER_CIPHER(&twofish_desc);
#endif
#ifdef LTC_SAFER
REGISTER_CIPHER(&safer_k64_desc);
REGISTER_CIPHER(&safer_sk64_desc);
REGISTER_CIPHER(&safer_k128_desc);
REGISTER_CIPHER(&safer_sk128_desc);
#endif
#ifdef LTC_RC2
REGISTER_CIPHER(&rc2_desc);
#endif
#ifdef LTC_DES
REGISTER_CIPHER(&des_desc);
REGISTER_CIPHER(&des3_desc);
#endif
#ifdef LTC_CAST5
REGISTER_CIPHER(&cast5_desc);
#endif
#ifdef LTC_NOEKEON
REGISTER_CIPHER(&noekeon_desc);
#endif
#ifdef LTC_SKIPJACK
REGISTER_CIPHER(&skipjack_desc);
#endif
#ifdef LTC_ANUBIS
REGISTER_CIPHER(&anubis_desc);
#endif
#ifdef LTC_KHAZAD
REGISTER_CIPHER(&khazad_desc);
#endif
#ifdef LTC_KSEED
REGISTER_CIPHER(&kseed_desc);
#endif
#ifdef LTC_KASUMI
REGISTER_CIPHER(&kasumi_desc);
#endif
#ifdef LTC_MULTI2
REGISTER_CIPHER(&multi2_desc);
#endif
#ifdef LTC_CAMELLIA
REGISTER_CIPHER(&camellia_desc);
#endif
#ifdef LTC_IDEA
REGISTER_CIPHER(&idea_desc);
#endif
#ifdef LTC_SERPENT
REGISTER_CIPHER(&serpent_desc);
#endif
#ifdef LTC_TEA
REGISTER_CIPHER(&tea_desc);
#endif
return CRYPT_OK;
}

View File

@ -1,95 +0,0 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@file crypt_register_all_hashes.c
Steffen Jaeckel
*/
#define REGISTER_HASH(h) do {\
LTC_ARGCHK(register_hash(h) != -1); \
} while(0)
int register_all_hashes(void)
{
#ifdef LTC_TIGER
REGISTER_HASH(&tiger_desc);
#endif
#ifdef LTC_MD2
REGISTER_HASH(&md2_desc);
#endif
#ifdef LTC_MD4
REGISTER_HASH(&md4_desc);
#endif
#ifdef LTC_MD5
REGISTER_HASH(&md5_desc);
#endif
#ifdef LTC_SHA1
REGISTER_HASH(&sha1_desc);
#endif
#ifdef LTC_SHA224
REGISTER_HASH(&sha224_desc);
#endif
#ifdef LTC_SHA256
REGISTER_HASH(&sha256_desc);
#endif
#ifdef LTC_SHA384
REGISTER_HASH(&sha384_desc);
#endif
#ifdef LTC_SHA512
REGISTER_HASH(&sha512_desc);
#endif
#ifdef LTC_SHA512_224
REGISTER_HASH(&sha512_224_desc);
#endif
#ifdef LTC_SHA512_256
REGISTER_HASH(&sha512_256_desc);
#endif
#ifdef LTC_SHA3
REGISTER_HASH(&sha3_224_desc);
REGISTER_HASH(&sha3_256_desc);
REGISTER_HASH(&sha3_384_desc);
REGISTER_HASH(&sha3_512_desc);
#endif
#ifdef LTC_KECCAK
REGISTER_HASH(&keccak_224_desc);
REGISTER_HASH(&keccak_256_desc);
REGISTER_HASH(&keccak_384_desc);
REGISTER_HASH(&keccak_512_desc);
#endif
#ifdef LTC_RIPEMD128
REGISTER_HASH(&rmd128_desc);
#endif
#ifdef LTC_RIPEMD160
REGISTER_HASH(&rmd160_desc);
#endif
#ifdef LTC_RIPEMD256
REGISTER_HASH(&rmd256_desc);
#endif
#ifdef LTC_RIPEMD320
REGISTER_HASH(&rmd320_desc);
#endif
#ifdef LTC_WHIRLPOOL
REGISTER_HASH(&whirlpool_desc);
#endif
#ifdef LTC_BLAKE2S
REGISTER_HASH(&blake2s_128_desc);
REGISTER_HASH(&blake2s_160_desc);
REGISTER_HASH(&blake2s_224_desc);
REGISTER_HASH(&blake2s_256_desc);
#endif
#ifdef LTC_BLAKE2S
REGISTER_HASH(&blake2b_160_desc);
REGISTER_HASH(&blake2b_256_desc);
REGISTER_HASH(&blake2b_384_desc);
REGISTER_HASH(&blake2b_512_desc);
#endif
#ifdef LTC_CHC_HASH
REGISTER_HASH(&chc_desc);
LTC_ARGCHK(chc_register(find_cipher_any("aes", 8, 16)) == CRYPT_OK);
#endif
return CRYPT_OK;
}

View File

@ -1,38 +0,0 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@file crypt_register_all_prngs.c
Steffen Jaeckel
*/
#define REGISTER_PRNG(h) do {\
LTC_ARGCHK(register_prng(h) != -1); \
} while(0)
int register_all_prngs(void)
{
#ifdef LTC_YARROW
REGISTER_PRNG(&yarrow_desc);
#endif
#ifdef LTC_FORTUNA
REGISTER_PRNG(&fortuna_desc);
#endif
#ifdef LTC_RC4
REGISTER_PRNG(&rc4_desc);
#endif
#ifdef LTC_CHACHA20_PRNG
REGISTER_PRNG(&chacha20_prng_desc);
#endif
#ifdef LTC_SOBER128
REGISTER_PRNG(&sober128_desc);
#endif
#ifdef LTC_SPRNG
REGISTER_PRNG(&sprng_desc);
#endif
return CRYPT_OK;
}

View File

@ -1,42 +0,0 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.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;
}

View File

@ -1,42 +0,0 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@file crypt_register_hash.c
Register a HASH, Tom St Denis
*/
/**
Register a hash with the descriptor table
@param hash The hash you wish to register
@return value >= 0 if successfully added (or already present), -1 if unsuccessful
*/
int register_hash(const struct ltc_hash_descriptor *hash)
{
int x;
LTC_ARGCHK(hash != NULL);
/* is it already registered? */
LTC_MUTEX_LOCK(&ltc_hash_mutex);
for (x = 0; x < TAB_SIZE; x++) {
if (XMEMCMP(&hash_descriptor[x], hash, sizeof(struct ltc_hash_descriptor)) == 0) {
LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
return x;
}
}
/* find a blank spot */
for (x = 0; x < TAB_SIZE; x++) {
if (hash_descriptor[x].name == NULL) {
XMEMCPY(&hash_descriptor[x], hash, sizeof(struct ltc_hash_descriptor));
LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
return x;
}
}
/* no spot */
LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
return -1;
}

View File

@ -1,42 +0,0 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@file crypt_register_prng.c
Register a PRNG, Tom St Denis
*/
/**
Register a PRNG with the descriptor table
@param prng The PRNG you wish to register
@return value >= 0 if successfully added (or already present), -1 if unsuccessful
*/
int register_prng(const struct ltc_prng_descriptor *prng)
{
int x;
LTC_ARGCHK(prng != NULL);
/* is it already registered? */
LTC_MUTEX_LOCK(&ltc_prng_mutex);
for (x = 0; x < TAB_SIZE; x++) {
if (XMEMCMP(&prng_descriptor[x], prng, sizeof(struct ltc_prng_descriptor)) == 0) {
LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
return x;
}
}
/* find a blank spot */
for (x = 0; x < TAB_SIZE; x++) {
if (prng_descriptor[x].name == NULL) {
XMEMCPY(&prng_descriptor[x], prng, sizeof(struct ltc_prng_descriptor));
LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
return x;
}
}
/* no spot */
LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
return -1;
}

View File

@ -1,351 +0,0 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@file crypt_sizes.c
Make various struct sizes available to dynamic languages
like Python - Larry Bugbee, February 2013
LB - Dec 2013 - revised to include compiler define options
*/
typedef struct {
const char *name;
const unsigned int size;
} crypt_size;
#define SZ_STRINGIFY_S(s) { #s, sizeof(struct s) }
#define SZ_STRINGIFY_T(s) { #s, sizeof(s) }
static const crypt_size s_crypt_sizes[] = {
/* hash state sizes */
SZ_STRINGIFY_S(ltc_hash_descriptor),
SZ_STRINGIFY_T(hash_state),
#ifdef LTC_CHC_HASH
SZ_STRINGIFY_S(chc_state),
#endif
#ifdef LTC_WHIRLPOOL
SZ_STRINGIFY_S(whirlpool_state),
#endif
#ifdef LTC_SHA3
SZ_STRINGIFY_S(sha3_state),
#endif
#ifdef LTC_SHA512
SZ_STRINGIFY_S(sha512_state),
#endif
#ifdef LTC_SHA256
SZ_STRINGIFY_S(sha256_state),
#endif
#ifdef LTC_SHA1
SZ_STRINGIFY_S(sha1_state),
#endif
#ifdef LTC_MD5
SZ_STRINGIFY_S(md5_state),
#endif
#ifdef LTC_MD4
SZ_STRINGIFY_S(md4_state),
#endif
#ifdef LTC_MD2
SZ_STRINGIFY_S(md2_state),
#endif
#ifdef LTC_TIGER
SZ_STRINGIFY_S(tiger_state),
#endif
#ifdef LTC_RIPEMD128
SZ_STRINGIFY_S(rmd128_state),
#endif
#ifdef LTC_RIPEMD160
SZ_STRINGIFY_S(rmd160_state),
#endif
#ifdef LTC_RIPEMD256
SZ_STRINGIFY_S(rmd256_state),
#endif
#ifdef LTC_RIPEMD320
SZ_STRINGIFY_S(rmd320_state),
#endif
#ifdef LTC_BLAKE2S
SZ_STRINGIFY_S(blake2s_state),
#endif
#ifdef LTC_BLAKE2B
SZ_STRINGIFY_S(blake2b_state),
#endif
/* block cipher key sizes */
SZ_STRINGIFY_S(ltc_cipher_descriptor),
SZ_STRINGIFY_T(symmetric_key),
#ifdef LTC_ANUBIS
SZ_STRINGIFY_S(anubis_key),
#endif
#ifdef LTC_CAMELLIA
SZ_STRINGIFY_S(camellia_key),
#endif
#ifdef LTC_BLOWFISH
SZ_STRINGIFY_S(blowfish_key),
#endif
#ifdef LTC_CAST5
SZ_STRINGIFY_S(cast5_key),
#endif
#ifdef LTC_DES
SZ_STRINGIFY_S(des_key),
SZ_STRINGIFY_S(des3_key),
#endif
#ifdef LTC_IDEA
SZ_STRINGIFY_S(idea_key),
#endif
#ifdef LTC_KASUMI
SZ_STRINGIFY_S(kasumi_key),
#endif
#ifdef LTC_KHAZAD
SZ_STRINGIFY_S(khazad_key),
#endif
#ifdef LTC_KSEED
SZ_STRINGIFY_S(kseed_key),
#endif
#ifdef LTC_MULTI2
SZ_STRINGIFY_S(multi2_key),
#endif
#ifdef LTC_NOEKEON
SZ_STRINGIFY_S(noekeon_key),
#endif
#ifdef LTC_RC2
SZ_STRINGIFY_S(rc2_key),
#endif
#ifdef LTC_RC5
SZ_STRINGIFY_S(rc5_key),
#endif
#ifdef LTC_RC6
SZ_STRINGIFY_S(rc6_key),
#endif
#ifdef LTC_SERPENT
SZ_STRINGIFY_S(serpent_key),
#endif
#ifdef LTC_SKIPJACK
SZ_STRINGIFY_S(skipjack_key),
#endif
#ifdef LTC_XTEA
SZ_STRINGIFY_S(xtea_key),
#endif
#ifdef LTC_RIJNDAEL
SZ_STRINGIFY_S(rijndael_key),
#endif
#ifdef LTC_SAFER
SZ_STRINGIFY_S(safer_key),
#endif
#ifdef LTC_SAFERP
SZ_STRINGIFY_S(saferp_key),
#endif
#ifdef LTC_TWOFISH
SZ_STRINGIFY_S(twofish_key),
#endif
/* mode sizes */
#ifdef LTC_ECB_MODE
SZ_STRINGIFY_T(symmetric_ECB),
#endif
#ifdef LTC_CFB_MODE
SZ_STRINGIFY_T(symmetric_CFB),
#endif
#ifdef LTC_OFB_MODE
SZ_STRINGIFY_T(symmetric_OFB),
#endif
#ifdef LTC_CBC_MODE
SZ_STRINGIFY_T(symmetric_CBC),
#endif
#ifdef LTC_CTR_MODE
SZ_STRINGIFY_T(symmetric_CTR),
#endif
#ifdef LTC_LRW_MODE
SZ_STRINGIFY_T(symmetric_LRW),
#endif
#ifdef LTC_F8_MODE
SZ_STRINGIFY_T(symmetric_F8),
#endif
#ifdef LTC_XTS_MODE
SZ_STRINGIFY_T(symmetric_xts),
#endif
/* stream cipher sizes */
#ifdef LTC_CHACHA
SZ_STRINGIFY_T(chacha_state),
#endif
#ifdef LTC_SALSA20
SZ_STRINGIFY_T(salsa20_state),
#endif
#ifdef LTC_SOSEMANUK
SZ_STRINGIFY_T(sosemanuk_state),
#endif
#ifdef LTC_RABBIT
SZ_STRINGIFY_T(rabbit_state),
#endif
#ifdef LTC_RC4_STREAM
SZ_STRINGIFY_T(rc4_state),
#endif
#ifdef LTC_SOBER128_STREAM
SZ_STRINGIFY_T(sober128_state),
#endif
/* MAC sizes -- no states for ccm, lrw */
#ifdef LTC_HMAC
SZ_STRINGIFY_T(hmac_state),
#endif
#ifdef LTC_OMAC
SZ_STRINGIFY_T(omac_state),
#endif
#ifdef LTC_PMAC
SZ_STRINGIFY_T(pmac_state),
#endif
#ifdef LTC_POLY1305
SZ_STRINGIFY_T(poly1305_state),
#endif
#ifdef LTC_EAX_MODE
SZ_STRINGIFY_T(eax_state),
#endif
#ifdef LTC_OCB_MODE
SZ_STRINGIFY_T(ocb_state),
#endif
#ifdef LTC_OCB3_MODE
SZ_STRINGIFY_T(ocb3_state),
#endif
#ifdef LTC_CCM_MODE
SZ_STRINGIFY_T(ccm_state),
#endif
#ifdef LTC_GCM_MODE
SZ_STRINGIFY_T(gcm_state),
#endif
#ifdef LTC_PELICAN
SZ_STRINGIFY_T(pelican_state),
#endif
#ifdef LTC_XCBC
SZ_STRINGIFY_T(xcbc_state),
#endif
#ifdef LTC_F9_MODE
SZ_STRINGIFY_T(f9_state),
#endif
#ifdef LTC_CHACHA20POLY1305_MODE
SZ_STRINGIFY_T(chacha20poly1305_state),
#endif
/* asymmetric keys */
#ifdef LTC_MRSA
SZ_STRINGIFY_T(rsa_key),
#endif
#ifdef LTC_MDSA
SZ_STRINGIFY_T(dsa_key),
#endif
#ifdef LTC_MDH
SZ_STRINGIFY_T(dh_key),
#endif
#ifdef LTC_MECC
SZ_STRINGIFY_T(ltc_ecc_curve),
SZ_STRINGIFY_T(ecc_point),
SZ_STRINGIFY_T(ecc_key),
#endif
/* DER handling */
#ifdef LTC_DER
SZ_STRINGIFY_T(ltc_asn1_list), /* a list entry */
SZ_STRINGIFY_T(ltc_utctime),
SZ_STRINGIFY_T(ltc_generalizedtime),
#endif
/* prng state sizes */
SZ_STRINGIFY_S(ltc_prng_descriptor),
SZ_STRINGIFY_T(prng_state),
#ifdef LTC_FORTUNA
SZ_STRINGIFY_S(fortuna_prng),
#endif
#ifdef LTC_CHACHA20_PRNG
SZ_STRINGIFY_S(chacha20_prng),
#endif
#ifdef LTC_RC4
SZ_STRINGIFY_S(rc4_prng),
#endif
#ifdef LTC_SOBER128
SZ_STRINGIFY_S(sober128_prng),
#endif
#ifdef LTC_YARROW
SZ_STRINGIFY_S(yarrow_prng),
#endif
/* sprng has no state as it uses other potentially available sources */
/* like /dev/random. See Developers Guide for more info. */
#ifdef LTC_ADLER32
SZ_STRINGIFY_T(adler32_state),
#endif
#ifdef LTC_CRC32
SZ_STRINGIFY_T(crc32_state),
#endif
SZ_STRINGIFY_T(ltc_mp_digit),
SZ_STRINGIFY_T(ltc_math_descriptor)
};
/* crypt_get_size()
* sizeout will be the size (bytes) of the named struct or union
* return -1 if named item not found
*/
int crypt_get_size(const char* namein, unsigned int *sizeout) {
int i;
int count = sizeof(s_crypt_sizes) / sizeof(s_crypt_sizes[0]);
for (i=0; i<count; i++) {
if (XSTRCMP(s_crypt_sizes[i].name, namein) == 0) {
*sizeout = s_crypt_sizes[i].size;
return 0;
}
}
return -1;
}
/* crypt_list_all_sizes()
* if names_list is NULL, names_list_size will be the minimum
* size needed to receive the complete names_list
* if names_list is NOT NULL, names_list must be the addr with
* sufficient memory allocated into which the names_list
* is to be written. Also, the value in names_list_size
* sets the upper bound of the number of characters to be
* written.
* a -1 return value signifies insufficient space made available
*/
int crypt_list_all_sizes(char *names_list, unsigned int *names_list_size) {
int i;
unsigned int total_len = 0;
char *ptr;
int number_len;
int count = sizeof(s_crypt_sizes) / sizeof(s_crypt_sizes[0]);
/* calculate amount of memory required for the list */
for (i=0; i<count; i++) {
number_len = snprintf(NULL, 0, "%s,%u\n", s_crypt_sizes[i].name, s_crypt_sizes[i].size);
if (number_len < 0) {
return -1;
}
total_len += number_len;
/* this last +1 is for newlines (and ending NULL) */
}
if (names_list == NULL) {
*names_list_size = total_len;
} else {
if (total_len > *names_list_size) {
return -1;
}
/* build the names list */
ptr = names_list;
for (i=0; i<count; i++) {
number_len = snprintf(ptr, total_len, "%s,%u\n", s_crypt_sizes[i].name, s_crypt_sizes[i].size);
if (number_len < 0) return -1;
if ((unsigned int)number_len > total_len) return -1;
total_len -= number_len;
ptr += number_len;
}
/* to remove the trailing new-line */
ptr -= 1;
*ptr = 0;
}
return 0;
}

View File

@ -1,33 +0,0 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@file crypt_unregister_cipher.c
Unregister a cipher, Tom St Denis
*/
/**
Unregister a cipher from the descriptor table
@param cipher The cipher descriptor to remove
@return CRYPT_OK on success
*/
int unregister_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 (XMEMCMP(&cipher_descriptor[x], cipher, sizeof(struct ltc_cipher_descriptor)) == 0) {
cipher_descriptor[x].name = NULL;
cipher_descriptor[x].ID = 255;
LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
return CRYPT_OK;
}
}
LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
return CRYPT_ERROR;
}

View File

@ -1,32 +0,0 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@file crypt_unregister_hash.c
Unregister a hash, Tom St Denis
*/
/**
Unregister a hash from the descriptor table
@param hash The hash descriptor to remove
@return CRYPT_OK on success
*/
int unregister_hash(const struct ltc_hash_descriptor *hash)
{
int x;
LTC_ARGCHK(hash != NULL);
/* is it already registered? */
LTC_MUTEX_LOCK(&ltc_hash_mutex);
for (x = 0; x < TAB_SIZE; x++) {
if (XMEMCMP(&hash_descriptor[x], hash, sizeof(struct ltc_hash_descriptor)) == 0) {
hash_descriptor[x].name = NULL;
LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
return CRYPT_OK;
}
}
LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
return CRYPT_ERROR;
}

View File

@ -1,32 +0,0 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@file crypt_unregister_prng.c
Unregister a PRNG, Tom St Denis
*/
/**
Unregister a PRNG from the descriptor table
@param prng The PRNG descriptor to remove
@return CRYPT_OK on success
*/
int unregister_prng(const struct ltc_prng_descriptor *prng)
{
int x;
LTC_ARGCHK(prng != NULL);
/* is it already registered? */
LTC_MUTEX_LOCK(&ltc_prng_mutex);
for (x = 0; x < TAB_SIZE; x++) {
if (XMEMCMP(&prng_descriptor[x], prng, sizeof(struct ltc_prng_descriptor)) == 0) {
prng_descriptor[x].name = NULL;
LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
return CRYPT_OK;
}
}
LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
return CRYPT_ERROR;
}

View File

@ -8,7 +8,7 @@
Convert error codes to ASCII strings, Tom St Denis
*/
static const char * const err_2_str[] =
static const char * const err_2_str[CRYPT_ERR_NUM] =
{
"CRYPT_OK",
"CRYPT_ERROR",
@ -44,15 +44,18 @@ static const char * const err_2_str[] =
"The input was longer than expected.",
"Invalid sized parameter.",
"Invalid size input for PK parameters.",
"Invalid size for prime.",
"Invalid padding.",
"Hash applied to too many bits.",
"Password context to decrypt key file is missing.",
"The PEM header was not recognized",
};
LTC_STATIC_ASSERT(correct_err_2_str_size, (sizeof(err_2_str)/sizeof(err_2_str[0])) == CRYPT_ERR_NUM)
/**
Convert an LTC error code to ASCII
@param err The error code
@ -60,7 +63,7 @@ static const char * const err_2_str[] =
*/
const char *error_to_string(int err)
{
if (err < 0 || err >= (int)(sizeof(err_2_str)/sizeof(err_2_str[0]))) {
if (err < 0 || err >= CRYPT_ERR_NUM) {
return "Invalid error code.";
}
return err_2_str[err];

View File

@ -0,0 +1,28 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@file password_free.c
Free the password inside a `struct password`, Steffen Jaeckel
*/
/**
Free a password
@param pw The password to be free'd
@param ctx The password context
*/
void password_free(struct password *pw, const struct password_ctx *ctx)
{
if (!ctx || !pw || !pw->pw)
return;
zeromem(pw->pw, pw->l);
if (ctx->free) {
ctx->free(pw->pw);
} else {
XFREE(pw->pw);
}
pw->pw = NULL;
pw->l = 0;
}

View File

@ -50,7 +50,7 @@ int pbes_decrypt(const pbes_arg *arg, unsigned char *dec_data, unsigned long *d
if (klen > sizeof(k)) return CRYPT_INVALID_ARG;
if ((err = arg->type.kdf(arg->pwd, arg->pwdlen, arg->salt->data, arg->salt->size, arg->iterations, hid, k, &klen)) != CRYPT_OK) goto LBL_ERROR;
if ((err = arg->type.kdf(&arg->pw, arg->salt->data, arg->salt->size, arg->iterations, hid, k, &klen)) != CRYPT_OK) goto LBL_ERROR;
if ((err = cbc_start(cid, iv, k, keylen, 0, &cbc)) != CRYPT_OK) goto LBL_ERROR;
if ((err = cbc_decrypt(arg->enc_data->data, dec_data, arg->enc_data->size, &cbc)) != CRYPT_OK) goto LBL_ERROR;
if ((err = cbc_done(&cbc)) != CRYPT_OK) goto LBL_ERROR;

View File

@ -4,28 +4,28 @@
#ifdef LTC_PBES
static int s_pkcs_5_alg1_wrap(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)
static int s_pkcs_5_alg1_wrap(const struct password *pwd,
const unsigned char *salt, unsigned long salt_len,
int iteration_count, int hash_idx,
unsigned char *out, unsigned long *outlen)
{
LTC_UNUSED_PARAM(salt_len);
return pkcs_5_alg1(password, password_len, salt, iteration_count, hash_idx, out, outlen);
return pkcs_5_alg1(pwd->pw, pwd->l, salt, iteration_count, hash_idx, out, outlen);
}
static int s_pkcs_12_wrap(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)
static int s_pkcs_12_wrap(const struct password *pwd,
const unsigned char *salt, unsigned long salt_len,
int iteration_count, int hash_idx,
unsigned char *out, unsigned long *outlen)
{
int err;
/* convert password to unicode/utf16-be */
unsigned long pwlen = password_len * 2;
unsigned long pwlen = pwd->l * 2;
unsigned char* pw;
if (*outlen < 32) return CRYPT_INVALID_ARG;
pw = XMALLOC(pwlen + 2);
if (pw == NULL) return CRYPT_MEM;
if ((err = pkcs12_utf8_to_utf16(password, password_len, pw, &pwlen)) != CRYPT_OK) goto LBL_ERROR;
if ((err = pkcs12_utf8_to_utf16(pwd->pw, pwd->l, pw, &pwlen)) != CRYPT_OK) goto LBL_ERROR;
pw[pwlen++] = 0;
pw[pwlen++] = 0;
/* derive KEY */

View File

@ -22,13 +22,21 @@ static const oid_id_st s_hmac_oid_names[] = {
{ "1.2.840.113549.2.13", "sha512-256" },
};
static int s_pkcs_5_alg2_wrap(const struct password *pwd,
const unsigned char *salt, unsigned long salt_len,
int iteration_count, int hash_idx,
unsigned char *out, unsigned long *outlen)
{
return pkcs_5_alg2(pwd->pw, pwd->l, salt, salt_len, iteration_count, hash_idx, out, outlen);
}
static const pbes_properties s_pbes2_default_types[] = {
{ pkcs_5_alg2, "sha1", "des", 8, 0 },
{ pkcs_5_alg2, "sha1", "rc2", 4, 0 },
{ pkcs_5_alg2, "sha1", "3des", 24, 0 },
{ pkcs_5_alg2, "sha1", "aes", 16, 0 },
{ pkcs_5_alg2, "sha1", "aes", 24, 0 },
{ pkcs_5_alg2, "sha1", "aes", 32, 0 },
{ s_pkcs_5_alg2_wrap, "sha1", "des", 8, 0 },
{ s_pkcs_5_alg2_wrap, "sha1", "rc2", 4, 0 },
{ s_pkcs_5_alg2_wrap, "sha1", "3des", 24, 0 },
{ s_pkcs_5_alg2_wrap, "sha1", "aes", 16, 0 },
{ s_pkcs_5_alg2_wrap, "sha1", "aes", 24, 0 },
{ s_pkcs_5_alg2_wrap, "sha1", "aes", 32, 0 },
};
typedef struct {

338
deps/libtomcrypt/src/misc/pem/pem.c vendored Normal file
View File

@ -0,0 +1,338 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@file pem.c
Const declarations for PEM, Steffen Jaeckel
*/
#ifdef LTC_PEM
const struct pem_header_id pem_std_headers[] = {
{
/* PKCS#8 encrypted */
SET_CSTR(.start, "-----BEGIN ENCRYPTED PRIVATE KEY-----"),
SET_CSTR(.end, "-----END ENCRYPTED PRIVATE KEY-----"),
.has_more_headers = no,
.flags = pf_encrypted_pkcs8,
},
{
/* PKCS#8 plain */
SET_CSTR(.start, "-----BEGIN PRIVATE KEY-----"),
SET_CSTR(.end, "-----END PRIVATE KEY-----"),
.has_more_headers = no,
.flags = pf_pkcs8,
},
{
/* X.509 Certificates */
SET_CSTR(.start, "-----BEGIN CERTIFICATE-----"),
SET_CSTR(.end, "-----END CERTIFICATE-----"),
.has_more_headers = no,
.flags = pf_x509,
},
{
/* Regular (plain) public keys */
SET_CSTR(.start, "-----BEGIN PUBLIC KEY-----"),
SET_CSTR(.end, "-----END PUBLIC KEY-----"),
.has_more_headers = no,
.flags = pf_public,
},
{
SET_CSTR(.start, "-----BEGIN RSA PUBLIC KEY-----"),
SET_CSTR(.end, "-----END RSA PUBLIC KEY-----"),
.has_more_headers = no,
.pka = LTC_PKA_RSA,
.flags = pf_public,
},
/* Regular plain or encrypted private keys */
{
SET_CSTR(.start, "-----BEGIN RSA PRIVATE KEY-----"),
SET_CSTR(.end, "-----END RSA PRIVATE KEY-----"),
.has_more_headers = maybe,
.pka = LTC_PKA_RSA,
},
{
SET_CSTR(.start, "-----BEGIN EC PRIVATE KEY-----"),
SET_CSTR(.end, "-----END EC PRIVATE KEY-----"),
.has_more_headers = maybe,
.pka = LTC_PKA_EC,
},
{
SET_CSTR(.start, "-----BEGIN DSA PRIVATE KEY-----"),
SET_CSTR(.end, "-----END DSA PRIVATE KEY-----"),
.has_more_headers = maybe,
.pka = LTC_PKA_DSA,
},
};
const unsigned long pem_std_headers_num = sizeof(pem_std_headers)/sizeof(pem_std_headers[0]);
/* Encrypted PEM files */
const struct str pem_proc_type_encrypted = { SET_CSTR(, "Proc-Type: 4,ENCRYPTED") };
#if defined(LTC_SSH)
const struct str pem_ssh_comment = { SET_CSTR(, "Comment: ") };
#endif
const struct str pem_dek_info_start = { SET_CSTR(, "DEK-Info: ") };
const struct blockcipher_info pem_dek_infos[] =
{
{ .name = "AES-128-CBC,", .algo = "aes", .keylen = 128 / 8, .mode = cm_cbc, },
{ .name = "AES-192-CBC,", .algo = "aes", .keylen = 192 / 8, .mode = cm_cbc, },
{ .name = "AES-256-CBC,", .algo = "aes", .keylen = 256 / 8, .mode = cm_cbc, },
{ .name = "AES-128-CFB,", .algo = "aes", .keylen = 128 / 8, .mode = cm_cfb, },
{ .name = "AES-192-CFB,", .algo = "aes", .keylen = 192 / 8, .mode = cm_cfb, },
{ .name = "AES-256-CFB,", .algo = "aes", .keylen = 256 / 8, .mode = cm_cfb, },
{ .name = "AES-128-CFB1,", .algo = "aes", .keylen = 128 / 8, .mode = cm_cfb1, },
{ .name = "AES-192-CFB1,", .algo = "aes", .keylen = 192 / 8, .mode = cm_cfb1, },
{ .name = "AES-256-CFB1,", .algo = "aes", .keylen = 256 / 8, .mode = cm_cfb1, },
{ .name = "AES-128-CFB8,", .algo = "aes", .keylen = 128 / 8, .mode = cm_cfb8, },
{ .name = "AES-192-CFB8,", .algo = "aes", .keylen = 192 / 8, .mode = cm_cfb8, },
{ .name = "AES-256-CFB8,", .algo = "aes", .keylen = 256 / 8, .mode = cm_cfb8, },
{ .name = "AES-128-CTR,", .algo = "aes", .keylen = 128 / 8, .mode = cm_ctr, },
{ .name = "AES-192-CTR,", .algo = "aes", .keylen = 192 / 8, .mode = cm_ctr, },
{ .name = "AES-256-CTR,", .algo = "aes", .keylen = 256 / 8, .mode = cm_ctr, },
{ .name = "AES-128-OFB,", .algo = "aes", .keylen = 128 / 8, .mode = cm_ofb, },
{ .name = "AES-192-OFB,", .algo = "aes", .keylen = 192 / 8, .mode = cm_ofb, },
{ .name = "AES-256-OFB,", .algo = "aes", .keylen = 256 / 8, .mode = cm_ofb, },
{ .name = "BF-CBC,", .algo = "blowfish", .keylen = 128 / 8, .mode = cm_cbc, },
{ .name = "BF-CFB,", .algo = "blowfish", .keylen = 128 / 8, .mode = cm_cfb, },
{ .name = "BF-OFB,", .algo = "blowfish", .keylen = 128 / 8, .mode = cm_ofb, },
{ .name = "CAMELLIA-128-CBC,", .algo = "camellia", .keylen = 128 / 8, .mode = cm_cbc, },
{ .name = "CAMELLIA-192-CBC,", .algo = "camellia", .keylen = 192 / 8, .mode = cm_cbc, },
{ .name = "CAMELLIA-256-CBC,", .algo = "camellia", .keylen = 256 / 8, .mode = cm_cbc, },
{ .name = "CAMELLIA-128-CFB,", .algo = "camellia", .keylen = 128 / 8, .mode = cm_cfb, },
{ .name = "CAMELLIA-192-CFB,", .algo = "camellia", .keylen = 192 / 8, .mode = cm_cfb, },
{ .name = "CAMELLIA-256-CFB,", .algo = "camellia", .keylen = 256 / 8, .mode = cm_cfb, },
{ .name = "CAMELLIA-128-CFB1,", .algo = "camellia", .keylen = 128 / 8, .mode = cm_cfb1, },
{ .name = "CAMELLIA-192-CFB1,", .algo = "camellia", .keylen = 192 / 8, .mode = cm_cfb1, },
{ .name = "CAMELLIA-256-CFB1,", .algo = "camellia", .keylen = 256 / 8, .mode = cm_cfb1, },
{ .name = "CAMELLIA-128-CFB8,", .algo = "camellia", .keylen = 128 / 8, .mode = cm_cfb8, },
{ .name = "CAMELLIA-192-CFB8,", .algo = "camellia", .keylen = 192 / 8, .mode = cm_cfb8, },
{ .name = "CAMELLIA-256-CFB8,", .algo = "camellia", .keylen = 256 / 8, .mode = cm_cfb8, },
{ .name = "CAMELLIA-128-CTR,", .algo = "camellia", .keylen = 128 / 8, .mode = cm_ctr, },
{ .name = "CAMELLIA-192-CTR,", .algo = "camellia", .keylen = 192 / 8, .mode = cm_ctr, },
{ .name = "CAMELLIA-256-CTR,", .algo = "camellia", .keylen = 256 / 8, .mode = cm_ctr, },
{ .name = "CAMELLIA-128-OFB,", .algo = "camellia", .keylen = 128 / 8, .mode = cm_ofb, },
{ .name = "CAMELLIA-192-OFB,", .algo = "camellia", .keylen = 192 / 8, .mode = cm_ofb, },
{ .name = "CAMELLIA-256-OFB,", .algo = "camellia", .keylen = 256 / 8, .mode = cm_ofb, },
{ .name = "CAST5-CBC,", .algo = "cast5", .keylen = 128 / 8, .mode = cm_cbc, },
{ .name = "CAST5-CFB,", .algo = "cast5", .keylen = 128 / 8, .mode = cm_cfb, },
{ .name = "CAST5-OFB,", .algo = "cast5", .keylen = 128 / 8, .mode = cm_ofb, },
{ .name = "ChaCha20,", .algo = "chacha20", .keylen = 256 / 8, .mode = cm_stream, },
{ .name = "DES-EDE-CBC,", .algo = "3des", .keylen = 128 / 8, .mode = cm_cbc, },
{ .name = "DES-EDE-CFB,", .algo = "3des", .keylen = 128 / 8, .mode = cm_cfb, },
{ .name = "DES-EDE-OFB,", .algo = "3des", .keylen = 128 / 8, .mode = cm_ofb, },
{ .name = "DES-EDE3-CBC,", .algo = "3des", .keylen = 192 / 8, .mode = cm_cbc, },
{ .name = "DES-EDE3-CFB,", .algo = "3des", .keylen = 192 / 8, .mode = cm_cfb, },
{ .name = "DES-EDE3-CFB1,", .algo = "3des", .keylen = 192 / 8, .mode = cm_cfb1, },
{ .name = "DES-EDE3-CFB8,", .algo = "3des", .keylen = 192 / 8, .mode = cm_cfb8, },
{ .name = "DES-EDE3-OFB,", .algo = "3des", .keylen = 192 / 8, .mode = cm_ofb, },
{ .name = "DES-CBC,", .algo = "des", .keylen = 64 / 8, .mode = cm_cbc, },
{ .name = "DES-CFB,", .algo = "des", .keylen = 64 / 8, .mode = cm_cfb, },
{ .name = "DES-CFB1,", .algo = "des", .keylen = 64 / 8, .mode = cm_cfb1, },
{ .name = "DES-CFB8,", .algo = "des", .keylen = 64 / 8, .mode = cm_cfb8, },
{ .name = "DES-OFB,", .algo = "des", .keylen = 64 / 8, .mode = cm_ofb, },
{ .name = "DESX-CBC,", .algo = "desx", .keylen = 192 / 8, .mode = cm_cbc, },
{ .name = "IDEA-CBC,", .algo = "idea", .keylen = 128 / 8, .mode = cm_cbc, },
{ .name = "IDEA-CFB,", .algo = "idea", .keylen = 128 / 8, .mode = cm_cfb, },
{ .name = "IDEA-OFB,", .algo = "idea", .keylen = 128 / 8, .mode = cm_ofb, },
{ .name = "RC5-CBC,", .algo = "rc5", .keylen = 128 / 8, .mode = cm_cbc, },
{ .name = "RC5-CFB,", .algo = "rc5", .keylen = 128 / 8, .mode = cm_cfb, },
{ .name = "RC5-OFB,", .algo = "rc5", .keylen = 128 / 8, .mode = cm_ofb, },
{ .name = "RC2-40-CBC,", .algo = "rc2", .keylen = 40 / 8, .mode = cm_cbc, },
{ .name = "RC2-64-CBC,", .algo = "rc2", .keylen = 64 / 8, .mode = cm_cbc, },
{ .name = "RC2-CBC,", .algo = "rc2", .keylen = 128 / 8, .mode = cm_cbc, },
{ .name = "RC2-CFB,", .algo = "rc2", .keylen = 128 / 8, .mode = cm_cfb, },
{ .name = "RC2-OFB,", .algo = "rc2", .keylen = 128 / 8, .mode = cm_ofb, },
{ .name = "SEED-CBC,", .algo = "seed", .keylen = 128 / 8, .mode = cm_cbc, },
{ .name = "SEED-CFB,", .algo = "seed", .keylen = 128 / 8, .mode = cm_cfb, },
{ .name = "SEED-OFB,", .algo = "seed", .keylen = 128 / 8, .mode = cm_ofb, },
};
const unsigned long pem_dek_infos_num = sizeof(pem_dek_infos)/sizeof(pem_dek_infos[0]);
int pem_decrypt(unsigned char *data, unsigned long *datalen,
unsigned char *key, unsigned long keylen,
unsigned char *iv, unsigned long ivlen,
unsigned char *tag, unsigned long taglen,
const struct blockcipher_info *info,
enum padding_type padding)
{
int err, cipher = -1;
struct {
union {
#ifdef LTC_CBC_MODE
symmetric_CBC cbc;
#endif
#ifdef LTC_CFB_MODE
symmetric_CFB cfb;
#endif
#ifdef LTC_CTR_MODE
symmetric_CTR ctr;
#endif
#ifdef LTC_OFB_MODE
symmetric_OFB ofb;
#endif
} ctx;
} s;
enum cipher_mode mode = info->mode & cm_modes;
if (mode != cm_stream) {
cipher = find_cipher(info->algo);
if (cipher == -1) {
return CRYPT_INVALID_CIPHER;
}
}
switch (info->mode) {
case cm_cbc:
#ifdef LTC_CBC_MODE
LTC_ARGCHK(ivlen == (unsigned long)cipher_descriptor[cipher].block_length);
if ((err = cbc_start(cipher, iv, key, keylen, 0, &s.ctx.cbc)) != CRYPT_OK) {
goto error_out;
}
if ((err = cbc_decrypt(data, data, *datalen, &s.ctx.cbc)) != CRYPT_OK) {
goto error_out;
}
if ((err = cbc_done(&s.ctx.cbc)) != CRYPT_OK) {
goto error_out;
}
if ((err = padding_depad(data, datalen, padding | s.ctx.cbc.blocklen)) != CRYPT_OK) {
goto error_out;
}
#else
return CRYPT_INVALID_CIPHER;
#endif
break;
case cm_cfb:
case cm_cfb1:
case cm_cfb8:
#ifdef LTC_CFB_MODE
if (info->mode == cm_cfb) {
if ((err = cfb_start(cipher, iv, key, keylen, 0, &s.ctx.cfb)) != CRYPT_OK) {
goto error_out;
}
} else {
if ((err = cfb_start_ex(cipher, iv, key, keylen, 0, info->mode == cm_cfb1 ? 1 : 8, &s.ctx.cfb)) != CRYPT_OK) {
goto error_out;
}
}
if ((err = cfb_decrypt(data, data, *datalen, &s.ctx.cfb)) != CRYPT_OK) {
goto error_out;
}
if ((err = cfb_done(&s.ctx.cfb)) != CRYPT_OK) {
goto error_out;
}
#else
return CRYPT_INVALID_CIPHER;
#endif
break;
case cm_ctr:
#ifdef LTC_CTR_MODE
if ((err = ctr_start(cipher, iv, key, keylen, 0, CTR_COUNTER_BIG_ENDIAN, &s.ctx.ctr)) != CRYPT_OK) {
goto error_out;
}
if ((err = ctr_decrypt(data, data, *datalen, &s.ctx.ctr)) != CRYPT_OK) {
goto error_out;
}
if ((err = ctr_done(&s.ctx.ctr)) != CRYPT_OK) {
goto error_out;
}
#else
return CRYPT_INVALID_CIPHER;
#endif
break;
case cm_ofb:
#ifdef LTC_OFB_MODE
if ((err = ofb_start(cipher, iv, key, keylen, 0, &s.ctx.ofb)) != CRYPT_OK) {
goto error_out;
}
if ((err = ofb_decrypt(data, data, *datalen, &s.ctx.ofb)) != CRYPT_OK) {
goto error_out;
}
if ((err = ofb_done(&s.ctx.ofb)) != CRYPT_OK) {
goto error_out;
}
#else
return CRYPT_INVALID_CIPHER;
#endif
break;
case cm_gcm:
#ifdef LTC_GCM_MODE
if ((err = gcm_memory(cipher,
key, keylen,
iv, ivlen,
NULL, 0,
data, *datalen, data,
tag, &taglen,
GCM_DECRYPT)) != CRYPT_OK) {
goto error_out;
}
#else
LTC_UNUSED_PARAM(tag);
LTC_UNUSED_PARAM(taglen);
return CRYPT_INVALID_CIPHER;
#endif
break;
case cm_stream:
#ifdef LTC_CHACHA
LTC_ARGCHK(ivlen == 16);
if ((err = chacha_memory(key, keylen, 20,
iv, ivlen, 0,
data, *datalen, data)) != CRYPT_OK) {
goto error_out;
}
#else
return CRYPT_INVALID_CIPHER;
#endif
break;
case cm_stream_openssh:
#ifdef LTC_CHACHA20POLY1305_MODE
if ((err = chacha20poly1305_memory(key, 32,
iv, ivlen,
NULL, 0,
data, *datalen, data,
tag, &taglen,
CHACHA20POLY1305_DECRYPT | CHACHA20POLY1305_OPENSSH_COMPAT)) != CRYPT_OK) {
goto error_out;
}
#else
return CRYPT_INVALID_CIPHER;
#endif
break;
default:
err = CRYPT_INVALID_ARG;
break;
}
error_out:
return err;
}
#ifndef LTC_NO_FILE
int pem_decode_filehandle(FILE *f, ltc_pka_key *k, const password_ctx *pw_ctx)
{
int err = pem_decode_pkcs_filehandle(f, k, pw_ctx);
if (err == CRYPT_OK || err != CRYPT_UNKNOWN_PEM)
return err;
#if defined(LTC_SSH)
rewind(f);
err = pem_decode_openssh_filehandle(f, k, pw_ctx);
#endif
return err;
}
#endif
int pem_decode(const void *buf, unsigned long len, ltc_pka_key *k, const password_ctx *pw_ctx)
{
int err = pem_decode_pkcs(buf, len, k, pw_ctx);
if (err == CRYPT_OK || err != CRYPT_UNKNOWN_PEM)
return err;
#if defined(LTC_SSH)
err = pem_decode_openssh(buf, len, k, pw_ctx);
#endif
return err;
}
#endif /* LTC_PEM */

292
deps/libtomcrypt/src/misc/pem/pem_pkcs.c vendored Normal file
View File

@ -0,0 +1,292 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@file pem_decode.c
Decode a PEM file, Steffen Jaeckel
*/
#ifdef LTC_PEM
extern const struct pem_header_id pem_std_headers[];
extern const unsigned long pem_std_headers_num;
static int s_decrypt_pem(unsigned char *pem, unsigned long *l, const struct pem_headers *hdr)
{
unsigned char iv[MAXBLOCKSIZE], key[MAXBLOCKSIZE];
unsigned long ivlen, klen;
int err;
if (hdr->info.keylen > sizeof(key)) {
return CRYPT_BUFFER_OVERFLOW;
}
if (!hdr->pw->pw) {
return CRYPT_INVALID_ARG;
}
ivlen = sizeof(iv);
if ((err = base16_decode(hdr->info.iv, XSTRLEN(hdr->info.iv), iv, &ivlen)) != CRYPT_OK) {
return err;
}
klen = hdr->info.keylen;
if ((err = pkcs_5_alg1_openssl(hdr->pw->pw, hdr->pw->l, iv, 1, find_hash("md5"), key, &klen))) {
return err;
}
err = pem_decrypt(pem, l, key, klen, iv, ivlen, NULL, 0, &hdr->info, LTC_PAD_PKCS7);
zeromem(key, sizeof(key));
zeromem(iv, sizeof(iv));
return err;
}
static int s_get_pka(ltc_asn1_list *pub, enum ltc_pka_id *pka)
{
der_flexi_check flexi_should[4];
ltc_asn1_list *seqid, *id;
enum ltc_oid_id oid_id;
int err;
unsigned long n = 0;
LTC_SET_DER_FLEXI_CHECK(flexi_should, n++, LTC_ASN1_SEQUENCE, &seqid);
LTC_SET_DER_FLEXI_CHECK(flexi_should, n++, LTC_ASN1_BIT_STRING, NULL);
LTC_SET_DER_FLEXI_CHECK(flexi_should, n, LTC_ASN1_EOL, NULL);
if ((err = der_flexi_sequence_cmp(pub, flexi_should)) != CRYPT_OK) {
return err;
}
n = 0;
LTC_SET_DER_FLEXI_CHECK(flexi_should, n++, LTC_ASN1_OBJECT_IDENTIFIER, &id);
LTC_SET_DER_FLEXI_CHECK(flexi_should, n, LTC_ASN1_EOL, NULL);
err = der_flexi_sequence_cmp(seqid, flexi_should);
if (err != CRYPT_OK && err != CRYPT_INPUT_TOO_LONG) {
return err;
}
if ((err = pk_get_oid_from_asn1(id, &oid_id)) != CRYPT_OK) {
return err;
}
return pk_get_pka_id(oid_id, pka);
}
typedef int (*import_fn)(const unsigned char *, unsigned long, void*);
static const import_fn s_import_x509_fns[LTC_PKA_NUM] = {
#ifdef LTC_MRSA
[LTC_PKA_RSA] = (import_fn)rsa_import_x509,
#endif
#ifdef LTC_MECC
[LTC_PKA_EC] = (import_fn)ecc_import_x509,
#endif
#ifdef LTC_CURVE25519
[LTC_PKA_X25519] = (import_fn)x25519_import_x509,
[LTC_PKA_ED25519] = (import_fn)ed25519_import_x509,
#endif
};
static int s_import_x509(unsigned char *pem, unsigned long l, ltc_pka_key *k)
{
enum ltc_pka_id pka = LTC_PKA_UNDEF;
ltc_asn1_list *d, *spki;
int err;
if ((err = x509_decode_spki(pem, l, &d, &spki)) != CRYPT_OK) {
return err;
}
err = s_get_pka(spki, &pka);
der_free_sequence_flexi(d);
if (err != CRYPT_OK) {
return err;
}
if (pka < 0
|| pka > sizeof(s_import_x509_fns)/sizeof(s_import_x509_fns[0])
|| s_import_x509_fns[pka] == NULL) {
return CRYPT_PK_INVALID_TYPE;
}
if ((err = s_import_x509_fns[pka](pem, l, &k->u)) == CRYPT_OK) {
k->id = pka;
}
return err;
}
static int s_import_pkcs8(unsigned char *pem, unsigned long l, ltc_pka_key *k, const password_ctx *pw_ctx)
{
int err;
enum ltc_oid_id pka;
ltc_asn1_list *alg_id, *priv_key;
ltc_asn1_list *p8_asn1 = NULL;
if ((err = pkcs8_decode_flexi(pem, l, pw_ctx, &p8_asn1)) != CRYPT_OK) {
goto cleanup;
}
if ((err = pkcs8_get_children(p8_asn1, &pka, &alg_id, &priv_key)) != CRYPT_OK) {
goto cleanup;
}
switch (pka) {
#ifdef LTC_MDH
case LTC_OID_DH:
err = dh_import_pkcs8_asn1(alg_id, priv_key, &k->u.dh);
k->id = LTC_PKA_DH;
break;
#endif
#ifdef LTC_MDSA
case LTC_OID_DSA:
err = dsa_import_pkcs8_asn1(alg_id, priv_key, &k->u.dsa);
k->id = LTC_PKA_DSA;
break;
#endif
#ifdef LTC_MRSA
case LTC_OID_RSA:
err = rsa_import_pkcs8_asn1(alg_id, priv_key, &k->u.rsa);
k->id = LTC_PKA_RSA;
break;
#endif
#ifdef LTC_MECC
case LTC_OID_EC:
err = ecc_import_pkcs8_asn1(alg_id, priv_key, &k->u.ecc);
k->id = LTC_PKA_EC;
break;
#endif
#ifdef LTC_CURVE25519
case LTC_OID_X25519:
err = x25519_import_pkcs8_asn1(alg_id, priv_key, &k->u.x25519);
k->id = LTC_PKA_X25519;
break;
case LTC_OID_ED25519:
err = ed25519_import_pkcs8_asn1(alg_id, priv_key, &k->u.ed25519);
k->id = LTC_PKA_ED25519;
break;
#endif
default:
err = CRYPT_PK_INVALID_TYPE;
}
cleanup:
if (p8_asn1) {
der_sequence_free(p8_asn1);
}
return err;
}
static int s_extract_pka(unsigned char *pem, unsigned long w, enum ltc_pka_id *pka)
{
ltc_asn1_list *pub;
int err = CRYPT_ERROR;
if ((err = der_decode_sequence_flexi(pem, &w, &pub)) != CRYPT_OK) {
return err;
}
err = s_get_pka(pub, pka);
der_sequence_free(pub);
return err;
}
static const import_fn s_import_openssl_fns[LTC_PKA_NUM] = {
#ifdef LTC_MRSA
[LTC_PKA_RSA] = (import_fn)rsa_import,
#endif
#ifdef LTC_MDSA
[LTC_PKA_DSA] = (import_fn)dsa_import,
#endif
#ifdef LTC_MECC
[LTC_PKA_EC] = (import_fn)ecc_import_openssl,
#endif
#ifdef LTC_CURVE25519
[LTC_PKA_X25519] = (import_fn)x25519_import,
[LTC_PKA_ED25519] = (import_fn)ed25519_import,
#endif
};
static int s_decode(struct get_char *g, ltc_pka_key *k, const password_ctx *pw_ctx)
{
unsigned char *pem = NULL;
unsigned long w, l, n;
int err = CRYPT_ERROR;
struct pem_headers hdr = { 0 };
struct password pw = { 0 };
enum ltc_pka_id pka;
XMEMSET(k, 0, sizeof(*k));
w = LTC_PEM_READ_BUFSIZE * 2;
retry:
pem = XREALLOC(pem, w);
for (n = 0; n < pem_std_headers_num; ++n) {
hdr.id = &pem_std_headers[n];
err = pem_read(pem, &w, &hdr, g);
if (err == CRYPT_BUFFER_OVERFLOW) {
goto retry;
} else if (err == CRYPT_OK) {
break;
} else if (err != CRYPT_UNKNOWN_PEM) {
goto cleanup;
}
hdr.id = NULL;
}
/* id not found */
if (hdr.id == NULL)
goto cleanup;
l = w;
if (hdr.id->flags & pf_pkcs8) {
err = s_import_pkcs8(pem, l, k, pw_ctx);
goto cleanup;
} else if (hdr.id->flags == pf_x509) {
err = s_import_x509(pem, l, k);
goto cleanup;
} else if ((hdr.id->flags & pf_public) && hdr.id->pka == LTC_PKA_UNDEF) {
if ((err = s_extract_pka(pem, w, &pka)) != CRYPT_OK) {
goto cleanup;
}
} else if (hdr.encrypted) {
if ((pw_ctx == NULL) || (pw_ctx->callback == NULL)) {
err = CRYPT_PW_CTX_MISSING;
goto cleanup;
}
hdr.pw = &pw;
if (pw_ctx->callback(&hdr.pw->pw, &hdr.pw->l, pw_ctx->userdata)) {
err = CRYPT_ERROR;
goto cleanup;
}
if ((err = s_decrypt_pem(pem, &l, &hdr)) != CRYPT_OK) {
goto cleanup;
}
pka = hdr.id->pka;
} else {
pka = hdr.id->pka;
}
if (pka < 0
|| pka > sizeof(s_import_openssl_fns)/sizeof(s_import_openssl_fns[0])
|| s_import_openssl_fns[pka] == NULL) {
err = CRYPT_PK_INVALID_TYPE;
goto cleanup;
}
if ((err = s_import_openssl_fns[pka](pem, l, &k->u)) == CRYPT_OK) {
k->id = pka;
}
cleanup:
password_free(hdr.pw, pw_ctx);
XFREE(pem);
return err;
}
#ifndef LTC_NO_FILE
int pem_decode_pkcs_filehandle(FILE *f, ltc_pka_key *k, const password_ctx *pw_ctx)
{
LTC_ARGCHK(f != NULL);
LTC_ARGCHK(k != NULL);
{
struct get_char g = { .get = pem_get_char_from_file, .data.f = f };
return s_decode(&g, k, pw_ctx);
}
}
#endif /* LTC_NO_FILE */
int pem_decode_pkcs(const void *buf, unsigned long len, ltc_pka_key *k, const password_ctx *pw_ctx)
{
LTC_ARGCHK(buf != NULL);
LTC_ARGCHK(len != 0);
LTC_ARGCHK(k != NULL);
{
struct get_char g = { .get = pem_get_char_from_buf, SET_BUFP(.data.buf, buf, len) };
return s_decode(&g, k, pw_ctx);
}
}
#endif /* LTC_PEM */

244
deps/libtomcrypt/src/misc/pem/pem_read.c vendored Normal file
View File

@ -0,0 +1,244 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@file pem_read.c
Read and interpret a PEM file, Steffen Jaeckel
*/
#ifdef LTC_PEM
extern const struct str pem_proc_type_encrypted;
#ifdef LTC_SSH
extern const struct str pem_ssh_comment;
#endif
extern const struct str pem_dek_info_start;
extern const struct blockcipher_info pem_dek_infos[];
extern const unsigned long pem_dek_infos_num;
#ifndef LTC_NO_FILE
int pem_get_char_from_file(struct get_char *g)
{
return getc(g->data.f);
}
#endif /* LTC_NO_FILE */
int pem_get_char_from_buf(struct get_char *g)
{
int ret;
if (g->data.buf.work == g->data.buf.end) {
return -1;
}
ret = *g->data.buf.work;
g->data.buf.work++;
return ret;
}
static void s_unget_line(char *buf, unsigned long buflen, struct get_char *g)
{
if (buflen > sizeof(g->unget_buf_))
return;
g->unget_buf.p = g->unget_buf_;
COPY_STR(g->unget_buf, buf, buflen);
}
static void s_tts(char *buf, unsigned long *buflen)
{
while(1) {
unsigned long blen = *buflen;
if (blen < 2)
return;
blen--;
switch (buf[blen]) {
case ' ':
case '\t':
buf[blen] = '\0';
*buflen = blen;
break;
default:
return;
}
}
}
static char* s_get_line(char *buf, unsigned long *buflen, struct get_char *g)
{
unsigned long blen = 0;
int c = -1, c_;
if (g->unget_buf.p) {
if (*buflen < g->unget_buf.len) {
return NULL;
}
XMEMCPY(buf, g->unget_buf.p, g->unget_buf.len);
*buflen = g->unget_buf.len;
RESET_STR(g->unget_buf);
return buf;
}
while(blen < *buflen) {
c_ = c;
c = g->get(g);
if (c == '\n') {
buf[blen] = '\0';
if (c_ == '\r') {
buf[--blen] = '\0';
}
s_tts(buf, &blen);
*buflen = blen;
return buf;
}
if (c == -1 || c == '\0') {
buf[blen] = '\0';
s_tts(buf, &blen);
*buflen = blen;
return buf;
}
buf[blen] = c;
blen++;
}
return NULL;
}
static LTC_INLINE int s_fits_buf(void *dest, unsigned long to_write, void *end)
{
unsigned char *d = dest;
unsigned char *e = end;
unsigned char *w = d + to_write;
if (w < d || w > e)
return 0;
return 1;
}
static int s_pem_decode_headers(struct pem_headers *hdr, struct get_char *g)
{
char buf[LTC_PEM_DECODE_BUFSZ], *alg_start;
unsigned long slen, tmplen, n;
int has_more_headers = hdr->id->has_more_headers == no ? 0 : 3;
/* Make sure the PEM has the appropriate extension headers if required.
*
* ```
* Proc-Type: 4,ENCRYPTED[\r]\n
* DEK-Info: <algorithm>,<IV>[\r]\n
* [\r]\n
* ```
*/
while (has_more_headers) {
slen = sizeof(buf);
if (!s_get_line(buf, &slen, g) || (has_more_headers > 1 && slen == 0)) {
return CRYPT_INVALID_PACKET;
}
switch (has_more_headers) {
case 3:
if (XMEMCMP(buf, pem_proc_type_encrypted.p, pem_proc_type_encrypted.len)) {
#ifdef LTC_SSH
if (XMEMCMP(buf, pem_ssh_comment.p, pem_ssh_comment.len))
#endif
s_unget_line(buf, slen, g);
if (hdr->id->has_more_headers == maybe)
return CRYPT_OK;
else
return CRYPT_INVALID_PACKET;
}
hdr->encrypted = 1;
break;
case 2:
hdr->info.algo = NULL;
if (XMEMCMP(buf, pem_dek_info_start.p, pem_dek_info_start.len))
return CRYPT_INVALID_PACKET;
alg_start = &buf[pem_dek_info_start.len];
for (n = 0; n < pem_dek_infos_num; ++n) {
unsigned long namelen = XSTRLEN(pem_dek_infos[n].name);
if (slen >= namelen + pem_dek_info_start.len && !XMEMCMP(alg_start, pem_dek_infos[n].name, namelen)) {
char *iv = alg_start + namelen;
hdr->info = pem_dek_infos[n];
tmplen = XSTRLEN(iv);
if (tmplen > sizeof(hdr->info.iv))
return CRYPT_INVALID_KEYSIZE;
XMEMCPY(hdr->info.iv, iv, tmplen);
break;
}
}
if (hdr->info.algo == NULL) {
return CRYPT_INVALID_CIPHER;
}
break;
case 1:
/* Make sure that there's an empty line in between */
if (buf[0] != '\0')
return CRYPT_INVALID_PACKET;
break;
default:
return CRYPT_INVALID_CIPHER;
}
has_more_headers--;
}
return CRYPT_OK;
}
int pem_read(void *pem, unsigned long *w, struct pem_headers *hdr, struct get_char *g)
{
char buf[LTC_PEM_DECODE_BUFSZ];
char *wpem = pem;
char *end = wpem + *w;
unsigned long slen, linelen;
int err, hdr_ok = 0;
int would_overflow = 0;
unsigned char empty_lines = 0;
linelen = sizeof(buf);
if (s_get_line(buf, &linelen, g) == NULL) {
return CRYPT_INVALID_PACKET;
}
if (hdr->id->start.len != linelen || XMEMCMP(buf, hdr->id->start.p, hdr->id->start.len)) {
s_unget_line(buf, linelen, g);
return CRYPT_UNKNOWN_PEM;
}
hdr->encrypted = hdr->id->flags & pf_encrypted;
if ((err = s_pem_decode_headers(hdr, g)) != CRYPT_OK)
return err;
/* Read the base64 encoded part of the PEM */
slen = sizeof(buf);
while (s_get_line(buf, &slen, g)) {
if (slen == hdr->id->end.len && !XMEMCMP(buf, hdr->id->end.p, slen)) {
hdr_ok = 1;
break;
}
if (!slen) {
if (empty_lines)
break;
empty_lines++;
}
if (!would_overflow && s_fits_buf(wpem, slen, end)) {
XMEMCPY(wpem, buf, slen);
} else {
would_overflow = 1;
}
wpem += slen;
slen = sizeof(buf);
}
if (!hdr_ok)
return CRYPT_INVALID_PACKET;
if (would_overflow || !s_fits_buf(wpem, 1, end)) {
/* NUL termination */
wpem++;
/* prevent a wrap-around */
if (wpem < (char*)pem)
return CRYPT_OVERFLOW;
*w = wpem - (char*)pem;
return CRYPT_BUFFER_OVERFLOW;
}
*w = wpem - (char*)pem;
*wpem++ = '\0';
if ((err = base64_strict_decode(pem, *w, pem, w)) != CRYPT_OK) {
return err;
}
return CRYPT_OK;
}
#endif /* LTC_PEM */

855
deps/libtomcrypt/src/misc/pem/pem_ssh.c vendored Normal file
View File

@ -0,0 +1,855 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@file pem_ssh.c
SSH specific functionality to process PEM files, Steffen Jaeckel
The basic format of the key is described here:
https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.key
*/
#if defined(LTC_PEM_SSH)
/* Table as of
* https://www.iana.org/assignments/ssh-parameters/ssh-parameters.xhtml#ssh-parameters-17
*/
const struct blockcipher_info ssh_ciphers[] =
{
{ .name = "none", .algo = "", .keylen = 0, .mode = cm_none },
{ .name = "aes128-cbc", .algo = "aes", .keylen = 128 / 8, .mode = cm_cbc },
{ .name = "aes128-ctr", .algo = "aes", .keylen = 128 / 8, .mode = cm_ctr },
{ .name = "aes192-cbc", .algo = "aes", .keylen = 192 / 8, .mode = cm_cbc },
{ .name = "aes192-ctr", .algo = "aes", .keylen = 192 / 8, .mode = cm_ctr },
{ .name = "aes256-cbc", .algo = "aes", .keylen = 256 / 8, .mode = cm_cbc },
{ .name = "aes256-ctr", .algo = "aes", .keylen = 256 / 8, .mode = cm_ctr },
{ .name = "aes128-gcm@openssh.com", .algo = "aes", .keylen = 128 / 8, .mode = cm_gcm },
{ .name = "aes256-gcm@openssh.com", .algo = "aes", .keylen = 256 / 8, .mode = cm_gcm },
{ .name = "blowfish128-cbc", .algo = "blowfish", .keylen = 128 / 8, .mode = cm_cbc },
{ .name = "blowfish128-ctr", .algo = "blowfish", .keylen = 128 / 8, .mode = cm_ctr },
/* The algo name doesn't matter, it's only used in pem-info */
{ .name = "chacha20-poly1305@openssh.com", .algo = "c20p1305", .keylen = 256 / 8, .mode = cm_stream | cm_openssh },
{ .name = "des-cbc", .algo = "des", .keylen = 64 / 8, .mode = cm_cbc },
{ .name = "3des-cbc", .algo = "3des", .keylen = 192 / 8, .mode = cm_cbc },
{ .name = "3des-ctr", .algo = "3des", .keylen = 192 / 8, .mode = cm_ctr },
{ .name = "serpent128-cbc", .algo = "serpent", .keylen = 128 / 8, .mode = cm_cbc },
{ .name = "serpent128-ctr", .algo = "serpent", .keylen = 128 / 8, .mode = cm_ctr },
{ .name = "serpent192-cbc", .algo = "serpent", .keylen = 192 / 8, .mode = cm_cbc },
{ .name = "serpent192-ctr", .algo = "serpent", .keylen = 192 / 8, .mode = cm_ctr },
{ .name = "serpent256-cbc", .algo = "serpent", .keylen = 256 / 8, .mode = cm_cbc },
{ .name = "serpent256-ctr", .algo = "serpent", .keylen = 256 / 8, .mode = cm_ctr },
{ .name = "twofish128-cbc", .algo = "twofish", .keylen = 128 / 8, .mode = cm_cbc },
{ .name = "twofish128-ctr", .algo = "twofish", .keylen = 128 / 8, .mode = cm_ctr },
{ .name = "twofish192-cbc", .algo = "twofish", .keylen = 192 / 8, .mode = cm_cbc },
{ .name = "twofish192-ctr", .algo = "twofish", .keylen = 192 / 8, .mode = cm_ctr },
{ .name = "twofish-cbc", .algo = "twofish", .keylen = 256 / 8, .mode = cm_cbc },
{ .name = "twofish256-cbc", .algo = "twofish", .keylen = 256 / 8, .mode = cm_cbc },
{ .name = "twofish256-ctr", .algo = "twofish", .keylen = 256 / 8, .mode = cm_ctr },
};
const unsigned long ssh_ciphers_num = sizeof(ssh_ciphers)/sizeof(ssh_ciphers[0]);
struct kdf_options {
const char *name;
const struct blockcipher_info *cipher;
unsigned char salt[64];
unsigned long saltlen;
ulong32 num_rounds;
struct password pw;
};
#ifdef LTC_MECC
static int s_ssh_find_ecc(const char *pka, const ltc_ecc_curve **curve)
{
int err;
const char* prefix = "ecdsa-sha2-";
unsigned long prefixlen = XSTRLEN(prefix);
if (strstr(pka, prefix) == NULL) return CRYPT_PK_INVALID_TYPE;
if ((err = ecc_find_curve(pka + prefixlen, curve)) != CRYPT_OK) return err;
return CRYPT_OK;
}
static int s_ssh_find_init_ecc(const char *pka, ltc_pka_key *key)
{
int err;
const ltc_ecc_curve *cu;
if ((err = s_ssh_find_ecc(pka, &cu)) != CRYPT_OK) return err;
return ecc_set_curve(cu, &key->u.ecc);
}
static int s_ssh_decode_ecdsa(const unsigned char *in, unsigned long *inlen, ltc_pka_key *pka_key, enum pem_flags type)
{
int err;
unsigned char groupname[64], buf0[512], buf1[512];
unsigned long groupnamelen = sizeof(groupname), buf0len = sizeof(buf0), buf1len = sizeof(buf1);
unsigned long remaining, cur_len, keylen;
const unsigned char *p, *key;
p = in;
cur_len = *inlen;
remaining = *inlen;
err = ssh_decode_sequence_multi(p, &cur_len,
LTC_SSHDATA_STRING, groupname, &groupnamelen,
LTC_SSHDATA_STRING, buf0, &buf0len,
LTC_SSHDATA_STRING, buf1, &buf1len,
LTC_SSHDATA_EOL, NULL);
if (err == CRYPT_OK) {
key = buf1;
keylen = buf1len;
} else if (err == CRYPT_BUFFER_OVERFLOW && buf0len != sizeof(buf0) && buf1len == sizeof(buf1)) {
key = buf0;
keylen = buf0len;
} else {
goto cleanup;
}
remaining -= cur_len;
cur_len = remaining;
err = ecc_set_key(key, keylen, type == pf_public ? PK_PUBLIC : PK_PRIVATE, &pka_key->u.ecc);
cleanup:
zeromem(groupname, sizeof(groupname));
zeromem(buf0, sizeof(buf0));
zeromem(buf1, sizeof(buf1));
if (err == CRYPT_OK) {
pka_key->id = LTC_PKA_EC;
*inlen -= remaining;
}
return err;
}
#endif
#ifdef LTC_CURVE25519
static int s_ssh_decode_ed25519(const unsigned char *in, unsigned long *inlen, ltc_pka_key *key, enum pem_flags type)
{
int err;
unsigned char pubkey[64], privkey[96];
unsigned long pubkeylen = sizeof(pubkey), privkeylen = sizeof(privkey);
unsigned long remaining, cur_len;
const unsigned char *p;
p = in;
cur_len = *inlen;
remaining = *inlen;
if ((err = ssh_decode_sequence_multi(p, &cur_len,
LTC_SSHDATA_STRING, pubkey, &pubkeylen,
LTC_SSHDATA_EOL, NULL)) != CRYPT_OK) {
goto cleanup;
}
if (type == pf_public) {
if ((err = ed25519_import_raw(pubkey, pubkeylen, PK_PUBLIC, &key->u.ed25519)) != CRYPT_OK) {
goto cleanup;
}
key->id = LTC_PKA_ED25519;
goto cleanup;
}
p += cur_len;
remaining -= cur_len;
cur_len = remaining;
if ((err = ssh_decode_sequence_multi(p, &cur_len,
LTC_SSHDATA_STRING, privkey, &privkeylen,
LTC_SSHDATA_EOL, NULL)) != CRYPT_OK) {
goto cleanup;
}
if ((err = ed25519_import_raw(privkey, privkeylen, PK_PRIVATE, &key->u.ed25519)) != CRYPT_OK) {
goto cleanup;
}
key->id = LTC_PKA_ED25519;
cleanup:
zeromem(pubkey, sizeof(pubkey));
zeromem(privkey, sizeof(privkey));
if (err == CRYPT_OK) {
remaining -= cur_len;
*inlen -= remaining;
}
return err;
}
#endif
#ifdef LTC_MRSA
static int s_ssh_decode_dsa(const unsigned char *in, unsigned long *inlen, ltc_pka_key *key, enum pem_flags type)
{
int err, stat;
unsigned long remaining, cur_len;
const unsigned char *p;
if ((err = dsa_int_init(&key->u.dsa)) != CRYPT_OK) {
return err;
}
p = in;
cur_len = *inlen;
remaining = *inlen;
if ((err = ssh_decode_sequence_multi(p, &cur_len,
LTC_SSHDATA_MPINT, key->u.dsa.p,
LTC_SSHDATA_MPINT, key->u.dsa.q,
LTC_SSHDATA_MPINT, key->u.dsa.g,
LTC_SSHDATA_MPINT, key->u.dsa.y,
LTC_SSHDATA_EOL, NULL)) != CRYPT_OK) {
goto cleanup;
}
key->u.dsa.qord = mp_unsigned_bin_size(key->u.dsa.q);
if ((err = dsa_int_validate_pqg(&key->u.dsa, &stat)) != CRYPT_OK) {
goto cleanup;
}
if (stat == 0) {
err = CRYPT_INVALID_PACKET;
goto cleanup;
}
if (type == pf_public) {
key->id = LTC_PKA_DSA;
key->u.dsa.type = PK_PUBLIC;
goto cleanup;
}
p += cur_len;
remaining -= cur_len;
cur_len = remaining;
if ((err = ssh_decode_sequence_multi(p, &cur_len,
LTC_SSHDATA_MPINT, key->u.dsa.x,
LTC_SSHDATA_EOL, NULL)) != CRYPT_OK) {
goto cleanup;
}
key->id = LTC_PKA_DSA;
key->u.dsa.type = PK_PRIVATE;
cleanup:
if (err != CRYPT_OK) {
dsa_free(&key->u.dsa);
} else {
remaining -= cur_len;
*inlen -= remaining;
}
return err;
}
#endif
#ifdef LTC_MRSA
static int s_ssh_decode_rsa(const unsigned char *in, unsigned long *inlen, ltc_pka_key *key, enum pem_flags type)
{
int err;
void *tmp1, *tmp2;
unsigned long remaining, cur_len;
const unsigned char *p;
if ((err = rsa_init(&key->u.rsa)) != CRYPT_OK) {
return err;
}
p = in;
cur_len = *inlen;
remaining = *inlen;
/* ssh-rsa public and private keys contain `e` and `N` in a different order
* public contains `e`, then `N`
* private contains `N`, then `e`
* change the order later on if we import a public key */
if ((err = ssh_decode_sequence_multi(p, &cur_len,
LTC_SSHDATA_MPINT, key->u.rsa.N,
LTC_SSHDATA_MPINT, key->u.rsa.e,
LTC_SSHDATA_EOL, NULL)) != CRYPT_OK) {
goto cleanup;
}
p += cur_len;
remaining -= cur_len;
cur_len = remaining;
if (type == pf_public) {
/* c.f. comment above */
void *exch = key->u.rsa.N;
key->u.rsa.N = key->u.rsa.e;
key->u.rsa.e = exch;
key->id = LTC_PKA_RSA;
key->u.rsa.type = PK_PUBLIC;
*inlen -= remaining;
goto cleanup;
}
if ((err = mp_init_multi(&tmp1, &tmp2, NULL)) != CRYPT_OK) {
goto cleanup;
}
if ((err = ssh_decode_sequence_multi(p, &cur_len,
LTC_SSHDATA_MPINT, key->u.rsa.d,
LTC_SSHDATA_MPINT, key->u.rsa.qP,
LTC_SSHDATA_MPINT, key->u.rsa.p,
LTC_SSHDATA_MPINT, key->u.rsa.q,
LTC_SSHDATA_EOL, NULL)) != CRYPT_OK) {
goto cleanup_tmps;
}
if ((err = mp_sub_d(key->u.rsa.p, 1, tmp1)) != CRYPT_OK) { goto cleanup_tmps; } /* tmp1 = q-1 */
if ((err = mp_sub_d(key->u.rsa.q, 1, tmp2)) != CRYPT_OK) { goto cleanup_tmps; } /* tmp2 = p-1 */
if ((err = mp_mod(key->u.rsa.d, tmp1, key->u.rsa.dP)) != CRYPT_OK) { goto cleanup_tmps; } /* dP = d mod p-1 */
if ((err = mp_mod(key->u.rsa.d, tmp2, key->u.rsa.dQ)) != CRYPT_OK) { goto cleanup_tmps; } /* dQ = d mod q-1 */
key->id = LTC_PKA_RSA;
key->u.rsa.type = PK_PRIVATE;
cleanup_tmps:
mp_clear_multi(tmp2, tmp1, NULL);
cleanup:
if (err != CRYPT_OK) {
rsa_free(&key->u.rsa);
} else {
remaining -= cur_len;
*inlen -= remaining;
}
return err;
}
#endif
struct ssh_pka {
struct str name;
enum ltc_pka_id id;
int (*find)(const char*, const ltc_ecc_curve **);
int (*init)(const char*, ltc_pka_key*);
int (*decode)(const unsigned char*, unsigned long*, ltc_pka_key*, enum pem_flags);
};
struct ssh_pka ssh_pkas[] = {
#ifdef LTC_CURVE25519
{ SET_CSTR(.name, "ssh-ed25519"),
LTC_PKA_ED25519,
NULL,
NULL,
s_ssh_decode_ed25519 },
#endif
#ifdef LTC_MRSA
{ SET_CSTR(.name, "ssh-rsa"),
LTC_PKA_RSA,
NULL,
NULL,
s_ssh_decode_rsa },
#endif
#ifdef LTC_MDSA
{ SET_CSTR(.name, "ssh-dss"),
LTC_PKA_DSA,
NULL,
NULL,
s_ssh_decode_dsa },
#endif
#ifdef LTC_MECC
{ { NULL, 0 },
LTC_PKA_EC,
s_ssh_find_ecc,
s_ssh_find_init_ecc,
s_ssh_decode_ecdsa },
#endif
};
static int s_decode_key(const unsigned char *in, unsigned long *inlen, ltc_pka_key *key, char **comment, enum pem_flags type)
{
int err;
ulong32 check1, check2;
unsigned char pka[64];
unsigned long pkalen = sizeof(pka);
unsigned long remaining, cur_len;
const unsigned char *p;
unsigned long n;
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(inlen != NULL);
LTC_ARGCHK(key != NULL);
p = in;
cur_len = *inlen;
remaining = *inlen;
if (type != pf_public) {
if ((err = ssh_decode_sequence_multi(p, &cur_len,
LTC_SSHDATA_UINT32, &check1,
LTC_SSHDATA_UINT32, &check2,
LTC_SSHDATA_EOL, NULL)) != CRYPT_OK) {
return err;
}
if (check1 != check2) {
return CRYPT_INVALID_PACKET;
}
p += cur_len;
remaining -= cur_len;
cur_len = remaining;
}
if ((err = ssh_decode_sequence_multi(p, &cur_len,
LTC_SSHDATA_STRING, pka, &pkalen,
LTC_SSHDATA_EOL, NULL)) != CRYPT_OK) {
return err;
}
p += cur_len;
remaining -= cur_len;
cur_len = remaining;
for (n = 0; n < sizeof(ssh_pkas)/sizeof(ssh_pkas[0]); ++n) {
if (ssh_pkas[n].name.p != NULL) {
if (pkalen != ssh_pkas[n].name.len
|| XMEMCMP(pka, ssh_pkas[n].name.p, ssh_pkas[n].name.len) != 0) continue;
} else {
if ((ssh_pkas[n].init == NULL) ||
(ssh_pkas[n].init((char*)pka, key) != CRYPT_OK)) continue;
}
if ((err = ssh_pkas[n].decode(p, &cur_len, key, type)) != CRYPT_OK) {
return err;
}
break;
}
if (n == sizeof(ssh_pkas)/sizeof(ssh_pkas[0])) {
return CRYPT_PK_INVALID_TYPE;
}
p += cur_len;
remaining -= cur_len;
cur_len = remaining;
if (cur_len != 0 && comment) {
unsigned long commentlen = cur_len;
char *c = XMALLOC(commentlen);
if (c == NULL) {
return CRYPT_MEM;
}
if ((err = ssh_decode_sequence_multi(p, &cur_len,
LTC_SSHDATA_STRING, c, &commentlen,
LTC_SSHDATA_EOL, NULL)) != CRYPT_OK) {
return err;
}
if (commentlen == 0) {
XFREE(c);
} else {
*comment = c;
}
}
p += cur_len;
remaining -= cur_len;
return remaining ? padding_depad(p, &remaining, LTC_PAD_SSH) : CRYPT_OK;
}
static LTC_INLINE void skip_spaces(char **r, unsigned long *l)
{
while(*l && (**r == ' ' || **r == '\t')) {
(*r)++;
(*l)--;
}
}
static LTC_INLINE void skip_chars(char **r, unsigned long *l)
{
while(*l && (**r != ' ' && **r != '\t')) {
(*l)--;
if (**r == '\n' || **r == '\r') {
*l = 0;
} else {
(*r)++;
}
}
}
static LTC_INLINE void skip_to_eol(char **r, unsigned long *l)
{
while(*l && (**r != '\n' && **r != '\r')) {
(*l)--;
(*r)++;
}
}
static int s_parse_line(char *line, unsigned long *len, ltc_pka_key *key, char **comment)
{
int err;
unsigned long n, rlen, olen;
enum authorized_keys_elements {
ake_algo_name = 0,
ake_b64_encoded_key = 1,
ake_comment = 2
};
struct str elements[3] = { 0 };
char *r = line;
unsigned char *buf = NULL;
rlen = *len;
/* Chop up string into the three authorized_keys_elements */
for (n = 0; n < sizeof(elements)/sizeof(elements[0]) && rlen; ++n) {
skip_spaces(&r, &rlen);
elements[n].p = r;
if (n != 2)
skip_chars(&r, &rlen);
else
skip_to_eol(&r, &rlen);
elements[n].len = r - elements[n].p;
*r = '\0';
r++;
}
for (n = 0; n < sizeof(ssh_pkas)/sizeof(ssh_pkas[0]); ++n) {
if (ssh_pkas[n].name.p != NULL) {
if (elements[ake_algo_name].len != ssh_pkas[n].name.len
|| XMEMCMP(elements[ake_algo_name].p, ssh_pkas[n].name.p, ssh_pkas[n].name.len) != 0) continue;
} else {
if ((ssh_pkas[n].find == NULL) ||
(ssh_pkas[n].find(elements[ake_algo_name].p, NULL) != CRYPT_OK)) continue;
}
olen = elements[ake_b64_encoded_key].len;
buf = XMALLOC(olen);
if (buf == NULL) {
return CRYPT_MEM;
}
if ((err = base64_strict_decode(elements[ake_b64_encoded_key].p, elements[ake_b64_encoded_key].len, buf, &olen)) == CRYPT_OK) {
err = s_decode_key(buf, &olen, key, comment, pf_public);
if (err == CRYPT_OK && key->id != ssh_pkas[n].id) {
err = CRYPT_PK_INVALID_TYPE;
}
}
XFREE(buf);
if (err == CRYPT_OK) {
/* Only use the comment that was maybe in the text we just processed, in case when
* there was no comment inside the SSH key.
*/
if (*comment == NULL && elements[ake_comment].p) {
*comment = XMALLOC(elements[ake_comment].len + 1);
if (*comment == NULL) {
return CRYPT_MEM;
}
XMEMCPY(*comment, elements[ake_comment].p, elements[ake_comment].len);
(*comment)[elements[ake_comment].len] = '\0';
}
*len = r - line;
return CRYPT_OK;
}
}
return CRYPT_PK_INVALID_TYPE;
}
static int s_read_authorized_keys(const void *buf, unsigned long len, ssh_authorized_key_cb cb, void *ctx)
{
char *s;
int err;
unsigned long clen = len;
ltc_pka_key *key = XCALLOC(1, sizeof(*key));
char *comment = NULL;
void *cpy = XMALLOC(len);
if (key == NULL || cpy == NULL) {
if (cpy)
XFREE(cpy);
if (key)
XFREE(key);
return CRYPT_MEM;
}
XMEMCPY(cpy, buf, len);
s = cpy;
while (clen && (err = s_parse_line(s, &clen, key, &comment)) == CRYPT_OK) {
if (cb(key, comment, ctx)) {
break;
}
s += clen;
len -= clen;
clen = len;
key = XCALLOC(1, sizeof(*key));
if (key == NULL) {
err = CRYPT_MEM;
break;
}
if (comment) {
XFREE(comment);
comment = NULL;
}
}
if (comment)
XFREE(comment);
if (cpy)
XFREE(cpy);
if (key)
XFREE(key);
return err;
}
static int s_decrypt_private_keys(unsigned char *in, unsigned long *inlen,
unsigned char *tag, unsigned long taglen,
struct kdf_options *opts)
{
int err, cipher;
unsigned long symkey_len, iv_len;
unsigned char symkey[MAXBLOCKSIZE], *iv, iv_[8] = { 0 };
enum cipher_mode mode = opts->cipher->mode & cm_modes;
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(inlen != NULL);
LTC_ARGCHK(opts != NULL);
if (mode != cm_stream) {
cipher = find_cipher(opts->cipher->algo);
if (cipher == -1) {
return CRYPT_INVALID_CIPHER;
}
iv = symkey + opts->cipher->keylen;
iv_len = mode == cm_gcm ? 12 : cipher_descriptor[cipher].block_length;
symkey_len = opts->cipher->keylen + iv_len;
} else {
iv = iv_;
iv_len = sizeof(iv_);
symkey_len = 64;
}
if (sizeof(symkey) < symkey_len) {
return CRYPT_OVERFLOW;
}
if ((err = bcrypt_pbkdf_openbsd(opts->pw.pw, opts->pw.l, opts->salt, opts->saltlen,
opts->num_rounds, find_hash("sha512"), symkey, &symkey_len)) != CRYPT_OK) {
return err;
}
err = pem_decrypt(in, inlen,
symkey, opts->cipher->keylen,
iv, iv_len,
tag, taglen,
opts->cipher, LTC_PAD_SSH);
zeromem(symkey, sizeof(symkey));
return err;
}
static int s_decode_header(unsigned char *in, unsigned long *inlen, struct kdf_options *opts)
{
int err;
unsigned char ciphername[64], kdfname[64], kdfoptions[128], pubkey1[2048];
unsigned long ciphernamelen = sizeof(ciphername), kdfnamelen = sizeof(kdfname);
unsigned long kdfoptionslen = sizeof(kdfoptions), pubkey1len = sizeof(pubkey1);
ulong32 num_keys;
unsigned long i;
void *magic = strstr((const char*)in, "openssh-key-v1");
unsigned long slen = XSTRLEN("openssh-key-v1");
unsigned char *start = &in[slen + 1];
unsigned long len = *inlen - slen - 1;
if (magic == NULL || magic != in) {
return CRYPT_INVALID_PACKET;
}
if ((err = ssh_decode_sequence_multi(start, &len,
LTC_SSHDATA_STRING, ciphername, &ciphernamelen,
LTC_SSHDATA_STRING, kdfname, &kdfnamelen,
LTC_SSHDATA_STRING, kdfoptions, &kdfoptionslen,
LTC_SSHDATA_UINT32, &num_keys,
LTC_SSHDATA_STRING, pubkey1, &pubkey1len,
LTC_SSHDATA_EOL, NULL)) != CRYPT_OK) {
return err;
}
if (num_keys != 1) {
return CRYPT_INVALID_PACKET;
}
*inlen = len + slen + 1;
for (i = 0; i < ssh_ciphers_num; ++i) {
if (XSTRCMP((char*)ciphername, ssh_ciphers[i].name) == 0) {
opts->cipher = &ssh_ciphers[i];
break;
}
}
if (opts->cipher == NULL) {
return CRYPT_INVALID_CIPHER;
}
if (XSTRCMP((char*)kdfname, "none") == 0) {
/* NOP */
opts->name = "none";
} else if (XSTRCMP((char*)kdfname, "bcrypt") == 0) {
opts->name = "bcrypt";
opts->saltlen = sizeof(opts->salt);
len = kdfoptionslen;
if ((err = ssh_decode_sequence_multi(kdfoptions, &len,
LTC_SSHDATA_STRING, opts->salt, &opts->saltlen,
LTC_SSHDATA_UINT32, &opts->num_rounds,
LTC_SSHDATA_EOL, NULL)) != CRYPT_OK) {
return err;
}
if (len != kdfoptionslen) {
return CRYPT_INPUT_TOO_LONG;
}
} else {
return CRYPT_INVALID_PACKET;
}
return err;
}
static const struct pem_header_id pem_openssh[] = {
{
SET_CSTR(.start, "-----BEGIN OPENSSH PRIVATE KEY-----"),
SET_CSTR(.end, "-----END OPENSSH PRIVATE KEY-----"),
.has_more_headers = no
},
{
SET_CSTR(.start, "---- BEGIN SSH2 PUBLIC KEY ----"),
SET_CSTR(.end, "---- END SSH2 PUBLIC KEY ----"),
.has_more_headers = maybe,
.flags = pf_public
},
};
static const unsigned long pem_openssh_num = sizeof(pem_openssh)/sizeof(pem_openssh[0]);
static int s_decode_openssh(struct get_char *g, ltc_pka_key *k, const password_ctx *pw_ctx)
{
unsigned char *pem = NULL, *p, *privkey = NULL, *tag;
unsigned long n, w, l, privkey_len, taglen;
int err;
struct pem_headers hdr;
struct kdf_options opts = { 0 };
XMEMSET(k, 0, sizeof(*k));
w = LTC_PEM_READ_BUFSIZE * 2;
retry:
pem = XREALLOC(pem, w);
for (n = 0; n < pem_openssh_num; ++n) {
hdr.id = &pem_openssh[n];
err = pem_read(pem, &w, &hdr, g);
if (err == CRYPT_BUFFER_OVERFLOW) {
goto retry;
} else if (err == CRYPT_OK) {
break;
} else if (err != CRYPT_UNKNOWN_PEM) {
goto cleanup;
}
hdr.id = NULL;
}
/* id not found */
if (hdr.id == NULL) {
goto cleanup;
}
p = pem;
l = w;
if (hdr.id->flags != pf_public) {
if ((err = s_decode_header(pem, &w, &opts)) != CRYPT_OK) {
goto cleanup;
}
p = pem + w;
l -= w;
w = l;
privkey_len = l;
privkey = XMALLOC(privkey_len);
if (privkey == NULL) {
return CRYPT_MEM;
}
if ((err = ssh_decode_sequence_multi(p, &w,
LTC_SSHDATA_STRING, privkey, &privkey_len,
LTC_SSHDATA_EOL, NULL)) != CRYPT_OK) {
goto cleanup;
}
if (XSTRCMP(opts.name, "none") != 0) {
if ((pw_ctx == NULL) || (pw_ctx->callback == NULL)) {
err = CRYPT_PW_CTX_MISSING;
goto cleanup;
}
if (pw_ctx->callback(&opts.pw.pw, &opts.pw.l, pw_ctx->userdata)) {
err = CRYPT_ERROR;
goto cleanup;
}
tag = p + w;
taglen = l - w;
w = privkey_len;
if ((err = s_decrypt_private_keys(privkey, &privkey_len,
tag, taglen,
&opts)) != CRYPT_OK) {
goto cleanup;
}
zeromem(opts.pw.pw, opts.pw.l);
}
p = privkey;
w = privkey_len;
}
if ((err = s_decode_key(p, &w, k, NULL, hdr.id->flags)) != CRYPT_OK) {
goto cleanup;
}
cleanup:
password_free(&opts.pw, pw_ctx);
if (privkey) {
zeromem(privkey, privkey_len);
XFREE(privkey);
}
XFREE(pem);
return err;
}
#ifndef LTC_NO_FILE
int pem_decode_openssh_filehandle(FILE *f, ltc_pka_key *k, const password_ctx *pw_ctx)
{
LTC_ARGCHK(f != NULL);
LTC_ARGCHK(k != NULL);
{
struct get_char g = { .get = pem_get_char_from_file, .data.f = f };
return s_decode_openssh(&g, k, pw_ctx);
}
}
int ssh_read_authorized_keys_filehandle(FILE *f, ssh_authorized_key_cb cb, void *ctx)
{
size_t tot_data;
void *buf;
int err;
LTC_ARGCHK(f != NULL);
LTC_ARGCHK(cb != NULL);
fseek(f, 0, SEEK_END);
tot_data = ftell(f);
rewind(f);
buf = XMALLOC(tot_data);
if (buf == NULL) {
return CRYPT_MEM;
}
if (fread(buf, 1, tot_data, f) != tot_data) {
err = CRYPT_ERROR;
} else {
err = s_read_authorized_keys(buf, tot_data, cb, ctx);
}
XFREE(buf);
return err;
}
#endif /* LTC_NO_FILE */
int pem_decode_openssh(const void *buf, unsigned long len, ltc_pka_key *k, const password_ctx *pw_ctx)
{
LTC_ARGCHK(buf != NULL);
LTC_ARGCHK(len != 0);
LTC_ARGCHK(k != NULL);
{
struct get_char g = { .get = pem_get_char_from_buf, SET_BUFP(.data.buf, buf, len) };
return s_decode_openssh(&g, k, pw_ctx);
}
}
int ssh_read_authorized_keys(const void *buf, unsigned long len, ssh_authorized_key_cb cb, void *ctx)
{
LTC_ARGCHK(buf != NULL);
LTC_ARGCHK(len != 0);
LTC_ARGCHK(cb != NULL);
return s_read_authorized_keys(buf, len, cb, ctx);
}
#endif /* defined(LTC_PEM_SSH) */

View File

@ -1,7 +1,6 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
#include <stdarg.h>
/**
@file ssh_decode_sequence_multi.c
@ -142,7 +141,7 @@ int ssh_decode_sequence_multi(const unsigned char *in, unsigned long *inlen, ...
err = CRYPT_INVALID_PACKET;
goto error;
} else {
if ((err = mp_read_unsigned_bin(vdata, (unsigned char *)in, size)) != CRYPT_OK) { goto error; }
if ((err = mp_read_unsigned_bin(vdata, in, size)) != CRYPT_OK) { goto error; }
}
in += size;
break;

View File

@ -1,7 +1,6 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
#include <stdarg.h>
/**
@file ssh_encode_sequence_multi.c

View File

@ -9,6 +9,28 @@
#ifdef LTC_CFB_MODE
static LTC_INLINE void s_shift1left_64(unsigned char *b, unsigned char v)
{
ulong64 bval;
LOAD64H(bval, b);
bval <<= 1;
bval |= v & 0x01u;
STORE64H(bval, b);
}
static LTC_INLINE void s_shift1left_128(unsigned char *b, unsigned char v)
{
ulong64 bval[2];
LOAD64H(bval[0], b);
LOAD64H(bval[1], b + 8);
bval[0] <<= 1;
bval[0] |= (bval[1] >> 63) & 0x01u;
bval[1] <<= 1;
bval[1] |= v & 0x01u;
STORE64H(bval[0], b);
STORE64H(bval[1], b + 8);
}
/**
CFB decrypt
@param ct Ciphertext
@ -20,11 +42,18 @@
int cfb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CFB *cfb)
{
int err;
ulong64 bitlen = len * 8, bits_per_round;
unsigned int cur_bit = 0;
unsigned char pt_ = 0, ct_ = 0;
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(cfb != NULL);
if (bitlen < len) {
return CRYPT_OVERFLOW;
}
if ((err = cipher_is_valid(cfb->cipher)) != CRYPT_OK) {
return err;
}
@ -35,18 +64,51 @@ int cfb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, s
return CRYPT_INVALID_ARG;
}
while (len-- > 0) {
bits_per_round = cfb->width == 1 ? 1 : 8;
while (bitlen > 0) {
if (cfb->padlen == cfb->blocklen) {
if ((err = cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key)) != CRYPT_OK) {
return err;
}
cfb->padlen = 0;
}
cfb->pad[cfb->padlen] = *ct;
*pt = *ct ^ cfb->IV[cfb->padlen];
++pt;
++ct;
++(cfb->padlen);
switch (cfb->width) {
case 1:
if (cur_bit++ % 8 == 0) {
ct_ = *ct++;
pt_ = 0;
} else {
ct_ <<= 1;
pt_ <<= 1;
}
if (cfb->blocklen == 16)
s_shift1left_128(cfb->pad, ct_ >> 7);
else
s_shift1left_64(cfb->pad, ct_ >> 7);
pt_ |= ((ct_ ^ cfb->IV[0]) >> 7) & 0x01u;
cfb->padlen = cfb->blocklen;
if (cur_bit % 8 == 0) {
*pt++ = pt_;
cur_bit = 0;
}
break;
case 8:
XMEMMOVE(cfb->pad, cfb->pad + 1, cfb->blocklen - 1);
cfb->pad[cfb->blocklen - 1] = *ct;
*pt++ = *ct++ ^ cfb->IV[0];
cfb->padlen = cfb->blocklen;
break;
case 64:
case 128:
cfb->pad[cfb->padlen] = *ct;
*pt++ = *ct++ ^ cfb->IV[cfb->padlen];
++(cfb->padlen);
break;
default:
return CRYPT_INVALID_ARG;
}
bitlen -= bits_per_round;
}
return CRYPT_OK;
}

View File

@ -9,6 +9,28 @@
#ifdef LTC_CFB_MODE
static LTC_INLINE void s_shift1left_64(unsigned char *b, unsigned char v)
{
ulong64 bval;
LOAD64H(bval, b);
bval <<= 1;
bval |= v & 0x01u;
STORE64H(bval, b);
}
static LTC_INLINE void s_shift1left_128(unsigned char *b, unsigned char v)
{
ulong64 bval[2];
LOAD64H(bval[0], b);
LOAD64H(bval[1], b + 8);
bval[0] <<= 1;
bval[0] |= (bval[1] >> 63) & 0x01u;
bval[1] <<= 1;
bval[1] |= v & 0x01u;
STORE64H(bval[0], b);
STORE64H(bval[1], b + 8);
}
/**
CFB encrypt
@param pt Plaintext
@ -20,11 +42,18 @@
int cfb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CFB *cfb)
{
int err;
ulong64 bitlen = len * 8, bits_per_round;
unsigned int cur_bit = 0;
unsigned char pt_ = 0, ct_ = 0;
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(cfb != NULL);
if (bitlen < len) {
return CRYPT_OVERFLOW;
}
if ((err = cipher_is_valid(cfb->cipher)) != CRYPT_OK) {
return err;
}
@ -35,17 +64,51 @@ int cfb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s
return CRYPT_INVALID_ARG;
}
while (len-- > 0) {
if (cfb->padlen == cfb->blocklen) {
if ((err = cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key)) != CRYPT_OK) {
return err;
}
cfb->padlen = 0;
}
cfb->pad[cfb->padlen] = (*ct = *pt ^ cfb->IV[cfb->padlen]);
++pt;
++ct;
++(cfb->padlen);
bits_per_round = cfb->width == 1 ? 1 : 8;
while (bitlen > 0) {
if (cfb->padlen == cfb->blocklen) {
if ((err = cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key)) != CRYPT_OK) {
return err;
}
cfb->padlen = 0;
}
switch (cfb->width) {
case 1:
if (cur_bit++ % 8 == 0) {
pt_ = *pt++;
ct_ = 0;
} else {
pt_ <<= 1;
ct_ <<= 1;
}
ct_ |= ((pt_ ^ cfb->IV[0]) >> 7) & 0x01u;
if (cfb->blocklen == 16)
s_shift1left_128(cfb->pad, ct_);
else
s_shift1left_64(cfb->pad, ct_);
cfb->padlen = cfb->blocklen;
if (cur_bit % 8 == 0) {
*ct++ = ct_;
cur_bit = 0;
}
break;
case 8:
XMEMMOVE(cfb->pad, cfb->pad + 1, cfb->blocklen - 1);
cfb->pad[cfb->blocklen - 1] = (*ct = *pt ^ cfb->IV[0]);
++pt;
++ct;
cfb->padlen = cfb->blocklen;
break;
case 64:
case 128:
cfb->pad[cfb->padlen] = (*ct = *pt ^ cfb->IV[cfb->padlen]);
++pt;
++ct;
++(cfb->padlen);
break;
}
bitlen -= bits_per_round;
}
return CRYPT_OK;
}

View File

@ -25,7 +25,7 @@ int cfb_getiv(unsigned char *IV, unsigned long *len, const symmetric_CFB *cfb)
*len = cfb->blocklen;
return CRYPT_BUFFER_OVERFLOW;
}
XMEMCPY(IV, cfb->IV, cfb->blocklen);
XMEMCPY(IV, cfb->pad, cfb->blocklen);
*len = cfb->blocklen;
return CRYPT_OK;

View File

@ -33,6 +33,7 @@ int cfb_setiv(const unsigned char *IV, unsigned long len, symmetric_CFB *cfb)
/* force next block */
cfb->padlen = 0;
XMEMCPY(cfb->pad, IV, len);
return cipher_descriptor[cfb->cipher].ecb_encrypt(IV, cfb->IV, &cfb->key);
}

View File

@ -10,6 +10,67 @@
#ifdef LTC_CFB_MODE
/**
Extended initialization of a CFB 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 width The width of the mode in bits (0 for default)
@param cfb The CFB state to initialize
@return CRYPT_OK if successful
*/
int cfb_start_ex(int cipher, const unsigned char *IV, const unsigned char *key,
int keylen, int num_rounds, int width, symmetric_CFB *cfb)
{
int x, err;
LTC_ARGCHK(IV != NULL);
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(cfb != NULL);
if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
return err;
}
switch (width) {
case 0:
width = cipher_descriptor[cipher].block_length * 8;
break;
case 1:
case 8:
LTC_ARGCHK(cipher_descriptor[cipher].block_length == 8
|| cipher_descriptor[cipher].block_length == 16);
break;
case 64:
case 128:
LTC_ARGCHK(width == cipher_descriptor[cipher].block_length * 8);
break;
default:
return CRYPT_INVALID_ARG;
}
/* copy data */
cfb->cipher = cipher;
cfb->width = width;
cfb->blocklen = cipher_descriptor[cipher].block_length;
for (x = 0; x < cfb->blocklen; x++) {
cfb->pad[x] = IV[x];
}
/* init the cipher */
if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &cfb->key)) != CRYPT_OK) {
return err;
}
/* encrypt the IV */
cfb->padlen = 0;
return cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key);
}
/**
Initialize a CFB context
@param cipher The index of the cipher desired
@ -23,32 +84,7 @@
int cfb_start(int cipher, const unsigned char *IV, const unsigned char *key,
int keylen, int num_rounds, symmetric_CFB *cfb)
{
int x, err;
LTC_ARGCHK(IV != NULL);
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(cfb != NULL);
if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
return err;
}
/* copy data */
cfb->cipher = cipher;
cfb->blocklen = cipher_descriptor[cipher].block_length;
for (x = 0; x < cfb->blocklen; x++) {
cfb->IV[x] = IV[x];
}
/* init the cipher */
if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &cfb->key)) != CRYPT_OK) {
return err;
}
/* encrypt the IV */
cfb->padlen = 0;
return cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->IV, cfb->IV, &cfb->key);
return cfb_start_ex(cipher, IV, key, keylen, num_rounds, 0, cfb);
}
#endif

View File

@ -268,7 +268,7 @@ static int s_der_decode_sequence_flexi(const unsigned char *in, unsigned long *i
}
l->size = len;
if ((l->data = XCALLOC(sizeof(wchar_t), l->size)) == NULL) {
if ((l->data = XCALLOC(l->size, sizeof(wchar_t))) == NULL) {
err = CRYPT_MEM;
goto error;
}

View File

@ -1,7 +1,6 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
#include <stdarg.h>
/**
@ -77,7 +76,7 @@ static int s_der_decode_sequence_va(const unsigned char *in, unsigned long inlen
return CRYPT_NOP;
}
list = XCALLOC(sizeof(*list), x);
list = XCALLOC(x, sizeof(*list));
if (list == NULL) {
return CRYPT_MEM;
}

View File

@ -1,7 +1,6 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
#include <stdarg.h>
/**
@ -80,7 +79,7 @@ int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...)
return CRYPT_NOP;
}
list = XCALLOC(sizeof(*list), x);
list = XCALLOC(x, sizeof(*list));
if (list == NULL) {
return CRYPT_MEM;
}

View File

@ -0,0 +1,38 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@file der_length_sequence.c
ASN.1 DER, length a SEQUENCE, Tom St Denis
*/
#ifdef LTC_DER
/**
Get the length of a DER sequence
@param list The sequences of items in the SEQUENCE
@param inlen The number of items
@param outlen [out] The length required in octets to store it
@return CRYPT_OK on success
*/
int der_flexi_sequence_cmp(const ltc_asn1_list *flexi, der_flexi_check *check)
{
ltc_asn1_list *cur;
if (flexi->type != LTC_ASN1_SEQUENCE) {
return CRYPT_INVALID_PACKET;
}
cur = flexi->child;
while(check->t != LTC_ASN1_EOL) {
if (!LTC_ASN1_IS_TYPE(cur, check->t)) {
return CRYPT_INVALID_PACKET;
}
if (check->pp != NULL) *check->pp = cur;
cur = cur->next;
check++;
}
return CRYPT_OK;
}
#endif

View File

@ -0,0 +1,106 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
#ifdef LTC_DER
typedef struct {
enum ltc_oid_id id;
enum ltc_pka_id pka;
const char* oid;
} oid_table_entry;
static const oid_table_entry pka_oids[] = {
{ LTC_OID_UNDEF, LTC_PKA_UNDEF, NULL },
{ LTC_OID_RSA, LTC_PKA_RSA, "1.2.840.113549.1.1.1" },
{ LTC_OID_DSA, LTC_PKA_DSA, "1.2.840.10040.4.1" },
{ LTC_OID_EC, LTC_PKA_EC, "1.2.840.10045.2.1" },
{ LTC_OID_EC_PRIMEF, LTC_PKA_EC, "1.2.840.10045.1.1" },
{ LTC_OID_X25519, LTC_PKA_X25519, "1.3.101.110" },
{ LTC_OID_ED25519, LTC_PKA_ED25519, "1.3.101.112" },
{ LTC_OID_DH, LTC_PKA_DH, "1.2.840.113549.1.3.1" },
};
static LTC_INLINE const oid_table_entry* s_get_entry(enum ltc_oid_id id)
{
if (id < LTC_OID_NUM)
return &pka_oids[id];
return NULL;
}
/*
Returns the OID requested.
@return CRYPT_OK if valid
*/
int pk_get_oid(enum ltc_oid_id id, const char **st)
{
const oid_table_entry* e = s_get_entry(id);
LTC_ARGCHK(st != NULL);
if (e != NULL) {
*st = e->oid;
return CRYPT_OK;
}
return CRYPT_INVALID_ARG;
}
/*
Returns the PKA ID requested.
@return CRYPT_OK if valid
*/
int pk_get_pka_id(enum ltc_oid_id id, enum ltc_pka_id *pka)
{
const oid_table_entry* e = s_get_entry(id);
LTC_ARGCHK(pka != NULL);
if (e != NULL) {
*pka = e->pka;
return CRYPT_OK;
}
return CRYPT_INVALID_ARG;
}
/*
Returns the OID ID requested.
@return CRYPT_OK if valid
*/
int pk_get_oid_id(enum ltc_pka_id pka, enum ltc_oid_id *oid)
{
unsigned int i;
LTC_ARGCHK(oid != NULL);
for (i = 1; i < sizeof(pka_oids)/sizeof(pka_oids[0]); ++i) {
if (pka_oids[i].pka == pka) {
*oid = pka_oids[i].id;
return CRYPT_OK;
}
}
return CRYPT_INVALID_ARG;
}
/*
Returns the PKA ID of an OID.
@return CRYPT_OK if valid
*/
int pk_get_oid_from_asn1(const ltc_asn1_list *oid, enum ltc_oid_id *id)
{
unsigned long i;
char tmp[LTC_OID_MAX_STRLEN] = { 0 };
int err;
LTC_ARGCHK(oid != NULL);
LTC_ARGCHK(id != NULL);
if (oid->type != LTC_ASN1_OBJECT_IDENTIFIER) return CRYPT_INVALID_ARG;
i = sizeof(tmp);
if ((err = pk_oid_num_to_str(oid->data, oid->size, tmp, &i)) != CRYPT_OK) {
return err;
}
for (i = 1; i < sizeof(pka_oids)/sizeof(pka_oids[0]); ++i) {
if (XSTRCMP(pka_oids[i].oid, tmp) == 0) {
*id = pka_oids[i].id;
return CRYPT_OK;
}
}
return CRYPT_INVALID_ARG;
}
#endif

View File

@ -1,37 +0,0 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
#ifdef LTC_DER
typedef struct {
enum ltc_oid_id id;
const char* oid;
} oid_table_entry;
static const oid_table_entry pka_oids[] = {
{ LTC_OID_RSA, "1.2.840.113549.1.1.1" },
{ LTC_OID_DSA, "1.2.840.10040.4.1" },
{ LTC_OID_EC, "1.2.840.10045.2.1" },
{ LTC_OID_EC_PRIMEF, "1.2.840.10045.1.1" },
{ LTC_OID_X25519, "1.3.101.110" },
{ LTC_OID_ED25519, "1.3.101.112" },
};
/*
Returns the OID requested.
@return CRYPT_OK if valid
*/
int pk_get_oid(enum ltc_oid_id id, const char **st)
{
unsigned int i;
LTC_ARGCHK(st != NULL);
for (i = 0; i < sizeof(pka_oids)/sizeof(pka_oids[0]); ++i) {
if (pka_oids[i].id == id) {
*st = pka_oids[i].oid;
return CRYPT_OK;
}
}
return CRYPT_INVALID_ARG;
}
#endif

View File

@ -11,7 +11,7 @@
int pk_oid_cmp_with_ulong(const char *o1, const unsigned long *o2, unsigned long o2size)
{
unsigned long i;
char tmp[256] = { 0 };
char tmp[LTC_OID_MAX_STRLEN] = { 0 };
int err;
if (o1 == NULL || o2 == NULL) return CRYPT_ERROR;

View File

@ -46,7 +46,7 @@ int pk_oid_num_to_str(const unsigned long *oid, unsigned long oidlen, char *OID,
{
int i;
unsigned long j, k;
char tmp[256] = { 0 };
char tmp[LTC_OID_MAX_STRLEN] = { 0 };
LTC_ARGCHK(oid != NULL);
LTC_ARGCHK(oidlen < INT_MAX);

View File

@ -15,7 +15,7 @@
@return CRYPT_OK on success
*/
int pkcs8_decode_flexi(const unsigned char *in, unsigned long inlen,
const void *pwd, unsigned long pwdlen,
const password_ctx *pw_ctx,
ltc_asn1_list **decoded_list)
{
unsigned long len = inlen;
@ -23,10 +23,13 @@ int pkcs8_decode_flexi(const unsigned char *in, unsigned long inlen,
unsigned char *dec_data = NULL;
ltc_asn1_list *l = NULL;
int err;
pbes_arg pbes;
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(decoded_list != NULL);
XMEMSET(&pbes, 0, sizeof(pbes));
*decoded_list = NULL;
if ((err = der_decode_sequence_flexi(in, &len, &l)) == CRYPT_OK) {
/* the following "if" detects whether it is encrypted or not */
@ -44,9 +47,11 @@ int pkcs8_decode_flexi(const unsigned char *in, unsigned long inlen,
LTC_ASN1_IS_TYPE(l->child->child->next, LTC_ASN1_SEQUENCE) &&
LTC_ASN1_IS_TYPE(l->child->next, LTC_ASN1_OCTET_STRING)) {
ltc_asn1_list *lalgoid = l->child->child;
pbes_arg pbes;
XMEMSET(&pbes, 0, sizeof(pbes));
if ((pw_ctx == NULL) || (pw_ctx->callback == NULL)) {
err = CRYPT_PW_CTX_MISSING;
goto LBL_DONE;
}
if (pbes1_extract(lalgoid, &pbes) == CRYPT_OK) {
/* Successfully extracted PBES1 parameters */
@ -58,9 +63,12 @@ int pkcs8_decode_flexi(const unsigned char *in, unsigned long inlen,
goto LBL_DONE;
}
if (pw_ctx->callback(&pbes.pw.pw, &pbes.pw.l, pw_ctx->userdata)) {
err = CRYPT_ERROR;
goto LBL_DONE;
}
pbes.enc_data = l->child->next;
pbes.pwd = pwd;
pbes.pwdlen = pwdlen;
dec_size = pbes.enc_data->size;
if ((dec_data = XMALLOC(dec_size)) == NULL) {
@ -86,11 +94,12 @@ int pkcs8_decode_flexi(const unsigned char *in, unsigned long inlen,
}
LBL_DONE:
if (l) der_free_sequence_flexi(l);
if (dec_data) {
zeromem(dec_data, dec_size);
XFREE(dec_data);
}
password_free(&pbes.pw, pw_ctx);
if (l) der_free_sequence_flexi(l);
return err;
}

View File

@ -0,0 +1,48 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@file pkcs8_get.c
PKCS#8 utility functions
*/
#ifdef LTC_PKCS_8
int pkcs8_get_children(const ltc_asn1_list *decoded_list, enum ltc_oid_id *pka, ltc_asn1_list **alg_id, ltc_asn1_list **priv_key)
{
int err;
unsigned long n;
der_flexi_check flexi_should[4];
ltc_asn1_list *seq_l, *version;
LTC_ARGCHK(ltc_mp.name != NULL);
if (alg_id == NULL) alg_id = &seq_l;
/* Setup for basic structure */
n=0;
LTC_SET_DER_FLEXI_CHECK(flexi_should, n++, LTC_ASN1_INTEGER, &version);
LTC_SET_DER_FLEXI_CHECK(flexi_should, n++, LTC_ASN1_SEQUENCE, alg_id);
LTC_SET_DER_FLEXI_CHECK(flexi_should, n++, LTC_ASN1_OCTET_STRING, priv_key);
LTC_SET_DER_FLEXI_CHECK(flexi_should, n, LTC_ASN1_EOL, NULL);
err = der_flexi_sequence_cmp(decoded_list, flexi_should);
switch (err) {
case CRYPT_OK:
case CRYPT_INPUT_TOO_LONG:
/* If there are attributes added after the private_key it is tagged with version 1 and
* we get an 'input too long' error but the rest is already decoded and can be
* handled the same as for version 0
*/
if (mp_cmp_d(version->data, 0) != LTC_MP_EQ && mp_cmp_d(version->data, 1) != LTC_MP_EQ) {
return CRYPT_INVALID_PACKET;
}
break;
default:
return err;
}
return pk_get_oid_from_asn1((*alg_id)->child, pka);
}
#endif /* LTC_PKCS_8 */

View File

@ -9,14 +9,6 @@
#ifdef LTC_DER
/* Check if it looks like a SubjectPublicKeyInfo */
#define LOOKS_LIKE_SPKI(l) ((l) != NULL) \
&& ((l)->type == LTC_ASN1_SEQUENCE) \
&& ((l)->child != NULL) \
&& ((l)->child->type == LTC_ASN1_OBJECT_IDENTIFIER) \
&& ((l)->next != NULL) \
&& ((l)->next->type == LTC_ASN1_BIT_STRING)
/**
Try to decode the public key from a X.509 certificate
@param in The input buffer
@ -27,7 +19,9 @@
@param parameters_len [in/out] The number of parameters to include
@param callback The callback
@param ctx The context passed to the callback
@return CRYPT_OK on success, CRYPT_NOP if no SubjectPublicKeyInfo was found
@return CRYPT_OK on success,
CRYPT_NOP if no SubjectPublicKeyInfo was found,
another error if decoding or memory allocation failed
*/
int x509_decode_public_key_from_certificate(const unsigned char *in, unsigned long inlen,
enum ltc_oid_id algorithm, ltc_asn1_type param_type,
@ -35,67 +29,35 @@ int x509_decode_public_key_from_certificate(const unsigned char *in, unsigned lo
public_key_decode_cb callback, void *ctx)
{
int err;
unsigned char *tmpbuf;
unsigned long tmpbuf_len, tmp_inlen;
ltc_asn1_list *decoded_list = NULL, *l;
unsigned char *tmpbuf = NULL;
unsigned long tmpbuf_len;
ltc_asn1_list *decoded_list = NULL, *spki;
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(inlen != 0);
LTC_ARGCHK(callback != NULL);
tmpbuf_len = inlen;
tmpbuf = XCALLOC(1, tmpbuf_len);
if (tmpbuf == NULL) {
err = CRYPT_MEM;
goto LBL_OUT;
if ((err = x509_decode_spki(in, inlen, &decoded_list, &spki)) != CRYPT_OK) {
return err;
}
tmp_inlen = inlen;
if ((err = der_decode_sequence_flexi(in, &tmp_inlen, &decoded_list)) == CRYPT_OK) {
l = decoded_list;
if (algorithm == LTC_OID_EC) {
err = callback(spki->data, spki->size, ctx);
} else {
err = CRYPT_NOP;
tmpbuf_len = inlen;
tmpbuf = XCALLOC(1, tmpbuf_len);
if (tmpbuf == NULL) {
err = CRYPT_MEM;
goto LBL_OUT;
}
/* Move 2 levels up in the tree
SEQUENCE
SEQUENCE
...
*/
if ((l->type == LTC_ASN1_SEQUENCE) && (l->child != NULL)) {
l = l->child;
if ((l->type == LTC_ASN1_SEQUENCE) && (l->child != NULL)) {
l = l->child;
/* Move forward in the tree until we find this combination
...
SEQUENCE
SEQUENCE
OBJECT IDENTIFIER <some PKA OID, e.g. 1.2.840.113549.1.1.1>
NULL
BIT STRING
*/
do {
/* The additional check for l->data is there to make sure
* we won't try to decode a list that has been 'shrunk'
*/
if ((l->type == LTC_ASN1_SEQUENCE)
&& (l->data != NULL)
&& LOOKS_LIKE_SPKI(l->child)) {
if (algorithm == LTC_OID_EC) {
err = callback(l->data, l->size, ctx);
} else {
err = x509_decode_subject_public_key_info(l->data, l->size,
algorithm, tmpbuf, &tmpbuf_len,
param_type, parameters, parameters_len);
if (err == CRYPT_OK) {
err = callback(tmpbuf, tmpbuf_len, ctx);
goto LBL_OUT;
}
}
}
l = l->next;
} while(l);
}
err = x509_decode_subject_public_key_info(spki->data, spki->size,
algorithm, tmpbuf, &tmpbuf_len,
param_type, parameters, parameters_len);
if (err == CRYPT_OK) {
err = callback(tmpbuf, tmpbuf_len, ctx);
goto LBL_OUT;
}
}

View File

@ -0,0 +1,82 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
/**
@file x509_decode_public_key_from_certificate.c
ASN.1 DER/X.509, decode a SubjectPublicKeyInfo
*/
#ifdef LTC_DER
/* Check if it looks like a SubjectPublicKeyInfo */
#define LOOKS_LIKE_SPKI(l) ((l) != NULL) \
&& ((l)->type == LTC_ASN1_SEQUENCE) \
&& ((l)->child != NULL) \
&& ((l)->child->type == LTC_ASN1_OBJECT_IDENTIFIER) \
&& ((l)->next != NULL) \
&& ((l)->next->type == LTC_ASN1_BIT_STRING)
/**
DER decode a X.509 certificate and return the SubjectPublicKeyInfo
@param in The input buffer
@param inlen The length of the input buffer
@param out [out] A pointer to the decoded linked list (you take ownership of this one and
`der_free_sequence_flexi()` it when you're done)
@param spki [out] A pointer to the SubjectPublicKeyInfo
@return CRYPT_OK on success, CRYPT_NOP if no SubjectPublicKeyInfo was found, another error if decoding failed
*/
int x509_decode_spki(const unsigned char *in, unsigned long inlen, ltc_asn1_list **out, ltc_asn1_list **spki)
{
int err;
unsigned long tmp_inlen;
ltc_asn1_list *decoded_list = NULL, *l;
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(inlen != 0);
tmp_inlen = inlen;
if ((err = der_decode_sequence_flexi(in, &tmp_inlen, &decoded_list)) == CRYPT_OK) {
l = decoded_list;
err = CRYPT_NOP;
/* Move 2 levels up in the tree
SEQUENCE
SEQUENCE
...
*/
if ((l->type == LTC_ASN1_SEQUENCE) && (l->child != NULL)) {
l = l->child;
if ((l->type == LTC_ASN1_SEQUENCE) && (l->child != NULL)) {
l = l->child;
/* Move forward in the tree until we find this combination
...
SEQUENCE
SEQUENCE
OBJECT IDENTIFIER <some PKA OID, e.g. 1.2.840.113549.1.1.1>
NULL
BIT STRING
*/
do {
/* The additional check for l->data is there to make sure
* we won't try to decode a list that has been 'shrunk'
*/
if ((l->type == LTC_ASN1_SEQUENCE)
&& (l->data != NULL)
&& LOOKS_LIKE_SPKI(l->child)) {
*out = decoded_list;
*spki = l;
return CRYPT_OK;
}
l = l->next;
} while(l);
}
}
}
if (decoded_list) der_free_sequence_flexi(decoded_list);
return err;
}
#endif

View File

@ -32,7 +32,7 @@
@return CRYPT_OK on success
*/
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,
enum ltc_oid_id algorithm, void *public_key, unsigned long *public_key_len,
ltc_asn1_type parameters_type, ltc_asn1_list* parameters, unsigned long *parameters_len)
{
int err;

View File

@ -32,7 +32,7 @@
@return CRYPT_OK on success
*/
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,
enum ltc_oid_id algorithm, const void* public_key, unsigned long public_key_len,
ltc_asn1_type parameters_type, ltc_asn1_list* parameters, unsigned long parameters_len)
{
int err;

Some files were not shown because too many files have changed in this diff Show More