sm: Rewrite to use non-deprecated OpenSSL 3.0 API

This commit is contained in:
Jakub Jelen 2021-05-06 10:53:56 +02:00
parent 07f5e63abf
commit 1b92501ef9
5 changed files with 338 additions and 40 deletions

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

@ -211,10 +211,10 @@ static void torture_sm_encrypt_des_ecb3_multiblock(void **state)
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY2 */};
unsigned char plain[] = {
0x80, 0x00, 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,
0x18, 0x0d, 0x91, 0xdf, 0xa1, 0x25, 0x2f, 0x81};
0x4B, 0xD3, 0x88, 0xFF, 0x6C, 0xD8, 0x1D, 0x4F};
unsigned char *out = NULL; /* allocates */
int out_len = 0;
int rv;
@ -235,6 +235,118 @@ static void torture_sm_encrypt_des_ecb3_multiblock(void **state)
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;
@ -251,6 +363,12 @@ int main(void)
/* 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);