Add SM2/SM3/SM4 examples
wolfCrypt-level ShangMi examples: SM3 hash (GB/T 32905 known answer), SM4-GCM with tamper detection, SM2 sign/verify including the ZA digest step, and SM2 ECDH. Requires the wolfSSL/wolfsm overlay.pull/610/head
parent
dbf6e9ad49
commit
eba0390017
|
|
@ -0,0 +1,30 @@
|
|||
CC=gcc
|
||||
WOLFSSL_INSTALL_DIR=/usr/local
|
||||
CFLAGS=-Wall -I$(WOLFSSL_INSTALL_DIR)/include
|
||||
LIBS=-L$(WOLFSSL_INSTALL_DIR)/lib -lwolfssl -lm
|
||||
|
||||
all: sm3-hash sm4-gcm-encrypt sm2-sign-verify sm2-ecdh
|
||||
|
||||
sm3-hash: sm3-hash.o
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
sm4-gcm-encrypt: sm4-gcm-encrypt.o
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
sm2-sign-verify: sm2-sign-verify.o
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
sm2-ecdh: sm2-ecdh.o
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
.PHONY: clean all check
|
||||
|
||||
clean:
|
||||
rm -f *.o sm3-hash sm4-gcm-encrypt sm2-sign-verify sm2-ecdh
|
||||
|
||||
check: all
|
||||
out=$$(./sm3-hash) && printf '%s' "$$out" | grep -q 'matches GB/T 32905 test vector'
|
||||
out=$$(./sm4-gcm-encrypt) && printf '%s' "$$out" | grep -q 'Tampered tag rejected as expected'
|
||||
out=$$(./sm2-sign-verify) && printf '%s' "$$out" | grep -q 'Signature verified'
|
||||
out=$$(./sm2-ecdh) && printf '%s' "$$out" | grep -q 'Shared secrets match'
|
||||
@echo "PASS: crypto-sm checks"
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
# wolfSSL SM2/SM3/SM4 Examples
|
||||
|
||||
Demonstrates the Chinese national (ShangMi) cryptographic algorithms at the
|
||||
wolfCrypt level:
|
||||
|
||||
* `sm3-hash.c` - SM3 hash (Chinese national standard GB/T 32905-2016),
|
||||
checked against the standard's "abc" test vector.
|
||||
* `sm4-gcm-encrypt.c` - SM4-GCM (GB/T 32907-2016) authenticated encryption
|
||||
with tamper detection.
|
||||
* `sm2-sign-verify.c` - SM2 (GB/T 32918) digital signatures, including the
|
||||
identity-based "ZA" digest step via `wc_ecc_sm2_create_digest()`.
|
||||
* `sm2-ecdh.c` - ECDH shared-secret agreement on the SM2 curve.
|
||||
|
||||
## Building wolfSSL
|
||||
|
||||
The SM algorithm implementations ship in the separate
|
||||
[wolfSSL/wolfsm](https://github.com/wolfSSL/wolfsm) overlay, so install that
|
||||
into a wolfSSL source tree first:
|
||||
|
||||
```
|
||||
git clone https://github.com/wolfSSL/wolfsm
|
||||
git clone https://github.com/wolfSSL/wolfssl
|
||||
cd wolfsm
|
||||
./install.sh ../wolfssl
|
||||
cd ../wolfssl
|
||||
./autogen.sh
|
||||
./configure --enable-sm2 --enable-sm3 --enable-sm4-gcm
|
||||
make
|
||||
sudo make install
|
||||
```
|
||||
|
||||
Other SM4 modes are available with `--enable-sm4-ecb`, `--enable-sm4-cbc`,
|
||||
`--enable-sm4-ctr` and `--enable-sm4-ccm`.
|
||||
|
||||
## Building and running the examples
|
||||
|
||||
```
|
||||
make
|
||||
./sm3-hash [message]
|
||||
./sm4-gcm-encrypt
|
||||
./sm2-sign-verify [message]
|
||||
./sm2-ecdh
|
||||
```
|
||||
|
|
@ -0,0 +1,140 @@
|
|||
/* sm2-ecdh.c
|
||||
*
|
||||
* Copyright (C) 2006-2026 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL. (formerly known as CyaSSL)
|
||||
*
|
||||
* wolfSSL is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfSSL 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
/* Example of ECDH over the SM2 curve: both sides compute the same shared
|
||||
* secret from their private key and the peer's public key.
|
||||
*
|
||||
* This is plain ECDH on the SM2P256V1 curve, not the full SM2 key exchange
|
||||
* protocol from GB/T 32918.3. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <wolfssl/options.h>
|
||||
#include <wolfssl/wolfcrypt/settings.h>
|
||||
#include <wolfssl/wolfcrypt/ecc.h>
|
||||
#include <wolfssl/wolfcrypt/sm2.h>
|
||||
#include <wolfssl/wolfcrypt/random.h>
|
||||
|
||||
#ifdef WOLFSSL_SM2
|
||||
|
||||
static void print_hex(const char* label, const byte* data, word32 len)
|
||||
{
|
||||
word32 i;
|
||||
|
||||
printf("%s: ", label);
|
||||
for (i = 0; i < len; i++)
|
||||
printf("%02x", data[i]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int ret;
|
||||
WC_RNG rng;
|
||||
int rngInit = 0;
|
||||
ecc_key alice;
|
||||
ecc_key bob;
|
||||
int aliceInit = 0;
|
||||
int bobInit = 0;
|
||||
byte secretA[32];
|
||||
byte secretB[32];
|
||||
word32 secretASz = (word32)sizeof(secretA);
|
||||
word32 secretBSz = (word32)sizeof(secretB);
|
||||
|
||||
ret = wc_InitRng(&rng);
|
||||
if (ret != 0) {
|
||||
printf("wc_InitRng failed %d\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
rngInit = 1;
|
||||
|
||||
ret = wc_ecc_init(&alice);
|
||||
if (ret != 0)
|
||||
goto exit;
|
||||
aliceInit = 1;
|
||||
ret = wc_ecc_init(&bob);
|
||||
if (ret != 0)
|
||||
goto exit;
|
||||
bobInit = 1;
|
||||
|
||||
ret = wc_ecc_sm2_make_key(&rng, &alice, WC_ECC_FLAG_NONE);
|
||||
if (ret == 0)
|
||||
ret = wc_ecc_sm2_make_key(&rng, &bob, WC_ECC_FLAG_NONE);
|
||||
if (ret != 0) {
|
||||
printf("wc_ecc_sm2_make_key failed %d\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
printf("Generated two SM2 keys\n");
|
||||
|
||||
#ifdef ECC_TIMING_RESISTANT
|
||||
/* Timing-resistant point math needs an RNG on the private key. */
|
||||
ret = wc_ecc_set_rng(&alice, &rng);
|
||||
if (ret == 0)
|
||||
ret = wc_ecc_set_rng(&bob, &rng);
|
||||
if (ret != 0) {
|
||||
printf("wc_ecc_set_rng failed %d\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Each side uses its own private key and the peer's public key. */
|
||||
ret = wc_ecc_sm2_shared_secret(&alice, &bob, secretA, &secretASz);
|
||||
if (ret == 0)
|
||||
ret = wc_ecc_sm2_shared_secret(&bob, &alice, secretB, &secretBSz);
|
||||
if (ret != 0) {
|
||||
printf("wc_ecc_sm2_shared_secret failed %d\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
print_hex("alice secret", secretA, secretASz);
|
||||
print_hex("bob secret", secretB, secretBSz);
|
||||
|
||||
if (secretASz != secretBSz ||
|
||||
memcmp(secretA, secretB, secretASz) != 0) {
|
||||
printf("Shared secrets differ!\n");
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
printf("Shared secrets match\n");
|
||||
ret = 0;
|
||||
|
||||
exit:
|
||||
if (bobInit)
|
||||
wc_ecc_free(&bob);
|
||||
if (aliceInit)
|
||||
wc_ecc_free(&alice);
|
||||
if (rngInit)
|
||||
wc_FreeRng(&rng);
|
||||
|
||||
return ret == 0 ? 0 : 1;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int main(void)
|
||||
{
|
||||
printf("Please install the wolfsm overlay and build wolfSSL with "
|
||||
"./configure --enable-sm2\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* WOLFSSL_SM2 */
|
||||
|
|
@ -0,0 +1,146 @@
|
|||
/* sm2-sign-verify.c
|
||||
*
|
||||
* Copyright (C) 2006-2026 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL. (formerly known as CyaSSL)
|
||||
*
|
||||
* wolfSSL is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfSSL 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
/* Example of SM2 (GB/T 32918) signing and verifying over the SM2 curve.
|
||||
*
|
||||
* SM2 does not sign the raw message: the message is first combined with the
|
||||
* signer's identity and public key into an SM3 digest (the "ZA" hash). */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <wolfssl/options.h>
|
||||
#include <wolfssl/wolfcrypt/settings.h>
|
||||
#include <wolfssl/wolfcrypt/ecc.h>
|
||||
#include <wolfssl/wolfcrypt/sm2.h>
|
||||
#include <wolfssl/wolfcrypt/sm3.h>
|
||||
#include <wolfssl/wolfcrypt/random.h>
|
||||
|
||||
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
|
||||
|
||||
/* Default identity from GM/T 0009-2012, also used for certificates. */
|
||||
static const byte sm2_id[] = "1234567812345678";
|
||||
|
||||
static void print_hex(const char* label, const byte* data, word32 len)
|
||||
{
|
||||
word32 i;
|
||||
|
||||
printf("%s: ", label);
|
||||
for (i = 0; i < len; i++)
|
||||
printf("%02x", data[i]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int ret;
|
||||
WC_RNG rng;
|
||||
int rngInit = 0;
|
||||
ecc_key key;
|
||||
int keyInit = 0;
|
||||
byte digest[WC_SM3_DIGEST_SIZE];
|
||||
byte sig[ECC_MAX_SIG_SIZE];
|
||||
word32 sigSz = (word32)sizeof(sig);
|
||||
int verified = 0;
|
||||
const char* msg = (argc > 1) ? argv[1] : "sm2 sign-verify example";
|
||||
|
||||
ret = wc_InitRng(&rng);
|
||||
if (ret != 0) {
|
||||
printf("wc_InitRng failed %d\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
rngInit = 1;
|
||||
|
||||
ret = wc_ecc_init(&key);
|
||||
if (ret != 0) {
|
||||
printf("wc_ecc_init failed %d\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
keyInit = 1;
|
||||
|
||||
ret = wc_ecc_sm2_make_key(&rng, &key, WC_ECC_FLAG_NONE);
|
||||
if (ret != 0) {
|
||||
printf("wc_ecc_sm2_make_key failed %d\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
printf("Generated SM2 key\n");
|
||||
|
||||
/* ZA digest: SM3 over the identity, curve parameters and public key,
|
||||
* then SM3 over ZA || message. */
|
||||
ret = wc_ecc_sm2_create_digest(sm2_id, (word16)(sizeof(sm2_id) - 1),
|
||||
(const byte*)msg, (int)strlen(msg),
|
||||
WC_HASH_TYPE_SM3, digest,
|
||||
(int)sizeof(digest), &key);
|
||||
if (ret != 0) {
|
||||
printf("wc_ecc_sm2_create_digest failed %d\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
print_hex("digest", digest, sizeof(digest));
|
||||
|
||||
ret = wc_ecc_sm2_sign_hash(digest, sizeof(digest), sig, &sigSz, &rng,
|
||||
&key);
|
||||
if (ret != 0) {
|
||||
printf("wc_ecc_sm2_sign_hash failed %d\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
print_hex("signature", sig, sigSz);
|
||||
|
||||
ret = wc_ecc_sm2_verify_hash(sig, sigSz, digest, sizeof(digest),
|
||||
&verified, &key);
|
||||
if (ret != 0 || verified != 1) {
|
||||
printf("wc_ecc_sm2_verify_hash failed: ret %d verified %d\n", ret,
|
||||
verified);
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
printf("Signature verified\n");
|
||||
|
||||
/* A modified digest must not verify. */
|
||||
digest[0] ^= 0x01;
|
||||
ret = wc_ecc_sm2_verify_hash(sig, sigSz, digest, sizeof(digest),
|
||||
&verified, &key);
|
||||
if (ret == 0 && verified == 1) {
|
||||
printf("Corrupted digest verified!\n");
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
printf("Corrupted digest rejected as expected\n");
|
||||
ret = 0;
|
||||
|
||||
exit:
|
||||
if (keyInit)
|
||||
wc_ecc_free(&key);
|
||||
if (rngInit)
|
||||
wc_FreeRng(&rng);
|
||||
|
||||
return ret == 0 ? 0 : 1;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int main(void)
|
||||
{
|
||||
printf("Please install the wolfsm overlay and build wolfSSL with "
|
||||
"./configure --enable-sm2 --enable-sm3\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* WOLFSSL_SM2 && WOLFSSL_SM3 */
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
/* sm3-hash.c
|
||||
*
|
||||
* Copyright (C) 2006-2026 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL. (formerly known as CyaSSL)
|
||||
*
|
||||
* wolfSSL is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfSSL 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
/* Example of incremental SM3 hashing (GB/T 32905-2016), checked against the
|
||||
* standard's "abc" test vector. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <wolfssl/options.h>
|
||||
#include <wolfssl/wolfcrypt/settings.h>
|
||||
#include <wolfssl/wolfcrypt/sm3.h>
|
||||
|
||||
#ifdef WOLFSSL_SM3
|
||||
|
||||
/* SM3("abc") from GB/T 32905-2016 Appendix A. */
|
||||
static const byte kat_abc[WC_SM3_DIGEST_SIZE] = {
|
||||
0x66, 0xc7, 0xf0, 0xf4, 0x62, 0xee, 0xed, 0xd9,
|
||||
0xd1, 0xf2, 0xd4, 0x6b, 0xdc, 0x10, 0xe4, 0xe2,
|
||||
0x41, 0x67, 0xc4, 0x87, 0x5c, 0xf2, 0xf7, 0xa2,
|
||||
0x29, 0x7d, 0xa0, 0x2b, 0x8f, 0x4b, 0xa8, 0xe0
|
||||
};
|
||||
|
||||
static void print_hex(const char* label, const byte* data, word32 len)
|
||||
{
|
||||
word32 i;
|
||||
|
||||
printf("%s: ", label);
|
||||
for (i = 0; i < len; i++)
|
||||
printf("%02x", data[i]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int ret;
|
||||
wc_Sm3 sm3;
|
||||
byte digest[WC_SM3_DIGEST_SIZE];
|
||||
const char* msg = (argc > 1) ? argv[1] : "abc";
|
||||
|
||||
ret = wc_InitSm3(&sm3, NULL, INVALID_DEVID);
|
||||
if (ret != 0) {
|
||||
printf("wc_InitSm3 failed %d\n", ret);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Data may be added in as many update calls as needed. */
|
||||
ret = wc_Sm3Update(&sm3, (const byte*)msg, (word32)strlen(msg));
|
||||
if (ret == 0)
|
||||
ret = wc_Sm3Final(&sm3, digest);
|
||||
wc_Sm3Free(&sm3);
|
||||
if (ret != 0) {
|
||||
printf("SM3 hash failed %d\n", ret);
|
||||
return 1;
|
||||
}
|
||||
|
||||
print_hex("SM3", digest, WC_SM3_DIGEST_SIZE);
|
||||
|
||||
if (argc <= 1) {
|
||||
if (memcmp(digest, kat_abc, WC_SM3_DIGEST_SIZE) != 0) {
|
||||
printf("Digest does not match GB/T 32905 test vector!\n");
|
||||
return 1;
|
||||
}
|
||||
printf("Digest matches GB/T 32905 test vector\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int main(void)
|
||||
{
|
||||
printf("Please install the wolfsm overlay and build wolfSSL with "
|
||||
"./configure --enable-sm3\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* WOLFSSL_SM3 */
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
/* sm4-gcm-encrypt.c
|
||||
*
|
||||
* Copyright (C) 2006-2026 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL. (formerly known as CyaSSL)
|
||||
*
|
||||
* wolfSSL is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfSSL 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
/* Example of SM4-GCM (GB/T 32907-2016 block cipher in GCM mode) authenticated
|
||||
* encryption: encrypt, decrypt, and reject a tampered tag. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <wolfssl/options.h>
|
||||
#include <wolfssl/wolfcrypt/settings.h>
|
||||
#include <wolfssl/wolfcrypt/sm4.h>
|
||||
#include <wolfssl/wolfcrypt/random.h>
|
||||
|
||||
#if defined(WOLFSSL_SM4) && defined(WOLFSSL_SM4_GCM)
|
||||
|
||||
#define NONCE_SZ 12
|
||||
#define TAG_SZ 16
|
||||
|
||||
static void print_hex(const char* label, const byte* data, word32 len)
|
||||
{
|
||||
word32 i;
|
||||
|
||||
printf("%s: ", label);
|
||||
for (i = 0; i < len; i++)
|
||||
printf("%02x", data[i]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int ret;
|
||||
wc_Sm4 sm4;
|
||||
int sm4Init = 0;
|
||||
WC_RNG rng;
|
||||
int rngInit = 0;
|
||||
byte key[SM4_KEY_SIZE];
|
||||
byte nonce[NONCE_SZ];
|
||||
byte tag[TAG_SZ];
|
||||
const char* msg = "sm4-gcm example plaintext";
|
||||
const char* aad = "example aad";
|
||||
byte cipher[64];
|
||||
byte plain[64];
|
||||
word32 msgSz = (word32)strlen(msg);
|
||||
|
||||
ret = wc_InitRng(&rng);
|
||||
if (ret != 0) {
|
||||
printf("wc_InitRng failed %d\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
rngInit = 1;
|
||||
|
||||
ret = wc_Sm4Init(&sm4, NULL, INVALID_DEVID);
|
||||
if (ret != 0) {
|
||||
printf("wc_Sm4Init failed %d\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
sm4Init = 1;
|
||||
|
||||
/* Fresh random key; a nonce must never repeat under the same key. */
|
||||
ret = wc_RNG_GenerateBlock(&rng, key, sizeof(key));
|
||||
if (ret == 0)
|
||||
ret = wc_RNG_GenerateBlock(&rng, nonce, sizeof(nonce));
|
||||
if (ret != 0) {
|
||||
printf("wc_RNG_GenerateBlock failed %d\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = wc_Sm4GcmSetKey(&sm4, key, sizeof(key));
|
||||
if (ret != 0) {
|
||||
printf("wc_Sm4GcmSetKey failed %d\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = wc_Sm4GcmEncrypt(&sm4, cipher, (const byte*)msg, msgSz, nonce,
|
||||
sizeof(nonce), tag, sizeof(tag), (const byte*)aad,
|
||||
(word32)strlen(aad));
|
||||
if (ret != 0) {
|
||||
printf("wc_Sm4GcmEncrypt failed %d\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
print_hex("key ", key, sizeof(key));
|
||||
print_hex("nonce ", nonce, sizeof(nonce));
|
||||
print_hex("ciphertext", cipher, msgSz);
|
||||
print_hex("tag ", tag, sizeof(tag));
|
||||
|
||||
ret = wc_Sm4GcmDecrypt(&sm4, plain, cipher, msgSz, nonce, sizeof(nonce),
|
||||
tag, sizeof(tag), (const byte*)aad,
|
||||
(word32)strlen(aad));
|
||||
if (ret != 0) {
|
||||
printf("wc_Sm4GcmDecrypt failed %d\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
if (memcmp(plain, msg, msgSz) != 0) {
|
||||
printf("Decrypted plaintext mismatch!\n");
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
printf("Decrypt success\n");
|
||||
|
||||
/* A tampered tag must fail authentication. */
|
||||
tag[0] ^= 0x01;
|
||||
ret = wc_Sm4GcmDecrypt(&sm4, plain, cipher, msgSz, nonce, sizeof(nonce),
|
||||
tag, sizeof(tag), (const byte*)aad,
|
||||
(word32)strlen(aad));
|
||||
if (ret == 0) {
|
||||
printf("Tampered tag accepted!\n");
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
printf("Tampered tag rejected as expected\n");
|
||||
ret = 0;
|
||||
|
||||
exit:
|
||||
if (sm4Init)
|
||||
wc_Sm4Free(&sm4);
|
||||
if (rngInit)
|
||||
wc_FreeRng(&rng);
|
||||
|
||||
return ret == 0 ? 0 : 1;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int main(void)
|
||||
{
|
||||
printf("Please install the wolfsm overlay and build wolfSSL with "
|
||||
"./configure --enable-sm4-gcm\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* WOLFSSL_SM4 && WOLFSSL_SM4_GCM */
|
||||
Loading…
Reference in New Issue