Merge pull request #2343 from Jakuje/ossl3v1
Working subset of #2337 (OpenSSL 3.0)
This commit is contained in:
commit
c42792c216
|
@ -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(
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -273,6 +273,7 @@ static sc_ossl_inline void CRYPTO_secure_malloc_done()
|
|||
|
||||
#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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}
|
||||
};
|
||||
|
|
|
@ -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}
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue