tls 1.3 init

This commit is contained in:
Zhi Guan
2021-07-28 16:32:10 +08:00
parent ce7dd7fccf
commit 62d1899760
66 changed files with 3080 additions and 18101 deletions

View File

@@ -47,13 +47,12 @@
*/
#ifndef NO_AES
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <gmssl/aes.h>
#include "bswap.h"
#include "rotate.h"
#include "endian.h"
#include "mem.h"
static const uint8_t S[256] = {
@@ -479,4 +478,3 @@ void aes_decrypt(const AES_KEY *aes_key, const uint8_t in[16], uint8_t out[16])
memset(state, 0, sizeof(state));
}
#endif

239
src/aes_modes.c Normal file
View File

@@ -0,0 +1,239 @@
/*
* 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>
#include <gmssl/aes.h>
#include <gmssl/gcm.h>
#include <gmssl/error.h>
#include "mem.h"
void aes_cbc_encrypt(const AES_KEY *key, const uint8_t iv[16],
const uint8_t *in, size_t nblocks, uint8_t *out)
{
while (nblocks--) {
gmssl_memxor(out, in, iv, 16);
aes_encrypt(key, out, out);
iv = out;
in += 16;
out += 16;
}
}
void aes_cbc_decrypt(const AES_KEY *key, const uint8_t iv[16],
const uint8_t *in, size_t nblocks, uint8_t *out)
{
while (nblocks--) {
aes_decrypt(key, in, out);
memxor(out, iv, 16);
iv = in;
in += 16;
out += 16;
}
}
int aes_cbc_padding_encrypt(const AES_KEY *key, const uint8_t iv[16],
const uint8_t *in, size_t inlen,
uint8_t *out, size_t *outlen)
{
uint8_t block[16];
size_t rem = inlen % 16;
int padding = 16 - rem;
if (in) {
memcpy(block, in + inlen - rem, rem);
}
memset(block + rem, padding, padding);
if (inlen/16) {
aes_cbc_encrypt(key, iv, in, inlen/16, out);
out += inlen - rem;
iv = out - 16;
}
aes_cbc_encrypt(key, iv, block, 1, out);
*outlen = inlen - rem + 16;
return 1;
}
int aes_cbc_padding_decrypt(const AES_KEY *key, const uint8_t iv[16],
const uint8_t *in, size_t inlen,
uint8_t *out, size_t *outlen)
{
uint8_t block[16];
int padding;
if (inlen == 0) {
error_print("warning: input lenght = 0");
return 0;
}
if (inlen%16 != 0 || inlen < 16) {
error_print("invalid cbc ciphertext length");
return -1;
}
if (inlen > 16) {
aes_cbc_decrypt(key, iv, in, inlen/16 - 1, out);
iv = in + inlen - 32;
}
aes_cbc_decrypt(key, iv, in + inlen - 16, 1, block);
padding = block[15];
if (padding < 1 || padding > 16) {
error_print();
return -1;
}
memcpy(out + inlen - 16, block, 16 - padding);
*outlen = inlen - padding;
return 1;
}
static void ctr_incr(uint8_t a[16])
{
int i;
for (i = 15; i > 0; i--) {
a[i]++;
if (a[i]) break;
}
}
void aes_ctr_encrypt(const AES_KEY *key, uint8_t ctr[16], const uint8_t *in, size_t inlen, uint8_t *out)
{
uint8_t block[16];
size_t len;
while (inlen) {
len = inlen < 16 ? inlen : 16;
aes_encrypt(key, ctr, block);
gmssl_memxor(out, in, block, len);
ctr_incr(ctr);
in += len;
out += len;
inlen -= len;
}
}
int aes_gcm_encrypt(const AES_KEY *key, const uint8_t *iv, size_t ivlen,
const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen,
uint8_t *out, const size_t taglen, uint8_t *tag)
{
const uint8_t *pin = in;
uint8_t *pout = out;
size_t left = inlen;
uint8_t H[16] = {0};
uint8_t Y[16];
uint8_t T[16];
aes_encrypt(key, H, H);
if (ivlen == 12) {
memcpy(Y, iv, 12);
Y[12] = Y[13] = Y[14] = 0;
Y[15] = 1;
} else {
ghash(H, NULL, 0, iv, ivlen, Y);
}
aes_encrypt(key, Y, T);
while (left) {
uint8_t block[16];
size_t len = left < 16 ? left : 16;
ctr_incr(Y);
aes_encrypt(key, Y, block);
gmssl_memxor(pout, pin, block, len);
pin += len;
pout += len;
left -= len;
}
ghash(H, aad, aadlen, out, inlen, H);
gmssl_memxor(tag, T, H, taglen);
return 1;
}
int aes_gcm_decrypt(const AES_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 *tag, size_t taglen, uint8_t *out)
{
const uint8_t *pin = in;
uint8_t *pout = out;
size_t left = inlen;
uint8_t H[16] = {0};
uint8_t Y[16];
uint8_t T[16];
aes_encrypt(key, H, H);
if (ivlen == 12) {
memcpy(Y, iv, 12);
Y[12] = Y[13] = Y[14] = 0;
Y[15] = 1;
} else {
ghash(H, NULL, 0, iv, ivlen, Y);
}
ghash(H, aad, aadlen, in, inlen, H);
aes_encrypt(key, Y, T);
gmssl_memxor(T, T, H, taglen);
if (memcmp(T, tag, taglen) != 0) {
error_print();
return -1;
}
while (left) {
uint8_t block[16];
size_t len = left < 16 ? left : 16;
ctr_incr(Y);
aes_encrypt(key, Y, block);
gmssl_memxor(pout, pin, block, len);
pin += len;
pout += len;
left -= len;
}
return 1;
}

View File

@@ -52,152 +52,68 @@
#include <stdlib.h>
#include <gmssl/oid.h>
#include <gmssl/block_cipher.h>
#include "internal/endian.h"
#include "endian.h"
int block_cipher_encrypt_init(BLOCK_CIPHER_KEY *key, const BLOCK_CIPHER *cipher,
const uint8_t *user_key, size_t keylen)
int block_cipher_set_encrypt_key(BLOCK_CIPHER_KEY *key, const BLOCK_CIPHER *cipher, const uint8_t *raw_key)
{
memset(key, 0, sizeof(BLOCK_CIPHER_KEY));
cipher->set_encrypt_key(key, raw_key);
key->cipher = cipher;
return key->cipher->set_encrypt_key(key, user_key, keylen);
}
int block_cipher_decrypt_init(BLOCK_CIPHER_KEY *key, const BLOCK_CIPHER *cipher,
const uint8_t *user_key, size_t keylen)
{
memset(key, 0, sizeof(BLOCK_CIPHER_KEY));
key->cipher = cipher;
return key->cipher->set_decrypt_key(key, user_key, keylen);
}
void block_cipher_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *in, uint8_t *out)
{
key->cipher->encrypt(key, in, out);
}
void block_cipher_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *in, uint8_t *out)
{
key->cipher->decrypt(key, in, out);
}
void block_cipher_ecb_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *in, size_t nblocks, uint8_t *out)
{
while (nblocks--) {
key->cipher->encrypt(key, in, out);
in += key->cipher->block_size;
out += key->cipher->block_size;
}
}
void block_cipher_ecb_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *in, size_t nblocks, uint8_t *out)
{
while (nblocks--) {
key->cipher->decrypt(key, in, out);
in += key->cipher->block_size;
out += key->cipher->block_size;
}
}
void block_cipher_cbc_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *iv,
const uint8_t *in, size_t nblocks, uint8_t *out)
{
while (nblocks--) {
gmssl_memxor(out, in, iv, key->cipher->block_size);
key->cipher->encrypt(key, out, out);
iv = out;
in += key->cipher->block_size;
out += key->cipher->block_size;
}
}
void block_cipher_cbc_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *iv,
const uint8_t *in, size_t nblocks, uint8_t *out)
{
while (nblocks--) {
key->cipher->decrypt(key, in, out);
gmssl_memxor(out, out, iv, key->cipher->block_size);
iv = in;
in += key->cipher->block_size;
out += key->cipher->block_size;
}
}
void block_cipher_ctr_encrypt(const BLOCK_CIPHER_KEY *key, uint8_t *counter,
const uint8_t *in, size_t nblocks, uint8_t *out)
{
size_t block_size = key->cipher->block_size;
uint8_t block[block_size];
uint64_t ctr = GETU64(counter + block_size - sizeof(uint64_t));
while (nblocks--) {
key->cipher->encrypt(key, counter, block);
gmssl_memxor(out, in, block, block_size);
in += block_size;
out += block_size;
ctr++;
PUTU64(counter + block_size - sizeof(uint64_t), ctr);
}
}
static const BLOCK_CIPHER aes_block_cipher_object = {
OID_aes,
AES128_KEY_SIZE,
AES256_KEY_SIZE,
AES_BLOCK_SIZE,
(block_cipher_set_encrypt_key_func)aes_set_encrypt_key,
(block_cipher_set_decrypt_key_func)aes_set_decrypt_key,
(block_cipher_encrypt_func)aes_encrypt,
(block_cipher_decrypt_func)aes_encrypt,
};
const BLOCK_CIPHER *BLOCK_CIPHER_aes(void)
{
return &aes_block_cipher_object;
}
static int set_encrypt_key(BLOCK_CIPHER_KEY *key, const uint8_t *user_key, size_t keylen)
{
if (keylen != SM4_KEY_SIZE) {
return -1;
}
sm4_set_encrypt_key(&key->u.sm4_key, user_key);
return 1;
}
static int set_decrypt_key(BLOCK_CIPHER_KEY *key, const uint8_t *user_key, size_t keylen)
int block_cipher_set_decrypt_key(BLOCK_CIPHER_KEY *key, const BLOCK_CIPHER *cipher, const uint8_t *raw_key)
{
if (keylen != SM4_KEY_SIZE) {
return -1;
}
sm4_set_decrypt_key(&key->u.sm4_key, user_key);
memset(key, 0, sizeof(BLOCK_CIPHER_KEY));
cipher->set_decrypt_key(key, raw_key);
key->cipher = cipher;
return 1;
}
int block_cipher_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *in, uint8_t *out)
{
key->cipher->encrypt(key, in, out);
return 1;
}
int block_cipher_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *in, uint8_t *out)
{
key->cipher->decrypt(key, in, out);
return 1;
}
static const BLOCK_CIPHER sm4_block_cipher_object = {
OID_sm4,
SM4_KEY_SIZE,
SM4_KEY_SIZE,
SM4_BLOCK_SIZE,
set_encrypt_key,
set_decrypt_key,
(block_cipher_set_encrypt_key_func)sm4_set_encrypt_key,
(block_cipher_set_decrypt_key_func)sm4_set_decrypt_key,
(block_cipher_encrypt_func)sm4_encrypt,
(block_cipher_decrypt_func)sm4_encrypt,
};
const BLOCK_CIPHER *BLOCK_CIPHER_sm4(void)
{
const BLOCK_CIPHER *BLOCK_CIPHER_sm4(void) {
return &sm4_block_cipher_object;
}
const BLOKC_CIPHER *block_cipher_from_name(const char *name)
{
if (strcmp(name, "aes") == 0) {
return BLOCK_CIPHER_aes();
} else if (strcmp(name, "sm4") == 0) {
return BLOCK_CIPHER_sm4();
}
return NULL;
static int aes128_set_encrypt_key(AES_KEY *aes_key, const uint8_t key[16]) {
return aes_set_encrypt_key(aes_key, key, 16);
}
static int aes128_set_decrypt_key(AES_KEY *aes_key, const uint8_t key[16]) {
return aes_set_decrypt_key(aes_key, key, 16);
}
static const BLOCK_CIPHER aes128_block_cipher_object = {
AES128_KEY_SIZE,
AES_BLOCK_SIZE,
(block_cipher_set_encrypt_key_func)aes128_set_encrypt_key,
(block_cipher_set_decrypt_key_func)aes128_set_decrypt_key,
(block_cipher_encrypt_func)aes_encrypt,
(block_cipher_decrypt_func)aes_encrypt,
};
const BLOCK_CIPHER *BLOCK_CIPHER_aes128(void) {
return &aes128_block_cipher_object;
}

View File

@@ -1,56 +0,0 @@
/*
* Copyright 2010-2016 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#ifndef GMSSL_MODES_LCL_H
#define GMSSL_MODES_LCL_H
# if defined(__GNUC__) && __GNUC__>=2
# if defined(__x86_64) || defined(__x86_64__)
# define BSWAP8(x) ({ uint64_t ret_=(x); \
asm ("bswapq %0" \
: "+r"(ret_)); ret_; })
# define BSWAP4(x) ({ uint32_t ret_=(x); \
asm ("bswapl %0" \
: "+r"(ret_)); ret_; })
# elif defined(__aarch64__)
# define BSWAP8(x) ({ uint64_t ret_; \
asm ("rev %0,%1" \
: "=r"(ret_) : "r"(x)); ret_; })
# define BSWAP4(x) ({ uint32_t ret_; \
asm ("rev %w0,%w1" \
: "=r"(ret_) : "r"(x)); ret_; })
# endif
# elif defined(_MSC_VER)
# if _MSC_VER>=1300
# pragma intrinsic(_byteswap_uint64,_byteswap_ulong)
# define BSWAP8(x) _byteswap_uint64((uint64_t)(x))
# define BSWAP4(x) _byteswap_ulong((uint32_t)(x))
# endif
#endif
#if defined(BSWAP4) && !defined(STRICT_ALIGNMENT)
# define GETU32(p) BSWAP4(*(const uint32_t *)(p))
# define PUTU32(p,v) *(uint32_t *)(p) = BSWAP4(v)
# define GETU64(p) BSWAP8(*(const uint64_t *)(p))
# define PUTU64(p,v) *(uint64_t *)(p) = BSWAP8(v)
#else
# define GETU32(p) ((uint32_t)(p)[0]<<24|(uint32_t)(p)[1]<<16|(uint32_t)(p)[2]<<8|(uint32_t)(p)[3])
# define PUTU32(p,v) ((p)[0]=(u8)((v)>>24),(p)[1]=(u8)((v)>>16),(p)[2]=(u8)((v)>>8),(p)[3]=(u8)(v))
# define GETU64(p) ((uint64_t)(p)[0]<<56|(uint64_t)(p)[1]<<48|(uint64_t)(p)[2]<<40|(uint64_t)(p)[3]<<32| \
(uint64_t)(p)[4]<<24|(uint64_t)(p)[5]<<16|(uint64_t)(p)[6]<<8|(uint64_t)(p)[7])
# define PUTU64(p,v) ((p)[0]=(u8)((v)>>56),(p)[1]=(u8)((v)>>48),(p)[2]=(u8)((v)>>40),(p)[3]=(u8)((v)>>32),\
(p)[4]=(u8)((v)>>24),(p)[5]=(u8)((v)>>16),(p)[6]=(u8)((v)>>8),(p)[7]=(u8)(v)
#endif
#define GETU32_LE(p) (*(const uint32_t *)(p))
#define PUTU32_LE(p,a) *(uint32_t *)(p) = (a)
#define PUTU64_LE(p,a) *(uint64_t *)(p) = (a)
#endif

View File

@@ -46,14 +46,12 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef NO_CHACHA20
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <gmssl/chacha20.h>
#include "bswap.h"
#include "rotate.h"
#include "endian.h"
void chacha20_set_key(CHACHA20_STATE *state,
const unsigned char key[CHACHA20_KEY_SIZE],
@@ -122,4 +120,3 @@ void chacha20_generate_keystream(CHACHA20_STATE *state, unsigned int counts, uns
state->d[12]++;
}
}
#endif

View File

@@ -1,134 +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 <stdlib.h>
#include <string.h>
#include <gmssl/cmac.h>
#include "internal/gf128.h"
/*
CMAC的主体是CBC-MAC或者说是CBC模式
CMAC初始化的时候需要初始化E_K()中分组密码中的密钥编排
用GSK算法通过密钥K生成K1, K2这两个密钥最后是用来和最后一个分组做异或的
*/
int cmac_init(CMAC_CTX *ctx, const BLOCK_CIPHER *cipher, const uint8_t *key, size_t keylen)
{
gf128_t L;
ctx->cipher = cipher;
cipher->set_encrypt_key(&ctx->cipher_key, key, keylen);
/* L = E_K(0^128) */
memset(ctx->temp_block, 0, 16);
cipher->encrypt(&ctx->cipher_key, ctx->temp_block, ctx->temp_block);
L = gf128_from_bytes(ctx->temp_block);
/* K1 = L * 2 over GF(2^128) */
L = gf128_mul2(L);
gf128_to_bytes(L, ctx->k1);
/* K2 = K1 * 2 over GF(2^128) */
L = gf128_mul2(L);
gf128_to_bytes(L, ctx->k2);
memset(&L, 0, sizeof(gf128_t));
return 0;
}
int cmac_update(CMAC_CTX *ctx, const uint8_t *in, size_t inlen)
{
if (ctx->last_block_nbytes) {
unsigned int left = BLOCK_CIPHER_BLOCK_SIZE - ctx->num;
if (inlen < left) {
memcpy(ctx->block + ctx->last_block_nbytes, in, inlen);
ctx->last_block_nbytes += inlen;
return 1;
} else {
memcpy(ctx->block + ctx->last_block_nbytes, in, inlen);
}
}
while (inlen > 16) {
XOR128(block, in);
ctx->cipher->encrypt(ctx->cipher_key, block, block);
}
return 0;
}
// 在Finish的时候我们不应该清空密钥的内容
int cmac_finish(CMAC_CTX *ctx, size_t maclen, uint8_t *mac)
{
if (ctx->last_block_nbytes == 16) {
xor128(ctx->data, ctx->k1);
} else {
ctx->data[ctx->last_block_nbytes] = 0x01;
memset(ctx->data + ctx->last_block_nbytes, 0, 16 - ctx->last_block_nbytes);
xor128(ctx->data, ctx->k2);
}
xor128(cipher, data);
ctx->cipher->encrypt(ctx->cipher_key, ctx->block, ctx->block);
memcpy(out, block, outlen);
return 0;
}
int cmac_finish_and_verify(CMAC_CTX *ctx, const uint8_t *mac, size_t maclen)
{
uint8_t buf[16];
cmac_finish(ctx, maclen, buf);
if (memcmp(buf, mac, maclen) != 0) {
return 0;
}
return 1;
}

View File

@@ -78,7 +78,6 @@ int cms_public_key_from_certificate(const SM2_KEY **sm2_key,
return 1;
}
int cms_issuer_and_serial_number_to_der(const X509_NAME *issuer,
const uint8_t *serial_number, size_t serial_number_len,
uint8_t **out, size_t *outlen)
@@ -148,12 +147,6 @@ bad:
return -1;
}
static const uint32_t SM2_cms_oid[] = {1,2,156,10197,6,1,4,2};
const char *cms_content_type_name(int type)
@@ -972,8 +965,10 @@ int sm2_recipient_info_decrypt_from_der(const SM2_KEY *sm2_key,
sm2_decrypt(sm2_key, enced_key, enced_key_len, key, keylen);
return -1;
}
#endif
int cms_enced_content_info_to_der(int enc_algor, const uint8_t enc_iv[16],
int cms_enced_content_info_to_der(int enc_algor, const uint8_t *enc_iv, size_t enc_iv_len,
int content_type, const uint8_t *enced_content, size_t enced_content_len,
const uint8_t *shared_info1, size_t shared_info1_len,
const uint8_t *shared_info2, size_t shared_info2_len,
@@ -982,7 +977,7 @@ int cms_enced_content_info_to_der(int enc_algor, const uint8_t enc_iv[16],
size_t len = 0;
if (cms_content_type_to_der(content_type, NULL, &len) != 1
|| x509_encryption_algor_to_der(enc_algor, enc_iv, NULL, &len) != 1
|| x509_encryption_algor_to_der(enc_algor, enc_iv, enc_iv_len, NULL, &len) != 1
|| asn1_implicit_octet_string_to_der(0, enced_content, enced_content_len, NULL, &len) < 0
|| asn1_implicit_octet_string_to_der(1, shared_info1, shared_info1_len, NULL, &len) < 0
|| asn1_implicit_octet_string_to_der(2, shared_info2, shared_info2_len, NULL, &len) < 0) {
@@ -991,7 +986,7 @@ int cms_enced_content_info_to_der(int enc_algor, const uint8_t enc_iv[16],
}
if (asn1_sequence_header_to_der(len, out, outlen) != 1
|| cms_content_type_to_der(content_type, out, outlen) != 1
|| x509_encryption_algor_to_der(enc_algor, enc_iv, out, outlen) != 1
|| x509_encryption_algor_to_der(enc_algor, enc_iv, enc_iv_len, out, outlen) != 1
|| asn1_implicit_octet_string_to_der(0, enced_content, enced_content_len, out, outlen) < 0
|| asn1_implicit_octet_string_to_der(1, shared_info1, shared_info1_len, out, outlen) < 0
|| asn1_implicit_octet_string_to_der(2, shared_info2, shared_info2_len, out, outlen) < 0) {
@@ -1001,10 +996,8 @@ int cms_enced_content_info_to_der(int enc_algor, const uint8_t enc_iv[16],
return 1;
}
int cms_enced_content_info_from_der(
int *content_type,
int *enc_algor, uint32_t *enc_algor_nodes, size_t *enc_algor_nodes_count,
const uint8_t **enc_iv, size_t *enc_iv_len,
int cms_enced_content_info_from_der(int *content_type,
int *enc_algor, const uint8_t **enc_iv, size_t *enc_iv_len,
const uint8_t **enced_content, size_t *enced_content_len,
const uint8_t **shared_info1, size_t *shared_info1_len,
const uint8_t **shared_info2, size_t *shared_info2_len,
@@ -1019,8 +1012,7 @@ int cms_enced_content_info_from_der(
return ret;
}
if (cms_content_type_from_der(content_type, &data, &datalen) != 1
|| x509_encryption_algor_from_der(enc_algor, enc_algor_nodes, enc_algor_nodes_count,
enc_iv, enc_iv_len, &data, &datalen) != 1
|| x509_encryption_algor_from_der(enc_algor, enc_iv, enc_iv_len, &data, &datalen) != 1
|| asn1_implicit_octet_string_from_der(0, enced_content, enced_content_len, &data, &datalen) < 0
|| asn1_implicit_octet_string_from_der(1, shared_info1, shared_info1_len, &data, &datalen) < 0
|| asn1_implicit_octet_string_from_der(1, shared_info2, shared_info2_len, &data, &datalen) < 0
@@ -1040,7 +1032,7 @@ int cms_enced_content_info_encrypt_to_der(const SM4_KEY *sm4_key, const uint8_t
int content_type, const uint8_t *content, size_t content_len,
const uint8_t *shared_info1, size_t shared_info1_len,
const uint8_t *shared_info2, size_t shared_info2_len,
uint8_t *enced_content_info, size_t *enced_content_info_len)
uint8_t **out, size_t *outlen)
{
uint8_t enced_content[content_len + 256];
size_t enced_content_len;
@@ -1050,13 +1042,11 @@ int cms_enced_content_info_encrypt_to_der(const SM4_KEY *sm4_key, const uint8_t
error_print();
return -1;
}
*enced_content_info_len = 0;
if (cms_enced_content_info_to_der(OID_sm4_cbc, iv,
if (cms_enced_content_info_to_der(OID_sm4_cbc, iv, 16,
content_type, enced_content, enced_content_len,
shared_info1, shared_info1_len,
shared_info2, shared_info2_len,
&enced_content_info, enced_content_info_len) != 1) {
out, outlen) != 1) {
error_print();
return -1;
}
@@ -1078,8 +1068,7 @@ int cms_enced_content_info_decrypt_from_der(const SM4_KEY *sm4_key,
size_t enced_content_len;
if (cms_enced_content_info_from_der(content_type,
&enc_algor, enc_algor_nodes, &enc_algor_nodes_count,
&enc_iv, &enc_iv_len,
&enc_algor, &enc_iv, &enc_iv_len,
&enced_content, &enced_content_len,
shared_info1, shared_info1_len,
shared_info2, shared_info2_len,
@@ -1096,9 +1085,16 @@ int cms_enced_content_info_decrypt_from_der(const SM4_KEY *sm4_key,
return 1;
}
int cms_enveloped_data_to_der()
{
}
#if 0
int cms_enveloped_data_from_der(const uint8_t **rcpt_infos, size_t *rcpt_infos_len,
int *content_type,
@@ -1272,16 +1268,19 @@ int cms_enveloped_data_decrypt_from_der(const SM2_KEY *sm2_key, const X509_CERTI
return -1;
}
int cms_signed_and_enveloped_data_to_der()
int cms_signed_and_enveloped_data_to_der(void)
{
return -1;
}
int cms_signed_and_enveloped_data_from_der()
int cms_signed_and_enveloped_data_from_der(void)
{
return -1;
}
int cms_signed_and_enveloped_data_print()
int cms_signed_and_enveloped_data_print(void)
{
return -1;
}
int cms_signed_and_enveloped_data_sign_encrypt_to_der(
@@ -1372,6 +1371,7 @@ int cms_signed_and_enveloped_data_decrypt_verify_from_der()
#endif
@@ -1379,8 +1379,7 @@ int cms_signed_and_enveloped_data_decrypt_verify_from_der()
int cms_enced_data_to_der(int enc_algor, const uint8_t enc_iv[16],
int cms_enced_data_to_der(int enc_algor, const uint8_t *enc_iv, size_t enc_iv_len,
int content_type, const uint8_t *enced_content, size_t enced_content_len,
const uint8_t *shared_info1, size_t shared_info1_len,
const uint8_t *shared_info2, size_t shared_info2_len,
@@ -1389,8 +1388,8 @@ int cms_enced_data_to_der(int enc_algor, const uint8_t enc_iv[16],
size_t len = 0;
if (asn1_int_to_der(CMS_version, NULL, &len) != 1
|| cms_enced_content_info_to_der(enc_algor, enc_iv,
content_type, enced_content, enced_content_len
|| cms_enced_content_info_to_der(enc_algor, enc_iv, enc_iv_len,
content_type, enced_content, enced_content_len,
shared_info1, shared_info1_len,
shared_info2, shared_info2_len,
NULL, &len) != 1) {
@@ -1399,8 +1398,8 @@ int cms_enced_data_to_der(int enc_algor, const uint8_t enc_iv[16],
}
if (asn1_sequence_header_to_der(len, out, outlen) != 1
|| asn1_int_to_der(CMS_version, out, outlen) != 1
|| cms_enced_content_info_to_der(enc_algor, enc_iv,
content_type, enced_content, enced_content_len
|| cms_enced_content_info_to_der(enc_algor, enc_iv, enc_iv_len,
content_type, enced_content, enced_content_len,
shared_info1, shared_info1_len,
shared_info2, shared_info2_len,
out, outlen) != 1) {
@@ -1410,8 +1409,8 @@ int cms_enced_data_to_der(int enc_algor, const uint8_t enc_iv[16],
return 1;
}
int cms_enced_data_from_der(
int *content_type,
int cms_enced_data_from_der(int *content_type,
int *enc_algor, uint32_t *enc_algor_nodes, size_t *enc_algor_nodes_count,
const uint8_t **enc_iv, size_t *enc_iv_len,
const uint8_t **enced_content, size_t *enced_content_len,
@@ -1430,8 +1429,7 @@ int cms_enced_data_from_der(
}
if (asn1_int_from_der(&version, &data, &datalen) != 1
|| cms_enced_content_info_from_der(content_type,
enc_algor, enc_algor_nodes, enc_algor_nodes_count,
enc_iv, enc_iv_len,
enc_algor, enc_iv, enc_iv_len,
enced_content, enced_content_len,
shared_info1, shared_info1_len,
shared_info2, shared_info2_len,
@@ -1456,7 +1454,7 @@ int cms_encrypted_data_encrypt_to_der(const SM4_KEY *sm4_key, const uint8_t iv[1
size_t len = 0;
if (asn1_int_to_der(CMS_version, NULL, &len) != 1
|| cms_encrypted_content_info_to_der(sm4_key, iv,
|| cms_enced_content_info_encrypt_to_der(sm4_key, iv,
content_type, content, content_len,
shared_info1, shared_info1_len,
shared_info2, shared_info2_len,
@@ -1466,7 +1464,7 @@ int cms_encrypted_data_encrypt_to_der(const SM4_KEY *sm4_key, const uint8_t iv[1
}
if (asn1_sequence_header_to_der(len, out, outlen) != 1
|| asn1_int_to_der(CMS_version, out, outlen) != 1
|| cms_encrypted_content_info_to_der(sm4_key, iv,
|| cms_enced_content_info_encrypt_to_der(sm4_key, iv,
content_type, content, content_len,
shared_info1, shared_info1_len,
shared_info2, shared_info2_len,
@@ -1490,10 +1488,10 @@ int cms_key_agreement_info_to_der(const SM2_KEY *pub_key, const X509_CERTIFICATE
return -1;
}
if (asn1_sequence_header_to_der(len, out, outlen) != 1
|| asn1_int_to_der(CMS_version, out, &outlen) != 1
|| sm2_public_key_info_to_der(pub_key, out, &outlen) != 1
|| x509_certificate_to_der(cert, out, &outlen) != 1
|| asn1_octet_string_to_der(user_id, user_id_len, out, &outlen) != 1) {
|| asn1_int_to_der(CMS_version, out, outlen) != 1
|| sm2_public_key_info_to_der(pub_key, out, outlen) != 1
|| x509_certificate_to_der(cert, out, outlen) != 1
|| asn1_octet_string_to_der(user_id, user_id_len, out, outlen) != 1) {
error_print();
return -1;
}
@@ -1506,6 +1504,7 @@ int cms_key_agreement_info_from_der(SM2_KEY *pub_key, X509_CERTIFICATE *cert,
int ret;
const uint8_t *data;
size_t datalen;
int version;
if ((ret = asn1_sequence_from_der(&data, &datalen, in, inlen)) != 1) {
if (ret < 0) error_print();
@@ -1521,6 +1520,3 @@ int cms_key_agreement_info_from_der(SM2_KEY *pub_key, X509_CERTIFICATE *cert,
}
return 1;
}
#endif

298
src/ctr.c
View File

@@ -1,298 +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>
/*
* GHASH(H, A, C) = X_{m + n + 1}
* A additional authenticated data, A = A_1, ..., A_{m-1}, A_m^*, nbits(A_m^*) = v
* C ciphertext, C = C_1, ..., C_{n-1}, C_n^*, nbits(C_n^*) = u
* H = E_K(0^128)
*
* X_i = 0 for i = 0
* = (X_{i-1} xor A_i ) * H for i = 1, ..., m-1
* = (X_{m-1} xor (A_m^* || 0^{128-v})) * H for i = m
* = (X_{i-1} xor C_i ) * H for i = m+1, ..., m + n 1
* = (X_{m+n-1} xor (C_m^* || 0^{128-u})) * H for i = m + n
* = (X_{m+n} xor (nbits(A)||nbits(A))) * H for i = m + n + 1
*/
void ghash_init(GHASH_CTX *ctx, const uint8_t h[16], const uint8_t *aad, size_t aadlen)
{
__uint128_t H;
__uint128_t X;
__uint128_t A;
memset(ctx, 0, sizeof(GHASH_CTX));
/* get H in GF(2^128) as little endian */
ctx->H = H = GETU128_LE(h);
ctx->aadlen = aadlen;
/* process AAD */
X = 0;
while (aadlen >= 16) {
A = GETU128_LE(aad);
X = gf128_add(X, A);
X = gf128_mul(X, H);
aad += 16;
aadlen -= 16;
}
if (aadlen) {
memcpy(ctx->buf, aad, aadlen);
A = GETU128_LE(ctx->block);
X = gf128_add(X, A);
X = gf128_mul(X, H);
}
ctx->H = H;
ctx->X = X;
/* this clean ok? */
H = X = A = 0;
}
void ghash_update(GHASH_CTX *ctx, const uint8_t *c, size_t clen)
{
__uint128_t X;
__uint128_t H;
__uint128_t C;
if (!c && clen) {
return 0;
}
ctx->cipherlen += clen;
X = ctx->X;
H = ctx->H;
if (ctx->num) {
unsigned int left = 16 - ctx->num;
if (clen < left) {
memcpy(ctx->block + ctx->num, c, clen);
ctx->num += clen;
return 1;
} else {
memcpy(ctx->block + ctx->num, c, left);
C = GETU128_LE(ctx->block);
X = GF128_ADD(X, C);
X = GF128_MUL(X, H);
c += left;
clen -= left;
}
}
while (clen >= 16) {
C = GETU128_LE(c);
X = gf128_add(X, C);
X = gf128_mul(X, H);
c += 16;
clen -= 16;
}
ctx->num = clen;
if (clen) {
memcpy(ctx->block, c, clen);
}
ctx->X = X;
X = H = C = 0;
}
void ghash_finish(GHASH_CTX *ctx, uint8_t out[16])
{
__uint128_t X = ctx->X;
__uint128_t H = ctx->H;
__uint128_t C;
if (ctx->num < 0) {
return 0;
}
if (ctx->num) {
memset(ctx->block + ctx->num, 0, 16 - ctx->num);
C = GETU128_LE(ctx->block);
X = GF128_ADD(X, C);
X = GF128_MUL(X, H);
}
PUTU64_LE(ctx->block, (uint64_t)ctx->aadlen << 3);
PUTU64_LE(ctx->block + sizeof(uint64_t), (uint64_t)ctx->cipherlen << 3);
C = GETU128_LE(ctx->block);
X = GF128_ADD(X, C);
X = GF128_MUL(X, H);
PUTU128_LE(out, X);
memset(ctx, 0, sizeof(GHASH_CTX));
X = H = C = 0;
}
/*
* GCM(K, IV, A, P)
*
* H = E_K(0^128)
* Y_0 = IV || 0^{31}1 if nbits(IV) == 96
* = GHASH(H, {}, IV) otherwise
* Y_i = Y_{i-1} + 1 for i = 1, ..., n
* C_i = P_i xor E_K(Y_i) for i = 1, ..., n
* C_n^* = P_n^* xor MSB_u(E_K(Y_n))
* T = MSB_t(GHASH(H, A, C) xor E_K(Y_0))
*/
int gcm_init(GCM_CTX *ctx, const BLOCK_CIPEHR *cipher,
const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen,
const uint8_t *aad, size_t aadlen)
{
memset(ctx, 0, sizeof(GCM_CTX));
ctx->cipher = cipher;
/* H = E_K(0^128) */
if (!cipher->set_encrypt_key(ctx->key, key, keylen)) {
return 0;
}
cipher->encrypt(ctx->key, ctx->block, ctx->block);
/* init counter as Y_0 */
if (ivlen == GCM_DEFAULT_IV_SIZE) {
memcpy(ctx->counter, iv, ivlen);
PUTU32(ctx->counter + 12, 1);
} else {
ghash_init(&ctx->ghash_ctx, ctx->block, NULL, 0);
ghash_update(&ctx->ghash_ctx, iv, ivlen);
ghash_finish(&ctx->ghash_ctx, ctx->counter);
}
ghash_init(&ctx->ghash-ctx, ctx->block, aad, aadlen);
return 1;
}
// gcm 加密解密显然是不一样的
int gcm_update(GCM_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out)
{
uint32_t r;
size_t i;
uint8_t *c = out;
size_t clen = inlen;
if (ctx->num) {
uint8_t *k = ctx->block + 16 - ctx->num;
size_t len = inlen < ctx->num ? inlen : ctx->num;
for (i = 0; i < len; i++) {
out[i] = in[i] ^ k[i];
}
in += len;
out += len;
inlen -= len;
ctx->num -= len;
}
/* gcm only use the last 32 bits as counter */
r = GETU32(ctx->counter + 12);
while (inlen >= 16) {
r++;
PUTU32(ctx->counter + 12, r);
ctx->cipher->encrypt(ctx->key, ctx->counter, out);
for (i = 0; i < 16; i++) {
out[i] ^= in[i];
}
in += 16;
out += 16;
inlen -= 16;
}
if (inlen) {
r++;
PUTU32(ctx->counter + 12, r);
ctx->cipher->encrypt(ctx->key, ctx->counter, ctx->block);
for (i = 0; i < inlen; i++) {
out[i] = in[i] ^ ctx->block[i];
}
ctx->num = 16 - inlen;
}
ghash_update(ctx->ghash_ctx, c, inlen);
return 1;
}
int gcm_encrypt_update(GCM_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out)
{
ctr_update(ctx->ctr_ctx, in, inlen, out);
ghash_update(ctx->ghash_ctx, out, inlen);
}
int gcm_encrypt_finish(GCM_CTX *ctx, size_t taglen, uint8_t *tag)
{
int i;
ghash_finish(ctx->ghash_ctx, ctx->block);
for (i = 0; i < ctx->taglen; i++) {
tag[i] = ctx->block[i] ^ ctx->enced_iv[i];
}
memset(ctx, 0, sizeof(GCM_CTX));
}
int gcm_decrypt_finish(GCM_CTX *ctx, const uint8_t *tag, size_t taglen)
{
uint8_t buf[16];
if (taglen != ctx->taglen) {
return 0;
}
gcm_finish(ctx, buf);
if (memcmp(buf, tag, taglen) != 0) {
return 0;
}
return 1;
}

View File

@@ -46,13 +46,11 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef NO_DES
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <gmssl/des.h>
#include "bswap.h"
#include "endian.h"
/* permuted choice 1 for key schedule, 64 bits to 56 bits */
@@ -205,7 +203,7 @@ static uint32_t substitution(const uint64_t A)
(((uint32_t)S8[(A ) & 0x3f]) );
}
#define ROL32(A,Si) (((A)<<(Si))|((A)>>(32-(Si))))
//#define ROL32(A,Si) (((A)<<(Si))|((A)>>(32-(Si))))
void des_set_encrypt_key(DES_KEY *key, const unsigned char user_key[8])
{
@@ -267,4 +265,3 @@ void des_encrypt(DES_KEY *key, const unsigned char in[DES_BLOCK_SIZE],
PUTU64(out, T);
}
#endif

351
src/ffx.c
View File

@@ -1,351 +0,0 @@
/* ====================================================================
* Copyright (c) 2014 - 2017 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 <ctype.h>
#include <string.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/ffx.h>
#include <openssl/e_os2.h>
#include "../modes/modes_lcl.h"
static uint32_t modulo[] = {
1,
10,
100,
1000,
10000,
100000,
1000000,
10000000,
100000000,
1000000000,
1000000000,
};
struct FFX_CTX_st {
EVP_CIPHER_CTX *cctx;
int flag;
};
FFX_CTX *FFX_CTX_new(void)
{
FFX_CTX *ret = NULL;
ret = OPENSSL_zalloc(sizeof(*ret));
return ret;
}
void FFX_CTX_free(FFX_CTX *ctx)
{
if (ctx) {
EVP_CIPHER_CTX_free(ctx->cctx);
}
OPENSSL_free(ctx);
}
int FFX_init(FFX_CTX *ctx, const EVP_CIPHER *cipher, const unsigned char *key,
int flag)
{
int ret = 0;
EVP_CIPHER_CTX *cctx = NULL;
if (!ctx || !cipher || !key) {
FFXerr(FFX_F_FFX_INIT, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if (EVP_CIPHER_mode(cipher) != EVP_CIPH_ECB_MODE) {
FFXerr(FFX_F_FFX_INIT, FFX_R_INVALID_CIPHER_MODE);
return 0;
}
if (EVP_CIPHER_block_size(cipher) != 16) {
FFXerr(FFX_F_FFX_INIT, FFX_R_INVALID_BLOCK_SIZE);
return 0;
}
if (!ctx->cctx) {
if (!(cctx = EVP_CIPHER_CTX_new())) {
FFXerr(FFX_F_FFX_INIT, ERR_R_MALLOC_FAILURE);
goto end;
}
ctx->cctx = cctx;
cctx = NULL;
}
ctx->flag = flag;
if (!EVP_EncryptInit_ex(ctx->cctx, cipher, NULL, key, NULL)) {
FFXerr(FFX_F_FFX_INIT, FFX_R_ENCRYPT_INIT_FAILURE);
goto end;
}
ret = 1;
end:
EVP_CIPHER_CTX_free(cctx);
return ret;
}
int FFX_encrypt(FFX_CTX *ctx, const char *in, char *out, size_t iolen,
unsigned char *tweak, size_t tweaklen)
{
int llen, rlen;
uint32_t lval, rval;
unsigned char pblock[16] = {
0x01, 0x02, 0x01, 0x0a, 0x00, 0x00, 0x0a, 0xff,
0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00};
unsigned char qblock[16];
char lbuf[FFX_MAX_DIGITS/2 + 2];
uint64_t yval;
size_t i;
if (!ctx || !in || !out || !tweak) {
FFXerr(FFX_F_FFX_ENCRYPT, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if (iolen < FFX_MIN_DIGITS || iolen > FFX_MAX_DIGITS) {
FFXerr(FFX_F_FFX_ENCRYPT, FFX_R_INVALID_INPUT_LENGTH);
return 0;
}
for (i = 0; i < iolen; i++) {
if (!isdigit(in[i])) {
FFXerr(FFX_F_FFX_ENCRYPT, FFX_R_INVALID_INPUT_DIGIT);
return 0;
}
}
llen = iolen / 2;
rlen = iolen - llen;
if (tweaklen < FFX_MIN_TWEAKLEN || tweaklen > FFX_MAX_TWEAKLEN) {
FFXerr(FFX_F_FFX_ENCRYPT, FFX_R_INVALID_TWEAK_LENGTH);
return 0;
}
memcpy(lbuf, in, llen);
lbuf[llen] = 0;
lval = atoi(lbuf);
rval = atoi(in + llen);
pblock[7] = llen & 0xff;
pblock[8] = iolen & 0xff;
pblock[12] = tweaklen & 0xff;
if (!EVP_Cipher(ctx->cctx, pblock, pblock,
EVP_CIPHER_CTX_block_size(ctx->cctx))) {
FFXerr(FFX_F_FFX_ENCRYPT, ERR_R_EVP_LIB);
return 0;
}
memset(qblock, 0, sizeof(qblock));
memcpy(qblock, tweak, tweaklen);
for (i = 0; i < FFX_NUM_ROUNDS; i += 2) {
unsigned char rblock[16];
size_t j;
qblock[11] = i & 0xff;
memcpy(qblock + 12, &rval, sizeof(rval));
for (j = 0; j < sizeof(rblock); j++) {
rblock[j] = pblock[j] ^ qblock[j];
}
if (!EVP_Cipher(ctx->cctx, rblock, rblock,
EVP_CIPHER_CTX_block_size(ctx->cctx))) {
FFXerr(FFX_F_FFX_ENCRYPT, ERR_R_EVP_LIB);
return 0;
}
yval = *((uint64_t *)rblock) % modulo[llen];
lval = (lval + yval) % modulo[llen];
qblock[11] = (i + 1) & 0xff;
memcpy(qblock + 12, &lval, sizeof(lval));
for (j = 0; j < sizeof(rblock); j++) {
rblock[j] = pblock[j] ^ qblock[j];
}
if (!EVP_Cipher(ctx->cctx, rblock, rblock,
EVP_CIPHER_CTX_block_size(ctx->cctx))) {
FFXerr(FFX_F_FFX_ENCRYPT, ERR_R_EVP_LIB);
return 0;
}
yval = *((uint64_t *)rblock) % modulo[rlen];
rval = (rval + yval) % modulo[rlen];
}
memset(out, '0', iolen);
sprintf(lbuf, "%d", rval);
memcpy(out + rlen - strlen(lbuf), lbuf, strlen(lbuf));
sprintf(lbuf, "%d", lval);
strcpy(out + iolen - strlen(lbuf), lbuf);
return 1;
}
int FFX_decrypt(FFX_CTX *ctx, const char *in, char *out, size_t iolen,
unsigned char *tweak, size_t tweaklen)
{
int llen, rlen;
uint32_t lval, rval;
unsigned char pblock[16] = {
0x01, 0x02, 0x01, 0x0a, 0x00, 0x00, 0x0a, 0xff,
0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00};
unsigned char qblock[16];
char lbuf[FFX_MAX_DIGITS/2 + 2];
uint64_t yval;
size_t i;
if (!ctx || !in || !out || !tweak) {
FFXerr(FFX_F_FFX_DECRYPT, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if (iolen < FFX_MIN_DIGITS || iolen > FFX_MAX_DIGITS) {
FFXerr(FFX_F_FFX_DECRYPT, FFX_R_INVALID_INPUT_LENGTH);
return 0;
}
for (i = 0; i < iolen; i++) {
if (!isdigit(in[i])) {
FFXerr(FFX_F_FFX_DECRYPT, FFX_R_INVALID_INPUT_DIGIT);
return 0;
}
}
rlen = iolen / 2;
llen = iolen - rlen;
if (tweaklen < FFX_MIN_TWEAKLEN || tweaklen > FFX_MAX_TWEAKLEN) {
FFXerr(FFX_F_FFX_DECRYPT, FFX_R_INVALID_TWEAK_LENGTH);
return 0;
}
memcpy(lbuf, in, llen);
lbuf[llen] = 0;
lval = atoi(lbuf);
rval = atoi(in + llen);
pblock[7] = rlen & 0xff;
pblock[8] = iolen & 0xff;
pblock[12] = tweaklen & 0xff;
if (!EVP_Cipher(ctx->cctx, pblock, pblock,
EVP_CIPHER_CTX_block_size(ctx->cctx))) {
FFXerr(FFX_F_FFX_DECRYPT, ERR_R_EVP_LIB);
return 0;
}
memset(qblock, 0, sizeof(qblock));
memcpy(qblock, tweak, tweaklen);
for (i = FFX_NUM_ROUNDS - 1; i > 0; i -= 2) {
unsigned char rblock[16];
size_t j;
qblock[11] = i & 0xff;
memcpy(qblock + 12, &rval, sizeof(rval));
for (j = 0; j < sizeof(rblock); j++) {
rblock[j] = pblock[j] ^ qblock[j];
}
if (!EVP_Cipher(ctx->cctx, rblock, rblock,
EVP_CIPHER_CTX_block_size(ctx->cctx))) {
FFXerr(FFX_F_FFX_DECRYPT, ERR_R_EVP_LIB);
return 0;
}
yval = *((uint64_t *)rblock) % modulo[llen];
lval = (lval >= yval) ? (lval - yval) : lval + modulo[llen] - yval;
qblock[11] = (i - 1) & 0xff;
memcpy(qblock + 12, &lval, sizeof(lval));
for (j = 0; j < sizeof(rblock); j++) {
rblock[j] = pblock[j] ^ qblock[j];
}
if (!EVP_Cipher(ctx->cctx, rblock, rblock,
EVP_CIPHER_CTX_block_size(ctx->cctx))) {
FFXerr(FFX_F_FFX_DECRYPT, ERR_R_EVP_LIB);
return 0;
}
yval = *((uint64_t *)rblock) % modulo[rlen];
rval = (rval >= yval) ? (rval - yval) : rval + modulo[rlen] - yval;
}
memset(out, '0', iolen);
sprintf(lbuf, "%d", rval);
memcpy(out + rlen - strlen(lbuf), lbuf, strlen(lbuf));
sprintf(lbuf, "%d", lval);
strcpy(out + iolen - strlen(lbuf), lbuf);
return 1;
}
static int luhn_table[10] = {0, 2, 4, 6, 8, 1, 3, 5, 7, 9};
int FFX_compute_luhn(const char *in, size_t inlen)
{
int r = 0;
int i;
for (i = inlen - 1; i >= 0; i--) {
int a;
if (!isdigit(in[i])) {
return -2;
}
a = in[i] - '0';
if (i % 2 != inlen % 2)
a = luhn_table[a];
r += a;
}
r = ((r * 9) % 10) + '0';
return r;
}

226
src/gcm.c
View File

@@ -49,12 +49,17 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <gmssl/gf128.h>
#include <gmssl/gcm.h>
#include <gmssl/oid.h>
#include <gmssl/error.h>
#include <gmssl/aes.h>
#include "endian.h"
/*
* GHASH(H, A, C) = X_{m + n + 1}
* A additional authenticated data, A = A_1, ..., A_{m-1}, A_m^*, nbits(A_m^*) = v
* C ciphertext, C = C_1, ..., C_{n-1}, C_n^*, nbits(C_n^*) = u
* A additional authenticated data, A = A_1, ..., A_{m-1}, A_{m^*}, nbits(A_{m^*}) = v
* C ciphertext, C = C_1, ..., C_{n-1}, C_{n^*}, nbits(C_{n^*}) = u
* H = E_K(0^128)
*
* X_i = 0 for i = 0
@@ -62,189 +67,74 @@
* = (X_{m-1} xor (A_m^* || 0^{128-v})) * H for i = m
* = (X_{i-1} xor C_i ) * H for i = m+1, ..., m + n 1
* = (X_{m+n-1} xor (C_m^* || 0^{128-u})) * H for i = m + n
* = (X_{m+n} xor (nbits(A)||nbits(A))) * H for i = m + n + 1
* = (X_{m+n} xor (nbits(A)||nbits(C))) * H for i = m + n + 1
*/
void ghash_init(GHASH_CTX *ctx, const uint8_t h[16], const uint8_t *aad, size_t aadlen)
void ghash(const uint8_t h[16], const uint8_t *aad, size_t aadlen, const uint8_t *c, size_t clen, uint8_t out[16])
{
__uint128_t H;
__uint128_t X;
__uint128_t A;
gf128_t H = gf128_from_bytes(h);
gf128_t X = gf128_zero();
gf128_t L;
memset(ctx, 0, sizeof(GHASH_CTX));
PUTU64(out, (uint64_t)aadlen << 3);
PUTU64(out + 8, (uint64_t)clen << 3);
L = gf128_from_bytes(out);
/* get H in GF(2^128) as little endian */
ctx->H = H = GETU128_LE(h);
ctx->aadlen = aadlen;
/* process AAD */
X = 0;
while (aadlen >= 16) {
A = GETU128_LE(aad);
X = gf128_add(X, A);
X = gf128_mul(X, H);
aad += 16;
aadlen -= 16;
}
if (aadlen) {
memcpy(ctx->buf, aad, aadlen);
A = GETU128_LE(ctx->block);
X = gf128_add(X, A);
X = gf128_mul(X, H);
}
ctx->H = H;
ctx->X = X;
/* this clean ok? */
H = X = A = 0;
}
void ghash_update(GHASH_CTX *ctx, const uint8_t *c, size_t clen)
{
__uint128_t X;
__uint128_t H;
__uint128_t C;
if (!c && clen) {
return 0;
}
ctx->cipherlen += clen;
X = ctx->X;
H = ctx->H;
if (ctx->num) {
unsigned int left = 16 - ctx->num;
if (clen < left) {
memcpy(ctx->block + ctx->num, c, clen);
ctx->num += clen;
return 1;
while (aadlen) {
gf128_t A;
if (aadlen >= 16) {
A = gf128_from_bytes(aad);
aad += 16;
aadlen -= 16;
} else {
memcpy(ctx->block + ctx->num, c, left);
C = GETU128_LE(ctx->block);
X = GF128_ADD(X, C);
X = GF128_MUL(X, H);
c += left;
clen -= left;
memset(out, 0, 16);
memcpy(out, aad, aadlen);
A = gf128_from_bytes(out);
aadlen = 0;
}
X = gf128_add(X, A);
X = gf128_mul(X, H);
}
while (clen >= 16) {
C = GETU128_LE(c);
while (clen) {
gf128_t C;
if (clen >= 16) {
C = gf128_from_bytes(c);
c += 16;
clen -= 16;
} else {
memset(out, 0, 16);
memcpy(out, c, clen);
C = gf128_from_bytes(out);
clen = 0;
}
X = gf128_add(X, C);
X = gf128_mul(X, H);
c += 16;
clen -= 16;
}
ctx->num = clen;
if (clen) {
memcpy(ctx->block, c, clen);
}
ctx->X = X;
X = H = C = 0;
X = gf128_add(X, L);
H = gf128_mul(X, H);
gf128_to_bytes(H, out);
}
void ghash_finish(GHASH_CTX *ctx, uint8_t out[16])
int gcm_encrypt(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,
uint8_t *out, size_t taglen, uint8_t *tag)
{
__uint128_t X = ctx->X;
__uint128_t H = ctx->H;
__uint128_t C;
if (ctx->num < 0) {
return 0;
if (key->cipher == BLOCK_CIPHER_sm4()) {
sm4_gcm_encrypt(&(key->u.sm4_key), iv, ivlen, aad, aadlen, in, inlen, out, taglen, tag);
return 1;
} else if (key->cipher == BLOCK_CIPHER_aes128()) {
aes_gcm_encrypt(&(key->u.aes_key), iv, ivlen, aad, aadlen, in, inlen, out, taglen, tag);
return 1;
}
if (ctx->num) {
memset(ctx->block + ctx->num, 0, 16 - ctx->num);
C = GETU128_LE(ctx->block);
X = GF128_ADD(X, C);
X = GF128_MUL(X, H);
}
PUTU64_LE(ctx->block, (uint64_t)ctx->aadlen << 3);
PUTU64_LE(ctx->block + sizeof(uint64_t), (uint64_t)ctx->cipherlen << 3);
C = GETU128_LE(ctx->block);
X = GF128_ADD(X, C);
X = GF128_MUL(X, H);
PUTU128_LE(out, X);
memset(ctx, 0, sizeof(GHASH_CTX));
X = H = C = 0;
error_print();
return -1;
}
/*
* GCM(K, IV, A, P)
*
* H = E_K(0^128)
* Y_0 = IV || 0^{31}1 if nbits(IV) == 96
* = GHASH(H, {}, IV) otherwise
* Y_i = Y_{i-1} + 1 for i = 1, ..., n
* C_i = P_i xor E_K(Y_i) for i = 1, ..., n
* C_n^* = P_n^* xor MSB_u(E_K(Y_n))
* T = MSB_t(GHASH(H, A, C) xor E_K(Y_0))
*/
int gcm_init(GCM_CTX *ctx, const BLOCK_CIPEHR *cipher,
const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen,
const uint8_t *aad, size_t aadlen)
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 *tag, size_t taglen, uint8_t *out)
{
memset(ctx, 0, sizeof(GCM_CTX));
ctx->cipher = cipher;
/* H = E_K(0^128) */
if (!cipher->set_encrypt_key(ctx->key, key, keylen)) {
return 0;
}
cipher->encrypt(ctx->key, ctx->block, ctx->block);
/* init counter as Y_0 */
if (ivlen == GCM_DEFAULT_IV_SIZE) {
memcpy(ctx->counter, iv, ivlen);
PUTU32(ctx->counter + 12, 1);
} else {
ghash_init(&ctx->ghash_ctx, ctx->block, NULL, 0);
ghash_update(&ctx->ghash_ctx, iv, ivlen);
ghash_finish(&ctx->ghash_ctx, ctx->counter);
}
ghash_init(&ctx->ghash-ctx, ctx->block, aad, aadlen);
return 1;
return -1;
}
int gcm_encrypt_update(GCM_CTX *ctx, const uint8_t *in, size_t iolen, uint8_t *out)
{
ctr_update(&ctx->ctr_ctx, in, iolen, out);
ghash_update(&ctx->ghash_ctx, out, iolen);
}
int gcm_decrypt_update(GCM_CTX *ctx, const uint8_t *in, size_t iolen, uint8_t *out)
{
ghash_update(&ctx->ghash_ctx, in, iolen);
}
int gcm_encrypt_finish(GCM_CTX *ctx, size_t taglen, uint8_t *tag)
{
int i;
ghash_finish(ctx->ghash_ctx, ctx->block);
for (i = 0; i < ctx->taglen; i++) {
tag[i] = ctx->block[i] ^ ctx->enced_iv[i];
}
memset(ctx, 0, sizeof(GCM_CTX));
}
int gcm_decrypt_finish(GCM_CTX *ctx, const uint8_t *tag, size_t taglen)
{
uint8_t buf[16];
if (taglen != ctx->taglen) {
return 0;
}
gcm_finish(ctx, buf);
if (memcmp(buf, tag, taglen) != 0) {
return 0;
}
return 1;
}

View File

@@ -51,30 +51,78 @@
* A * 2 mod f(x)
*/
#include "internal/endian.h"
#include "internal/gf128.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <gmssl/hex.h>
#include <gmssl/gf128.h>
#include "endian.h"
gf128_t gf128_zero(void)
{
uint8_t zero[16] = {0};
return gf128_from_bytes(zero);
}
gf128_t gf128_from_hex(const char *s)
{
uint8_t bin[16];
hex2bin(s, strlen(s), bin);
return gf128_from_bytes(bin);
}
int gf128_equ_hex(gf128_t a, const char *s)
{
uint8_t bin1[16];
uint8_t bin2[16];
hex2bin(s, strlen(s), bin1);
gf128_to_bytes(a, bin2);
return memcmp(bin1, bin2, sizeof(bin1)) == 0;
}
void gf128_print_bits(gf128_t a)
{
int i;
for (i = 0; i < 128; i++) {
printf("%d", (int)(a % 2));
a >>= 1;
}
printf("\n");
}
void gf128_print(const char *s, gf128_t a)
{
uint8_t be[16];
int i;
printf("%s", s);
gf128_to_bytes(a, be);
for (i = 0; i < 16; i++) {
printf("%02X", be[i]);
}
printf("\n");
}
#ifdef GMSSL_HAVE_UINT128
gf128_t gf128_mul(gf128_t a, gf128_t b)
{
const gf128_t mask = (gf128_t)1 << 127;
gf128_t r = 0;
gf128_t mask = (gf128_t)1 << 127;
int i;
for (i = 0; i < 128; i++) {
// r = r * 2 over gf(2^128)
// r = r * 2
if (r & mask)
r = (r << 1) ^ 0x87;
else r <<= 1;
// if b[i] == 1, r = r + a
// if b[127-i] == 1, r = r + a
if (b & mask)
r ^= a;
b <<= 1;
}
return r;
}
@@ -90,21 +138,37 @@ gf128_t gf128_mul2(gf128_t a)
else return (a << 1);
}
gf128_t gf128_reverse(gf128_t a)
{
gf128_t r = 0;
int i;
for (i = 0; i < 128; i++) {
r = (r << 1) | (a & 1);
a >>= 1;
}
return r;
}
gf128_t gf128_from_bytes(const uint8_t p[16])
{
uint64_t hi = GETU64(p);
uint64_t lo = GETU64(p + 8);
return (gf128_t)hi << 64 | lo;
gf128_t r = (gf128_t)hi << 64 | lo;
r = gf128_reverse(r);
return r;
}
void gf128_to_bytes(gf128_t a, uint8_t p[16])
{
a = gf128_reverse(a);
uint64_t hi = a >> 64;
uint64_t lo = a;
PUTU64(p, hi);
PUTU64(p + 8, lo);
}
#else
gf128_t gf128_from_bytes(const uint8_t p[16])
{
@@ -137,10 +201,11 @@ gf128_t gf128_mul(gf128_t a, gf128_t b)
for (i = 0; i < 64; i++) {
if (r.hi & mask) {
r.hi = r.hi << 1 | r.lo >> 63;
r.lo = (r.lo << 1) ^ 0x87;
r.lo = (r.lo << 1);
r.lo ^= 0x87;
} else {
r.hi = a.hi << 1 | a.lo >> 63;
r.lo = a.lo << 1;
r.hi = r.hi << 1 | r.lo >> 63;
r.lo = r.lo << 1;
}
if (b.hi & mask) {
@@ -155,8 +220,8 @@ gf128_t gf128_mul(gf128_t a, gf128_t b)
r.hi = r.hi << 1 | r.lo >> 63;
r.lo = (r.lo << 1) ^ 0x87;
} else {
r.hi = a.hi << 1 | a.lo >> 63;
r.lo = a.lo << 1;
r.hi = r.hi << 1 | r.lo >> 63;
r.lo = r.lo << 1;
}
if (b.lo & mask) {

View File

@@ -1,75 +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.
*/
/* GF(2^128) defined by f(x) = x^128 + x^7 + x^2 + x + 1
* A + B mod f(x) = a xor b
* A * 2 mod f(x)
*/
#ifndef GMSSL_GF128_H
#define GMSSL_GF128_H
#ifdef GMSSL_HAVE_UINT128
typedef unsigned __int128 gf128_t;
#else
#include <stdint.h>
typedef struct {
uint64_t hi;
uint64_t lo;
} gf128_t;
#endif
gf128_t gf128_add(gf128_t a, gf128_t b);
gf128_t gf128_mul(gf128_t a, gf128_t b);
gf128_t gf128_mul2(gf128_t a);
gf128_t gf128_from_bytes(const uint8_t p[16]);
void gf128_to_bytes(gf128_t a, uint8_t p[16]);
#endif

View File

@@ -51,7 +51,7 @@
#include <string.h>
#include <stdlib.h>
#include <gmssl/hash_drbg.h>
#include "bswap.h"
#include "endian.h"
static int hash_df(const DIGEST *digest, const uint8_t *in, size_t inlen,
size_t outlen, uint8_t *out)

View File

@@ -143,7 +143,7 @@ int hex2bin(const char *in, size_t inlen, uint8_t *out)
{
int c;
if (inlen % 2) {
error_print();
error_print("hex %s len = %zu\n", in, inlen);
return -1;
}
@@ -164,6 +164,13 @@ int hex2bin(const char *in, size_t inlen, uint8_t *out)
return 1;
}
int hex_to_bytes(const char *in, size_t inlen, uint8_t *out, size_t *outlen)
{
*outlen = inlen/2;
return hex2bin(in, inlen, out);
}
void memxor(void *r, const void *a, size_t len)
{
uint8_t *pr = r;

View File

@@ -46,58 +46,10 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* ====================================================================
* Copyright (c) 2014 - 2017 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 <string.h>
#include <gmssl/md5.h>
#include "bswap.h"
#include "endian.h"
static void md5_compress_blocks(uint32_t state[4],
@@ -166,7 +118,7 @@ void md5_finish(MD5_CTX *ctx, unsigned char *dgst)
}
}
#define ROL32(X, n) (((X) << (n)) | ((X) >> (32-(n))))
//#define ROL32(X, n) (((X) << (n)) | ((X) >> (32-(n))))
#define F(B, C, D) (((B) & (C)) | ((~(B)) & (D)))
#define G(B, C, D) (((B) & (D)) | ((C) & (~(D))))
#define H(B, C, D) ((B) ^ (C) ^ (D))

View File

@@ -45,13 +45,10 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef NO_RC4
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <gmssl/rc4.h>
void rc4_set_key(RC4_STATE *state, const unsigned char *key, size_t keylen)
@@ -118,5 +115,3 @@ unsigned char rc4_generate_keybyte(RC4_STATE *state)
rc4_generate_keystream(state, 1, out);
return out[0];
}
#endif

View File

@@ -1,68 +0,0 @@
/*
* Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
/*
* 应该看看Intel Intrisics中是否支持这个指令以及VS是否也支持这个指令
* 这样我们就不需要内联汇编了
*/
/*
* Engage compiler specific rotate intrinsic function if available.
*/
#undef ROL32
#ifndef PEDANTIC
# if defined(_MSC_VER)
# define ROL32(a,n) _lrotl(a,n)
# elif defined(__ICC)
# define ROL32(a,n) _rotl(a,n)
# elif defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
/*
* Some GNU C inline assembler templates. Note that these are
* rotates by *constant* number of bits! But that's exactly
* what we need here...
* <appro@fy.chalmers.se>
*/
# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
# define ROL32(a,n) ({ register unsigned int ret; \
asm ( \
"roll %1,%0" \
: "=r"(ret) \
: "I"(n), "0"((unsigned int)(a)) \
: "cc"); \
ret; \
})
# elif defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \
defined(__powerpc) || defined(__ppc__) || defined(__powerpc64__)
# define ROL32(a,n) ({ register unsigned int ret; \
asm ( \
"rlwinm %0,%1,%2,0,31" \
: "=r"(ret) \
: "r"(a), "I"(n)); \
ret; \
})
# elif defined(__s390x__)
# define ROL32(a,n) ({ register unsigned int ret; \
asm ("rll %0,%1,%2" \
: "=r"(ret) \
: "r"(a), "I"(n)); \
ret; \
})
# endif
# endif
#endif /* PEDANTIC */
#ifndef ROL32
# define ROL32(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
#endif
#define ROR32(a,n) ROL32((a),32-(n))
#define ROL64(a,n) (((a)<<(n))|((a)>>(64-(n))))
#define ROR64(a,n) ROL64(a,64-n)

View File

@@ -49,8 +49,7 @@
#include <string.h>
#include <gmssl/sha1.h>
#include "bswap.h"
#include "rotate.h"
#include "endian.h"
static void sha1_compress_blocks(uint32_t dgst[5],

View File

@@ -51,8 +51,8 @@
#include <stdlib.h>
#include <string.h>
#include <gmssl/sha2.h>
#include "bswap.h"
#include "rotate.h"
#include "endian.h"
static void sha256_compress_blocks(uint32_t state[8],
const unsigned char *data, size_t blocks);

View File

@@ -51,8 +51,7 @@
#include <stdlib.h>
#include <string.h>
#include <gmssl/sha2.h>
#include "bswap.h"
#include "rotate.h"
#include "endian.h"
static void sha512_compress_blocks(uint64_t state[8],

View File

@@ -49,8 +49,9 @@
#include <string.h>
#include <gmssl/sm3.h>
#include "bswap.h"
#include "rotate.h"
//#include "bswap.h"
//#include "rotate.h"
#include "endian.h"
#ifdef SM3_SSE3
# include <x86intrin.h>

View File

@@ -1,208 +0,0 @@
/* ====================================================================
* Copyright (c) 2014 - 2019 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 <gmssl/sm4.h>
#include "internal/bswap.h"
#include "internal/rotate.h"
#include "sm4_lcl.h"
#ifdef SMS4_AVX2
# include <immintrin.h>
# define GET_BLKS(x0, x1, x2, x3, in) \
t0 = _mm256_i32gather_epi32((int *)(in+4*0), vindex_4i, 4); \
t1 = _mm256_i32gather_epi32((int *)(in+4*1), vindex_4i, 4); \
t2 = _mm256_i32gather_epi32((int *)(in+4*2), vindex_4i, 4); \
t3 = _mm256_i32gather_epi32((int *)(in+4*3), vindex_4i, 4); \
x0 = _mm256_shuffle_epi8(t0, vindex_swap); \
x1 = _mm256_shuffle_epi8(t1, vindex_swap); \
x2 = _mm256_shuffle_epi8(t2, vindex_swap); \
x3 = _mm256_shuffle_epi8(t3, vindex_swap)
# define PUT_BLKS(out, x0, x1, x2, x3) \
t0 = _mm256_shuffle_epi8(x0, vindex_swap); \
t1 = _mm256_shuffle_epi8(x1, vindex_swap); \
t2 = _mm256_shuffle_epi8(x2, vindex_swap); \
t3 = _mm256_shuffle_epi8(x3, vindex_swap); \
_mm256_storeu_si256((__m256i *)(out+32*0), t0); \
_mm256_storeu_si256((__m256i *)(out+32*1), t1); \
_mm256_storeu_si256((__m256i *)(out+32*2), t2); \
_mm256_storeu_si256((__m256i *)(out+32*3), t3); \
x0 = _mm256_i32gather_epi32((int *)(out+8*0), vindex_read, 4); \
x1 = _mm256_i32gather_epi32((int *)(out+8*1), vindex_read, 4); \
x2 = _mm256_i32gather_epi32((int *)(out+8*2), vindex_read, 4); \
x3 = _mm256_i32gather_epi32((int *)(out+8*3), vindex_read, 4); \
_mm256_storeu_si256((__m256i *)(out+32*0), x0); \
_mm256_storeu_si256((__m256i *)(out+32*1), x1); \
_mm256_storeu_si256((__m256i *)(out+32*2), x2); \
_mm256_storeu_si256((__m256i *)(out+32*3), x3)
# define _mm256_rotl_epi32(a, i) _mm256_xor_si256( \
_mm256_slli_epi32(a, i), _mm256_srli_epi32(a, 32 - i))
# define INDEX_MASK_TBOX 0xff
# define ROUND_TBOX(x0, x1, x2, x3, x4, i) \
t0 = _mm256_set1_epi32(*(rk + i)); \
t1 = _mm256_xor_si256(x1, x2); \
t2 = _mm256_xor_si256(x3, t0); \
x4 = _mm256_xor_si256(t1, t2); \
t0 = _mm256_and_si256(x4, vindex_mask); \
t0 = _mm256_i32gather_epi32((int *)SMS4_T, t0, 4); \
t0 = _mm256_rotl_epi32(t0, 8); \
x4 = _mm256_srli_epi32(x4, 8); \
x0 = _mm256_xor_si256(x0, t0); \
t0 = _mm256_and_si256(x4, vindex_mask); \
t0 = _mm256_i32gather_epi32((int *)SMS4_T, t0, 4); \
t0 = _mm256_rotl_epi32(t0, 16); \
x4 = _mm256_srli_epi32(x4, 8); \
x0 = _mm256_xor_si256(x0, t0); \
t0 = _mm256_and_si256(x4, vindex_mask); \
t0 = _mm256_i32gather_epi32((int *)SMS4_T, t0, 4); \
t0 = _mm256_rotl_epi32(t0, 24); \
x4 = _mm256_srli_epi32(x4, 8); \
x0 = _mm256_xor_si256(x0, t0); \
t1 = _mm256_i32gather_epi32((int *)SMS4_T, x4, 4); \
x4 = _mm256_xor_si256(x0, t1)
# define INDEX_MASK_DBOX 0xffff
# define ROUND_DBOX(x0, x1, x2, x3, x4, i) \
t0 = _mm256_set1_epi32(*(rk + i)); \
t1 = _mm256_xor_si256(x1, x2); \
t2 = _mm256_xor_si256(x3, t0); \
x4 = _mm256_xor_si256(t1, t2); \
t0 = _mm256_srli_epi32(x4, 16); \
t1 = _mm256_i32gather_epi32((int *)SMS4_D, t0, 4); \
t2 = _mm256_and_si256(x4, vindex_mask); \
t3 = _mm256_i32gather_epi32((int *)SMS4_D, t2, 4); \
t0 = _mm256_rotl_epi32(t3, 16); \
x4 = _mm256_xor_si256(x0, t1); \
x4 = _mm256_xor_si256(x4, t0)
# define ROUND ROUND_TBOX
# define INDEX_MASK INDEX_MASK_TBOX
void sm4_avx2_ecb_encrypt_blocks(const unsigned char *in, unsigned char *out,
size_t blocks, const SM4_KEY *key)
{
const int *rk = (int *)key->rk;
__m256i x0, x1, x2, x3, x4;
__m256i t0, t1, t2, t3;
__m256i vindex_4i = _mm256_setr_epi32(0,4,8,12,16,20,24,28);
__m256i vindex_mask = _mm256_set1_epi32(INDEX_MASK);
__m256i vindex_read = _mm256_setr_epi32(0,8,16,24,1,9,17,25);
__m256i vindex_swap = _mm256_setr_epi8(
3,2,1,0,7,6,5,4,11,10,9,8,15,14,13,12,
3,2,1,0,7,6,5,4,11,10,9,8,15,14,13,12
);
while (blocks >= 8) {
GET_BLKS(x0, x1, x2, x3, in);
ROUNDS(x0, x1, x2, x3, x4);
PUT_BLKS(out, x0, x4, x3, x2);
in += 128;
out += 128;
blocks -= 8;
}
while (blocks--) {
sm4_encrypt(in, out, key);
in += 16;
out += 16;
}
}
void sm4_avx2_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out,
size_t blocks, const SM4_KEY *key, const unsigned char iv[16])
{
const int *rk = (int *)key->rk;
__m256i x0, x1, x2, x3, x4;
__m256i t0, t1, t2, t3;
__m256i vindex_4i = _mm256_setr_epi32(0,4,8,12,16,20,24,28);
__m256i vindex_mask = _mm256_set1_epi32(INDEX_MASK);
__m256i vindex_read = _mm256_setr_epi32(0,8,16,24,1,9,17,25);
__m256i vindex_swap = _mm256_setr_epi8(
3,2,1,0,7,6,5,4,11,10,9,8,15,14,13,12,
3,2,1,0,7,6,5,4,11,10,9,8,15,14,13,12
);
__m256i incr = _mm256_setr_epi32(0, 1, 2, 3, 4, 5, 6, 7);
int c0 = (int)GETU32(iv );
int c1 = (int)GETU32(iv + 4);
int c2 = (int)GETU32(iv + 8);
int c3 = (int)GETU32(iv + 12);
while (blocks >= 8) {
x0 = _mm256_set1_epi32(c0);
x1 = _mm256_set1_epi32(c1);
x2 = _mm256_set1_epi32(c2);
x3 = _mm256_set1_epi32(c3);
x3 = _mm256_add_epi32(x3, incr);
ROUNDS(x0, x1, x2, x3, x4);
GET_BLKS(t0, t1, t2, t3, in);
x0 = _mm256_xor_si256(x0, t0);
x4 = _mm256_xor_si256(x4, t1);
x3 = _mm256_xor_si256(x3, t2);
x2 = _mm256_xor_si256(x2, t3);
PUT_BLKS(out, x0, x4, x3, x2);
c3 += 8;
in += 128;
out += 128;
blocks -= 8;
}
if (blocks) {
unsigned char ctr[16];
memcpy(ctr, iv, 12);
PUTU32(ctr + 12, c3);
sm4_ctr32_encrypt_blocks(in, out, blocks, key, ctr);
}
}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -48,8 +48,7 @@
*/
#include <gmssl/sm4.h>
#include "bswap.h"
#include "rotate.h"
#include "endian.h"
#include "sm4_lcl.h"
@@ -79,11 +78,6 @@
t1 = SM4_T[x4]; \
x4 = x0 ^ t1
#define ROUND_DBOX(x0, x1, x2, x3, x4, i) \
x4 = x1 ^ x2 ^ x3 ^ *(rk + i); \
x4 = x0 ^ SM4_D[(uint16_t)(x4 >> 16)] ^ \
ROL32(SM4_D[(uint16_t)x4], 16)
#define ROUND ROUND_TBOX

View File

@@ -48,6 +48,7 @@
#include <gmssl/sm4.h>
#include <gmssl/error.h>
#include <gmssl/gcm.h>
#include "mem.h"
void sm4_cbc_encrypt(const SM4_KEY *key, const uint8_t iv[16],
@@ -125,3 +126,109 @@ int sm4_cbc_padding_decrypt(const SM4_KEY *key, const uint8_t iv[16],
*outlen = inlen - padding;
return 1;
}
static void ctr_incr(uint8_t a[16])
{
int i;
for (i = 15; i > 0; i--) {
a[i]++;
if (a[i]) break;
}
}
void sm4_ctr_encrypt(const SM4_KEY *key, uint8_t ctr[16], const uint8_t *in, size_t inlen, uint8_t *out)
{
uint8_t block[16];
size_t len;
while (inlen) {
len = inlen < 16 ? inlen : 16;
sm4_encrypt(key, ctr, block);
gmssl_memxor(out, in, block, len);
ctr_incr(ctr);
in += len;
out += len;
inlen -= len;
}
}
int sm4_gcm_encrypt(const SM4_KEY *key, const uint8_t *iv, size_t ivlen,
const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen,
uint8_t *out, const size_t taglen, uint8_t *tag)
{
const uint8_t *pin = in;
uint8_t *pout = out;
size_t left = inlen;
uint8_t H[16] = {0};
uint8_t Y[16];
uint8_t T[16];
sm4_encrypt(key, H, H);
if (ivlen == 12) {
memcpy(Y, iv, 12);
Y[12] = Y[13] = Y[14] = 0;
Y[15] = 1;
} else {
ghash(H, NULL, 0, iv, ivlen, Y);
}
sm4_encrypt(key, Y, T);
while (left) {
uint8_t block[16];
size_t len = left < 16 ? left : 16;
ctr_incr(Y);
sm4_encrypt(key, Y, block);
gmssl_memxor(pout, pin, block, len);
pin += len;
pout += len;
left -= len;
}
ghash(H, aad, aadlen, out, inlen, H);
gmssl_memxor(tag, T, H, taglen);
return 1;
}
int sm4_gcm_decrypt(const SM4_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 *tag, size_t taglen, uint8_t *out)
{
const uint8_t *pin = in;
uint8_t *pout = out;
size_t left = inlen;
uint8_t H[16] = {0};
uint8_t Y[16];
uint8_t T[16];
sm4_encrypt(key, H, H);
if (ivlen == 12) {
memcpy(Y, iv, 12);
Y[12] = Y[13] = Y[14] = 0;
Y[15] = 1;
} else {
ghash(H, NULL, 0, iv, ivlen, Y);
}
ghash(H, aad, aadlen, in, inlen, H);
sm4_encrypt(key, Y, T);
gmssl_memxor(T, T, H, taglen);
if (memcmp(T, tag, taglen) != 0) {
error_print();
return -1;
}
while (left) {
uint8_t block[16];
size_t len = left < 16 ? left : 16;
ctr_incr(Y);
sm4_encrypt(key, Y, block);
gmssl_memxor(pout, pin, block, len);
pin += len;
pout += len;
left -= len;
}
return 1;
}

View File

@@ -48,8 +48,7 @@
*/
#include <gmssl/sm4.h>
#include "bswap.h"
#include "rotate.h"
#include "endian.h"
#include "sm4_lcl.h"
static uint32_t FK[4] = {

View File

@@ -322,6 +322,8 @@ int tls_record_length(const uint8_t *record)
}
// 这个函数应该是处理的这个函数是不应该用的通常我们在加密的时候header 明文数据是分离的但是输出的record是一个
int tls_record_encrypt(const SM3_HMAC_CTX *hmac_ctx, const SM4_KEY *cbc_key,
const uint8_t seq_num[8], const uint8_t *in, size_t inlen,
@@ -683,6 +685,9 @@ int tls_record_get_handshake_server_hello(const uint8_t *record,
int tls_record_set_handshake_certificate(uint8_t *record, size_t *recordlen,
const uint8_t *data, size_t datalen)
{
@@ -1024,7 +1029,6 @@ int tls_record_get_handshake_client_key_exchange_pke(const uint8_t *record,
return 1;
}
int tls_record_set_handshake_certificate_verify(uint8_t *record, size_t *recordlen,
const uint8_t *sig, size_t siglen)
{
@@ -1050,6 +1054,8 @@ int tls_record_get_handshake_certificate_verify(const uint8_t *record,
return 1;
}
//FIXME: TLS 1.3 中的verify_data长度和hashLen一样,并且长度是不单独编码的,
// 因此这个函数应该改一下了
int tls_record_set_handshake_finished(uint8_t *record, size_t *recordlen,
const uint8_t verify_data[12])
{

File diff suppressed because it is too large Load Diff

View File

@@ -55,6 +55,10 @@
#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,
@@ -114,6 +118,65 @@ int tls_prf(const uint8_t *secret, size_t secretlen, const char *label,
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)
@@ -250,6 +313,7 @@ int tls_sign_server_ecdh_params(const SM2_KEY *server_sign_key,
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;
}

View File

@@ -292,6 +292,8 @@ const char *tls_curve_type_name(int type)
return NULL;
}
// FIXME: 是否应该将函数名改为 tls_curve_name() 这样和 TLS_curve_xxx 保持一致
const char *tls_named_curve_name(int curve)
{
switch (curve) {
@@ -417,6 +419,27 @@ int tls_extension_print(FILE *fp, int type, const uint8_t *data, size_t datalen,
tls_signature_scheme_name(sig_alg), sig_alg);
}
break;
case TLS_extension_key_share:
if (tls_uint16array_from_bytes(&p, &len, &data, &datalen) != 1
|| datalen) {
error_print();
return -1;
}
while (len) {
uint16_t group;
const uint8_t *key_exch;
size_t key_exch_len;
if (tls_uint16_from_bytes(&group, &p, &len) != 1
|| tls_uint16array_from_bytes(&key_exch, &key_exch_len, &p, &len) != 1) {
error_print();
return -1;
}
format_print(fp, format, indent, "group : %s\n", tls_named_curve_name(group));
format_bytes(fp, format, indent, "key_exchange : ", key_exch, key_exch_len);
}
break;
default:
format_bytes(fp, format, indent, "raw_data : ", data, datalen);
}
@@ -524,7 +547,8 @@ int tls_server_hello_print(FILE *fp, const uint8_t *data, size_t datalen, int fo
tls_compression_method_name(comp_meth), comp_meth);
if (datalen > 0) {
if (tls_uint16array_from_bytes(&exts, &exts_len, &data, &datalen) != 1) goto bad;
format_bytes(fp, format, indent, "Extensions : ", exts, exts_len); // FIXME: extensions_print
//format_bytes(fp, format, indent, "Extensions : ", exts, exts_len); // FIXME: extensions_print
tls_extensions_print(fp, exts, exts_len, format, indent);
}
return 1;
bad:

View File

@@ -49,7 +49,7 @@
#include <stdlib.h>
#include <string.h>
#include <gmssl/zuc.h>
#include "bswap.h"
#include "endian.h"
static const ZUC_UINT15 KD[16] = {
0x44D7,0x26BC,0x626B,0x135E,0x5789,0x35E2,0x7135,0x09AF,

View File

@@ -50,7 +50,7 @@
#include <stdlib.h>
#include <string.h>
#include <gmssl/zuc.h>
#include "bswap.h"
#include "endian.h"
static void zuc_set_eia_iv(unsigned char iv[16], ZUC_UINT32 count, ZUC_UINT5 bearer,
ZUC_BIT direction)