sm: Rewrite to use non-deprecated OpenSSL 3.0 API
This commit is contained in:
parent
07f5e63abf
commit
1b92501ef9
@ -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,19 +196,84 @@ 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;
|
||||
|
||||
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);
|
||||
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user