mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-08-07 12:33:39 +08:00
remove old api
This commit is contained in:
@@ -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
|
|
||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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],
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|||||||
68
src/hmac.c
68
src/hmac.c
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
224
src/tls.c
@@ -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
|
||||||
|
|||||||
532
src/tls13.c
532
src/tls13.c
@@ -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;
|
||||||
|
|
||||||
return -1;
|
if (gcm_decrypt(key, iv, 12, aad, 5, in, mlen, gmac, GHASH_SIZE, out) != 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
347
src/tls_cipher.c
347
src/tls_cipher.c
@@ -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;
|
|
||||||
}
|
|
||||||
226
tests/aestest.c
226
tests/aestest.c
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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");
|
||||||
}
|
}
|
||||||
|
|||||||
141
tests/gcmtest.c
141
tests/gcmtest.c
@@ -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;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -156,5 +156,5 @@ int main(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
0
tests/pemtest.c
Normal file
0
tests/pemtest.c
Normal 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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user