remove old api

This commit is contained in:
Zhi Guan
2021-07-31 22:07:25 +08:00
parent f7b4533cdd
commit 2ecba70472
30 changed files with 1025 additions and 953 deletions

View File

@@ -1,109 +0,0 @@
/*
* Copyright (c) 2014 - 2021 The GmSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the GmSSL Project.
* (http://gmssl.org/)"
*
* 4. The name "GmSSL Project" must not be used to endorse or promote
* products derived from this software without prior written
* permission. For written permission, please contact
* guanzhi1980@gmail.com.
*
* 5. Products derived from this software may not be called "GmSSL"
* nor may "GmSSL" appear in their names without prior written
* permission of the GmSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the GmSSL Project
* (http://gmssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef GMSSL_CIPHER_H
#define GMSSL_CIPHER_H
#ifdef __cplusplus
extern "C" {
#endif
struct cipher_st {
int nid;
size_t block_size;
size_t key_size;
size_t iv_size;
unsigned long flags;
int (*init)(CIPHER_CTX *ctx, const uint8_t *key);
int (*encrypt)(CIPHER_CTX *ctx);
};
struct cipher_ctx_st {
CIPHER *cipher;
int is_encrypt;
uint8_t iv[16];
uint8_t block[16];
};
int cipher_encyrpt_init(CIPHER_CTX *ctx, const CIPHER *cipher, const uint8_t *key, const uint8_t *iv);
int cipher_encrypt_update(CIPHER_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen);
int cipher_encrypt_finish(CIPHER_CTX *ctx, uint8_t *out, size_t *outlen);
int cipher_decrypt_init(CIPHER_CTX *ctx, const CIPHER *cipher, const uint8_t *key, const uint8_t *iv);
int cipher_decrypt_update(CIPHER_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen);
int cipher_decrypt_finish(CIPHER_CTX *ctx, uint8_t *out, size_t *outlen);
int cipher_init(CIPHER_CTX *ctx, const CIPHER *cipher, const uint8_t *key, const uint8_t *iv, int enc);
int cipher_update(CIPHER_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen);
int cipher_finish(CIPHER_CTX *ctx, uint8_t *out, size_t *outlen);
const CIPHER *CIPHER_sm4_ecb(void);
const CIPHER *CIPHER_sm4_cbc(void);
const CIPHER *CIPHER_sm4_ofb(void);
const CIPHER *CIPHER_sm4_cfb1(void);
const CIPHER *CIPHER_sm4_cfb8(void);
const CIPHER *CIPHER_sm4_cfb128(void);
const CIPHER *CIPHER_sm4_ctr(void);
const CIPHER *CIPHER_sm4_gcm(void);
const CIPHER *CIPHER_zuc(void);
const CIPHER *CIPHER_zuc256(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -75,6 +75,8 @@ extern "C" {
#define GCM_MAX_PLAINTEXT_SIZE ((((uint64_t)1 << 39) - 256) >> 3) #define GCM_MAX_PLAINTEXT_SIZE ((((uint64_t)1 << 39) - 256) >> 3)
#define GHASH_SIZE (16)
#define GCM_IS_LITTLE_ENDIAN 1 #define GCM_IS_LITTLE_ENDIAN 1

View File

@@ -65,8 +65,8 @@ int hex_to_bytes(const char *in, size_t inlen, uint8_t *out, size_t *outlen);
int hex2bin(const char *in, size_t inlen, uint8_t *out); int hex2bin(const char *in, size_t inlen, uint8_t *out);
int OPENSSL_hexchar2int(unsigned char c); //int OPENSSL_hexchar2int(unsigned char c);
unsigned char *OPENSSL_hexstr2buf(const char *str, size_t *len); //unsigned char *OPENSSL_hexstr2buf(const char *str, size_t *len);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -73,7 +73,6 @@ size_t hmac_size(const HMAC_CTX *ctx);
int hmac_init(HMAC_CTX *ctx, const DIGEST *digest, const unsigned char *key, size_t keylen); int hmac_init(HMAC_CTX *ctx, const DIGEST *digest, const unsigned char *key, size_t keylen);
int hmac_update(HMAC_CTX *ctx, const unsigned char *data, size_t datalen); int hmac_update(HMAC_CTX *ctx, const unsigned char *data, size_t datalen);
int hmac_finish(HMAC_CTX *ctx, unsigned char *mac, size_t *maclen); int hmac_finish(HMAC_CTX *ctx, unsigned char *mac, size_t *maclen);
int hmac_reset(HMAC_CTX *ctx);
int hmac(const DIGEST *md, const unsigned char *key, size_t keylen, int hmac(const DIGEST *md, const unsigned char *key, size_t keylen,
const unsigned char *data, size_t dlen, const unsigned char *data, size_t dlen,

View File

@@ -60,11 +60,9 @@ extern "C" {
#endif #endif
#define SM4_KEY_SIZE 16 #define SM4_KEY_SIZE (16)
#define SM4_KEY_LENGTH 16 #define SM4_BLOCK_SIZE (16)
#define SM4_BLOCK_SIZE 16 #define SM4_NUM_ROUNDS (32)
#define SM4_IV_LENGTH (SM4_BLOCK_SIZE)
#define SM4_NUM_ROUNDS 32
typedef struct { typedef struct {
@@ -72,10 +70,9 @@ typedef struct {
} SM4_KEY; } SM4_KEY;
void sm4_set_encrypt_key(SM4_KEY *key, const unsigned char user_key[16]); void sm4_set_encrypt_key(SM4_KEY *sm4_key, const uint8_t key[16]);
void sm4_set_decrypt_key(SM4_KEY *key, const unsigned char user_key[16]); void sm4_set_decrypt_key(SM4_KEY *sm4_key, const uint8_t key[16]);
void sm4_encrypt(const SM4_KEY *key, const unsigned char in[16], unsigned char out[16]); void sm4_encrypt(const SM4_KEY *sm4_key, const uint8_t in[16], uint8_t out[16]);
#define sm4_decrypt(key,in,out) sm4_encrypt(key,in,out)
void sm4_cbc_encrypt(const SM4_KEY *key, const uint8_t iv[16], void sm4_cbc_encrypt(const SM4_KEY *key, const uint8_t iv[16],

View File

@@ -92,6 +92,8 @@ int tls_uint24array_copy_from_bytes(uint8_t *data, size_t *datalen, size_t maxle
typedef enum { typedef enum {
TLS_version_tls12_major = 3,
TLS_version_tls12_minor = 3,
TLS_version_tlcp = 0x0101, TLS_version_tlcp = 0x0101,
TLS_version_ssl2 = 0x0200, TLS_version_ssl2 = 0x0200,
TLS_version_ssl3 = 0x0300, TLS_version_ssl3 = 0x0300,

View File

@@ -135,6 +135,11 @@ int gcm_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *iv, size_t ivlen,
const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen, const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen,
const uint8_t *tag, size_t taglen, uint8_t *out) const uint8_t *tag, size_t taglen, uint8_t *out)
{ {
if (key->cipher == BLOCK_CIPHER_sm4()) {
sm4_gcm_decrypt(&(key->u.sm4_key), iv, ivlen, aad, aadlen, in, inlen, tag, taglen, out);
} else if (key->cipher == BLOCK_CIPHER_aes128()) {
aes_gcm_decrypt(&(key->u.aes_key), iv, ivlen, aad, aadlen, in, inlen, tag, taglen, out);
}
error_print();
return -1; return -1;
} }

View File

@@ -85,7 +85,7 @@ void gf128_print_bits(gf128_t a)
{ {
int i; int i;
for (i = 0; i < 128; i++) { for (i = 0; i < 128; i++) {
printf("%d", (int)(a % 2)); printf("%d", a % 2);
a >>= 1; a >>= 1;
} }
printf("\n"); printf("\n");

View File

@@ -48,23 +48,13 @@
#include <string.h> #include <string.h>
#include <gmssl/hmac.h> #include <gmssl/hmac.h>
#include <gmssl/error.h>
#define IPAD 0x36 #define IPAD 0x36
#define OPAD 0x5C #define OPAD 0x5C
int hmac_ctx_init(HMAC_CTX *ctx)
{
memset(ctx, 0, sizeof(HMAC_CTX));
return 1;
}
void hmac_ctx_cleanup(HMAC_CTX *ctx)
{
memset(ctx, 0, sizeof(HMAC_CTX));
}
int hmac_init(HMAC_CTX *ctx, const DIGEST *digest, const unsigned char *key, size_t keylen) int hmac_init(HMAC_CTX *ctx, const DIGEST *digest, const unsigned char *key, size_t keylen)
{ {
uint8_t i_key[DIGEST_MAX_BLOCK_SIZE] = {0}; uint8_t i_key[DIGEST_MAX_BLOCK_SIZE] = {0};
@@ -73,7 +63,8 @@ int hmac_init(HMAC_CTX *ctx, const DIGEST *digest, const unsigned char *key, siz
int i; int i;
if (!ctx || !digest || !key || !keylen) { if (!ctx || !digest || !key || !keylen) {
return 0; error_print();
return -1;
} }
ctx->digest = digest; ctx->digest = digest;
@@ -107,34 +98,45 @@ int hmac_init(HMAC_CTX *ctx, const DIGEST *digest, const unsigned char *key, siz
int hmac_update(HMAC_CTX *ctx, const unsigned char *data, size_t datalen) int hmac_update(HMAC_CTX *ctx, const unsigned char *data, size_t datalen)
{ {
if (!ctx || (!data && datalen != 0)) { if (!ctx || (!data && datalen != 0)) {
return 0; error_print();
return -1;
} }
return digest_update(&ctx->digest_ctx, data, datalen); if (digest_update(&ctx->digest_ctx, data, datalen) != 1) {
error_print();
return -1;
}
return 1;
} }
int hmac_finish(HMAC_CTX *ctx, unsigned char *mac, size_t *maclen) int hmac_finish(HMAC_CTX *ctx, unsigned char *mac, size_t *maclen)
{ {
int ret = 0; if (digest_finish(&ctx->digest_ctx, mac, maclen) != 1) {
size_t i; error_print();
size_t blocksize;
if (!digest_finish(&ctx->digest_ctx, mac, maclen)) {
return -1; return -1;
} }
memcpy(&ctx->digest_ctx, &ctx->o_ctx, sizeof(DIGEST_CTX)); memcpy(&ctx->digest_ctx, &ctx->o_ctx, sizeof(DIGEST_CTX));
if (!digest_update(&ctx->digest_ctx, mac, *maclen) if (digest_update(&ctx->digest_ctx, mac, *maclen) != 1
|| !digest_finish(&ctx->digest_ctx, mac, maclen)) { || digest_finish(&ctx->digest_ctx, mac, maclen) != 1) {
goto end; error_print();
return -1;
} }
return 1;
ret = 1;
end:
return ret;
} }
int hmac_reset(HMAC_CTX *ctx) int hmac_finish_and_verify(HMAC_CTX *ctx, const uint8_t *mac, size_t maclen)
{ {
memcpy(&ctx->digest_ctx, &ctx->i_ctx, sizeof(DIGEST_CTX)); uint8_t hmac[64];
size_t hmaclen;
if (hmac_finish(ctx, hmac, &hmaclen) != 1) {
error_print();
return -1;
}
if (maclen != hmaclen
|| memcmp(hmac, mac, maclen) != 0) {
error_print();
return -1;
}
return 1; return 1;
} }
@@ -145,14 +147,14 @@ int hmac(const DIGEST *digest, const unsigned char *key, size_t keylen,
int ret = 0; int ret = 0;
HMAC_CTX ctx; HMAC_CTX ctx;
if (!hmac_ctx_init(&ctx) if (hmac_init(&ctx, digest, key, keylen) != 1
|| !hmac_init(&ctx, digest, key, keylen) || hmac_update(&ctx, data, datalen) != 1
|| !hmac_update(&ctx, data, datalen) || hmac_finish(&ctx, mac, maclen) != 1) {
|| !hmac_finish(&ctx, mac, maclen)) {
goto end; goto end;
} }
ret = 1; ret = 1;
end: end:
hmac_ctx_cleanup(&ctx); memset(&ctx, 0, sizeof(ctx));
return ret; return ret;
} }

View File

@@ -129,13 +129,14 @@ int pbkdf2_genkey(const DIGEST *digest,
size_t outlen, uint8_t *out) size_t outlen, uint8_t *out)
{ {
HMAC_CTX ctx; HMAC_CTX ctx;
HMAC_CTX ctx_tmpl;
uint32_t iter = 1; uint32_t iter = 1;
uint8_t iter_be[4]; uint8_t iter_be[4];
uint8_t tmp_block[64]; uint8_t tmp_block[64];
uint8_t key_block[64]; uint8_t key_block[64];
size_t len; size_t len;
hmac_init(&ctx, digest, (uint8_t *)pass, passlen); hmac_init(&ctx_tmpl, digest, (uint8_t *)pass, passlen);
while (outlen > 0) { while (outlen > 0) {
int i; int i;
@@ -143,16 +144,16 @@ int pbkdf2_genkey(const DIGEST *digest,
PUTU32(iter_be, iter); PUTU32(iter_be, iter);
iter++; iter++;
ctx = ctx_tmpl;
hmac_update(&ctx, salt, saltlen); hmac_update(&ctx, salt, saltlen);
hmac_update(&ctx, iter_be, sizeof(iter_be)); hmac_update(&ctx, iter_be, sizeof(iter_be));
hmac_finish(&ctx, tmp_block, &len); hmac_finish(&ctx, tmp_block, &len);
hmac_reset(&ctx);
memcpy(key_block, tmp_block, len); memcpy(key_block, tmp_block, len);
for (i = 1; i < count; i++) { for (i = 1; i < count; i++) {
ctx = ctx_tmpl;
hmac_update(&ctx, tmp_block, len); hmac_update(&ctx, tmp_block, len);
hmac_finish(&ctx, tmp_block, &len); hmac_finish(&ctx, tmp_block, &len);
hmac_reset(&ctx);
memxor(key_block, tmp_block, len); memxor(key_block, tmp_block, len);
} }

View File

@@ -67,7 +67,7 @@ void sm4_cbc_decrypt(const SM4_KEY *key, const uint8_t iv[16],
const uint8_t *in, size_t nblocks, uint8_t *out) const uint8_t *in, size_t nblocks, uint8_t *out)
{ {
while (nblocks--) { while (nblocks--) {
sm4_decrypt(key, in, out); sm4_encrypt(key, in, out);
memxor(out, iv, 16); memxor(out, iv, 16);
iv = in; iv = in;
in += 16; in += 16;

View File

@@ -83,7 +83,7 @@ static uint32_t CK[32] = {
x4 = x0 ^ L32_(x4); \ x4 = x0 ^ L32_(x4); \
*(rk + 31 - i) = x4 *(rk + 31 - i) = x4
void sm4_set_encrypt_key(SM4_KEY *key, const unsigned char user_key[16]) void sm4_set_encrypt_key(SM4_KEY *key, const uint8_t user_key[16])
{ {
uint32_t *rk = key->rk; uint32_t *rk = key->rk;
uint32_t x0, x1, x2, x3, x4; uint32_t x0, x1, x2, x3, x4;
@@ -100,7 +100,7 @@ void sm4_set_encrypt_key(SM4_KEY *key, const unsigned char user_key[16])
x0 = x1 = x2 = x3 = x4 = 0; x0 = x1 = x2 = x3 = x4 = 0;
} }
void sm4_set_decrypt_key(SM4_KEY *key, const unsigned char user_key[16]) void sm4_set_decrypt_key(SM4_KEY *key, const uint8_t user_key[16])
{ {
uint32_t *rk = key->rk; uint32_t *rk = key->rk;
uint32_t x0, x1, x2, x3, x4; uint32_t x0, x1, x2, x3, x4;

224
src/tls.c
View File

@@ -322,7 +322,118 @@ int tls_record_length(const uint8_t *record)
} }
int tls_cbc_encrypt(const SM3_HMAC_CTX *inited_hmac_ctx, const SM4_KEY *enc_key,
const uint8_t seq_num[8], const uint8_t header[5],
const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen)
{
SM3_HMAC_CTX hmac_ctx;
uint8_t last_blocks[32 + 16] = {0};
uint8_t *mac, *padding, *iv;
int rem, padding_len;
int i;
if (!inited_hmac_ctx || !enc_key || !seq_num || !header || (!in && inlen) || !out || !outlen) {
error_print();
return -1;
}
if (inlen > (1 << 14)) {
error_print("invalid tls record data length %zu\n", inlen);
return -1;
}
rem = (inlen + 32) % 16;
memcpy(last_blocks, in + inlen - rem, rem);
mac = last_blocks + rem;
memcpy(&hmac_ctx, inited_hmac_ctx, sizeof(SM3_HMAC_CTX));
sm3_hmac_update(&hmac_ctx, seq_num, 8);
sm3_hmac_update(&hmac_ctx, header, 5);
sm3_hmac_update(&hmac_ctx, in, inlen);
sm3_hmac_finish(&hmac_ctx, mac);
padding = mac + 32;
padding_len = 16 - rem - 1;
for (i = 0; i <= padding_len; i++) {
padding[i] = padding_len;
}
iv = out;
if (rand_bytes(iv, 16) != 1) {
error_print();
return -1;
}
out += 16;
if (inlen >= 16) {
sm4_cbc_encrypt(enc_key, iv, in, inlen/16, out);
out += inlen - rem;
iv = out - 16;
}
sm4_cbc_encrypt(enc_key, iv, last_blocks, sizeof(last_blocks)/16, out);
*outlen = 16 + inlen - rem + sizeof(last_blocks);
return 1;
}
int tls_cbc_decrypt(const SM3_HMAC_CTX *inited_hmac_ctx, const SM4_KEY *dec_key,
const uint8_t seq_num[8], const uint8_t enced_header[5],
const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen)
{
SM3_HMAC_CTX hmac_ctx;
const uint8_t *iv;
const uint8_t *padding;
const uint8_t *mac;
uint8_t header[5];
int padding_len;
int i;
if (!inited_hmac_ctx || !dec_key || !seq_num || !enced_header || !in || !inlen || !out || !outlen) {
error_print();
return -1;
}
if (inlen % 16
|| inlen < (16 + 0 + 32 + 16) // iv + data + mac + padding
|| inlen > (16 + (1<<14) + 32 + 256)) {
error_print("invalid tls cbc ciphertext length %zu\n", inlen);
return -1;
}
iv = in;
in += 16;
inlen -= 16;
sm4_cbc_decrypt(dec_key, iv, in, inlen/16, out);
padding_len = out[inlen - 1];
padding = out + inlen - padding_len - 1;
if (padding < out + 32) {
error_print();
return -1;
}
for (i = 0; i < padding_len; i++) {
if (padding[i] != padding_len) {
error_print("tls ciphertext cbc-padding check failure");
return -1;
}
}
*outlen = inlen - 32 - padding_len - 1;
header[0] = enced_header[0];
header[1] = enced_header[1];
header[2] = enced_header[2];
header[3] = (*outlen) >> 8;
header[4] = (*outlen);
mac = padding - 32;
memcpy(&hmac_ctx, inited_hmac_ctx, sizeof(SM3_HMAC_CTX));
sm3_hmac_update(&hmac_ctx, seq_num, 8);
sm3_hmac_update(&hmac_ctx, header, 5);
sm3_hmac_update(&hmac_ctx, out, *outlen);
if (sm3_hmac_finish_and_verify(&hmac_ctx, mac) != 1) {
error_print("tls ciphertext mac check failure");
return -1;
}
return 1;
}
// 这个函数应该是处理的这个函数是不应该用的通常我们在加密的时候header 明文数据是分离的但是输出的record是一个 // 这个函数应该是处理的这个函数是不应该用的通常我们在加密的时候header 明文数据是分离的但是输出的record是一个
int tls_record_encrypt(const SM3_HMAC_CTX *hmac_ctx, const SM4_KEY *cbc_key, int tls_record_encrypt(const SM3_HMAC_CTX *hmac_ctx, const SM4_KEY *cbc_key,
@@ -378,6 +489,62 @@ int tls_random_generate(uint8_t random[32])
return 1; return 1;
} }
int tls_prf(const uint8_t *secret, size_t secretlen, const char *label,
const uint8_t *seed, size_t seedlen,
const uint8_t *more, size_t morelen,
size_t outlen, uint8_t *out)
{
SM3_HMAC_CTX inited_hmac_ctx;
SM3_HMAC_CTX hmac_ctx;
uint8_t A[32];
uint8_t hmac[32];
size_t len;
if (!secret || !secretlen || !label || !seed || !seedlen
|| (!more && morelen) || !outlen || !out) {
error_print();
return -1;
}
sm3_hmac_init(&inited_hmac_ctx, secret, secretlen);
memcpy(&hmac_ctx, &inited_hmac_ctx, sizeof(SM3_HMAC_CTX));
sm3_hmac_update(&hmac_ctx, (uint8_t *)label, strlen(label));
sm3_hmac_update(&hmac_ctx, seed, seedlen);
sm3_hmac_update(&hmac_ctx, more, morelen);
sm3_hmac_finish(&hmac_ctx, A);
memcpy(&hmac_ctx, &inited_hmac_ctx, sizeof(SM3_HMAC_CTX));
sm3_hmac_update(&hmac_ctx, A, sizeof(A));
sm3_hmac_update(&hmac_ctx, (uint8_t *)label, strlen(label));
sm3_hmac_update(&hmac_ctx, seed, seedlen);
sm3_hmac_update(&hmac_ctx, more, morelen);
sm3_hmac_finish(&hmac_ctx, hmac);
len = outlen < sizeof(hmac) ? outlen : sizeof(hmac);
memcpy(out, hmac, len);
out += len;
outlen -= len;
while (outlen) {
memcpy(&hmac_ctx, &inited_hmac_ctx, sizeof(SM3_HMAC_CTX));
sm3_hmac_update(&hmac_ctx, A, sizeof(A));
sm3_hmac_finish(&hmac_ctx, A);
memcpy(&hmac_ctx, &inited_hmac_ctx, sizeof(SM3_HMAC_CTX));
sm3_hmac_update(&hmac_ctx, A, sizeof(A));
sm3_hmac_update(&hmac_ctx, (uint8_t *)label, strlen(label));
sm3_hmac_update(&hmac_ctx, seed, seedlen);
sm3_hmac_update(&hmac_ctx, more, morelen);
sm3_hmac_finish(&hmac_ctx, hmac);
len = outlen < sizeof(hmac) ? outlen : sizeof(hmac);
memcpy(out, hmac, len);
out += len;
outlen -= len;
}
return 1;
}
int tls_pre_master_secret_generate(uint8_t pre_master_secret[48], int version) int tls_pre_master_secret_generate(uint8_t pre_master_secret[48], int version)
{ {
@@ -396,6 +563,63 @@ int tls_pre_master_secret_generate(uint8_t pre_master_secret[48], int version)
int tls_sign_server_ecdh_params(const SM2_KEY *server_sign_key,
const uint8_t client_random[32], const uint8_t server_random[32],
int curve, const SM2_POINT *point, uint8_t *sig, size_t *siglen)
{
uint8_t server_ecdh_params[69];
SM2_SIGN_CTX sign_ctx;
if (!server_sign_key || !client_random || !server_random
|| curve != TLS_curve_sm2p256v1 || !point || !sig || !siglen) {
error_print();
return -1;
}
server_ecdh_params[0] = TLS_curve_type_named_curve;
server_ecdh_params[1] = curve >> 8;
server_ecdh_params[2] = curve;
server_ecdh_params[3] = 65;
sm2_point_to_uncompressed_octets(point, server_ecdh_params + 4);
sm2_sign_init(&sign_ctx, server_sign_key, SM2_DEFAULT_ID);
sm2_sign_update(&sign_ctx, client_random, 32);
sm2_sign_update(&sign_ctx, server_random, 32);
sm2_sign_update(&sign_ctx, server_ecdh_params, 69);
sm2_sign_finish(&sign_ctx, sig, siglen);
return 1;
}
int tls_verify_server_ecdh_params(const SM2_KEY *server_sign_key,
const uint8_t client_random[32], const uint8_t server_random[32],
int curve, const SM2_POINT *point, const uint8_t *sig, size_t siglen)
{
int ret;
uint8_t server_ecdh_params[69];
SM2_SIGN_CTX verify_ctx;
if (!server_sign_key || !client_random || !server_random
|| curve != TLS_curve_sm2p256v1 || !point || !sig || !siglen
|| siglen > TLS_MAX_SIGNATURE_SIZE) {
error_print();
return -1;
}
server_ecdh_params[0] = TLS_curve_type_named_curve;
server_ecdh_params[1] = curve >> 8;
server_ecdh_params[2] = curve;
server_ecdh_params[3] = 65;
sm2_point_to_uncompressed_octets(point, server_ecdh_params + 4);
sm2_verify_init(&verify_ctx, server_sign_key, SM2_DEFAULT_ID);
sm2_verify_update(&verify_ctx, client_random, 32);
sm2_verify_update(&verify_ctx, server_random, 32);
sm2_verify_update(&verify_ctx, server_ecdh_params, 69);
ret = sm2_verify_finish(&verify_ctx, sig, siglen);
if (ret != 1) error_print();
return ret;
}
// handshakes // handshakes

View File

@@ -65,45 +65,66 @@
#include <gmssl/pem.h> #include <gmssl/pem.h>
#include <gmssl/tls.h> #include <gmssl/tls.h>
#include <gmssl/digest.h> #include <gmssl/digest.h>
#include <gmssl/block_cipher.h>
#include <gmssl/gcm.h> #include <gmssl/gcm.h>
#include <gmssl/hmac.h> #include <gmssl/hmac.h>
#include <gmssl/hkdf.h>
#include "mem.h" #include "mem.h"
int tls13_gcm_encrypt(const BLOCK_CIPHER_KEY *enc_key,
const uint8_t iv[12], size_t padding_len, /*
struct {
opaque content[TLSPlaintext.length];
ContentType type;
uint8 zeros[length_of_padding];
} TLSInnerPlaintext;
struct {
ContentType opaque_type = application_data; // 23
ProtocolVersion legacy_record_version = 0x0303; // TLS v1.2
uint16 length;
opaque encrypted_record[TLSCiphertext.length];
} TLSCiphertext;
*/
int tls13_gcm_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12],
const uint8_t seq_num[8], int record_type, const uint8_t seq_num[8], int record_type,
const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) const uint8_t *in, size_t inlen, size_t padding_len, // TLSInnerPlaintext.content
uint8_t *out, size_t *outlen) // TLSCiphertext.encrypted_record
{ {
uint8_t nonce[12]; uint8_t nonce[12];
uint8_t *mbuf = malloc(inlen + 256);
uint8_t aad[5]; uint8_t aad[5];
uint8_t *gmac; uint8_t *gmac;
uint8_t *mbuf = malloc(inlen + 256); // FIXME: update gcm_encrypt API
size_t mlen, clen; size_t mlen, clen;
// nonce = (zeros|seq_num) xor (iv)
nonce[0] = nonce[1] = nonce[2] = 0; nonce[0] = nonce[1] = nonce[2] = 0;
memcpy(nonce + 3, seq_num, 8); memcpy(nonce + 3, seq_num, 8);
gmssl_memxor(nonce, nonce, iv, 12); gmssl_memxor(nonce, nonce, iv, 12);
// TLSInnerPlaintext
memcpy(mbuf, in, inlen); memcpy(mbuf, in, inlen);
mbuf[inlen] = record_type; mbuf[inlen] = record_type;
memset(mbuf + inlen + 1, 0, padding_len); memset(mbuf + inlen + 1, 0, padding_len);
mlen = inlen + 1 + padding_len; mlen = inlen + 1 + padding_len;
clen = mlen + 16; clen = mlen + GHASH_SIZE;
// aad = TLSCiphertext header
aad[0] = TLS_record_application_data; aad[0] = TLS_record_application_data;
aad[1] = 3; aad[1] = TLS_version_tls12_major;
aad[2] = 3; aad[2] = TLS_version_tls12_minor;
aad[3] = clen >> 8; aad[3] = clen >> 8;
aad[4] = clen; aad[4] = clen;
gmac = out + mlen; gmac = out + mlen;
gcm_encrypt(enc_key, nonce, sizeof(nonce), aad, sizeof(aad), mbuf, mlen, out, 16, gmac); if (gcm_encrypt(key, nonce, sizeof(nonce), aad, sizeof(aad), mbuf, mlen, out, 16, gmac) != 1) {
error_print();
return -1;
}
return 1; return 1;
} }
int tls13_gcm_decrypt(const BLOCK_CIPHER_KEY *sm4_key, const uint8_t iv[12], int tls13_gcm_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12],
const uint8_t seq_num[8], const uint8_t *in, size_t inlen, const uint8_t seq_num[8], const uint8_t *in, size_t inlen,
int *record_type, uint8_t *out, size_t *outlen) int *record_type, uint8_t *out, size_t *outlen)
{ {
@@ -113,62 +134,335 @@ int tls13_gcm_decrypt(const BLOCK_CIPHER_KEY *sm4_key, const uint8_t iv[12],
const uint8_t *gmac; const uint8_t *gmac;
size_t i; size_t i;
// nonce = (zeros|seq_num) xor (iv)
nonce[0] = nonce[1] = nonce[2] = 0; nonce[0] = nonce[1] = nonce[2] = 0;
memcpy(nonce + 3, seq_num, 8); memcpy(nonce + 3, seq_num, 8);
gmssl_memxor(nonce, nonce, iv, 12); gmssl_memxor(nonce, nonce, iv, 12);
// aad = TLSCiphertext header
aad[0] = TLS_record_application_data; aad[0] = TLS_record_application_data;
aad[1] = 3; aad[1] = TLS_version_tls12_major;
aad[2] = 3; aad[2] = TLS_version_tls12_minor;
aad[3] = inlen >> 8; aad[3] = inlen >> 8;
aad[4] = inlen;
mlen = inlen - 16; if (inlen < GHASH_SIZE) {
error_print();
return -1;
}
mlen = inlen - GHASH_SIZE;
gmac = in + mlen;
if (gcm_decrypt(key, iv, 12, aad, 5, in, mlen, gmac, GHASH_SIZE, out) != 1) {
return -1;
}
int tls13_record_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12],
const uint8_t seq_num[8], const uint8_t *in, size_t inlen, size_t padding_len,
uint8_t *out, size_t *outlen)
{
if (tls13_gcm_encrypt(key, iv, padding_len,
seq_num, in[0], in + 5, inlen - 5, out + 5, outlen) != 1) {
error_print(); error_print();
return -1; return -1;
} }
out[0] = TLS_record_application_data; // remove padding, get record_type
out[1] = in[1]; *record_type = 0;
out[2] = in[2]; while (mlen--) {
out[3] = (*outlen) >> 8; if (out[mlen] != 0) {
out[4] = (*outlen); *record_type = out[mlen];
(*outlen) += 5; break;
}
}
if (!tls_record_type_name(*record_type)) {
error_print();
return -1;
}
return 1;
}
int tls13_record_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12],
const uint8_t seq_num[8], const uint8_t *record, size_t recordlen, size_t padding_len,
uint8_t *enced_record, size_t *enced_recordlen)
{
if (tls13_gcm_encrypt(key, iv,
seq_num, record[0], record + 5, recordlen - 5, padding_len,
enced_record + 5, enced_recordlen) != 1) {
error_print();
return -1;
}
enced_record[0] = TLS_record_application_data;
enced_record[1] = TLS_version_tls12_major;
enced_record[2] = TLS_version_tls12_minor;
enced_record[3] = (*enced_recordlen) >> 8;
enced_record[4] = (*enced_recordlen);
(*enced_recordlen) += 5;
return 1; return 1;
} }
int tls13_record_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12], int tls13_record_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t iv[12],
const uint8_t seq_num[8], const uint8_t *in, size_t inlen, const uint8_t seq_num[8], const uint8_t *enced_record, size_t enced_recordlen,
uint8_t *out, size_t *outlen) uint8_t *record, size_t *recordlen)
{ {
int record_type; int record_type;
if (tls13_gcm_decrypt(key, iv, seq_num, in + 5, inlen - 5, if (tls13_gcm_decrypt(key, iv,
&record_type, out + 5, outlen) != 1) { seq_num, enced_record + 5, enced_recordlen - 5,
&record_type, record + 5, recordlen) != 1) {
error_print();
return -1;
}
record[0] = record_type;
record[1] = TLS_version_tls12_major;
record[2] = TLS_version_tls12_minor;
record[3] = (*recordlen) >> 8;
record[4] = (*recordlen);
(*recordlen) += 5;
return 1;
}
int tls13_send(TLS_CONNECT *conn, const uint8_t *data, size_t datalen, size_t padding_len)
{
const BLOCK_CIPHER_KEY *key;
const uint8_t *iv;
uint8_t *seq_num;
uint8_t *record = conn->record;
size_t recordlen;
tls_trace("<<<< [ApplicationData]\n");
if (conn->is_client) {
key = &conn->client_write_key;
iv = conn->client_write_iv;
seq_num = conn->client_seq_num;
} else {
key = &conn->server_write_key;
iv = conn->server_write_iv;
seq_num = conn->server_seq_num;
}
if (tls13_gcm_encrypt(key, iv,
seq_num, TLS_record_application_data, data, datalen, padding_len,
record + 5, &recordlen) != 1) {
error_print(); error_print();
return -1; return -1;
} }
out[0] = record_type; record[0] = TLS_record_application_data;
out[1] = in[1]; record[1] = TLS_version_tls12 >> 8;
out[2] = in[2]; record[2] = TLS_version_tls12 & 0xff;
out[3] = (*outlen) >> 8; record[3] = recordlen >> 8;
out[4] = (*outlen); record[4] = recordlen;
recordlen += 5;
tls_record_send(record, recordlen, conn->sock);
tls_seq_num_incr(seq_num);
return 1; return 1;
} }
int tls13_recv(TLS_CONNECT *conn, uint8_t *data, size_t *datalen)
{
int record_type;
uint8_t *record = conn->record;
size_t recordlen;
const BLOCK_CIPHER_KEY *key;
const uint8_t *iv;
uint8_t *seq_num;
tls_trace(">>>> [ApplicationData]\n");
if (conn->is_client) {
key = &conn->client_write_key;
iv = conn->client_write_iv;
seq_num = conn->client_seq_num;
} else {
key = &conn->server_write_key;
iv = conn->server_write_iv;
seq_num = conn->server_seq_num;
}
if (tls12_record_recv(record, &recordlen, conn->sock) != 1) {
error_print();
return -1;
}
if (record[0] != TLS_record_application_data) {
error_print();
return -1;
}
if (tls13_gcm_decrypt(key, iv,
seq_num, record + 5, recordlen - 5,
&record_type, data, datalen) != 1) {
error_print();
return -1;
}
tls_seq_num_incr(seq_num);
if (record_type != TLS_record_application_data) {
error_print();
return -1;
}
return 1;
}
/*
HKDF-Expand-Label(Secret, Label, Context, Length) =
HKDF-Expand(Secret, HkdfLabel, Length);
HkdfLabel = struct {
uint16 length = Length;
opaque label<7..255> = "tls13 " + Label;
opaque context<0..255> = Context; }
Derive-Secret(Secret, Label, Messages) =
HKDF-Expand-Label(Secret, Label, Hash(Messages), Hash.length)
*/
int tls13_hkdf_extract(const DIGEST *digest, const uint8_t salt[32], const uint8_t in[32], uint8_t out[32])
{
size_t dgstlen;
if (hkdf_extract(digest, salt, 32, in, 32, out, &dgstlen) != 1
|| dgstlen != 32) {
error_print();
return -1;
}
return 1;
}
int tls13_hkdf_expand_label(const DIGEST *digest, const uint8_t secret[32],
const char *label, const uint8_t *context, size_t context_len,
size_t outlen, uint8_t *out)
{
uint8_t label_len;
uint8_t hkdf_label[2 + 256 + 256];
uint8_t *p = hkdf_label;
size_t hkdf_label_len = 0;
label_len = strlen("tls13") + strlen(label);
tls_uint16_to_bytes((uint16_t)outlen, &p, &hkdf_label_len);
tls_uint8_to_bytes(label_len, &p, &hkdf_label_len);
tls_array_to_bytes((uint8_t *)"tls13", strlen("tls13"), &p, &hkdf_label_len);
tls_array_to_bytes((uint8_t *)label, strlen(label), &p, &hkdf_label_len);
tls_uint8array_to_bytes(context, context_len, &p, &hkdf_label_len);
hkdf_expand(digest, secret, 32, hkdf_label, hkdf_label_len, outlen, out);
return 1;
}
int tls13_derive_secret(const uint8_t secret[32], const char *label, const DIGEST_CTX *dgst_ctx, uint8_t out[32])
{
DIGEST_CTX ctx = *dgst_ctx;
uint8_t dgst[64];
size_t dgstlen;
if (digest_finish(&ctx, dgst, &dgstlen) != 1
|| tls13_hkdf_expand_label(dgst_ctx->digest, secret, label, dgst, 32, dgstlen, out) != 1) {
error_print();
return -1;
}
return 1;
}
/*
data to be signed in certificate_verify:
- A string that consists of octet 32 (0x20) repeated 64 times
- The context string
- A single 0 byte which serves as the separator
- The content to be signed
*/
int tls13_sign(const SM2_KEY *key, const DIGEST_CTX *dgst_ctx, uint8_t *sig, size_t *siglen, int is_server)
{
uint8_t client_context_str[] = "TLS 1.3, client CertificateVerify";
uint8_t server_context_str[] = "TLS 1.3, server CertificateVerify";
SM2_SIGN_CTX sm2_ctx;
DIGEST_CTX temp_dgst_ctx;
uint8_t prefix[64];
uint8_t *context_str = is_server ? server_context_str : client_context_str;
size_t context_str_len = sizeof(client_context_str);
uint8_t dgst[64];
size_t dgstlen;
memset(prefix, 0x20, 64);
temp_dgst_ctx = *dgst_ctx;
digest_finish(&temp_dgst_ctx, dgst, &dgstlen);
sm2_sign_init(&sm2_ctx, key, SM2_DEFAULT_ID);
sm2_sign_update(&sm2_ctx, prefix, 64);
sm2_sign_update(&sm2_ctx, context_str, context_str_len);
sm2_sign_update(&sm2_ctx, dgst, dgstlen);
sm2_sign_finish(&sm2_ctx, sig, siglen);
return 1;
}
int tls13_verify(const SM2_KEY *key, const DIGEST_CTX *dgst_ctx, const uint8_t *sig, size_t siglen, int is_server)
{
uint8_t client_context_str[] = "TLS 1.3, client CertificateVerify";
uint8_t server_context_str[] = "TLS 1.3, server CertificateVerify";
int ret;
SM2_SIGN_CTX sm2_ctx;
DIGEST_CTX temp_dgst_ctx;
uint8_t prefix[64];
uint8_t dgst[64];
size_t dgstlen;
memset(prefix, 0x20, 64);
temp_dgst_ctx = *dgst_ctx;
digest_finish(&temp_dgst_ctx, dgst, &dgstlen);
sm2_verify_init(&sm2_ctx, key, SM2_DEFAULT_ID);
sm2_verify_update(&sm2_ctx, prefix, 64);
sm2_verify_update(&sm2_ctx, is_server ? server_context_str : client_context_str, sizeof(server_context_str));
sm2_verify_update(&sm2_ctx, dgst, dgstlen);
ret = sm2_verify_finish(&sm2_ctx, sig, siglen);
return ret;
}
/*
verify_data in Finished
finished_key =
HKDF-Expand-Label(BaseKey, "finished", "", Hash.length)
Structure of this message:
struct {
opaque verify_data[Hash.length];
} Finished;
The verify_data value is computed as follows:
verify_data =
HMAC(finished_key,
Transcript-Hash(Handshake Context,
Certificate*, CertificateVerify*))
*/
int tls13_compute_verify_data(const uint8_t *handshake_traffic_secret,
const DIGEST_CTX *dgst_ctx, uint8_t *verify_data, size_t *verify_data_len)
{
DIGEST_CTX temp_dgst_ctx;
uint8_t dgst[64];
size_t dgstlen;
uint8_t finished_key[64];
size_t finished_key_len;
temp_dgst_ctx = *dgst_ctx;
digest_finish(&temp_dgst_ctx, dgst, &dgstlen);
finished_key_len = dgstlen;
tls13_hkdf_expand_label(dgst_ctx->digest, handshake_traffic_secret,
"finished", NULL, 0, finished_key_len, finished_key);
hmac(dgst_ctx->digest, finished_key, finished_key_len, dgst, dgstlen, verify_data, verify_data_len);
return 1;
}
/*
Handshakes
*/
int tls_ext_supported_versions_to_bytes(const int *versions, size_t versions_count, int tls_ext_supported_versions_to_bytes(const int *versions, size_t versions_count,
uint8_t **out, size_t *outlen) uint8_t **out, size_t *outlen)
{ {
@@ -597,56 +891,6 @@ int tls13_record_get_handshake_encrypted_extensions(const uint8_t *record)
return 1; return 1;
} }
int tls13_sign(const SM2_KEY *key, const DIGEST_CTX *dgst_ctx, uint8_t *sig, size_t *siglen, int is_server)
{
uint8_t client_context_str[] = "TLS 1.3, client CertificateVerify";
uint8_t server_context_str[] = "TLS 1.3, server CertificateVerify";
SM2_SIGN_CTX sm2_ctx;
DIGEST_CTX temp_dgst_ctx;
uint8_t prefix[64];
uint8_t *context_str = is_server ? server_context_str : client_context_str;
size_t context_str_len = sizeof(client_context_str);
uint8_t dgst[64];
size_t dgstlen;
memset(prefix, 0x20, 64);
temp_dgst_ctx = *dgst_ctx;
digest_finish(&temp_dgst_ctx, dgst, &dgstlen);
sm2_sign_init(&sm2_ctx, key, SM2_DEFAULT_ID);
sm2_sign_update(&sm2_ctx, prefix, 64);
sm2_sign_update(&sm2_ctx, context_str, context_str_len);
sm2_sign_update(&sm2_ctx, dgst, dgstlen);
sm2_sign_finish(&sm2_ctx, sig, siglen);
return 1;
}
int tls13_verify(const SM2_KEY *key, const DIGEST_CTX *dgst_ctx, const uint8_t *sig, size_t siglen, int is_server)
{
uint8_t client_context_str[] = "TLS 1.3, client CertificateVerify";
uint8_t server_context_str[] = "TLS 1.3, server CertificateVerify";
int ret;
SM2_SIGN_CTX sm2_ctx;
DIGEST_CTX temp_dgst_ctx;
uint8_t prefix[64];
uint8_t dgst[64];
size_t dgstlen;
memset(prefix, 0x20, 64);
temp_dgst_ctx = *dgst_ctx;
digest_finish(&temp_dgst_ctx, dgst, &dgstlen);
sm2_verify_init(&sm2_ctx, key, SM2_DEFAULT_ID);
sm2_verify_update(&sm2_ctx, prefix, 64);
sm2_verify_update(&sm2_ctx, is_server ? server_context_str : client_context_str, sizeof(server_context_str));
sm2_verify_update(&sm2_ctx, dgst, dgstlen);
ret = sm2_verify_finish(&sm2_ctx, sig, siglen);
return ret;
}
/* /*
ClientHello.Extensions.signature_algorithms 列出客户端支持的签名+哈希算法 ClientHello.Extensions.signature_algorithms 列出客户端支持的签名+哈希算法
@@ -814,26 +1058,6 @@ int tls13_record_get_handshake_certificate(const uint8_t *record, uint8_t *data,
} }
int tls13_compute_verify_data(const uint8_t *handshake_traffic_secret,
const DIGEST_CTX *dgst_ctx, uint8_t *verify_data, size_t *verify_data_len)
{
DIGEST_CTX temp_dgst_ctx;
uint8_t dgst[64];
size_t dgstlen;
uint8_t finished_key[64];
size_t finished_key_len;
temp_dgst_ctx = *dgst_ctx;
digest_finish(&temp_dgst_ctx, dgst, &dgstlen);
finished_key_len = dgstlen;
tls13_hkdf_expand_label(dgst_ctx->digest, handshake_traffic_secret,
"finished", NULL, 0, finished_key_len, finished_key);
hmac(dgst_ctx->digest, finished_key, finished_key_len, dgst, dgstlen, verify_data, verify_data_len);
return 1;
}
@@ -1839,95 +2063,3 @@ int tls13_accept(TLS_CONNECT *conn, int port,
tls_trace("Connection Established!\n\n"); tls_trace("Connection Established!\n\n");
return 1; return 1;
} }
int tls13_send(TLS_CONNECT *conn, const uint8_t *data, size_t datalen, size_t padding_len)
{
const BLOCK_CIPHER_KEY *key;
const uint8_t *iv;
uint8_t *seq_num;
uint8_t *record = conn->record;
size_t recordlen;
tls_trace("<<<< [ApplicationData]\n");
if (conn->is_client) {
key = &conn->client_write_key;
iv = conn->client_write_iv;
seq_num = conn->client_seq_num;
} else {
key = &conn->server_write_key;
iv = conn->server_write_iv;
seq_num = conn->server_seq_num;
}
if (tls13_gcm_encrypt(key, iv, padding_len,
seq_num, TLS_record_application_data, data, datalen,
record + 5, &recordlen) != 1) {
error_print();
return -1;
}
record[0] = TLS_record_application_data;
record[1] = TLS_version_tls12 >> 8;
record[2] = TLS_version_tls12 & 0xff;
record[3] = recordlen >> 8;
record[4] = recordlen;
recordlen += 5;
tls_record_send(record, recordlen, conn->sock);
tls_seq_num_incr(seq_num);
return 1;
}
int tls13_recv(TLS_CONNECT *conn, uint8_t *data, size_t *datalen)
{
int record_type;
uint8_t *record = conn->record;
size_t recordlen;
const BLOCK_CIPHER_KEY *key;
const uint8_t *iv;
uint8_t *seq_num;
tls_trace(">>>> [ApplicationData]\n");
if (conn->is_client) {
key = &conn->client_write_key;
iv = conn->client_write_iv;
seq_num = conn->client_seq_num;
} else {
key = &conn->server_write_key;
iv = conn->server_write_iv;
seq_num = conn->server_seq_num;
}
if (tls12_record_recv(record, &recordlen, conn->sock) != 1) {
error_print();
return -1;
}
if (record[0] != TLS_record_application_data) {
error_print();
return -1;
}
if (tls13_gcm_decrypt(key, iv,
seq_num, record + 5, recordlen - 5,
&record_type, data, datalen) != 1) {
error_print();
return -1;
}
tls_seq_num_incr(seq_num);
if (record_type != TLS_record_application_data) {
error_print();
return -1;
}
return 1;
}

View File

@@ -1,347 +0,0 @@
/*
* Copyright (c) 2021 - 2021 The GmSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the GmSSL Project.
* (http://gmssl.org/)"
*
* 4. The name "GmSSL Project" must not be used to endorse or promote
* products derived from this software without prior written
* permission. For written permission, please contact
* guanzhi1980@gmail.com.
*
* 5. Products derived from this software may not be called "GmSSL"
* nor may "GmSSL" appear in their names without prior written
* permission of the GmSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the GmSSL Project
* (http://gmssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <gmssl/tls.h>
#include <gmssl/x509.h>
#include <gmssl/rand.h>
#include <gmssl/error.h>
#include <gmssl/digest.h>
#include <gmssl/hkdf.h>
#include "mem.h"
int tls_prf(const uint8_t *secret, size_t secretlen, const char *label,
const uint8_t *seed, size_t seedlen,
const uint8_t *more, size_t morelen,
size_t outlen, uint8_t *out)
{
SM3_HMAC_CTX inited_hmac_ctx;
SM3_HMAC_CTX hmac_ctx;
uint8_t A[32];
uint8_t hmac[32];
size_t len;
if (!secret || !secretlen || !label || !seed || !seedlen
|| (!more && morelen) || !outlen || !out) {
error_print();
return -1;
}
sm3_hmac_init(&inited_hmac_ctx, secret, secretlen);
memcpy(&hmac_ctx, &inited_hmac_ctx, sizeof(SM3_HMAC_CTX));
sm3_hmac_update(&hmac_ctx, (uint8_t *)label, strlen(label));
sm3_hmac_update(&hmac_ctx, seed, seedlen);
sm3_hmac_update(&hmac_ctx, more, morelen);
sm3_hmac_finish(&hmac_ctx, A);
memcpy(&hmac_ctx, &inited_hmac_ctx, sizeof(SM3_HMAC_CTX));
sm3_hmac_update(&hmac_ctx, A, sizeof(A));
sm3_hmac_update(&hmac_ctx, (uint8_t *)label, strlen(label));
sm3_hmac_update(&hmac_ctx, seed, seedlen);
sm3_hmac_update(&hmac_ctx, more, morelen);
sm3_hmac_finish(&hmac_ctx, hmac);
len = outlen < sizeof(hmac) ? outlen : sizeof(hmac);
memcpy(out, hmac, len);
out += len;
outlen -= len;
while (outlen) {
memcpy(&hmac_ctx, &inited_hmac_ctx, sizeof(SM3_HMAC_CTX));
sm3_hmac_update(&hmac_ctx, A, sizeof(A));
sm3_hmac_finish(&hmac_ctx, A);
memcpy(&hmac_ctx, &inited_hmac_ctx, sizeof(SM3_HMAC_CTX));
sm3_hmac_update(&hmac_ctx, A, sizeof(A));
sm3_hmac_update(&hmac_ctx, (uint8_t *)label, strlen(label));
sm3_hmac_update(&hmac_ctx, seed, seedlen);
sm3_hmac_update(&hmac_ctx, more, morelen);
sm3_hmac_finish(&hmac_ctx, hmac);
len = outlen < sizeof(hmac) ? outlen : sizeof(hmac);
memcpy(out, hmac, len);
out += len;
outlen -= len;
}
return 1;
}
/*
HKDF-Expand-Label(Secret, Label, Context, Length) =
HKDF-Expand(Secret, HkdfLabel, Length);
HkdfLabel = struct {
uint16 length = Length;
opaque label<7..255> = "tls13 " + Label;
opaque context<0..255> = Context; }
Derive-Secret(Secret, Label, Messages) =
HKDF-Expand-Label(Secret, Label, Hash(Messages), Hash.length)
*/
int tls13_hkdf_extract(const DIGEST *digest, const uint8_t salt[32], const uint8_t in[32], uint8_t out[32])
{
size_t dgstlen;
if (hkdf_extract(digest, salt, 32, in, 32, out, &dgstlen) != 1
|| dgstlen != 32) {
error_print();
return -1;
}
return 1;
}
int tls13_hkdf_expand_label(const DIGEST *digest, const uint8_t secret[32],
const char *label, const uint8_t *context, size_t context_len,
size_t outlen, uint8_t *out)
{
uint8_t label_len;
uint8_t hkdf_label[2 + 256 + 256];
uint8_t *p = hkdf_label;
size_t hkdf_label_len = 0;
label_len = strlen("tls13") + strlen(label);
tls_uint16_to_bytes((uint16_t)outlen, &p, &hkdf_label_len);
tls_uint8_to_bytes(label_len, &p, &hkdf_label_len);
tls_array_to_bytes((uint8_t *)"tls13", strlen("tls13"), &p, &hkdf_label_len);
tls_array_to_bytes((uint8_t *)label, strlen(label), &p, &hkdf_label_len);
tls_uint8array_to_bytes(context, context_len, &p, &hkdf_label_len);
hkdf_expand(digest, secret, 32, hkdf_label, hkdf_label_len, outlen, out);
return 1;
}
int tls13_derive_secret(const uint8_t secret[32], const char *label, const DIGEST_CTX *dgst_ctx, uint8_t out[32])
{
DIGEST_CTX ctx = *dgst_ctx;
uint8_t dgst[64];
size_t dgstlen;
if (digest_finish(&ctx, dgst, &dgstlen) != 1
|| tls13_hkdf_expand_label(dgst_ctx->digest, secret, label, dgst, 32, dgstlen, out) != 1) {
error_print();
return -1;
}
return 1;
}
int tls_cbc_encrypt(const SM3_HMAC_CTX *inited_hmac_ctx, const SM4_KEY *enc_key,
const uint8_t seq_num[8], const uint8_t header[5],
const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen)
{
SM3_HMAC_CTX hmac_ctx;
uint8_t last_blocks[32 + 16] = {0};
uint8_t *mac, *padding, *iv;
int rem, padding_len;
int i;
if (!inited_hmac_ctx || !enc_key || !seq_num || !header || (!in && inlen) || !out || !outlen) {
error_print();
return -1;
}
if (inlen > (1 << 14)) {
error_print("invalid tls record data length %zu\n", inlen);
return -1;
}
rem = (inlen + 32) % 16;
memcpy(last_blocks, in + inlen - rem, rem);
mac = last_blocks + rem;
memcpy(&hmac_ctx, inited_hmac_ctx, sizeof(SM3_HMAC_CTX));
sm3_hmac_update(&hmac_ctx, seq_num, 8);
sm3_hmac_update(&hmac_ctx, header, 5);
sm3_hmac_update(&hmac_ctx, in, inlen);
sm3_hmac_finish(&hmac_ctx, mac);
padding = mac + 32;
padding_len = 16 - rem - 1;
for (i = 0; i <= padding_len; i++) {
padding[i] = padding_len;
}
iv = out;
if (rand_bytes(iv, 16) != 1) {
error_print();
return -1;
}
out += 16;
if (inlen >= 16) {
sm4_cbc_encrypt(enc_key, iv, in, inlen/16, out);
out += inlen - rem;
iv = out - 16;
}
sm4_cbc_encrypt(enc_key, iv, last_blocks, sizeof(last_blocks)/16, out);
*outlen = 16 + inlen - rem + sizeof(last_blocks);
return 1;
}
int tls_cbc_decrypt(const SM3_HMAC_CTX *inited_hmac_ctx, const SM4_KEY *dec_key,
const uint8_t seq_num[8], const uint8_t enced_header[5],
const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen)
{
SM3_HMAC_CTX hmac_ctx;
const uint8_t *iv;
const uint8_t *padding;
const uint8_t *mac;
uint8_t header[5];
int padding_len;
int i;
if (!inited_hmac_ctx || !dec_key || !seq_num || !enced_header || !in || !inlen || !out || !outlen) {
error_print();
return -1;
}
if (inlen % 16
|| inlen < (16 + 0 + 32 + 16) // iv + data + mac + padding
|| inlen > (16 + (1<<14) + 32 + 256)) {
error_print("invalid tls cbc ciphertext length %zu\n", inlen);
return -1;
}
iv = in;
in += 16;
inlen -= 16;
sm4_cbc_decrypt(dec_key, iv, in, inlen/16, out);
padding_len = out[inlen - 1];
padding = out + inlen - padding_len - 1;
if (padding < out + 32) {
error_print();
return -1;
}
for (i = 0; i < padding_len; i++) {
if (padding[i] != padding_len) {
error_print("tls ciphertext cbc-padding check failure");
return -1;
}
}
*outlen = inlen - 32 - padding_len - 1;
header[0] = enced_header[0];
header[1] = enced_header[1];
header[2] = enced_header[2];
header[3] = (*outlen) >> 8;
header[4] = (*outlen);
mac = padding - 32;
memcpy(&hmac_ctx, inited_hmac_ctx, sizeof(SM3_HMAC_CTX));
sm3_hmac_update(&hmac_ctx, seq_num, 8);
sm3_hmac_update(&hmac_ctx, header, 5);
sm3_hmac_update(&hmac_ctx, out, *outlen);
if (sm3_hmac_finish_and_verify(&hmac_ctx, mac) != 1) {
error_print("tls ciphertext mac check failure");
return -1;
}
return 1;
}
int tls_sign_server_ecdh_params(const SM2_KEY *server_sign_key,
const uint8_t client_random[32], const uint8_t server_random[32],
int curve, const SM2_POINT *point, uint8_t *sig, size_t *siglen)
{
uint8_t server_ecdh_params[69];
SM2_SIGN_CTX sign_ctx;
if (!server_sign_key || !client_random || !server_random
|| curve != TLS_curve_sm2p256v1 || !point || !sig || !siglen) {
error_print();
return -1;
}
server_ecdh_params[0] = TLS_curve_type_named_curve;
server_ecdh_params[1] = curve >> 8;
server_ecdh_params[2] = curve;
server_ecdh_params[3] = 65;
sm2_point_to_uncompressed_octets(point, server_ecdh_params + 4);
sm2_sign_init(&sign_ctx, server_sign_key, SM2_DEFAULT_ID);
sm2_sign_update(&sign_ctx, client_random, 32);
sm2_sign_update(&sign_ctx, server_random, 32);
sm2_sign_update(&sign_ctx, server_ecdh_params, 69);
sm2_sign_finish(&sign_ctx, sig, siglen);
return 1;
}
int tls_verify_server_ecdh_params(const SM2_KEY *server_sign_key,
const uint8_t client_random[32], const uint8_t server_random[32],
int curve, const SM2_POINT *point, const uint8_t *sig, size_t siglen)
{
int ret;
uint8_t server_ecdh_params[69];
SM2_SIGN_CTX verify_ctx;
if (!server_sign_key || !client_random || !server_random
|| curve != TLS_curve_sm2p256v1 || !point || !sig || !siglen
|| siglen > TLS_MAX_SIGNATURE_SIZE) {
error_print();
return -1;
}
server_ecdh_params[0] = TLS_curve_type_named_curve;
server_ecdh_params[1] = curve >> 8;
server_ecdh_params[2] = curve;
server_ecdh_params[3] = 65;
sm2_point_to_uncompressed_octets(point, server_ecdh_params + 4);
sm2_verify_init(&verify_ctx, server_sign_key, SM2_DEFAULT_ID);
sm2_verify_update(&verify_ctx, client_random, 32);
sm2_verify_update(&verify_ctx, server_random, 32);
sm2_verify_update(&verify_ctx, server_ecdh_params, 69);
ret = sm2_verify_finish(&verify_ctx, sig, siglen);
if (ret != 1) error_print();
return ret;
}

View File

@@ -51,8 +51,55 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <gmssl/aes.h> #include <gmssl/aes.h>
#include <gmssl/hex.h>
#include <gmssl/error.h>
int main(void)
int test_aes_ctr(void)
{
// NIST SP 800-38A F.5.1
char *hex_key = "2b7e151628aed2a6abf7158809cf4f3c";
char *hex_ctr = "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff";
char *hex_msg = "6bc1bee22e409f96e93d7e117393172a"
"ae2d8a571e03ac9c9eb76fac45af8e51"
"30c81c46a35ce411e5fbc1191a0a52ef"
"f69f2445df4f9b17ad2b417be66c3710";
char *hex_out = "874d6191b620e3261bef6864990db6ce"
"9806f66b7970fdff8617187bb9fffdff"
"5ae4df3edbd5d35e5b4f09020db03eab"
"1e031dda2fbe03d1792170a0f3009cee";
int err = 0;
AES_KEY aes_key;
uint8_t key[32];
uint8_t ctr[16];
uint8_t msg[64];
uint8_t out[64];
uint8_t buf[64];
size_t keylen, ctrlen, msglen, outlen, buflen;
hex_to_bytes(hex_key, strlen(hex_key), key, &keylen);
hex_to_bytes(hex_ctr, strlen(hex_ctr), ctr, &ctrlen);
hex_to_bytes(hex_msg, strlen(hex_msg), msg, &msglen);
hex_to_bytes(hex_out, strlen(hex_out), out, &outlen);
aes_set_encrypt_key(&aes_key, key, keylen);
aes_ctr_encrypt(&aes_key, ctr, msg, msglen, buf);
buflen = msglen;
format_bytes(stdout, 0, 0, "aes_ctr(msg) = ", buf, buflen);
format_bytes(stdout, 0, 0, " = ", out, outlen);
hex_to_bytes(hex_ctr, strlen(hex_ctr), ctr, &ctrlen);
aes_ctr_encrypt(&aes_key, ctr, buf, buflen, buf);
format_bytes(stdout, 0, 0, "msg = ", msg, msglen);
format_bytes(stdout, 0, 0, " = ", buf, buflen);
return 1;
}
int test_aes(void)
{ {
int err = 0; int err = 0;
AES_KEY aes_key; AES_KEY aes_key;
@@ -185,3 +232,180 @@ int main(void)
return 0; return 0;
} }
struct {
char *K;
char *P;
char *A;
char *IV;
char *C;
char *T;
} aes_gcm_tests[] = {
// test 1
{
"00000000000000000000000000000000",
"",
"",
"000000000000000000000000",
"",
"58e2fccefa7e3061367f1d57a4e7455a",
},
// test 2
{
"00000000000000000000000000000000",
"00000000000000000000000000000000",
"",
"000000000000000000000000",
"0388dace60b6a392f328c2b971b2fe78",
"ab6e47d42cec13bdf53a67b21257bddf",
},
// test 3
{
"feffe9928665731c6d6a8f9467308308",
"d9313225f88406e5a55909c5aff5269a"
"86a7a9531534f7da2e4c303d8a318a72"
"1c3c0c95956809532fcf0e2449a6b525"
"b16aedf5aa0de657ba637b391aafd255",
"",
"cafebabefacedbaddecaf888",
"42831ec2217774244b7221b784d0d49c"
"e3aa212f2c02a4e035c17e2329aca12e"
"21d514b25466931c7d8f6a5aac84aa05"
"1ba30b396a0aac973d58e091473f5985",
"4d5c2af327cd64a62cf35abd2ba6fab4",
},
// test 4
{
"feffe9928665731c6d6a8f9467308308",
"d9313225f88406e5a55909c5aff5269a"
"86a7a9531534f7da2e4c303d8a318a72"
"1c3c0c95956809532fcf0e2449a6b525"
"b16aedf5aa0de657ba637b39",
"feedfacedeadbeeffeedfacedeadbeef"
"abaddad2",
"cafebabefacedbaddecaf888",
"42831ec2217774244b7221b784d0d49c"
"e3aa212f2c02a4e035c17e2329aca12e"
"21d514b25466931c7d8f6a5aac84aa05"
"1ba30b396a0aac973d58e091",
"5bc94fbc3221a5db94fae95ae7121a47",
},
// test 5
{
"feffe9928665731c6d6a8f9467308308",
"d9313225f88406e5a55909c5aff5269a"
"86a7a9531534f7da2e4c303d8a318a72"
"1c3c0c95956809532fcf0e2449a6b525"
"b16aedf5aa0de657ba637b39",
"feedfacedeadbeeffeedfacedeadbeef"
"abaddad2",
"cafebabefacedbad",
"61353b4c2806934a777ff51fa22a4755"
"699b2a714fcdc6f83766e5f97b6c7423"
"73806900e49f24b22b097544d4896b42"
"4989b5e1ebac0f07c23f4598",
"3612d2e79e3b0785561be14aaca2fccb",
},
// test 6
{
"feffe9928665731c6d6a8f9467308308",
"d9313225f88406e5a55909c5aff5269a"
"86a7a9531534f7da2e4c303d8a318a72"
"1c3c0c95956809532fcf0e2449a6b525"
"b16aedf5aa0de657ba637b39",
"feedfacedeadbeeffeedfacedeadbeef"
"abaddad2",
"9313225df88406e555909c5aff5269aa"
"6a7a9538534f7da1e4c303d2a318a728"
"c3c0c95156809539fcf0e2429a6b5254"
"16aedbf5a0de6a57a637b39b",
"8ce24998625615b603a033aca13fb894"
"be9112a5c3a211a8ba262a3cca7e2ca7"
"01e4a9a4fba43c90ccdcb281d48c7c6f"
"d62875d2aca417034c34aee5",
"619cc5aefffe0bfa462af43c1699d050",
},
// test 7
{
"00000000000000000000000000000000"
"0000000000000000",
"",
"",
"000000000000000000000000",
"",
"cd33b28ac773f74ba00ed1f312572435",
},
};
int test_aes_gcm(void)
{
uint8_t K[32];
uint8_t P[64];
uint8_t A[32];
uint8_t IV[64];
uint8_t C[64];
uint8_t T[16];
size_t Klen, Plen, Alen, IVlen, Clen, Tlen;
AES_KEY aes_key;
uint8_t out[64];
uint8_t tag[16];
uint8_t buf[64];
int i;
printf("%s\n", __FUNCTION__);
for (i = 0; i < sizeof(aes_gcm_tests)/sizeof(aes_gcm_tests[0]); i++) {
int ok = 1;
hex_to_bytes(aes_gcm_tests[i].K, strlen(aes_gcm_tests[i].K), K, &Klen);
hex_to_bytes(aes_gcm_tests[i].P, strlen(aes_gcm_tests[i].P), P, &Plen);
hex_to_bytes(aes_gcm_tests[i].A, strlen(aes_gcm_tests[i].A), A, &Alen);
hex_to_bytes(aes_gcm_tests[i].IV, strlen(aes_gcm_tests[i].IV), IV, &IVlen);
hex_to_bytes(aes_gcm_tests[i].C, strlen(aes_gcm_tests[i].C), C, &Clen);
hex_to_bytes(aes_gcm_tests[i].T, strlen(aes_gcm_tests[i].T), T, &Tlen);
aes_set_encrypt_key(&aes_key, K, Klen);
aes_gcm_encrypt(&aes_key, IV, IVlen, A, Alen, P, Plen, out, Tlen, tag);
if (aes_gcm_decrypt(&aes_key, IV, IVlen, A, Alen, out, Plen, tag, Tlen, buf) != 1) {
error_print();
ok = 0;
}
if (memcmp(buf, P, Plen) != 0) {
error_print();
ok = 0;
}
printf(" test %d %s\n", i + 1, ok ? "ok" : "error");
/*
format_print(stdout, 0, 2, "K = %s\n", aes_gcm_tests[i].K);
format_print(stdout, 0, 2, "P = %s\n", aes_gcm_tests[i].P);
format_print(stdout, 0, 2, "A = %s\n", aes_gcm_tests[i].A);
format_print(stdout, 0, 2, "IV = %s\n", aes_gcm_tests[i].IV);
format_print(stdout, 0, 2, "C = %s\n", aes_gcm_tests[i].C);
format_bytes(stdout, 0, 2, " = ", out, Plen);
format_print(stdout, 0, 2, "T = %s\n", aes_gcm_tests[i].T);
format_bytes(stdout, 0, 2, " = ", tag, Tlen);
printf("\n");
*/
}
return 0;
}
int main(void)
{
test_aes();
test_aes_ctr();
test_aes_gcm();
return 0;
}

View File

@@ -85,6 +85,7 @@ int main(void)
if (memcmp(buf, testdata, sizeof(testdata)) != 0) { if (memcmp(buf, testdata, sizeof(testdata)) != 0) {
printf("chacha20 test 1 failed\n"); printf("chacha20 test 1 failed\n");
return -1;
} else { } else {
printf("chacha20 test 1 ok\n"); printf("chacha20 test 1 ok\n");
} }

View File

@@ -50,69 +50,110 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <gmssl/gcm.h> #include <gmssl/gcm.h>
#include <gmssl/hex.h>
#include <gmssl/error.h>
struct { struct {
char *K; char *H;
char *P; char *A;
char *IV;
char *C; char *C;
char *T; char *T;
} gcm_tests[] = { } ghash_tests[] = {
/* test 1 */ // test 1
{ {
"66e94bd4ef8a2c3b884cfa59ca342b2e",
"",
"",
"00000000000000000000000000000000", "00000000000000000000000000000000",
"",
"000000000000000000000000",
"",
"58e2fccefa7e3061367f1d57a4e7455a",
}, },
/* test 2 */ // test 2
{ {
"00000000000000000000000000000000", "66e94bd4ef8a2c3b884cfa59ca342b2e",
"00000000000000000000000000000000", "",
"000000000000000000000000",
"0388dace60b6a392f328c2b971b2fe78", "0388dace60b6a392f328c2b971b2fe78",
"ab6e47d42cec13bdf53a67b21257bddf", "f38cbb1ad69223dcc3457ae5b6b0f885",
}, },
// test 3
{
"b83b533708bf535d0aa6e52980d53b78",
"",
"42831ec2217774244b7221b784d0d49c"
"e3aa212f2c02a4e035c17e2329aca12e"
"21d514b25466931c7d8f6a5aac84aa05"
"1ba30b396a0aac973d58e091473f5985",
"7f1b32b81b820d02614f8895ac1d4eac",
},
// test 4
{
"b83b533708bf535d0aa6e52980d53b78",
"feedfacedeadbeeffeedfacedeadbeef"
"abaddad2",
"42831ec2217774244b7221b784d0d49c"
"e3aa212f2c02a4e035c17e2329aca12e"
"21d514b25466931c7d8f6a5aac84aa05"
"1ba30b396a0aac973d58e091",
"698e57f70e6ecc7fd9463b7260a9ae5f",
},
// test 5
{
"b83b533708bf535d0aa6e52980d53b78",
"feedfacedeadbeeffeedfacedeadbeef"
"abaddad2",
"61353b4c2806934a777ff51fa22a4755"
"699b2a714fcdc6f83766e5f97b6c7423"
"73806900e49f24b22b097544d4896b42"
"4989b5e1ebac0f07c23f4598",
"df586bb4c249b92cb6922877e444d37b",
},
// test 6
{
"b83b533708bf535d0aa6e52980d53b78",
"feedfacedeadbeeffeedfacedeadbeef"
"abaddad2",
"8ce24998625615b603a033aca13fb894"
"be9112a5c3a211a8ba262a3cca7e2ca7"
"01e4a9a4fba43c90ccdcb281d48c7c6f"
"d62875d2aca417034c34aee5",
"1c5afe9760d3932f3c9a878aac3dc3de",
},
};
int test_ghash(void)
{
uint8_t H[16];
uint8_t A[32];
uint8_t C[64];
uint8_t T[16];
uint8_t out[16];
size_t Hlen, Alen, Clen, Tlen;
int i;
printf("%s\n", __FUNCTION__);
for (i = 0; i < sizeof(ghash_tests)/sizeof(ghash_tests[0]); i++) {
hex_to_bytes(ghash_tests[i].H, strlen(ghash_tests[i].H), H, &Hlen);
hex_to_bytes(ghash_tests[i].A, strlen(ghash_tests[i].A), A, &Alen);
hex_to_bytes(ghash_tests[i].C, strlen(ghash_tests[i].C), C, &Clen);
hex_to_bytes(ghash_tests[i].T, strlen(ghash_tests[i].T), T, &Tlen);
ghash(H, A, Alen, C, Clen, out);
printf(" test %d %s\n", i + 1, memcmp(out ,T, Tlen) == 0 ? "ok" : "error");
/*
format_print(stdout, 0, 2, "H = %s\n", ghash_tests[i].H);
format_print(stdout, 0, 2, "A = %s\n", ghash_tests[i].A);
format_print(stdout, 0, 2, "C = %s\n", ghash_tests[i].C);
format_bytes(stdout, 0, 2, "GHASH(H,A,C) = ", out, 16);
format_print(stdout, 0, 2, " = %s\n\n", ghash_tests[i].T);
*/
}
return 1;
} }
int main(void) int main(void)
{ {
int err = 0; test_ghash();
GCM_CTX ctx; return 1;
uint8_t *key = NULL;
uint8_t *iv = NULL;
uint8_t *p = NULL;
uint8_t *c = NULL;
uint8_t *tag = NULL;
size_t keylen, ivlen, plen, clen, taglen, len, i;
for (i = 0; i < sizeof(gcm_tests)/sizeof(gcm_tests[0]); i++) {
key = OPENSSL_hexstr2buf(gcm_tests[i].K, &keylen);
iv = OPENSSL_hexstr2buf(gcm_tests[i].IV, &ivlen);
p = OPENSSL_hexstr2buf(gcm_tests[i].P, &plen);
c = OPENSSL_hexstr2buf(gcm_tests[i].C, &clen);
tag = OPENSSL_hexstr2buf(gcm_tests[i].T, &taglen);
buf = malloc(plen);
gcm_init(&ctx, taglen, key, keylen, iv, ivlen, aad, aadlen);
gcm_update(&ctx, p, plen, buf, &len);
if (!gcm_finish_verify(&ctx, tag, taglen)) {
printf("gcm test %zu failed\n", i+1);
err++;
} else {
printf("gcm test %zu ok\n", i+1);
}
free(key);
free(iv);
free(p);
free(c);
free(tag);
free(buf);
}
return err;
} }

View File

@@ -51,26 +51,16 @@
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
#include <gmssl/hex.h> #include <gmssl/hex.h>
#include "internal/gf128.h" #include <gmssl/gf128.h>
/*
static gf128_t gf128_from_hex(const char *s) a = de300f9301a499a965f8bf677e99e80d
{ b = 14b267838ec9ef1bb7b5ce8c19e34bc6
uint8_t bin[16]; a + b = ca8268108f6d76b2d24d71eb677aa3cb
assert(strlen(s) == 32); a - b = ca8268108f6d76b2d24d71eb677aa3cb
hex2bin(s, strlen(s), bin); a * b = 28e63413cd53b01a3b469375781942c6
return gf128_from_bytes(bin); a * 2 = bc601f2603493352cbf17ecefd33d09d
} */
static int gf128_equ_hex(gf128_t a, const char *s)
{
uint8_t bin1[16];
uint8_t bin2[16];
assert(strlen(s) == 32);
hex2bin(s, strlen(s), bin1);
gf128_to_bytes(a, bin2);
return memcmp(bin1, bin2, sizeof(bin1)) == 0;
}
int main(void) int main(void)
{ {
@@ -81,9 +71,25 @@ int main(void)
gf128_t b = gf128_from_hex("14b267838ec9ef1bb7b5ce8c19e34bc6"); gf128_t b = gf128_from_hex("14b267838ec9ef1bb7b5ce8c19e34bc6");
gf128_t r; gf128_t r;
/*
r = gf128_add(a, b);
gf128_print("a + b = ", r);
r = gf128_mul(a, b);
gf128_print("a * b = ", r);
r = gf128_mul2(a);
gf128_print("a * 2 = ", r);
*/
gf128_t H = gf128_from_hex("66e94bd4ef8a2c3b884cfa59ca342b2e");
gf128_t C = gf128_from_hex("0388dace60b6a392f328c2b971b2fe78");
gf128_t T = gf128_mul(C, H);
gf128_print("C = ", C);
gf128_print("H = ", H);
gf128_print("C * H = ", T);

View File

@@ -49,6 +49,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h>
#include <gmssl/hex.h> #include <gmssl/hex.h>
#include <gmssl/digest.h> #include <gmssl/digest.h>
#include <gmssl/hash_drbg.h> #include <gmssl/hash_drbg.h>
@@ -66,31 +67,36 @@
#define V1 "f9afadfbbf2c3d1004f9baca38be247342e5fbb83281915d5de18beb963712a344e89bb0e6b925a7bbc32eadb8b441efc1fa0c649df42a" #define V1 "f9afadfbbf2c3d1004f9baca38be247342e5fbb83281915d5de18beb963712a344e89bb0e6b925a7bbc32eadb8b441efc1fa0c649df42a"
#define C1 "1d41cbbd634909e4761c232fcfd6a6c2edf0a7f4d3d3c164f74a88955f355efce2d86c1e9fa897b7005ef9d4d3a51bf4fc0b805ab896c9" #define C1 "1d41cbbd634909e4761c232fcfd6a6c2edf0a7f4d3d3c164f74a88955f355efce2d86c1e9fa897b7005ef9d4d3a51bf4fc0b805ab896c9"
#define PR1 "2edb396eeb8960f77943c2a59075a786"
#define PR2 "30b565b63a5012676940d3ef17d9e996"
int main(void) int main(void)
{ {
HASH_DRBG drbg; HASH_DRBG drbg;
unsigned char *entropy = NULL; uint8_t entropy[sizeof(EntropyInput)/2];
unsigned char *nonce = NULL; uint8_t nonce[sizeof(Nonce)/2];
unsigned char *personalstr = NULL; uint8_t personalstr[sizeof(PersonalizationString)/2];
unsigned char *v = NULL; uint8_t v[sizeof(V0)/2];
unsigned char *c = NULL; uint8_t c[sizeof(C0)/2];
uint8_t entropy_pr1[sizeof(EntropyInputPR1)/2];
uint8_t pr1[sizeof(PR1)/2];
uint8_t pr2[sizeof(PR2)/2];
size_t entropy_len, nonce_len, personalstr_len, vlen, clen; size_t entropy_len, nonce_len, personalstr_len, vlen, clen;
unsigned char *entropy_pr1 = NULL;
size_t entropy_pr1len; size_t entropy_pr1len;
size_t pr1_len, pr2_len;
unsigned char out[640/8]; unsigned char out[640/8];
int i;
entropy = OPENSSL_hexstr2buf(EntropyInput, &entropy_len); hex_to_bytes(EntropyInput, strlen(EntropyInput), entropy, &entropy_len);
nonce = OPENSSL_hexstr2buf(Nonce, &nonce_len); hex_to_bytes(Nonce, strlen(Nonce), nonce, &nonce_len);
personalstr = OPENSSL_hexstr2buf(PersonalizationString, &personalstr_len); hex_to_bytes(PersonalizationString, strlen(PersonalizationString), personalstr, &personalstr_len);
v = OPENSSL_hexstr2buf(V0, &vlen); hex_to_bytes(V0, strlen(V0), v, &vlen);
c = OPENSSL_hexstr2buf(C0, &clen); hex_to_bytes(C0, strlen(C0), c, &clen);
hex_to_bytes(EntropyInputPR1, strlen(EntropyInputPR1), entropy_pr1, &entropy_pr1len);
entropy_pr1 = OPENSSL_hexstr2buf(EntropyInputPR1, &entropy_pr1len); hex_to_bytes(PR1, strlen(PR1), pr1, &pr1_len);
hex_to_bytes(PR2, strlen(PR2), pr2, &pr2_len);
hash_drbg_init(&drbg, DIGEST_sha1(), hash_drbg_init(&drbg, DIGEST_sha1(),
@@ -108,12 +114,6 @@ int main(void)
printf("ok\n"); printf("ok\n");
} }
unsigned char *pr1 = NULL;
unsigned char *pr2 = NULL;
size_t pr1_len, pr2_len;
pr1 = OPENSSL_hexstr2buf("2edb396eeb8960f77943c2a59075a786", &pr1_len);
pr2 = OPENSSL_hexstr2buf("30b565b63a5012676940d3ef17d9e996", &pr2_len);
hash_drbg_reseed(&drbg, pr1, pr1_len, NULL, 0); hash_drbg_reseed(&drbg, pr1, pr1_len, NULL, 0);
hash_drbg_generate(&drbg, NULL, 0, 640/8, out); hash_drbg_generate(&drbg, NULL, 0, 640/8, out);
@@ -121,7 +121,6 @@ int main(void)
hash_drbg_reseed(&drbg, pr2, pr2_len, NULL, 0); hash_drbg_reseed(&drbg, pr2, pr2_len, NULL, 0);
hash_drbg_generate(&drbg, NULL, 0, 640/8, out); hash_drbg_generate(&drbg, NULL, 0, 640/8, out);
int i;
for (i = 0; i < sizeof(out); i++) { for (i = 0; i < sizeof(out); i++) {
printf("%02x", out[i]); printf("%02x", out[i]);
} }

View File

@@ -50,9 +50,11 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h>
#include <gmssl/md5.h> #include <gmssl/md5.h>
#include <gmssl/hex.h> #include <gmssl/hex.h>
static char *teststr[] = { static char *teststr[] = {
"", "",
"a", "a",
@@ -77,17 +79,14 @@ int main(int argc, char **argv)
{ {
int err = 0; int err = 0;
char *p; char *p;
unsigned char *dgstbuf = NULL; uint8_t dgst[16];
uint8_t dgstbuf[16];
size_t dgstbuflen; size_t dgstbuflen;
unsigned char dgst[16];
size_t i; size_t i;
for (i = 0; i < sizeof(teststr)/sizeof(teststr[0]); i++) { for (i = 0; i < sizeof(teststr)/sizeof(teststr[0]); i++) {
if (!(dgstbuf = OPENSSL_hexstr2buf(dgsthex[i], &dgstbuflen))) { hex_to_bytes(dgsthex[i], strlen(dgsthex[i]), dgstbuf, &dgstbuflen);
goto end; md5_digest((uint8_t *)teststr[i], strlen(teststr[i]), dgst);
}
md5_digest((unsigned char *)teststr[i], strlen(teststr[i]), dgst);
if (memcmp(dgstbuf, dgst, sizeof(dgst)) != 0) { if (memcmp(dgstbuf, dgst, sizeof(dgst)) != 0) {
int n; int n;
@@ -102,12 +101,7 @@ int main(int argc, char **argv)
} else { } else {
printf("md5 test %lu ok\n", i+1); printf("md5 test %lu ok\n", i+1);
} }
free(dgstbuf);
dgstbuf = NULL;
} }
end:
if (dgstbuf) free(dgstbuf);
return err; return err;
} }

View File

@@ -156,5 +156,5 @@ int main(void)
} }
} }
return 0; return 1;
} }

0
tests/pemtest.c Normal file
View File

View File

@@ -49,6 +49,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h>
#include <gmssl/sha1.h> #include <gmssl/sha1.h>
#include <gmssl/hex.h> #include <gmssl/hex.h>
@@ -78,19 +79,17 @@ int main(void)
{ {
int err = 0; int err = 0;
SHA1_CTX ctx; SHA1_CTX ctx;
unsigned char dgst[20]; uint8_t dgst[20];
unsigned char *dgstbuf = NULL; uint8_t dgstbuf[20];
size_t dgstlen;
size_t i, j; size_t i, j;
for (i = 0; i < sizeof(teststr)/sizeof(teststr[0]); i++) { for (i = 0; i < sizeof(teststr)/sizeof(teststr[0]); i++) {
hex_to_bytes(dgsthex[i], strlen(dgsthex[i]), dgstbuf, &dgstlen);
if (!(dgstbuf = OPENSSL_hexstr2buf(dgsthex[i], NULL))) {
goto end;
}
sha1_init(&ctx); sha1_init(&ctx);
for (j = 0; j < testcnt[i]; j++) { for (j = 0; j < testcnt[i]; j++) {
sha1_update(&ctx, (unsigned char *)teststr[i], strlen(teststr[i])); sha1_update(&ctx, (uint8_t *)teststr[i], strlen(teststr[i]));
} }
sha1_finish(&ctx, dgst); sha1_finish(&ctx, dgst);
@@ -105,12 +104,7 @@ int main(void)
} else { } else {
printf("sha1 test %lu ok\n", i+1); printf("sha1 test %lu ok\n", i+1);
} }
free(dgstbuf);
dgstbuf = NULL;
} }
end:
if (dgstbuf) free(dgstbuf);
return err; return err;
} }

View File

@@ -49,6 +49,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h>
#include <gmssl/hex.h> #include <gmssl/hex.h>
#include <gmssl/sha2.h> #include <gmssl/sha2.h>
@@ -100,19 +101,17 @@ int main(int argc, char **argv)
{ {
int err = 0; int err = 0;
SHA224_CTX ctx; SHA224_CTX ctx;
unsigned char dgst[SHA224_DIGEST_SIZE]; uint8_t dgst[SHA224_DIGEST_SIZE];
unsigned char *dgstbuf = NULL; uint8_t dgstbuf[SHA224_DIGEST_SIZE];
size_t dgstlen;
size_t i, j; size_t i, j;
for (i = 0; i < 7; i++) { for (i = 0; i < 7; i++) {
hex_to_bytes(tests[i].dgsthex, strlen(tests[i].dgsthex), dgstbuf, &dgstlen);
if (!(dgstbuf = OPENSSL_hexstr2buf(tests[i].dgsthex, NULL))) {
goto end;
}
sha224_init(&ctx); sha224_init(&ctx);
for (j = 0; j < tests[i].count; j++) { for (j = 0; j < tests[i].count; j++) {
sha224_update(&ctx, (unsigned char *)tests[i].data, tests[i].length); sha224_update(&ctx, (uint8_t *)tests[i].data, tests[i].length);
} }
sha224_finish(&ctx, dgst); sha224_finish(&ctx, dgst);
@@ -127,12 +126,7 @@ int main(int argc, char **argv)
} else { } else {
printf("sha224 test %lu ok\n", i+1); printf("sha224 test %lu ok\n", i+1);
} }
free(dgstbuf);
dgstbuf = NULL;
} }
end:
if (dgstbuf) free(dgstbuf);
return err; return err;
} }

View File

@@ -50,6 +50,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h>
#include <gmssl/hex.h> #include <gmssl/hex.h>
#include <gmssl/sha2.h> #include <gmssl/sha2.h>
@@ -99,19 +100,17 @@ int main(int argc, char **argv)
{ {
int err = 0; int err = 0;
SHA256_CTX ctx; SHA256_CTX ctx;
unsigned char dgst[SHA256_DIGEST_SIZE]; uint8_t dgst[SHA256_DIGEST_SIZE];
unsigned char *dgstbuf = NULL; uint8_t dgstbuf[SHA256_DIGEST_SIZE];
size_t dgstlen;
size_t i, j; size_t i, j;
for (i = 0; i < 7; i++) { for (i = 0; i < 7; i++) {
hex_to_bytes(tests[i].dgsthex, strlen(tests[i].dgsthex), dgstbuf, &dgstlen);
if (!(dgstbuf = OPENSSL_hexstr2buf(tests[i].dgsthex, NULL))) {
goto end;
}
sha256_init(&ctx); sha256_init(&ctx);
for (j = 0; j < tests[i].count; j++) { for (j = 0; j < tests[i].count; j++) {
sha256_update(&ctx, (unsigned char *)tests[i].data, tests[i].length); sha256_update(&ctx, (uint8_t *)tests[i].data, tests[i].length);
} }
sha256_finish(&ctx, dgst); sha256_finish(&ctx, dgst);
@@ -126,12 +125,7 @@ int main(int argc, char **argv)
} else { } else {
printf("sha256 test %lu ok\n", i+1); printf("sha256 test %lu ok\n", i+1);
} }
free(dgstbuf);
dgstbuf = NULL;
} }
end:
if (dgstbuf) free(dgstbuf);
return err; return err;
} }

View File

@@ -50,6 +50,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h>
#include <gmssl/hex.h> #include <gmssl/hex.h>
#include <gmssl/sha2.h> #include <gmssl/sha2.h>
@@ -105,19 +106,17 @@ int main(void)
{ {
int err = 0; int err = 0;
SHA384_CTX ctx; SHA384_CTX ctx;
unsigned char dgst[SHA384_DIGEST_SIZE]; uint8_t dgst[SHA384_DIGEST_SIZE];
unsigned char *dgstbuf = NULL; uint8_t dgstbuf[SHA384_DIGEST_SIZE];
size_t dgstlen;
size_t i, j; size_t i, j;
for (i = 0; i < 7; i++) { for (i = 0; i < 7; i++) {
hex_to_bytes(tests[i].dgsthex, strlen(tests[i].dgsthex), dgstbuf, &dgstlen);
if (!(dgstbuf = OPENSSL_hexstr2buf(tests[i].dgsthex, NULL))) {
goto end;
}
sha384_init(&ctx); sha384_init(&ctx);
for (j = 0; j < tests[i].count; j++) { for (j = 0; j < tests[i].count; j++) {
sha384_update(&ctx, (unsigned char *)tests[i].data, tests[i].length); sha384_update(&ctx, (uint8_t *)tests[i].data, tests[i].length);
} }
sha384_finish(&ctx, dgst); sha384_finish(&ctx, dgst);
@@ -132,12 +131,7 @@ int main(void)
} else { } else {
printf("sha384 test %lu ok\n", i+1); printf("sha384 test %lu ok\n", i+1);
} }
free(dgstbuf);
dgstbuf = NULL;
} }
end:
if (dgstbuf) free(dgstbuf);
return err; return err;
} }

View File

@@ -50,6 +50,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h>
#include <gmssl/hex.h> #include <gmssl/hex.h>
#include <gmssl/sha2.h> #include <gmssl/sha2.h>
@@ -106,19 +107,17 @@ int main(void)
{ {
int err = 0; int err = 0;
SHA512_CTX ctx; SHA512_CTX ctx;
unsigned char dgst[SHA512_DIGEST_SIZE]; uint8_t dgst[SHA512_DIGEST_SIZE];
unsigned char *dgstbuf = NULL; uint8_t dgstbuf[SHA512_DIGEST_SIZE];
size_t dgstlen;
size_t i, j; size_t i, j;
for (i = 0; i < 7; i++) { for (i = 0; i < 7; i++) {
hex_to_bytes(tests[i].dgsthex, strlen(tests[i].dgsthex), dgstbuf, &dgstlen);
if (!(dgstbuf = OPENSSL_hexstr2buf(tests[i].dgsthex, NULL))) {
goto end;
}
sha512_init(&ctx); sha512_init(&ctx);
for (j = 0; j < tests[i].count; j++) { for (j = 0; j < tests[i].count; j++) {
sha512_update(&ctx, (unsigned char *)tests[i].data, tests[i].length); sha512_update(&ctx, (uint8_t *)tests[i].data, tests[i].length);
} }
sha512_finish(&ctx, dgst); sha512_finish(&ctx, dgst);
@@ -133,12 +132,7 @@ int main(void)
} else { } else {
printf("sha512 test %lu ok\n", i+1); printf("sha512 test %lu ok\n", i+1);
} }
free(dgstbuf);
dgstbuf = NULL;
} }
end:
if (dgstbuf) free(dgstbuf);
return err; return err;
} }

View File

@@ -50,6 +50,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h>
#include <gmssl/sm3.h> #include <gmssl/sm3.h>
#include <gmssl/hex.h> #include <gmssl/hex.h>
@@ -178,17 +179,15 @@ int main(int argc, char **argv)
{ {
int err = 0; int err = 0;
char *p; char *p;
unsigned char *testbuf = NULL; uint8_t testbuf[sizeof(testhex)/2];
unsigned char *dgstbuf = NULL; uint8_t dgstbuf[32];
size_t testbuflen, dgstbuflen; size_t testbuflen, dgstbuflen;
unsigned char dgst[32]; uint8_t dgst[32];
size_t i; size_t i;
for (i = 0; i < sizeof(testhex)/sizeof(testhex[0]); i++) { for (i = 0; i < sizeof(testhex)/sizeof(testhex[0]); i++) {
if (!(testbuf = OPENSSL_hexstr2buf(testhex[i], &testbuflen)) hex_to_bytes(testhex[i], strlen(testhex[i]), testbuf, &testbuflen);
|| !(dgstbuf = OPENSSL_hexstr2buf(dgsthex[i], &dgstbuflen))) { hex_to_bytes(dgsthex[i], strlen(dgsthex[i]), dgstbuf, &dgstbuflen);
goto end;
}
sm3_digest(testbuf, testbuflen, dgst); sm3_digest(testbuf, testbuflen, dgst);
@@ -205,15 +204,7 @@ int main(int argc, char **argv)
} else { } else {
printf("sm3 test %lu ok\n", i+1); printf("sm3 test %lu ok\n", i+1);
} }
free(testbuf);
free(dgstbuf);
testbuf = NULL;
dgstbuf = NULL;
} }
end:
if (testbuf) free(testbuf);
if (dgstbuf) free(dgstbuf);
return err; return err;
} }

View File

@@ -1,62 +0,0 @@
/*
* Copyright (c) 2014 - 2020 The GmSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the GmSSL Project.
* (http://gmssl.org/)"
*
* 4. The name "GmSSL Project" must not be used to endorse or promote
* products derived from this software without prior written
* permission. For written permission, please contact
* guanzhi1980@gmail.com.
*
* 5. Products derived from this software may not be called "GmSSL"
* nor may "GmSSL" appear in their names without prior written
* permission of the GmSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the GmSSL Project
* (http://gmssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
__uint128_t a = 0;
uint64_t al = 1;
uint64_t ah = 1;
a = ((__uint128_t)ah << 64) | al;
return (int)a;
}