Merge pull request #2343 from Jakuje/ossl3v1

Working subset of #2337 (OpenSSL 3.0)
This commit is contained in:
Frank Morgner 2021-06-07 14:38:30 +02:00 committed by GitHub
commit c42792c216
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 655 additions and 78 deletions

View File

@ -133,7 +133,7 @@ esac
AX_CODE_COVERAGE()
AX_CHECK_COMPILE_FLAG([-Wunknown-warning-option], [have_unknown_warning_option="yes"], [have_unknown_warning_option="no"], [-Werror])
AX_CHECK_COMPILE_FLAG([-Wunknown-warning-option], [have_unknown_warning_option="yes"], [have_unknown_warning_option="no"])
AM_CONDITIONAL([HAVE_UNKNOWN_WARNING_OPTION], [test "${have_unknown_warning_option}" = "yes"])
AC_ARG_ENABLE(

View File

@ -519,8 +519,8 @@ static int cwa_internal_auth(sc_card_t * card, u8 * sig, size_t sig_len, u8 * da
* @return SC_SUCCESS if ok; else errorcode
*/
static int cwa_prepare_external_auth(sc_card_t * card,
RSA * icc_pubkey,
RSA * ifd_privkey,
const RSA * icc_pubkey,
const RSA * ifd_privkey,
u8 * sig,
size_t sig_len)
{
@ -594,7 +594,7 @@ static int cwa_prepare_external_auth(sc_card_t * card,
buf3[127] = 0xBC; /* iso padding */
/* encrypt with ifd private key */
len2 = RSA_private_decrypt(128, buf3, buf2, ifd_privkey, RSA_NO_PADDING);
len2 = RSA_private_decrypt(128, buf3, buf2, (RSA *)ifd_privkey, RSA_NO_PADDING);
if (len2 < 0) {
msg = "Prepare external auth: ifd_privk encrypt failed";
res = SC_ERROR_SM_ENCRYPT_FAILED;
@ -630,7 +630,7 @@ static int cwa_prepare_external_auth(sc_card_t * card,
}
/* re-encrypt result with icc public key */
len1 = RSA_public_encrypt(len3, buf3, buf1, icc_pubkey, RSA_NO_PADDING);
len1 = RSA_public_encrypt(len3, buf3, buf1, (RSA *)icc_pubkey, RSA_NO_PADDING);
if (len1 <= 0 || (size_t) len1 != sig_len) {
msg = "Prepare external auth: icc_pubk encrypt failed";
res = SC_ERROR_SM_ENCRYPT_FAILED;
@ -842,8 +842,8 @@ static int cwa_compare_signature(u8 * data, size_t dlen, u8 * ifd_data)
* @return SC_SUCCESS if ok; else error code
*/
static int cwa_verify_internal_auth(sc_card_t * card,
RSA * icc_pubkey,
RSA * ifd_privkey,
const RSA * icc_pubkey,
const RSA * ifd_privkey,
u8 * ifdbuf,
size_t ifdlen,
u8 * sig,
@ -901,7 +901,7 @@ static int cwa_verify_internal_auth(sc_card_t * card,
*/
/* decrypt data with our ifd priv key */
len1 = RSA_private_decrypt(sig_len, sig, buf1, ifd_privkey, RSA_NO_PADDING);
len1 = RSA_private_decrypt(sig_len, sig, buf1, (RSA *)ifd_privkey, RSA_NO_PADDING);
if (len1 <= 0) {
msg = "Verify Signature: decrypt with ifd privk failed";
res = SC_ERROR_SM_ENCRYPT_FAILED;
@ -911,7 +911,7 @@ static int cwa_verify_internal_auth(sc_card_t * card,
/* OK: now we have SIGMIN in buf1 */
/* check if SIGMIN data matches SIG or N.ICC-SIG */
/* evaluate DS[SK.ICC.AUTH](SIG) trying to decrypt with icc pubk */
len3 = RSA_public_encrypt(len1, buf1, buf3, icc_pubkey, RSA_NO_PADDING);
len3 = RSA_public_encrypt(len1, buf1, buf3, (RSA *) icc_pubkey, RSA_NO_PADDING);
if (len3 <= 0)
goto verify_nicc_sig; /* evaluate N.ICC-SIG and retry */
res = cwa_compare_signature(buf3, len3, ifdbuf);
@ -945,7 +945,7 @@ static int cwa_verify_internal_auth(sc_card_t * card,
}
/* ok: check again with new data */
/* evaluate DS[SK.ICC.AUTH](I.ICC-SIG) trying to decrypt with icc pubk */
len3 = RSA_public_encrypt(len2, buf2, buf3, icc_pubkey, RSA_NO_PADDING);
len3 = RSA_public_encrypt(len2, buf2, buf3, (RSA *)icc_pubkey, RSA_NO_PADDING);
if (len3 <= 0) {
msg = "Verify Signature: cannot get valid SIG data";
res = SC_ERROR_INVALID_DATA;

View File

@ -143,7 +143,7 @@ CERT_HANDLE_FUNCTION(default_cert_handle) {
int r;
X509 *cert_data = NULL;
EVP_PKEY *pkey = NULL;
RSA * rsa = NULL;
const RSA * rsa = NULL;
int certtype = 0;
int modulus_len = 0;
const prdata* key = get_prkey_by_cert(items, cert);

View File

@ -527,7 +527,9 @@ sc_pkcs15_prkey_attrs_from_cert(struct sc_pkcs15_card *p15card, struct sc_pkcs15
key_info = (struct sc_pkcs15_prkey_info *) key_object->data;
#if OPENSSL_VERSION_NUMBER < 0x30000000L
ERR_load_ERR_strings();
#endif
ERR_load_crypto_strings();
sc_log(ctx, "CertValue(%"SC_FORMAT_LEN_SIZE_T"u) %p",

View File

@ -273,6 +273,7 @@ static sc_ossl_inline void CRYPTO_secure_malloc_done()
#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@ -522,7 +522,7 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len
size_t signat_len_tmp;
unsigned char *signat_tmp = NULL;
EVP_PKEY_CTX *ctx;
EC_KEY *eckey;
const EC_KEY *eckey;
int r;
sc_log(context, "Trying to verify using EVP");

View File

@ -812,7 +812,7 @@ out:
*/
#define NUM_INTERFACES 2
#define DEFAULT_INTERFACE 0
ck_interface interfaces[NUM_INTERFACES] = {
CK_INTERFACE interfaces[NUM_INTERFACES] = {
{"PKCS 11", (void *)&pkcs11_function_list_3_0, 0},
{"PKCS 11", (void *)&pkcs11_function_list, 0}
};

View File

@ -176,7 +176,7 @@ allocate_function_list(int v3)
/* The compatibility interfaces that can be returned from Interface functions
* if the V3 API is used, but the proxied module does not support V3 API */
#define NUM_INTERFACES 1
ck_interface compat_interfaces[NUM_INTERFACES] = {
CK_INTERFACE compat_interfaces[NUM_INTERFACES] = {
{"PKCS 11", NULL, 0}
};

View File

@ -63,9 +63,9 @@ extern "C" {
version of this file, please consider deleting the revision macro
(you may use a macro with a different name to keep track of your
versions). */
#define CRYPTOKI_VERSION_MAJOR 2
#define CRYPTOKI_VERSION_MINOR 20
#define CRYPTOKI_VERSION_REVISION 6
#define CRYPTOKI_VERSION_MAJOR 3
#define CRYPTOKI_VERSION_MINOR 0
#define CRYPTOKI_VERSION_REVISION 0
/* Compatibility interface is default, unless CRYPTOKI_GNU is
@ -1786,6 +1786,8 @@ typedef struct ck_c_initialize_args *CK_C_INITIALIZE_ARGS_PTR;
#undef ck_rv_t
#undef ck_notify_t
#undef ck_interface
#undef ck_function_list
#undef ck_function_list_3_0

View File

@ -769,7 +769,9 @@ awp_encode_key_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *obj
int r = 0;
LOG_FUNC_CALLED(ctx);
#if OPENSSL_VERSION_NUMBER < 0x30000000L
ERR_load_ERR_strings();
#endif
ERR_load_crypto_strings();
key_info = (struct sc_pkcs15_prkey_info *)obj->data;
@ -827,7 +829,9 @@ awp_encode_key_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *obj
sc_log(ctx, "cosm_encode_key_info() label:%s",ki->label.value);
done:
#if OPENSSL_VERSION_NUMBER < 0x30000000L
ERR_load_ERR_strings();
#endif
ERR_load_crypto_strings();
LOG_FUNC_RETURN(ctx, r);
}
@ -933,7 +937,9 @@ awp_encode_cert_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *ob
LOG_FUNC_CALLED(ctx);
#if OPENSSL_VERSION_NUMBER < 0x30000000L
ERR_load_ERR_strings();
#endif
ERR_load_crypto_strings();
if (!obj || !ci)

View File

@ -40,6 +40,7 @@
#error "Need OpenSSL"
#endif
#include <openssl/evp.h>
#include <openssl/des.h>
#include <openssl/sha.h>
@ -49,6 +50,7 @@
#include "sm-common.h"
#if OPENSSL_VERSION_NUMBER < 0x30000000L
/*
* From crypto/des/des_locl.h of OpenSSL .
*/
@ -120,18 +122,34 @@ DES_3cbc_encrypt(DES_cblock *input, DES_cblock *output, long length,
}
memcpy(*iv,icv_out,sizeof(DES_cblock));
}
#else
#include <openssl/provider.h>
/* The single-DES algorithm is not available in the default provider anymore
* so we need to load the legacy provider. This is not done on the application
* start, but only as needed */
OSSL_PROVIDER *legacy_provider = NULL;
#endif
DES_LONG
DES_cbc_cksum_3des_emv96(const unsigned char *in, DES_cblock *output,
long length, DES_key_schedule *schedule, DES_key_schedule *schedule2,
long length, unsigned char *key,
const_DES_cblock *ivec)
{
register DES_LONG tout0,tout1,tin0,tin1;
register long l=length;
DES_LONG tin[2];
unsigned char *out = &(*output)[0];
const unsigned char *iv = &(*ivec)[0];
#if OPENSSL_VERSION_NUMBER < 0x30000000L
register DES_LONG tout0,tout1,tin0,tin1;
DES_LONG tin[2];
DES_cblock kk, k2;
DES_key_schedule ks,ks2;
memcpy(&kk, key, 8);
memcpy(&k2, key + 8, 8);
DES_set_key_unchecked(&kk,&ks);
DES_set_key_unchecked(&k2,&ks2);
c2l(iv,tout0);
c2l(iv,tout1);
@ -147,7 +165,7 @@ DES_cbc_cksum_3des_emv96(const unsigned char *in, DES_cblock *output,
tin0^=tout0; tin[0]=tin0;
tin1^=tout1; tin[1]=tin1;
DES_encrypt1((DES_LONG *)tin,schedule, DES_ENCRYPT);
DES_encrypt1((DES_LONG *)tin, &ks, DES_ENCRYPT);
tout0=tin[0];
tout1=tin[1];
}
@ -161,9 +179,8 @@ DES_cbc_cksum_3des_emv96(const unsigned char *in, DES_cblock *output,
tin0^=tout0; tin[0]=tin0;
tin1^=tout1; tin[1]=tin1;
DES_encrypt3((DES_LONG *)tin,schedule,schedule2,schedule);
DES_encrypt3((DES_LONG *)tin, &ks, &ks2, &ks);
tout1=tin[1];
if (out != NULL)
{
l2c(tout0,out);
@ -179,22 +196,87 @@ DES_cbc_cksum_3des_emv96(const unsigned char *in, DES_cblock *output,
| ((tout1 << 8L) & 0x00FF0000)
| ((tout1 << 24L) & 0xFF000000);
return(tout1);
#else
EVP_CIPHER_CTX *cctx = NULL;
unsigned char outv[8], tmpout[4];
int tmplen;
/* Prepare IV */
memcpy(outv, iv, sizeof outv);
cctx = EVP_CIPHER_CTX_new();
if (l > 8) {
if (legacy_provider == NULL) {
legacy_provider = OSSL_PROVIDER_load(NULL, "legacy");
}
if (!EVP_EncryptInit_ex2(cctx, EVP_des_cbc(), key, iv, NULL)) {
EVP_CIPHER_CTX_free(cctx);
return SC_ERROR_INTERNAL;
}
/* Disable padding, otherwise it will fail to decrypt non-padded inputs */
EVP_CIPHER_CTX_set_padding(cctx, 0);
for (; l > 8; l -= 8, in += 8) {
if (!EVP_EncryptUpdate(cctx, outv, &tmplen, in, 8)) {
EVP_CIPHER_CTX_free(cctx);
return SC_ERROR_INTERNAL;
}
}
if (!EVP_EncryptFinal_ex(cctx, outv + tmplen, &tmplen)) {
EVP_CIPHER_CTX_free(cctx);
return SC_ERROR_INTERNAL;
}
}
/* We need to return first 4 bytes from here */
memcpy(tmpout, outv, 4);
if (!EVP_EncryptInit_ex2(cctx, EVP_des_ede_cbc(), key, outv, NULL)) {
EVP_CIPHER_CTX_free(cctx);
return SC_ERROR_INTERNAL;
}
/* Disable padding, otherwise it will fail to decrypt non-padded inputs */
EVP_CIPHER_CTX_set_padding(cctx, 0);
if (!EVP_EncryptUpdate(cctx, outv, &tmplen, in, l)) {
EVP_CIPHER_CTX_free(cctx);
return SC_ERROR_INTERNAL;
}
if (!EVP_EncryptFinal_ex(cctx, outv + tmplen, &tmplen)) {
EVP_CIPHER_CTX_free(cctx);
return SC_ERROR_INTERNAL;
}
if (out != NULL) {
memcpy(out, tmpout, 4);
memcpy(out+4, outv+4, 4);
}
EVP_CIPHER_CTX_free(cctx);
return ((outv[7] << 0L) & 0x000000FF) |
((outv[6] << 8L) & 0x0000FF00) |
((outv[5] << 16L) & 0x00FF0000) |
((outv[4] << 24L) & 0xFF000000);
#endif
}
DES_LONG
DES_cbc_cksum_3des(const unsigned char *in, DES_cblock *output,
long length, DES_key_schedule *schedule, DES_key_schedule *schedule2,
long length, unsigned char *key,
const_DES_cblock *ivec)
{
register DES_LONG tout0,tout1,tin0,tin1;
register long l=length;
DES_LONG tin[2];
unsigned char *out = &(*output)[0];
const unsigned char *iv = &(*ivec)[0];
#if OPENSSL_VERSION_NUMBER < 0x30000000L
register DES_LONG tout0,tout1,tin0,tin1;
DES_LONG tin[2];
DES_cblock kk, k2;
DES_key_schedule ks,ks2;
c2l(iv,tout0);
c2l(iv,tout1);
memcpy(&kk, key, 8);
memcpy(&k2, key + 8, 8);
DES_set_key_unchecked(&kk,&ks);
DES_set_key_unchecked(&k2,&ks2);
c2l(iv, tout0);
c2l(iv, tout1);
for (; l>0; l-=8)
{
@ -208,7 +290,7 @@ DES_cbc_cksum_3des(const unsigned char *in, DES_cblock *output,
tin0^=tout0; tin[0]=tin0;
tin1^=tout1; tin[1]=tin1;
DES_encrypt3((DES_LONG *)tin,schedule,schedule2,schedule);
DES_encrypt3((DES_LONG *)tin, &ks, &ks2, &ks);
/* fix 15/10/91 eay - thanks to keithr@sco.COM */
tout0=tin[0];
tout1=tin[1];
@ -228,6 +310,40 @@ DES_cbc_cksum_3des(const unsigned char *in, DES_cblock *output,
| ((tout1 << 8L) & 0x00FF0000)
| ((tout1 << 24L) & 0xFF000000);
return(tout1);
#else
EVP_CIPHER_CTX *cctx = NULL;
unsigned char outv[8];
int tmplen;
/* Prepare IV */
memcpy(outv, iv, sizeof outv);
cctx = EVP_CIPHER_CTX_new();
if (!EVP_EncryptInit_ex2(cctx, EVP_des_ede_cbc(), key, iv, NULL)) {
EVP_CIPHER_CTX_free(cctx);
return SC_ERROR_INTERNAL;
}
/* Disable padding, otherwise it will fail to decrypt non-padded inputs */
EVP_CIPHER_CTX_set_padding(cctx, 0);
for (; l > 0; l -= 8, in += 8) {
if (!EVP_EncryptUpdate(cctx, outv, &tmplen, in, 8)) {
EVP_CIPHER_CTX_free(cctx);
return SC_ERROR_INTERNAL;
}
}
if (!EVP_EncryptFinal_ex(cctx, outv + tmplen, &tmplen)) {
EVP_CIPHER_CTX_free(cctx);
return SC_ERROR_INTERNAL;
}
if (out != NULL) {
memcpy(out, outv, sizeof outv);
}
EVP_CIPHER_CTX_free(cctx);
return ((outv[7] << 0L) & 0x000000FF) |
((outv[6] << 8L) & 0x0000FF00) |
((outv[5] << 16L) & 0x00FF0000) |
((outv[4] << 24L) & 0xFF000000);
#endif
}
@ -235,9 +351,14 @@ int
sm_encrypt_des_ecb3(unsigned char *key, unsigned char *data, int data_len,
unsigned char **out, int *out_len)
{
#if OPENSSL_VERSION_NUMBER < 0x30000000L
int ii;
DES_cblock kk,k2;
DES_key_schedule ks,ks2;
#else
EVP_CIPHER_CTX *cctx = NULL;
int tmplen;
#endif
if (!out || !out_len)
@ -251,6 +372,7 @@ sm_encrypt_des_ecb3(unsigned char *key, unsigned char *data, int data_len,
if (!(*out))
return -1;
#if OPENSSL_VERSION_NUMBER < 0x30000000L
memcpy(&kk, key, 8);
memcpy(&k2, key + 8, 8);
@ -260,6 +382,27 @@ sm_encrypt_des_ecb3(unsigned char *key, unsigned char *data, int data_len,
for (ii=0; ii<data_len; ii+=8)
DES_ecb2_encrypt( (DES_cblock *)(data + ii),
(DES_cblock *)(*out + ii), &ks, &ks2, DES_ENCRYPT);
#else
cctx = EVP_CIPHER_CTX_new();
if (!EVP_EncryptInit_ex2(cctx, EVP_des_ede_ecb(), key, NULL, NULL)) {
EVP_CIPHER_CTX_free(cctx);
return SC_ERROR_INTERNAL;
}
/* Disable padding, otherwise it will fail to decrypt non-padded inputs */
EVP_CIPHER_CTX_set_padding(cctx, 0);
if (!EVP_EncryptUpdate(cctx, *out, &tmplen, data, data_len)) {
EVP_CIPHER_CTX_free(cctx);
return SC_ERROR_INTERNAL;
}
*out_len = tmplen;
if (!EVP_EncryptFinal_ex(cctx, *out + *out_len, &tmplen)) {
EVP_CIPHER_CTX_free(cctx);
return SC_ERROR_INTERNAL;
}
*out_len += tmplen;
EVP_CIPHER_CTX_free(cctx);
#endif
return 0;
}
@ -270,10 +413,16 @@ sm_decrypt_des_cbc3(struct sc_context *ctx, unsigned char *key,
unsigned char *data, size_t data_len,
unsigned char **out, size_t *out_len)
{
#if OPENSSL_VERSION_NUMBER < 0x30000000L
DES_cblock kk,k2;
DES_key_schedule ks,ks2;
DES_cblock icv={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
size_t st;
#else
unsigned char icv[] = {0x00 ,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
EVP_CIPHER_CTX *cctx = NULL;
int tmplen;
#endif
SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_SM);
if (!out || !out_len)
@ -286,6 +435,7 @@ sm_decrypt_des_cbc3(struct sc_context *ctx, unsigned char *key,
if (!(*out))
LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "SM decrypt_des_cbc3: allocation error");
#if OPENSSL_VERSION_NUMBER < 0x30000000L
memcpy(&kk, key, 8);
memcpy(&k2, key + 8, 8);
@ -295,21 +445,48 @@ sm_decrypt_des_cbc3(struct sc_context *ctx, unsigned char *key,
for (st=0; st<data_len; st+=8)
DES_3cbc_encrypt((DES_cblock *)(data + st),
(DES_cblock *)(*out + st), 8, &ks, &ks2, &icv, DES_DECRYPT);
#else
cctx = EVP_CIPHER_CTX_new();
if (!EVP_DecryptInit_ex2(cctx, EVP_des_ede_cbc(), key, icv, NULL)) {
EVP_CIPHER_CTX_free(cctx);
SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_SM, SC_ERROR_INTERNAL);
}
/* Disable padding, otherwise it will fail to decrypt non-padded inputs */
EVP_CIPHER_CTX_set_padding(cctx, 0);
if (!EVP_DecryptUpdate(cctx, *out, &tmplen, data, data_len)) {
EVP_CIPHER_CTX_free(cctx);
SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_SM, SC_ERROR_INTERNAL);
}
*out_len = tmplen;
if (!EVP_DecryptFinal_ex(cctx, *out + *out_len, &tmplen)) {
EVP_CIPHER_CTX_free(cctx);
SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_SM, SC_ERROR_INTERNAL);
}
*out_len += tmplen;
EVP_CIPHER_CTX_free(cctx);
#endif
SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_SM, SC_SUCCESS);
}
/* This function expects the data to be a multilpe of DES block size */
int
sm_encrypt_des_cbc3(struct sc_context *ctx, unsigned char *key,
const unsigned char *in, size_t in_len,
unsigned char **out, size_t *out_len, int not_force_pad)
{
#if OPENSSL_VERSION_NUMBER < 0x30000000L
DES_cblock kk,k2;
DES_key_schedule ks,ks2;
DES_cblock icv={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
size_t st;
#else
unsigned char icv[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
EVP_CIPHER_CTX *cctx = NULL;
int tmplen;
#endif
unsigned char *data;
size_t data_len, st;
size_t data_len;
SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_SM);
sc_debug(ctx, SC_LOG_DEBUG_SM,
@ -345,6 +522,7 @@ sm_encrypt_des_cbc3(struct sc_context *ctx, unsigned char *key,
LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "SM encrypt_des_cbc3: failure");
}
#if OPENSSL_VERSION_NUMBER < 0x30000000L
memcpy(&kk, key, 8);
memcpy(&k2, key + 8, 8);
@ -353,6 +531,27 @@ sm_encrypt_des_cbc3(struct sc_context *ctx, unsigned char *key,
for (st=0; st<data_len; st+=8)
DES_3cbc_encrypt((DES_cblock *)(data + st), (DES_cblock *)(*out + st), 8, &ks, &ks2, &icv, DES_ENCRYPT);
#else
cctx = EVP_CIPHER_CTX_new();
if (!EVP_EncryptInit_ex2(cctx, EVP_des_ede_cbc(), key, icv, NULL)) {
EVP_CIPHER_CTX_free(cctx);
SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_SM, SC_ERROR_INTERNAL);
}
/* Disable padding, otherwise it will fail to decrypt non-padded inputs */
EVP_CIPHER_CTX_set_padding(cctx, 0);
if (!EVP_EncryptUpdate(cctx, *out, &tmplen, data, data_len)) {
EVP_CIPHER_CTX_free(cctx);
SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_SM, SC_ERROR_INTERNAL);
}
*out_len = tmplen;
if (!EVP_EncryptFinal_ex(cctx, *out + *out_len, &tmplen)) {
EVP_CIPHER_CTX_free(cctx);
SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_SM, SC_ERROR_INTERNAL);
}
*out_len += tmplen;
EVP_CIPHER_CTX_free(cctx);
#endif
free(data);
SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_SM, SC_SUCCESS);

View File

@ -31,9 +31,9 @@ extern "C" {
#include "libopensc/sm.h"
DES_LONG DES_cbc_cksum_3des(const unsigned char *in, DES_cblock *output, long length,
DES_key_schedule *schedule, DES_key_schedule *schedule2, const_DES_cblock *ivec);
unsigned char *key, const_DES_cblock *ivec);
DES_LONG DES_cbc_cksum_3des_emv96(const unsigned char *in, DES_cblock *output,
long length, DES_key_schedule *schedule, DES_key_schedule *schedule2,
long length, unsigned char *key,
const_DES_cblock *ivec);
int sm_encrypt_des_ecb3(unsigned char *key, unsigned char *data, int data_len,
unsigned char **out, int *out_len);

View File

@ -49,8 +49,6 @@ int
sm_cwa_get_mac(struct sc_context *ctx, unsigned char *key, DES_cblock *icv,
unsigned char *in, int in_len, DES_cblock *out, int force_padding)
{
DES_cblock kk, k2;
DES_key_schedule ks,ks2;
unsigned char padding[8] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
unsigned char *buf;
@ -73,11 +71,7 @@ sm_cwa_get_mac(struct sc_context *ctx, unsigned char *key, DES_cblock *icv,
sc_debug(ctx, SC_LOG_DEBUG_SM, "sm_cwa_get_mac() data to MAC(%i) %s", in_len, sc_dump_hex(buf, in_len));
sc_debug(ctx, SC_LOG_DEBUG_SM, "sm_cwa_get_mac() ICV %s", sc_dump_hex((unsigned char *)icv, 8));
memcpy(&kk, key, 8);
memcpy(&k2, key + 8, 8);
DES_set_key_unchecked(&kk,&ks);
DES_set_key_unchecked(&k2,&ks2);
DES_cbc_cksum_3des_emv96(buf, out, in_len ,&ks, &ks2, icv);
DES_cbc_cksum_3des_emv96(buf, out, in_len, key, icv);
free(buf);
LOG_FUNC_RETURN(ctx, SC_SUCCESS);

View File

@ -129,8 +129,6 @@ sm_gp_get_cryptogram(unsigned char *session_key,
unsigned char *out, int out_len)
{
unsigned char block[24];
DES_cblock kk,k2;
DES_key_schedule ks,ks2;
DES_cblock cksum={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
if (out_len!=8)
@ -140,11 +138,7 @@ sm_gp_get_cryptogram(unsigned char *session_key,
memcpy(block + 8, right, 8);
memcpy(block + 16, "\x80\0\0\0\0\0\0\0",8);
memcpy(&kk, session_key, 8);
memcpy(&k2, session_key + 8, 8);
DES_set_key_unchecked(&kk,&ks);
DES_set_key_unchecked(&k2,&ks2);
DES_cbc_cksum_3des(block,&cksum, sizeof(block),&ks,&ks2,&cksum);
DES_cbc_cksum_3des(block,&cksum, sizeof(block), session_key, &cksum);
memcpy(out, cksum, 8);
@ -158,8 +152,6 @@ sm_gp_get_mac(unsigned char *key, DES_cblock *icv,
{
int len;
unsigned char *block;
DES_cblock kk, k2;
DES_key_schedule ks,ks2;
block = malloc(in_len + 8);
if (!block)
@ -170,12 +162,7 @@ sm_gp_get_mac(unsigned char *key, DES_cblock *icv,
len = in_len + 8;
len -= (len%8);
memcpy(&kk, key, 8);
memcpy(&k2, key + 8, 8);
DES_set_key_unchecked(&kk,&ks);
DES_set_key_unchecked(&k2,&ks2);
DES_cbc_cksum_3des(block, out, len ,&ks, &ks2, icv);
DES_cbc_cksum_3des(block, out, len, key, icv);
free(block);
return 0;

View File

@ -31,7 +31,7 @@ p11test_SOURCES = p11test.c p11test_loader.c \
p11test_case_pss_oaep.c \
p11test_case_interface.c \
p11test_helpers.c
p11test_CFLAGS = -DNDEBUG $(CMOCKA_CFLAGS)
p11test_CFLAGS = $(CMOCKA_CFLAGS)
p11test_LDADD = $(OPTIONAL_OPENSSL_LIBS) $(CMOCKA_LIBS)
if WIN32

View File

@ -37,6 +37,7 @@
/* Global variable keeping information about token we are using */
token_info_t token;
int debug_flag = 0;
void display_usage() {
fprintf(stdout,
@ -98,7 +99,7 @@ int main(int argc, char** argv) {
token.slot_id = (unsigned long) -1;
token.log.outfile = NULL;
while ((command = getopt(argc, argv, "?hm:s:p:io:")) != -1) {
while ((command = getopt(argc, argv, "?hm:s:p:io:v")) != -1) {
switch (command) {
case 'o':
token.log.outfile = strdup(optarg);
@ -120,6 +121,9 @@ int main(int argc, char** argv) {
case '?':
display_usage();
return 0;
case 'v':
debug_flag = 1;
break;
default:
break;
}

View File

@ -20,6 +20,7 @@
*/
#include "p11test_case_common.h"
#include "../../libopensc/sc-ossl-compat.h"
char name_buffer[11];
char flag_buffer[11];
@ -208,8 +209,8 @@ int callback_certificates(test_certs_t *objects,
if (EVP_PKEY_base_id(evp) == EVP_PKEY_RSA) {
/* Extract public RSA key */
RSA *rsa = EVP_PKEY_get0_RSA(evp);
if ((o->key.rsa = RSAPublicKey_dup(rsa)) == NULL) {
const RSA *rsa = EVP_PKEY_get0_RSA(evp);
if ((o->key.rsa = RSAPublicKey_dup((RSA *)rsa)) == NULL) {
fail_msg("RSAPublicKey_dup failed");
return -1;
}
@ -218,7 +219,7 @@ int callback_certificates(test_certs_t *objects,
} else if (EVP_PKEY_base_id(evp) == EVP_PKEY_EC) {
/* Extract public EC key */
EC_KEY *ec = EVP_PKEY_get0_EC_KEY(evp);
const EC_KEY *ec = EVP_PKEY_get0_EC_KEY(evp);
if ((o->key.ec = EC_KEY_dup(ec)) == NULL) {
fail_msg("EC_KEY_dup failed");
return -1;
@ -447,7 +448,6 @@ int callback_public_keys(test_certs_t *objects,
if (strcmp((char *)curve->data, "edwards25519")) {
debug_print(" [WARN %s ] Unknown curve name. "
" expected edwards25519, got %s", o->id_str, curve->data);
return -1;
}
evp_type = EVP_PKEY_ED25519;
break;
@ -455,7 +455,6 @@ int callback_public_keys(test_certs_t *objects,
if (strcmp((char *)curve->data, "curve25519")) {
debug_print(" [WARN %s ] Unknown curve name. "
" expected curve25519, got %s", o->id_str, curve->data);
return -1;
}
evp_type = EVP_PKEY_X25519;
break;
@ -466,12 +465,13 @@ int callback_public_keys(test_certs_t *objects,
ASN1_PRINTABLESTRING_free(curve);
} else if (d2i_ASN1_OBJECT(&obj, &a, (long)template[6].ulValueLen) != NULL) {
int nid = OBJ_obj2nid(obj);
ASN1_OBJECT_free(obj);
switch (o->key_type) {
case CKK_EC_EDWARDS:
if (nid != NID_ED25519) {
debug_print(" [WARN %s ] Unknown OID. "
" expected NID_ED25519 (%d), got %d", o->id_str, NID_ED25519, nid);
return -1;
}
evp_type = EVP_PKEY_ED25519;
break;
@ -479,7 +479,6 @@ int callback_public_keys(test_certs_t *objects,
if (nid != NID_X25519) {
debug_print(" [WARN %s ] Unknown OID. "
" expected NID_X25519 (%d), got %d", o->id_str, NID_X25519, nid);
return -1;
}
evp_type = EVP_PKEY_X25519;
break;
@ -487,7 +486,6 @@ int callback_public_keys(test_certs_t *objects,
debug_print(" [WARN %s ] Unknown key type %lu", o->id_str, o->key_type);
return -1;
}
ASN1_OBJECT_free(obj);
} else {
debug_print(" [WARN %s ] Failed to convert EC_PARAMS"
" to curve name or object id", o->id_str);
@ -780,8 +778,12 @@ const char *get_mechanism_name(int mech_id)
return "ECDH1_COFACTOR_DERIVE";
case CKM_EC_KEY_PAIR_GEN:
return "EC_KEY_PAIR_GEN";
case CKM_EC_EDWARDS_KEY_PAIR_GEN:
return "EC_EDWARDS_KEY_PAIR_GEN";
case CKM_RSA_PKCS_KEY_PAIR_GEN:
return "RSA_PKCS_KEY_PAIR_GEN";
case CKM_GENERIC_SECRET_KEY_GEN:
return "GENERIC_SECRET_KEY_GEN";
case CKM_MD5_RSA_PKCS:
return "MD5_RSA_PKCS";
case CKM_RIPEMD160_RSA_PKCS:
@ -802,6 +804,8 @@ const char *get_mechanism_name(int mech_id)
return "MD5_HMAC";
case CKM_SHA_1_HMAC:
return "SHA_1_HMAC";
case CKM_SHA224_HMAC:
return "SHA224_HMAC";
case CKM_SHA256_HMAC:
return "SHA256_HMAC";
case CKM_SHA384_HMAC:

View File

@ -498,9 +498,7 @@ int verify_message(test_cert_t *o, token_info_t *info, CK_BYTE *message,
CK_FUNCTION_LIST_PTR fp = info->function_pointer;
CK_MECHANISM sign_mechanism = { mech->mech, NULL_PTR, 0 };
static int verify_support = 1;
#ifndef NDEBUG
char *name;
#endif
if (!verify_support)
goto openssl_verify;
@ -531,15 +529,11 @@ int verify_message(test_cert_t *o, token_info_t *info, CK_BYTE *message,
/* Final */
rv = fp->C_VerifyFinal(info->session_handle,
sign, sign_length);
#ifndef NDEBUG
name = "C_VerifyFinal";
#endif
} else {
rv = fp->C_Verify(info->session_handle,
message, message_length, sign, sign_length);
#ifndef NDEBUG
name = "C_Verify";
#endif
}
if (rv == CKR_OK) {
mech->result_flags |= FLAGS_SIGN;

View File

@ -33,12 +33,12 @@
#define MAX_MECHS 200
#ifndef NDEBUG
#define debug_print(fmt, ...) \
{ fprintf(stderr, fmt "\n", ##__VA_ARGS__); } while (0)
#else
#define debug_print(fmt, ...)
#endif
#define debug_print(fmt, ...) \
do { \
if (debug_flag) { \
fprintf(stderr, fmt "\n", ##__VA_ARGS__); \
} \
} while (0)
#define FLAGS_SIGN 0x01
#define FLAGS_SIGN_OPENSSL 0x02
@ -89,6 +89,7 @@ typedef struct {
} token_info_t;
extern token_info_t token;
extern int debug_flag;
#endif /* P11TEST_COMMON_H */

View File

@ -32,6 +32,13 @@ compression_SOURCES = compression.c
compression_LDADD = $(LDADD) $(OPTIONAL_ZLIB_LIBS)
endif
if ENABLE_OPENSSL
noinst_PROGRAMS += sm
TESTS += sm
sm_SOURCES = sm.c
sm_LDADD = $(top_builddir)/src/sm/libsm.la $(LDADD)
endif
endif

View File

@ -241,7 +241,7 @@ static int setup_sc_context(void **state)
sc_context_t *ctx = NULL;
int rv;
rv = sc_establish_context(&ctx, "fuzz");
rv = sc_establish_context(&ctx, "asn1");
assert_non_null(ctx);
assert_int_equal(rv, SC_SUCCESS);

376
src/tests/unittests/sm.c Normal file
View File

@ -0,0 +1,376 @@
/*
* sm.c: Unit tests for Secure Messaging
*
* Copyright (C) 2021 Red Hat, Inc.
*
* Author: Jakub Jelen <jjelen@redhat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "torture.h"
#include "libopensc/log.c"
#include "sm/sm-common.h"
/* Setup context */
static int setup_sc_context(void **state)
{
sc_context_t *ctx = NULL;
int rv;
rv = sc_establish_context(&ctx, "sm");
assert_non_null(ctx);
assert_int_equal(rv, SC_SUCCESS);
*state = ctx;
return 0;
}
/* Cleanup context */
static int teardown_sc_context(void **state)
{
sc_context_t *ctx = *state;
int rv;
rv = sc_release_context(ctx);
assert_int_equal(rv, SC_SUCCESS);
return 0;
}
static void torture_sm_incr_ssc(void **state)
{
unsigned char in[] = {0x00, 0x00};
(void)state;
/* just make sure it does not crash */
sm_incr_ssc(NULL, 0);
/* zero-length input should not underflow the buffer */
sm_incr_ssc(in, 0);
/* shortest possible input */
in[0] = 0x42;
sm_incr_ssc(in, 1);
assert_int_equal(in[0], 0x43);
/* overflow to the second byte */
in[0] = 0x00;
in[1] = 0xff;
sm_incr_ssc(in, 2);
assert_int_equal(in[0], 0x01);
assert_int_equal(in[1], 0x00);
/* overflow */
in[0] = 0xff;
in[1] = 0xff;
sm_incr_ssc(in, 2);
assert_int_equal(in[0], 0x00);
assert_int_equal(in[1], 0x00);
}
static void torture_sm_crypt_des_cbc3(void **state)
{
sc_context_t *ctx = *state;
/* Test vector from
* https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-20.pdf
* 5.2.1.1 The Variable Plaintext Known Answer Test -TCBC Mode
*/
unsigned char key[] = {
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY1 */
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY2 */};
unsigned char plain[] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
unsigned char ciphertext[] = {0x95, 0xF8, 0xA5, 0xE5, 0xDD, 0x31, 0xD9, 0x00};
unsigned char *out = NULL; /* allocates */
size_t out_len = 0;
int rv;
rv = sm_encrypt_des_cbc3(ctx, key, plain, sizeof(plain), &out, &out_len, 1);
assert_int_equal(rv, SC_SUCCESS);
assert_int_equal(out_len, sizeof(ciphertext));
assert_memory_equal(out, ciphertext, sizeof(ciphertext));
free(out);
out = NULL;
out_len = 0;
rv = sm_decrypt_des_cbc3(ctx, key, ciphertext, sizeof(ciphertext), &out, &out_len);
assert_int_equal(rv, SC_SUCCESS);
assert_memory_equal(out, plain, sizeof(plain));
free(out);
}
static void torture_sm_crypt_des_cbc3_multiblock(void **state)
{
/* not a test vector -- generated by openssl 1.1.1 */
sc_context_t *ctx = *state;
unsigned char key[] = {
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY1 */
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY2 */};
unsigned char plain[] = {
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00};
unsigned char ciphertext[] = {
0x95, 0xF8, 0xA5, 0xE5, 0xDD, 0x31, 0xD9, 0x00,
0xAF, 0xA0, 0x77, 0x1d, 0x35, 0xE1, 0xCC, 0x26};
unsigned char *out = NULL; /* allocates */
size_t out_len = 0;
int rv;
rv = sm_encrypt_des_cbc3(ctx, key, plain, sizeof(plain), &out, &out_len, 1);
assert_int_equal(rv, SC_SUCCESS);
assert_int_equal(out_len, sizeof(ciphertext));
assert_memory_equal(out, ciphertext, sizeof(ciphertext));
free(out);
out = NULL;
out_len = 0;
rv = sm_decrypt_des_cbc3(ctx, key, ciphertext, sizeof(ciphertext), &out, &out_len);
assert_int_equal(rv, SC_SUCCESS);
assert_memory_equal(out, plain, sizeof(plain));
free(out);
}
static void torture_sm_crypt_des_cbc3_force_pad(void **state)
{
/* not a test vector -- generated by openssl 1.1.1 */
sc_context_t *ctx = *state;
unsigned char key[] = {
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY1 */
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY2 */};
unsigned char plain[] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
unsigned char ciphertext[] = {
0x95, 0xF8, 0xA5, 0xE5, 0xDD, 0x31, 0xD9, 0x00,
0xC6, 0xD3, 0xE1, 0x4F, 0xFB, 0xDE, 0xDF, 0xF9};
unsigned char *out = NULL; /* allocates */
size_t out_len = 0;
int rv;
rv = sm_encrypt_des_cbc3(ctx, key, plain, sizeof(plain), &out, &out_len, 0);
assert_int_equal(rv, SC_SUCCESS);
assert_int_equal(out_len, sizeof(ciphertext));
assert_memory_equal(out, ciphertext, sizeof(ciphertext));
free(out);
out = NULL;
out_len = 0;
rv = sm_decrypt_des_cbc3(ctx, key, ciphertext, sizeof(ciphertext), &out, &out_len);
assert_int_equal(rv, SC_SUCCESS);
assert_memory_equal(out, plain, sizeof(plain));
free(out);
}
static void torture_sm_encrypt_des_ecb3(void **state)
{
/* Test vector from
* https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-20.pdf
* 5.2.1.1 The Variable Plaintext Known Answer Test -TCBC Mode
*/
unsigned char key[] = {
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY1 */
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY2 */};
unsigned char plain[] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
unsigned char ciphertext[] = {0x95, 0xF8, 0xA5, 0xE5, 0xDD, 0x31, 0xD9, 0x00};
unsigned char *out = NULL; /* allocates */
int out_len = 0;
int rv;
(void)state;
rv = sm_encrypt_des_ecb3(key, plain, sizeof(plain), &out, &out_len);
assert_int_equal(rv, SC_SUCCESS);
assert_int_equal(out_len, sizeof(ciphertext));
assert_memory_equal(out, ciphertext, sizeof(ciphertext));
free(out);
out = NULL;
out_len = 0;
rv = sm_encrypt_des_ecb3(key, ciphertext, sizeof(ciphertext), &out, &out_len);
assert_int_equal(rv, SC_SUCCESS);
assert_memory_equal(out, plain, sizeof(plain));
free(out);
}
static void torture_sm_encrypt_des_ecb3_multiblock(void **state)
{
/* not a test vector -- generated by openssl 1.1.1 */
unsigned char key[] = {
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY1 */
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY2 */};
unsigned char plain[] = {
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
unsigned char ciphertext[] = {
0x95, 0xF8, 0xA5, 0xE5, 0xDD, 0x31, 0xD9, 0x00,
0x4B, 0xD3, 0x88, 0xFF, 0x6C, 0xD8, 0x1D, 0x4F};
unsigned char *out = NULL; /* allocates */
int out_len = 0;
int rv;
(void)state;
rv = sm_encrypt_des_ecb3(key, plain, sizeof(plain), &out, &out_len);
assert_int_equal(rv, SC_SUCCESS);
assert_int_equal(out_len, sizeof(ciphertext));
assert_memory_equal(out, ciphertext, sizeof(ciphertext));
free(out);
out = NULL;
out_len = 0;
rv = sm_encrypt_des_ecb3(key, ciphertext, sizeof(ciphertext), &out, &out_len);
assert_int_equal(rv, SC_SUCCESS);
assert_memory_equal(out, plain, sizeof(plain));
free(out);
}
static void torture_DES_cbc_cksum_3des(void **state)
{
/* not a test vector -- generated by openssl 1.1.1 */
unsigned char key[] = {
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY1 */
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY2 */};
unsigned char iv[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
unsigned char plain[] = {
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
unsigned char checksum_ref[] = {
0x95, 0xF8, 0xA5, 0xE5, 0xDD, 0x31, 0xD9, 0x00};
unsigned long sum_ref = 0xdd31d900UL;
unsigned char checksum[8];
unsigned long sum;
(void)state;
sum = DES_cbc_cksum_3des(plain, &checksum, sizeof(plain), key, &iv);
assert_int_equal(sum, sum_ref);
assert_memory_equal(checksum, checksum_ref, sizeof(checksum_ref));
/* The checksum argument is not required */
sum = DES_cbc_cksum_3des(plain, NULL, sizeof(plain), key, &iv);
assert_int_equal(sum, sum_ref);
}
static void torture_DES_cbc_cksum_3des_multiblock(void **state)
{
/* not a test vector -- generated by openssl 1.1.1 */
unsigned char key[] = {
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY1 */
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY2 */};
unsigned char iv[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
/* I think this function assumes/requires full blocks */
unsigned char plain[] = {
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
unsigned char checksum_ref[] = {
0xC6, 0x3F, 0x6E, 0x72, 0xC7, 0xCF, 0x4E, 0x07};
unsigned long sum_ref = 0xc7cf4e07UL;
unsigned char checksum[8];
unsigned long sum;
(void)state;
sum = DES_cbc_cksum_3des(plain, &checksum, sizeof(plain), key, &iv);
assert_memory_equal(checksum, checksum_ref, sizeof(checksum_ref));
assert_int_equal(sum, sum_ref);
/* The checksum argument is not required */
sum = DES_cbc_cksum_3des(plain, NULL, sizeof(plain), key, &iv);
assert_int_equal(sum, sum_ref);
}
static void torture_DES_cbc_cksum_3des_emv96(void **state)
{
/* not a test vector -- generated by openssl 1.1.1 */
unsigned char key[] = {
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY1 */
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY2 */};
unsigned char iv[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
unsigned char plain[] = {
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
unsigned char checksum_ref[] = {
0x00, 0x00, 0x00, 0x00, 0xDD, 0x31, 0xD9, 0x00};
unsigned long sum_ref = 0xdd31d900UL;
unsigned char checksum[8];
unsigned long sum;
(void)state;
sum = DES_cbc_cksum_3des_emv96(plain, &checksum, sizeof(plain), key, &iv);
assert_int_equal(sum, sum_ref);
assert_memory_equal(checksum, checksum_ref, sizeof(checksum_ref));
/* The checksum argument is not required */
sum = DES_cbc_cksum_3des_emv96(plain, NULL, sizeof(plain), key, &iv);
assert_int_equal(sum, sum_ref);
}
static void torture_DES_cbc_cksum_3des_emv96_multiblock(void **state)
{
/* not a test vector -- generated by openssl 1.1.1 */
unsigned char key[] = {
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY1 */
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY2 */};
unsigned char iv[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
/* I think this function assumes/requires full blocks */
unsigned char plain[] = {
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
unsigned char checksum_ref[] = {
0x95, 0xf8, 0xA5, 0xe5, 0xC7, 0xCF, 0x4E, 0x07};
unsigned long sum_ref = 0xc7cf4e07UL;
unsigned char checksum[8] = {0};
unsigned long sum;
(void)state;
sum = DES_cbc_cksum_3des_emv96(plain, &checksum, sizeof(plain), key, &iv);
assert_memory_equal(checksum, checksum_ref, sizeof(checksum_ref));
assert_int_equal(sum, sum_ref);
/* The checksum argument is not required */
sum = DES_cbc_cksum_3des_emv96(plain, NULL, sizeof(plain), key, &iv);
assert_int_equal(sum, sum_ref);
}
int main(void)
{
int rc;
struct CMUnitTest tests[] = {
/* sm_incr_ssc */
cmocka_unit_test(torture_sm_incr_ssc),
/* sm_encrypt_des_cbc3 and sm_decrypt_des_cbc3 */
cmocka_unit_test_setup_teardown(torture_sm_crypt_des_cbc3,
setup_sc_context, teardown_sc_context),
cmocka_unit_test_setup_teardown(torture_sm_crypt_des_cbc3_multiblock,
setup_sc_context, teardown_sc_context),
cmocka_unit_test_setup_teardown(torture_sm_crypt_des_cbc3_force_pad,
setup_sc_context, teardown_sc_context),
/* sm_encrypt_des_ecb3 */
cmocka_unit_test(torture_sm_encrypt_des_ecb3),
cmocka_unit_test(torture_sm_encrypt_des_ecb3_multiblock),
/* DES_cbc_cksum_3des */
cmocka_unit_test(torture_DES_cbc_cksum_3des),
cmocka_unit_test(torture_DES_cbc_cksum_3des_multiblock),
/* DES_cbc_cksum_3des_emv96 */
cmocka_unit_test(torture_DES_cbc_cksum_3des_emv96),
cmocka_unit_test(torture_DES_cbc_cksum_3des_emv96_multiblock),
};
rc = cmocka_run_group_tests(tests, NULL, NULL);
return rc;
}