Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support SM3 and SM4 #271

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,16 @@ AC_ARG_WITH([openssl],
]
)

AC_ARG_WITH([openssl-smX],
AS_HELP_STRING([--with-openssl-smX], [libtpms supports SM3 and SM4, default not support]), [with_openssl_sm=yes], [with_openssl_sm=no])
AS_IF([test "x$with_openssl_sm" != "xno"], [
AC_DEFINE([ALG_SM3_256], [1], ["1 denotes to support SM3, and 0 not support"])
AC_DEFINE([ALG_SM4], [1], ["1 denotes to support SM3, and 0 not support"])
])
AS_IF([test "x$with_openssl_sm" = "xno"], [
AC_DEFINE([ALG_SM3_256], [0], ["1 denotes to support SM3, and 0 not support"])
AC_DEFINE([ALG_SM4], [0], ["1 denotes to support SM3, and 0 not support"])
])
case "$cryptolib" in
freebl)
AM_CONDITIONAL(LIBTPMS_USE_FREEBL, true)
Expand Down
6 changes: 5 additions & 1 deletion src/tpm2/HashTestData.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,11 @@ TPM2B_SHA512 c_SHA512_digest = {{64, {
TPM2B_TYPE(EMPTY, 1);

#if ALG_SM3_256 == YES
TPM2B_EMPTY c_SM3_256_digest = {{0, {0}}};
TPM2B_TYPE(SM3_256, 32);
TPM2B_SM3_256 c_SM3_256_digest = {{32, {
0xbb,0x9e,0x23,0x79,0xfe,0xbb,0xf8,0xb0,0x1d,0x27,0x5f,0x30,0x71,0xbe,0xce,0x8a,
0xb7,0x3f,0xee,0x6b,0xed,0xd7,0xee,0x45,0x4f,0x80,0xca,0x70,0x6c,0x09,0xb6,0x1a
}}};
#endif

#if ALG_SHA3_256 == YES
Expand Down
12 changes: 10 additions & 2 deletions src/tpm2/Marshal.c
Original file line number Diff line number Diff line change
Expand Up @@ -1178,8 +1178,16 @@ TPMI_AES_KEY_BITS_Marshal(TPMI_AES_KEY_BITS *source, BYTE **buffer, INT32 *size)
written += TPM_KEY_BITS_Marshal(source, buffer, size);
return written;
}

UINT16 // libtpms added begin
#if ALG_SM4 // libtpms added begin
UINT16
TPMI_SM4_KEY_BITS_Marshal(TPMI_SM4_KEY_BITS *source, BYTE **buffer, INT32 *size)
{
UINT16 written = 0;
written += TPM_KEY_BITS_Marshal(source, buffer, size);
return written;
}
#endif // libtpms added end
UINT16
TPMI_TDES_KEY_BITS_Marshal(TPMI_TDES_KEY_BITS *source, BYTE **buffer, INT32 *size)
{
UINT16 written = 0;
Expand Down
8 changes: 6 additions & 2 deletions src/tpm2/Marshal_fp.h
Original file line number Diff line number Diff line change
Expand Up @@ -238,8 +238,12 @@ extern "C" {
TPM2B_ATTEST_Marshal(TPM2B_ATTEST *source, BYTE **buffer, INT32 *size);
UINT16
TPMI_AES_KEY_BITS_Marshal(TPMI_AES_KEY_BITS *source, BYTE **buffer, INT32 *size);
UINT16 // libtpms added
TPMI_TDES_KEY_BITS_Marshal(TPMI_TDES_KEY_BITS *source, BYTE **buffer, INT32 *size);
#if ALG_SM4 // libtpms begin
UINT16
TPMI_SM4_KEY_BITS_Marshal(TPMI_SM4_KEY_BITS *source, BYTE **buffer, INT32 *size);
#endif
UINT16
TPMI_TDES_KEY_BITS_Marshal(TPMI_TDES_KEY_BITS *source, BYTE **buffer, INT32 *size); // libtpms end
UINT16
TPMI_CAMELLIA_KEY_BITS_Marshal(TPMI_CAMELLIA_KEY_BITS *source, BYTE **buffer, INT32 *size);
UINT16
Expand Down
154 changes: 146 additions & 8 deletions src/tpm2/NVMarshal.c
Original file line number Diff line number Diff line change
Expand Up @@ -774,8 +774,8 @@ PCR_SAVE_Marshal(PCR_SAVE *data, BYTE **buffer, INT32 *size)
written += Array_Marshal((BYTE *)&data->Sm3_256, array_size,
buffer, size);
#endif
#if ALG_SHA3_256 || ALG_SHA3_384 || ALG_SHA3_512 || ALG_SM3_256
#error SHA3 and SM3 are not supported
#if ALG_SHA3_256 || ALG_SHA3_384 || ALG_SHA3_512
#error SHA3 are not supported
#endif

/* end marker */
Expand Down Expand Up @@ -879,8 +879,8 @@ PCR_SAVE_Unmarshal(PCR_SAVE *data, BYTE **buffer, INT32 *size,
t = (BYTE *)&data->Sm3_256;
break;
#endif
#if ALG_SHA3_256 || ALG_SHA3_384 || ALG_SHA3_512 || ALG_SM3_256
#error SHA3 and SM3 are not supported
#if ALG_SHA3_256 || ALG_SHA3_384 || ALG_SHA3_512
#error SHA3 are not supported
#endif
case TPM_ALG_NULL:
/* end marker */
Expand Down Expand Up @@ -990,8 +990,8 @@ PCR_Marshal(PCR *data, BYTE **buffer, INT32 *size)
written += Array_Marshal((BYTE *)&data->Sm3_256Pcr, array_size,
buffer, size);
#endif
#if ALG_SHA3_256 || ALG_SHA3_384 || ALG_SHA3_512 || ALG_SM3_256
#error SHA3 and SM3 are not supported
#if ALG_SHA3_256 || ALG_SHA3_384 || ALG_SHA3_512
#error SHA3 are not supported
#endif

/* end marker */
Expand Down Expand Up @@ -1061,8 +1061,8 @@ PCR_Unmarshal(PCR *data, BYTE **buffer, INT32 *size,
t = (BYTE *)&data->Sm3_256Pcr;
break;
#endif
#if ALG_SHA3_256 || ALG_SHA3_384 || ALG_SHA3_512 || ALG_SM3_256
#error SHA3 and SM3 are not supported
#if ALG_SHA3_256 || ALG_SHA3_384 || ALG_SHA3_512
#error SHA3 are not supported
#endif
case TPM_ALG_NULL:
/* end marker */
Expand Down Expand Up @@ -2026,7 +2026,133 @@ tpmHashStateSHA512_Unmarshal(SHA512_CTX *data, BYTE **buffer, INT32 *size,
return rc;
}
#endif
#if ALG_SM3_256

#define HASH_STATE_SM3_256_MAGIC 0x10854a09
#define HASH_STATE_SM3_256_VERSION 2

static UINT16
tpmHashStateSM3_256_Marshal(tpmHashStateSM3_256_t *data, BYTE **buffer, INT32 *size,
UINT16 hashAlg)
{
UINT16 written = 0;
UINT16 array_size;
SM3_CTX *sm3_ctx = NULL;
BLOCK_SKIP_INIT;

sm3_ctx = EVP_MD_CTX_md_data(*data);
written = NV_HEADER_Marshal(buffer, size,
HASH_STATE_SM3_256_VERSION,
HASH_STATE_SM3_256_MAGIC, 1);
written += UINT32_Marshal(&sm3_ctx->A, buffer, size);
written += UINT32_Marshal(&sm3_ctx->B, buffer, size);
written += UINT32_Marshal(&sm3_ctx->C, buffer, size);
written += UINT32_Marshal(&sm3_ctx->D, buffer, size);
written += UINT32_Marshal(&sm3_ctx->E, buffer, size);
written += UINT32_Marshal(&sm3_ctx->F, buffer, size);
written += UINT32_Marshal(&sm3_ctx->G, buffer, size);
written += UINT32_Marshal(&sm3_ctx->H, buffer, size);
written += UINT32_Marshal(&sm3_ctx->Nl, buffer, size);
written += UINT32_Marshal(&sm3_ctx->Nh, buffer, size);
/* data must be written as array */
array_size = sizeof(sm3_ctx->data);
written += UINT16_Marshal(&array_size, buffer, size);
written += Array_Marshal((BYTE *)&sm3_ctx->data[0], array_size, buffer, size);
written += UINT32_Marshal(&sm3_ctx->num, buffer, size);
written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
/* future versions append below this line */

BLOCK_SKIP_WRITE_POP(size);

BLOCK_SKIP_WRITE_CHECK;

return written;
}
static UINT16
tpmHashStateSM3_256_Unmarshal(tpmHashStateSM3_256_t *data, BYTE **buffer, INT32 *size,
UINT16 hashAlg)
{
UINT16 rc = TPM_RC_SUCCESS;
UINT16 array_size;
NV_HEADER hdr;
SM3_CTX *sm3_ctx = NULL;

(*data) = EVP_MD_CTX_new();
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we shouldn't create a context here but fill the data just like we fill it with sha1 etc.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The risk with sm3 is that its data structure has always been opaque it seems. That leaves OpenSSL the opportunity to shuffle things around. They may not do that but the risk is there. In contrast to that we have the SHAT_CTX, SHA256_CTX, etc. that are available via sha.h, so there's less of a risk with them on that level.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the OpenSSL 3.0 migration guide , users are strongly encouraged to update their code to use the high level APIs instead. Low level APIs have been deprecated in OpenSSL 3.0, and will most likely be removed in a future versions.
OpenSSL intentionally avoids the user to perceive the internal structure of XXX_CTX, we can only use its pointer. So we don't need to care about its structure.
In the long term, we need to switch to the "high level" APIs (such as the EVP APIs).

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know... but it's not going to be that simple. See my comment over there: #215 (comment)

if ((*data) == NULL) {
rc = TPM_RC_FAILURE;
}
if (rc == TPM_RC_SUCCESS) {
EVP_DigestInit_ex(*data, EVP_sm3(), NULL);
sm3_ctx = EVP_MD_CTX_md_data(*data);
}

if (rc == TPM_RC_SUCCESS) {
rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
HASH_STATE_SM3_256_VERSION,
HASH_STATE_SM3_256_MAGIC);
}

if (rc == TPM_RC_SUCCESS) {
rc = UINT32_Unmarshal(&sm3_ctx->A, buffer, size);
}
if (rc == TPM_RC_SUCCESS) {
rc = UINT32_Unmarshal(&sm3_ctx->B, buffer, size);
}
if (rc == TPM_RC_SUCCESS) {
rc = UINT32_Unmarshal(&sm3_ctx->C, buffer, size);
}
if (rc == TPM_RC_SUCCESS) {
rc = UINT32_Unmarshal(&sm3_ctx->D, buffer, size);
}
if (rc == TPM_RC_SUCCESS) {
rc = UINT32_Unmarshal(&sm3_ctx->E, buffer, size);
}
if (rc == TPM_RC_SUCCESS) {
rc = UINT32_Unmarshal(&sm3_ctx->F, buffer, size);
}
if (rc == TPM_RC_SUCCESS) {
rc = UINT32_Unmarshal(&sm3_ctx->G, buffer, size);
}
if (rc == TPM_RC_SUCCESS) {
rc = UINT32_Unmarshal(&sm3_ctx->H, buffer, size);
}
if (rc == TPM_RC_SUCCESS) {
rc = UINT32_Unmarshal(&sm3_ctx->Nl, buffer, size);
}
if (rc == TPM_RC_SUCCESS) {
rc = UINT32_Unmarshal(&sm3_ctx->Nh, buffer, size);
}
if (rc == TPM_RC_SUCCESS) {
rc = UINT16_Unmarshal(&array_size, buffer, size);
}
if (rc == TPM_RC_SUCCESS &&
array_size != sizeof(sm3_ctx->data)) {
TPMLIB_LogTPM2Error("HASH_STATE_SM3_256: Bad array size for data; "
"expected %zu, got %u\n",
sizeof(sm3_ctx->data), array_size);
rc = TPM_RC_BAD_PARAMETER;
}
if (rc == TPM_RC_SUCCESS) {
rc = Array_Unmarshal((BYTE *)&sm3_ctx->data[0], array_size,
buffer, size);
}
if (rc == TPM_RC_SUCCESS) {
rc = UINT32_Unmarshal(&sm3_ctx->num, buffer, size);
}

/* version 2 starts having indicator for next versions that we can skip;
this allows us to downgrade state */
if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
"HASH_STATE_SM3_256", "version 3 or later");
/* future versions nest-append here */
}

skip_future_versions:

return rc;
}
#endif
#define ANY_HASH_STATE_MAGIC 0x349d494b
#define ANY_HASH_STATE_VERSION 2

Expand Down Expand Up @@ -2063,6 +2189,12 @@ ANY_HASH_STATE_Marshal(ANY_HASH_STATE *data, BYTE **buffer, INT32 *size,
written += tpmHashStateSHA512_Marshal(&data->Sha512, buffer, size,
ALG_SHA512_VALUE);
break;
#endif
#if ALG_SM3_256
case ALG_SM3_256_VALUE:
written += tpmHashStateSM3_256_Marshal(&data->Sm3_256, buffer, size,
ALG_SM3_256_VALUE);
break;
#endif
default:
break;
Expand Down Expand Up @@ -2113,6 +2245,12 @@ ANY_HASH_STATE_Unmarshal(ANY_HASH_STATE *data, BYTE **buffer, INT32 *size,
rc = tpmHashStateSHA512_Unmarshal(&data->Sha512, buffer, size,
ALG_SHA512_VALUE);
break;
#endif
#if ALG_SM3_256
case ALG_SM3_256_VALUE:
rc = tpmHashStateSM3_256_Unmarshal(&data->Sm3_256, buffer, size,
ALG_SM3_256_VALUE);
break;
#endif
}

Expand Down
1 change: 0 additions & 1 deletion src/tpm2/StateMarshal.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@

#include <stdlib.h>

#include "config.h"

#include "StateMarshal.h"
#include "Volatile.h"
Expand Down
4 changes: 2 additions & 2 deletions src/tpm2/SymmetricTestData.h
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ const BYTE dataOut_SM4128_ECB [] = {
0x2F, 0x1D, 0x30, 0x5A, 0x7F, 0xB1, 0x7D, 0xF9,
0x85, 0xF8, 0x1C, 0x84, 0x82, 0x19, 0x23, 0x04,
0x00, 0x2A, 0x8A, 0x4E, 0xFA, 0x86, 0x3C, 0xCA,
0xD0, 0x24, 0xAC, 0x03, 0x00, 0xBB, 0x40, 0xD2}
0xD0, 0x24, 0xAC, 0x03, 0x00, 0xBB, 0x40, 0xD2};
const BYTE dataOut_SM4128_CBC [] = {
0x78, 0xEB, 0xB1, 0x1C, 0xC4, 0x0B, 0x0A, 0x48,
0x31, 0x2A, 0xAE, 0xB2, 0x04, 0x02, 0x44, 0xCB,
Expand All @@ -389,7 +389,7 @@ const BYTE dataOut_SM4128_OFB [] = {
echo "AAAAAAAABBBBBBBBCCCCCCCCDDDDDDDDEEEEEEEEFFFFFFFFAAAAAAAABBBBBBBB" | xxd -p -r > plain.txt
openssl enc -sm4-ctr -in plain.txt -iv "F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF" -out out.txt -K "0123456789ABCDEFFEDCBA9876543210"
*/
const BYTE dataOut_SM4_CTR [] = {
const BYTE dataOut_SM4128_CTR [] = {
0xF4, 0x88, 0x4C, 0x6D, 0x39, 0x7E, 0x0B, 0x06,
0x3D, 0xAC, 0xD9, 0x46, 0x1A, 0xA4, 0xA5, 0x6A,
0x60, 0xDD, 0xA7, 0x5F, 0x86, 0xBC, 0xFE, 0xA4,
Expand Down
1 change: 1 addition & 0 deletions src/tpm2/TpmProfile.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
// A.2 TpmProfile.h
#ifndef _TPM_PROFILE_H_
#define _TPM_PROFILE_H_
#include "config.h" /* libtpms added */
// Table 2:4 - Defines for Logic Values
#undef TRUE
#define TRUE 1
Expand Down
4 changes: 4 additions & 0 deletions src/tpm2/Unmarshal_fp.h
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,10 @@ extern "C" {
#endif /* libtpms added */
LIB_EXPORT TPM_RC
TPMI_AES_KEY_BITS_Unmarshal(TPMI_AES_KEY_BITS *target, BYTE **buffer, INT32 *size);
#if ALG_SM4 /* libtpms added begin */
TPM_RC
TPMI_SM4_KEY_BITS_Unmarshal(TPMI_SM4_KEY_BITS *target, BYTE **buffer, INT32 *size);
#endif /* libtpms added end */
LIB_EXPORT TPM_RC
TPMI_CAMELLIA_KEY_BITS_Unmarshal(TPMI_CAMELLIA_KEY_BITS *target, BYTE **buffer, INT32 *size);
LIB_EXPORT TPM_RC /* libtpms added */
Expand Down
1 change: 0 additions & 1 deletion src/tpm2/Volatile.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
#endif
#include <string.h>

#include "config.h"

#include "assert.h"
#include "NVMarshal.h"
Expand Down
4 changes: 3 additions & 1 deletion src/tpm2/crypto/CryptSym.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ typedef union tpmCryptKeySchedule_t {
encrypt(SWIZZLE(keySchedule, in, out))
# define DECRYPT(keySchedule, in, out) \
decrypt(SWIZZLE(keySchedule, in, out))

#define FINAL(keySchedule) final((void *)(keySchedule))
/* Note that the macros rely on encrypt as local values in the functions that use these
macros. Those parameters are set by the macro that set the key schedule to be used for the
call. */
Expand All @@ -132,11 +132,13 @@ typedef union tpmCryptKeySchedule_t {
case TPM_ALG_##ALG: \
TpmCryptSetEncryptKey##ALG(key, keySizeInBits, &keySchedule.alg); \
encrypt = (TpmCryptSetSymKeyCall_t)TpmCryptEncrypt##ALG; \
final = (TpmCryptSymFinal_t)TpmCryptFinal##ALG; \
break;
#define DECRYPT_CASE(ALG, alg) \
case TPM_ALG_##ALG: \
TpmCryptSetDecryptKey##ALG(key, keySizeInBits, &keySchedule.alg); \
decrypt = (TpmCryptSetSymKeyCall_t)TpmCryptDecrypt##ALG; \
final = (TpmCryptSymFinal_t)TpmCryptFinal##ALG; \
break;

#endif
9 changes: 7 additions & 2 deletions src/tpm2/crypto/openssl/CryptCmac.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,8 @@ CryptCmacData(
BYTE *key = cmacState->symKey.t.buffer;
UINT16 keySizeInBits = cmacState->keySizeBits;
tpmCryptKeySchedule_t keySchedule;
TpmCryptSetSymKeyCall_t encrypt;
TpmCryptSetSymKeyCall_t encrypt;
TpmCryptSymFinal_t final;
//
memset(&keySchedule, 0, sizeof(keySchedule)); /* libtpms added: coverity */
// Set up the encryption values based on the algorithm
Expand All @@ -142,6 +143,8 @@ CryptCmacData(
cmacState->iv.t.buffer[cmacState->bcount] ^= *buffer++;
}
}
if (final)
FINAL(&keySchedule);
}

/* 10.2.6.3.3 CryptCmacEnd() */
Expand All @@ -162,6 +165,7 @@ CryptCmacEnd(
UINT16 keySizeInBits = cState->keySizeBits;
tpmCryptKeySchedule_t keySchedule;
TpmCryptSetSymKeyCall_t encrypt;
TpmCryptSymFinal_t final;
TPM2B_IV subkey = {{0, {0}}};
BOOL xorVal;
UINT16 i;
Expand Down Expand Up @@ -203,7 +207,8 @@ CryptCmacEnd(
ENCRYPT(&keySchedule, cState->iv.t.buffer, cState->iv.t.buffer);
i = (UINT16)MIN(cState->iv.t.size, outSize);
MemoryCopy(outBuffer, cState->iv.t.buffer, i);

if (final)
FINAL(&keySchedule);
return i;
}

Expand Down
Loading