forked from wolfSSL/wolfssl
Implement CTS
Ciphertext stealing on top of CBC is implemented with `wolfSSL_CRYPTO_cts128_encrypt` and `wolfSSL_CRYPTO_cts128_decrypt` APIs
This commit is contained in:
@@ -6815,7 +6815,7 @@ then
|
|||||||
AM_CFLAGS="-DOPENSSL_EXTRA -DWOLFSSL_ALWAYS_VERIFY_CB $AM_CFLAGS"
|
AM_CFLAGS="-DOPENSSL_EXTRA -DWOLFSSL_ALWAYS_VERIFY_CB $AM_CFLAGS"
|
||||||
AM_CFLAGS="-DWOLFSSL_VERIFY_CB_ALL_CERTS -DWOLFSSL_EXTRA_ALERTS $AM_CFLAGS"
|
AM_CFLAGS="-DWOLFSSL_VERIFY_CB_ALL_CERTS -DWOLFSSL_EXTRA_ALERTS $AM_CFLAGS"
|
||||||
AM_CFLAGS="-DHAVE_EXT_CACHE -DWOLFSSL_FORCE_CACHE_ON_TICKET $AM_CFLAGS"
|
AM_CFLAGS="-DHAVE_EXT_CACHE -DWOLFSSL_FORCE_CACHE_ON_TICKET $AM_CFLAGS"
|
||||||
AM_CFLAGS="-DWOLFSSL_AKID_NAME $AM_CFLAGS"
|
AM_CFLAGS="-DWOLFSSL_AKID_NAME -DHAVE_CTS $AM_CFLAGS"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$ENABLED_OPENSSLEXTRA" = "x509small"
|
if test "$ENABLED_OPENSSLEXTRA" = "x509small"
|
||||||
|
80
src/ssl.c
80
src/ssl.c
@@ -99,6 +99,7 @@
|
|||||||
#include <wolfssl/openssl/ecdsa.h>
|
#include <wolfssl/openssl/ecdsa.h>
|
||||||
#include <wolfssl/openssl/ecdh.h>
|
#include <wolfssl/openssl/ecdh.h>
|
||||||
#include <wolfssl/openssl/err.h>
|
#include <wolfssl/openssl/err.h>
|
||||||
|
#include <wolfssl/openssl/modes.h>
|
||||||
#include <wolfssl/openssl/opensslv.h>
|
#include <wolfssl/openssl/opensslv.h>
|
||||||
#include <wolfssl/openssl/rc4.h>
|
#include <wolfssl/openssl/rc4.h>
|
||||||
#include <wolfssl/openssl/stack.h>
|
#include <wolfssl/openssl/stack.h>
|
||||||
@@ -30511,7 +30512,84 @@ int wolfSSL_AES_unwrap_key(AES_KEY *key, const unsigned char *iv,
|
|||||||
#endif /* HAVE_AES_KEYWRAP && !HAVE_FIPS && !HAVE_SELFTEST */
|
#endif /* HAVE_AES_KEYWRAP && !HAVE_FIPS && !HAVE_SELFTEST */
|
||||||
#endif /* NO_AES */
|
#endif /* NO_AES */
|
||||||
|
|
||||||
#ifndef NO_ASN_TIME
|
#ifdef HAVE_CTS
|
||||||
|
/*
|
||||||
|
* Ciphertext stealing interface compatible with RFC2040 and RFC3962.
|
||||||
|
*/
|
||||||
|
size_t wolfSSL_CRYPTO_cts128_encrypt(const unsigned char *in,
|
||||||
|
unsigned char *out, size_t len, const void *key,
|
||||||
|
unsigned char *iv, WOLFSSL_CBC128_CB cbc)
|
||||||
|
{
|
||||||
|
byte lastBlk[WOLFSSL_CTS128_BLOCK_SZ] = {0};
|
||||||
|
int lastBlkLen = len % WOLFSSL_CTS128_BLOCK_SZ;
|
||||||
|
WOLFSSL_ENTER("wolfSSL_CRYPTO_cts128_encrypt");
|
||||||
|
|
||||||
|
if (in == NULL || out == NULL || len < WOLFSSL_CTS128_BLOCK_SZ ||
|
||||||
|
cbc == NULL) {
|
||||||
|
WOLFSSL_MSG("Bad parameter");
|
||||||
|
return WOLFSSL_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastBlkLen == 0)
|
||||||
|
lastBlkLen = WOLFSSL_CTS128_BLOCK_SZ;
|
||||||
|
|
||||||
|
/* Encrypt data up to last block */
|
||||||
|
(*cbc)(in, out, len - lastBlkLen, key, iv, 1);
|
||||||
|
|
||||||
|
/* Move to last block */
|
||||||
|
in += len - lastBlkLen;
|
||||||
|
out += len - lastBlkLen;
|
||||||
|
|
||||||
|
/* RFC2040: Pad Pn with zeros at the end to create P of length BB. */
|
||||||
|
XMEMCPY(lastBlk, in, lastBlkLen);
|
||||||
|
/* RFC2040: Select the first Ln bytes of En-1 to create Cn */
|
||||||
|
XMEMCPY(out, out - WOLFSSL_CTS128_BLOCK_SZ, lastBlkLen);
|
||||||
|
(*cbc)(lastBlk, out - WOLFSSL_CTS128_BLOCK_SZ, WOLFSSL_CTS128_BLOCK_SZ,
|
||||||
|
key, iv, 1);
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t wolfSSL_CRYPTO_cts128_decrypt(const unsigned char *in,
|
||||||
|
unsigned char *out, size_t len, const void *key,
|
||||||
|
unsigned char *iv, WOLFSSL_CBC128_CB cbc)
|
||||||
|
{
|
||||||
|
byte lastBlk[WOLFSSL_CTS128_BLOCK_SZ] = {0};
|
||||||
|
byte prevBlk[WOLFSSL_CTS128_BLOCK_SZ] = {0};
|
||||||
|
int lastBlkLen = len % WOLFSSL_CTS128_BLOCK_SZ;
|
||||||
|
WOLFSSL_ENTER("wolfSSL_CRYPTO_cts128_decrypt");
|
||||||
|
|
||||||
|
if (in == NULL || out == NULL || len <= WOLFSSL_CTS128_BLOCK_SZ ||
|
||||||
|
cbc == NULL) {
|
||||||
|
WOLFSSL_MSG("Bad parameter");
|
||||||
|
return WOLFSSL_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastBlkLen == 0)
|
||||||
|
lastBlkLen = WOLFSSL_CTS128_BLOCK_SZ;
|
||||||
|
|
||||||
|
/* Decrypt up to last two blocks */
|
||||||
|
(*cbc)(in, out, len - lastBlkLen - WOLFSSL_CTS128_BLOCK_SZ, key, iv, 0);
|
||||||
|
|
||||||
|
/* Move to last two blocks */
|
||||||
|
in += len - lastBlkLen - WOLFSSL_CTS128_BLOCK_SZ;
|
||||||
|
out += len - lastBlkLen - WOLFSSL_CTS128_BLOCK_SZ;
|
||||||
|
|
||||||
|
/* RFC2040: Decrypt Cn-1 to create Dn.
|
||||||
|
* Use 0 buffer as IV to do straight decryption.
|
||||||
|
* This places the Cn-1 block at lastBlk */
|
||||||
|
(*cbc)(in, prevBlk, WOLFSSL_CTS128_BLOCK_SZ, key, lastBlk, 0);
|
||||||
|
/* RFC2040: Append the tail (BB minus Ln) bytes of Xn to Cn
|
||||||
|
* to create En. */
|
||||||
|
XMEMCPY(prevBlk, in + WOLFSSL_CTS128_BLOCK_SZ, lastBlkLen);
|
||||||
|
/* Cn and Cn-1 can now be decrypted */
|
||||||
|
(*cbc)(prevBlk, out, WOLFSSL_CTS128_BLOCK_SZ, key, iv, 0);
|
||||||
|
(*cbc)(lastBlk, lastBlk, WOLFSSL_CTS128_BLOCK_SZ, key, iv, 0);
|
||||||
|
XMEMCPY(out + WOLFSSL_CTS128_BLOCK_SZ, lastBlk, lastBlkLen);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_CTS */
|
||||||
|
|
||||||
#ifndef NO_BIO
|
#ifndef NO_BIO
|
||||||
int wolfSSL_ASN1_UTCTIME_print(WOLFSSL_BIO* bio, const WOLFSSL_ASN1_UTCTIME* a)
|
int wolfSSL_ASN1_UTCTIME_print(WOLFSSL_BIO* bio, const WOLFSSL_ASN1_UTCTIME* a)
|
||||||
{
|
{
|
||||||
|
84
tests/api.c
84
tests/api.c
@@ -313,6 +313,7 @@
|
|||||||
#include <wolfssl/openssl/hmac.h>
|
#include <wolfssl/openssl/hmac.h>
|
||||||
#include <wolfssl/openssl/objects.h>
|
#include <wolfssl/openssl/objects.h>
|
||||||
#include <wolfssl/openssl/rand.h>
|
#include <wolfssl/openssl/rand.h>
|
||||||
|
#include <wolfssl/openssl/modes.h>
|
||||||
#ifdef OPENSSL_ALL
|
#ifdef OPENSSL_ALL
|
||||||
#include <wolfssl/openssl/txt_db.h>
|
#include <wolfssl/openssl/txt_db.h>
|
||||||
#include <wolfssl/openssl/lhash.h>
|
#include <wolfssl/openssl/lhash.h>
|
||||||
@@ -41975,6 +41976,88 @@ static void test_wolfSSL_AES_cbc_encrypt(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_wolfSSL_CRYPTO_cts128(void)
|
||||||
|
{
|
||||||
|
#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(OPENSSL_EXTRA) \
|
||||||
|
&& defined(HAVE_CTS)
|
||||||
|
byte tmp[64] = {0}; /* Largest vector size */
|
||||||
|
/* Test vectors taken form RFC3962 Appendix B */
|
||||||
|
const testVector vects[] = {
|
||||||
|
{
|
||||||
|
"\x49\x20\x77\x6f\x75\x6c\x64\x20\x6c\x69\x6b\x65\x20\x74\x68\x65"
|
||||||
|
"\x20",
|
||||||
|
"\xc6\x35\x35\x68\xf2\xbf\x8c\xb4\xd8\xa5\x80\x36\x2d\xa7\xff\x7f"
|
||||||
|
"\x97",
|
||||||
|
17, 17
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"\x49\x20\x77\x6f\x75\x6c\x64\x20\x6c\x69\x6b\x65\x20\x74\x68\x65"
|
||||||
|
"\x20\x47\x65\x6e\x65\x72\x61\x6c\x20\x47\x61\x75\x27\x73\x20",
|
||||||
|
"\xfc\x00\x78\x3e\x0e\xfd\xb2\xc1\xd4\x45\xd4\xc8\xef\xf7\xed\x22"
|
||||||
|
"\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5",
|
||||||
|
31, 31
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"\x49\x20\x77\x6f\x75\x6c\x64\x20\x6c\x69\x6b\x65\x20\x74\x68\x65"
|
||||||
|
"\x20\x47\x65\x6e\x65\x72\x61\x6c\x20\x47\x61\x75\x27\x73\x20\x43",
|
||||||
|
"\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8"
|
||||||
|
"\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84",
|
||||||
|
32, 32
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"\x49\x20\x77\x6f\x75\x6c\x64\x20\x6c\x69\x6b\x65\x20\x74\x68\x65"
|
||||||
|
"\x20\x47\x65\x6e\x65\x72\x61\x6c\x20\x47\x61\x75\x27\x73\x20\x43"
|
||||||
|
"\x68\x69\x63\x6b\x65\x6e\x2c\x20\x70\x6c\x65\x61\x73\x65\x2c",
|
||||||
|
"\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
|
||||||
|
"\xb3\xff\xfd\x94\x0c\x16\xa1\x8c\x1b\x55\x49\xd2\xf8\x38\x02\x9e"
|
||||||
|
"\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5",
|
||||||
|
47, 47
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"\x49\x20\x77\x6f\x75\x6c\x64\x20\x6c\x69\x6b\x65\x20\x74\x68\x65"
|
||||||
|
"\x20\x47\x65\x6e\x65\x72\x61\x6c\x20\x47\x61\x75\x27\x73\x20\x43"
|
||||||
|
"\x68\x69\x63\x6b\x65\x6e\x2c\x20\x70\x6c\x65\x61\x73\x65\x2c\x20",
|
||||||
|
"\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
|
||||||
|
"\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8"
|
||||||
|
"\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8",
|
||||||
|
48, 48
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"\x49\x20\x77\x6f\x75\x6c\x64\x20\x6c\x69\x6b\x65\x20\x74\x68\x65"
|
||||||
|
"\x20\x47\x65\x6e\x65\x72\x61\x6c\x20\x47\x61\x75\x27\x73\x20\x43"
|
||||||
|
"\x68\x69\x63\x6b\x65\x6e\x2c\x20\x70\x6c\x65\x61\x73\x65\x2c\x20"
|
||||||
|
"\x61\x6e\x64\x20\x77\x6f\x6e\x74\x6f\x6e\x20\x73\x6f\x75\x70\x2e",
|
||||||
|
"\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
|
||||||
|
"\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8"
|
||||||
|
"\x48\x07\xef\xe8\x36\xee\x89\xa5\x26\x73\x0d\xbc\x2f\x7b\xc8\x40"
|
||||||
|
"\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8",
|
||||||
|
64, 64
|
||||||
|
}
|
||||||
|
};
|
||||||
|
byte keyBytes[AES_128_KEY_SIZE] = {
|
||||||
|
0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20,
|
||||||
|
0x74, 0x65, 0x72, 0x69, 0x79, 0x61, 0x6b, 0x69
|
||||||
|
};
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < sizeof(vects)/sizeof(vects[0]); i++) {
|
||||||
|
AES_KEY encKey;
|
||||||
|
AES_KEY decKey;
|
||||||
|
byte iv[AES_IV_SIZE] = {0}; /* All-zero IV for all cases */
|
||||||
|
AssertIntEQ(AES_set_encrypt_key(keyBytes, AES_128_KEY_SIZE * 8, &encKey), 0);
|
||||||
|
AssertIntEQ(AES_set_decrypt_key(keyBytes, AES_128_KEY_SIZE * 8, &decKey), 0);
|
||||||
|
AssertIntEQ(CRYPTO_cts128_encrypt((const unsigned char*)vects[i].input,
|
||||||
|
tmp, vects[i].inLen, &encKey, iv, (cbc128_f)AES_cbc_encrypt),
|
||||||
|
vects[i].outLen);
|
||||||
|
AssertIntEQ(XMEMCMP(tmp, vects[i].output, vects[i].outLen), 0);
|
||||||
|
XMEMSET(iv, 0, sizeof(iv));
|
||||||
|
AssertIntEQ(CRYPTO_cts128_decrypt((const unsigned char*)vects[i].output,
|
||||||
|
tmp, vects[i].outLen, &decKey, iv, (cbc128_f)AES_cbc_encrypt),
|
||||||
|
vects[i].inLen);
|
||||||
|
AssertIntEQ(XMEMCMP(tmp, vects[i].input, vects[i].inLen), 0);
|
||||||
|
}
|
||||||
|
#endif /* !NO_AES && HAVE_AES_CBC && OPENSSL_EXTRA && HAVE_CTS */
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(OPENSSL_ALL)
|
#if defined(OPENSSL_ALL)
|
||||||
#if !defined(NO_ASN)
|
#if !defined(NO_ASN)
|
||||||
static void test_wolfSSL_ASN1_STRING_to_UTF8(void)
|
static void test_wolfSSL_ASN1_STRING_to_UTF8(void)
|
||||||
@@ -51945,6 +52028,7 @@ void ApiTest(void)
|
|||||||
test_wolfSSL_DC_cert();
|
test_wolfSSL_DC_cert();
|
||||||
test_wolfSSL_DES_ncbc();
|
test_wolfSSL_DES_ncbc();
|
||||||
test_wolfSSL_AES_cbc_encrypt();
|
test_wolfSSL_AES_cbc_encrypt();
|
||||||
|
test_wolfSSL_CRYPTO_cts128();
|
||||||
test_wolfssl_EVP_aes_gcm_AAD_2_parts();
|
test_wolfssl_EVP_aes_gcm_AAD_2_parts();
|
||||||
test_wolfssl_EVP_aes_gcm();
|
test_wolfssl_EVP_aes_gcm();
|
||||||
test_wolfSSL_PKEY_up_ref();
|
test_wolfSSL_PKEY_up_ref();
|
||||||
|
@@ -30,6 +30,7 @@ nobase_include_HEADERS+= \
|
|||||||
wolfssl/openssl/lhash.h \
|
wolfssl/openssl/lhash.h \
|
||||||
wolfssl/openssl/md4.h \
|
wolfssl/openssl/md4.h \
|
||||||
wolfssl/openssl/md5.h \
|
wolfssl/openssl/md5.h \
|
||||||
|
wolfssl/openssl/modes.h \
|
||||||
wolfssl/openssl/ripemd.h \
|
wolfssl/openssl/ripemd.h \
|
||||||
wolfssl/openssl/obj_mac.h \
|
wolfssl/openssl/obj_mac.h \
|
||||||
wolfssl/openssl/objects.h \
|
wolfssl/openssl/objects.h \
|
||||||
|
45
wolfssl/openssl/modes.h
Normal file
45
wolfssl/openssl/modes.h
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/* modes.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006-2021 wolfSSL Inc.
|
||||||
|
*
|
||||||
|
* This file is part of wolfSSL.
|
||||||
|
*
|
||||||
|
* wolfSSL is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* wolfSSL is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||||
|
*/
|
||||||
|
#ifndef WOLFSSL_OPENSSL_MODES_H
|
||||||
|
#define WOLFSSL_OPENSSL_MODES_H
|
||||||
|
|
||||||
|
#include <wolfssl/wolfcrypt/settings.h>
|
||||||
|
#include <wolfssl/openssl/ssl.h>
|
||||||
|
|
||||||
|
typedef void (*WOLFSSL_CBC128_CB) (const unsigned char *in,
|
||||||
|
unsigned char *out, size_t len, const void *key,
|
||||||
|
unsigned char *iv, int enc);
|
||||||
|
|
||||||
|
WOLFSSL_API size_t wolfSSL_CRYPTO_cts128_encrypt(const unsigned char *in,
|
||||||
|
unsigned char *out, size_t len, const void *key,
|
||||||
|
unsigned char *iv, WOLFSSL_CBC128_CB cbc);
|
||||||
|
WOLFSSL_API size_t wolfSSL_CRYPTO_cts128_decrypt(const unsigned char *in,
|
||||||
|
unsigned char *out, size_t len, const void *key,
|
||||||
|
unsigned char *iv, WOLFSSL_CBC128_CB cbc);
|
||||||
|
|
||||||
|
#define WOLFSSL_CTS128_BLOCK_SZ 16
|
||||||
|
|
||||||
|
/* Compatibility layer defines */
|
||||||
|
#define CRYPTO_cts128_encrypt wolfSSL_CRYPTO_cts128_encrypt
|
||||||
|
#define CRYPTO_cts128_decrypt wolfSSL_CRYPTO_cts128_decrypt
|
||||||
|
#define cbc128_f WOLFSSL_CBC128_CB
|
||||||
|
|
||||||
|
#endif /* WOLFSSL_OPENSSL_MODES_H */
|
Reference in New Issue
Block a user