expose all functions

This commit is contained in:
Zhi Guan
2022-05-01 09:46:46 +08:00
parent d667028914
commit d1b3816319
37 changed files with 263 additions and 982 deletions

5
.gitignore vendored
View File

@@ -212,6 +212,11 @@ apps/gmca/.ca
/engines/sdf
/engines/skf
/sdf/*
/skf/*
/src/skf*
/src/sdf*
include/openssl/srp.h
/*.sh

View File

@@ -49,9 +49,9 @@ add_library(
src/sm4_enc.c
src/sm4_modes.c
src/sm4_setkey.c
# src/sm9_keygen.c
src/sm9_math.c
# src/sm9_sign.c
src/sm9_alg.c
# src/sm9_key.c
# src/sm9_lib.c
src/tlcp.c
src/tls.c
src/tls12.c
@@ -65,9 +65,8 @@ add_library(
src/x509_oid.c
src/x509_req.c
src/x509_str.c
src/zuc_core.c
src/zuc_eea.c
src/zuc_eia.c
src/zuc.c
src/zuc_modes.c
)
@@ -79,6 +78,7 @@ SET_TARGET_PROPERTIES(gmssl PROPERTIES VERSION 3.0 SOVERSION 3)
add_executable(
gmssl-bin
tools/gmssl.c
tools/version.c
tools/rand.c
tools/sm2keygen.c
tools/sm2sign.c
@@ -88,6 +88,13 @@ add_executable(
tools/sm3.c
tools/sm3hmac.c
tools/sm4.c
tools/zuc.c
tools/sm9setup.c
tools/sm9keygen.c
tools/sm9sign.c
tools/sm9verify.c
tools/sm9encrypt.c
tools/sm9decrypt.c
tools/certgen.c
tools/certparse.c
tools/certverify.c

View File

@@ -54,7 +54,11 @@
void memxor(void *r, const void *a, size_t len);
void gmssl_memxor(void *r, const void *a, const void *b, size_t len);
int gmssl_memcmp(const void *s1, const void *s2, size_t n);
int gmssl_secure_memcmp(const volatile void * volatile in_a, const volatile void * volatile in_b, size_t len);
void gmssl_secure_clear(void *ptr, size_t len);
#endif

View File

@@ -51,8 +51,8 @@
#include <string.h>
#include <stdlib.h>
#include <gmssl/aes.h>
#include "endian.h"
#include "mem.h"
#include <gmssl/endian.h>
#include <gmssl/mem.h>
static const uint8_t S[256] = {

View File

@@ -53,7 +53,7 @@
#include <gmssl/aes.h>
#include <gmssl/gcm.h>
#include <gmssl/error.h>
#include "mem.h"
#include <gmssl/mem.h>
void aes_cbc_encrypt(const AES_KEY *key, const uint8_t iv[16],

View File

@@ -56,7 +56,7 @@
#include <gmssl/oid.h>
#include <gmssl/asn1.h>
#include <gmssl/error.h>
#include "endian.h"
#include <gmssl/endian.h>
/*

View File

@@ -52,8 +52,7 @@
#include <stdlib.h>
#include <gmssl/oid.h>
#include <gmssl/block_cipher.h>
#include "endian.h"
#include <gmssl/endian.h>
int block_cipher_set_encrypt_key(BLOCK_CIPHER_KEY *key, const BLOCK_CIPHER *cipher, const uint8_t *raw_key)

View File

@@ -51,7 +51,8 @@
#include <string.h>
#include <stdlib.h>
#include <gmssl/chacha20.h>
#include "endian.h"
#include <gmssl/endian.h>
void chacha20_init(CHACHA20_STATE *state,
const uint8_t key[CHACHA20_KEY_SIZE],

View File

@@ -50,7 +50,7 @@
#include <string.h>
#include <stdlib.h>
#include <gmssl/des.h>
#include "endian.h"
#include <gmssl/endian.h>
/* permuted choice 1 for key schedule, 64 bits to 56 bits */

View File

@@ -1,116 +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.
*/
#ifndef GMSSL_ENDIAN_H
#define GMSSL_ENDIAN_H
/* Big Endian R/W */
#define GETU16(p) \
((uint16_t)(p)[0] << 8 | \
(uint16_t)(p)[1])
#define GETU32(p) \
((uint32_t)(p)[0] << 24 | \
(uint32_t)(p)[1] << 16 | \
(uint32_t)(p)[2] << 8 | \
(uint32_t)(p)[3])
#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])
// 注意PUTU32(buf, val++) 会出错!
#define PUTU16(p,V) \
((p)[0] = (uint8_t)((V) >> 8), \
(p)[1] = (uint8_t)(V))
#define PUTU32(p,V) \
((p)[0] = (uint8_t)((V) >> 24), \
(p)[1] = (uint8_t)((V) >> 16), \
(p)[2] = (uint8_t)((V) >> 8), \
(p)[3] = (uint8_t)(V))
#define PUTU64(p,V) \
((p)[0] = (uint8_t)((V) >> 56), \
(p)[1] = (uint8_t)((V) >> 48), \
(p)[2] = (uint8_t)((V) >> 40), \
(p)[3] = (uint8_t)((V) >> 32), \
(p)[4] = (uint8_t)((V) >> 24), \
(p)[5] = (uint8_t)((V) >> 16), \
(p)[6] = (uint8_t)((V) >> 8), \
(p)[7] = (uint8_t)(V))
/* Little Endian R/W */
#define GETU16_LE(p) (*(const uint16_t *)(p))
#define GETU32_LE(p) (*(const uint32_t *)(p))
#define GETU64_LE(p) (*(const uint64_t *)(p))
#define PUTU16_LE(p,V) *(uint16_t *)(p) = (V)
#define PUTU32_LE(p,V) *(uint32_t *)(p) = (V)
#define PUTU64_LE(p,V) *(uint64_t *)(p) = (V)
/* Rotate */
#define ROL32(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
#define ROL64(a,n) (((a)<<(n))|((a)>>(64-(n))))
#define ROR32(a,n) ROL32((a),32-(n))
#define ROR64(a,n) ROL64(a,64-n)
#endif

View File

@@ -54,7 +54,8 @@
#include <gmssl/oid.h>
#include <gmssl/error.h>
#include <gmssl/aes.h>
#include "endian.h"
#include <gmssl/endian.h>
/*
* GHASH(H, A, C) = X_{m + n + 1}

View File

@@ -57,7 +57,7 @@
#include <stdlib.h>
#include <gmssl/hex.h>
#include <gmssl/gf128.h>
#include "endian.h"
#include <gmssl/endian.h>
gf128_t gf128_zero(void)

View File

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

View File

@@ -194,13 +194,49 @@ void gmssl_memxor(void *r, const void *a, const void *b, size_t len)
}
}
int gmssl_memcmp(const void *s1, const void *s2, size_t n)
// Note: comments and code from OpenSSL crypto/cryptlib.c:CRYPTO_memcmp()
/* volatile unsigned char* pointers are there because
* 1. Accessing a variable declared volatile via a pointer
* that lacks a volatile qualifier causes undefined behavior.
* 2. When the variable itself is not volatile the compiler is
* not required to keep all those reads and can convert
* this into canonical memcmp() which doesn't read the whole block.
* Pointers to volatile resolve the first problem fully. The second
* problem cannot be resolved in any Standard-compliant way but this
* works the problem around. Compilers typically react to
* pointers to volatile by preserving the reads and writes through them.
* The latter is not required by the Standard if the memory pointed to
* is not volatile.
* Pointers themselves are volatile in the function signature to work
* around a subtle bug in gcc 4.6+ which causes writes through
* pointers to volatile to not be emitted in some rare,
* never needed in real life, pieces of code.
*/
int gmssl_secure_memcmp(const volatile void * volatile in_a, const volatile void * volatile in_b, size_t len)
{
return memcmp(s1, s2, n);
size_t i;
const volatile unsigned char *a = in_a;
const volatile unsigned char *b = in_b;
unsigned char x = 0;
for (i = 0; i < len; i++) {
x |= a[i] ^ b[i];
}
return x;
}
/*
* Pointer to memset is volatile so that compiler must de-reference
* the pointer and can't assume that it points to any function in
* particular (such as memset, which it then might further "optimize")
*/
typedef void *(*memset_t)(void *, int, size_t);
static volatile memset_t memset_func = memset;
void gmssl_secure_clear(void *ptr, size_t len)
{
memset_func(ptr, 0, len);
}

View File

@@ -49,7 +49,7 @@
#include <string.h>
#include <gmssl/md5.h>
#include "endian.h"
#include <gmssl/endian.h>
#define F(B, C, D) (((B) & (C)) | ((~(B)) & (D)))

View File

@@ -1,35 +0,0 @@
int ssl_init(void)
{
// 不需要这个函数
return 1;
}
typedef struct {
} SSL_CTX;
// nginx中用的是PEM
int ssl_use_certificate()
{
}
int ssl_use_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_str_t *key, ngx_array_t *passwords)
{
}
ngx_ssl_ciphers SSL_CTX_set_cipher_list
ngx_ssl_client_certificate SSL_CTX_set_verify
SSL_CTX_set_verify_depth
SSL_CTX_load_verify_locations
SSL_load_client_CA_file
ngx_ssl_trusted_certificate SSL_CTX_set_verify
SSL_CTX_set_verify_depth
SSL_CTX_load_verify_locations

603
src/oid.c
View File

@@ -1,603 +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>
#include <assert.h>
#include <gmssl/oid.h>
#include <gmssl/asn1.h>
#include <gmssl/error.h>
/*
asn1_type_from_octets 函数有三种返回值
* -1 说明编码的前缀错误,也就是不属于本类型的字节点
* 0 即 OID_undef说明前缀是匹配的但是我们不识别这个 OID
* >=1 一个被识别出来的 OID
asn1_type_from_octets 函数不识别 type 的编码,如 asn1_sm_oid_from_octets 不识别 DER_sm
但是返回值为 OID_undef而不是 -1
*/
static uint8_t DER_sm[] = { 0x2A, 0x81, 0x1C, 0xCF, 0x55, 0x01 };
static uint8_t DER_sm1[] = { 0x66 };
static uint8_t DER_ssf33[] = { 0x67 };
static uint8_t DER_sm4[] = { 0x68 };
static uint8_t DER_zuc[] = { 0x86, 0x20 };
static uint8_t DER_sm2[] = { 0x82, 0x2D };
static uint8_t DER_sm2sign[] = { 0x82, 0x2D, 0x01 };
static uint8_t DER_sm2keyagreement[] = { 0x82, 0x2D, 0x02 };
static uint8_t DER_sm2encrypt[] = { 0x82, 0x2D, 0x03 };
static uint8_t DER_sm9[] = { 0x82, 0x2E };
static uint8_t DER_sm9sign[] = { 0x82, 0x2E, 0x01 };
static uint8_t DER_sm9keyagreement[] = { 0x82, 0x2E, 0x02 };
static uint8_t DER_sm9encrypt[] = { 0x82, 0x2E, 0x03 };
static uint8_t DER_sm3[] = { 0x83, 0x11 };
static uint8_t DER_sm3_keyless[] = { 0x83, 0x11, 0x01 };
static uint8_t DER_hmac_sm3[] = { 0x83, 0x11, 0x02 };
static uint8_t DER_sm2sign_with_sm3[] = { 0x83, 0x75 };
static uint8_t DER_rsasign_with_sm3[] = { 0x83, 0x78 };
static const struct {
uint8_t *der;
size_t derlen;
char *name;
char *desc;
} sm_oids[] = {
{ DER_sm1, 1, "sm1", "SM1" },
{ DER_ssf33, 1, "ssf33", "SSF33" },
{ DER_sm4, 1, "sm4", "SM4" },
{ DER_zuc, 2, "zuc", "ZUC" },
{ DER_sm2, 2, "sm2p256v1", "SM2" },
{ DER_sm2sign, 3, "sm2sign", "SM2 Signature Scheme" },
{ DER_sm2keyagreement, 3, "sm2keyagreement", "SM2 Key Agreement" },
{ DER_sm2encrypt, 3, "sm2encrypt", "SM2 Encryption" },
{ DER_sm9, 2, "sm9", "SM9" },
{ DER_sm9sign, 3, "sm9sign", "SM9 Signature Scheme" },
{ DER_sm9keyagreement, 3, "sm9keyagreement", "SM9 Key Agreement" },
{ DER_sm9encrypt, 3, "sm9encrypt", "SM9 Encrpytion" },
{ DER_sm3, 2, "sm3", "SM3" },
{ DER_sm3_keyless, 3, "sm3-keyless", "SM3 without Key" },
{ DER_hmac_sm3, 3, "hmac-sm3", "HMAC-SM3" },
{ DER_sm2sign_with_sm3, 2, "sm2sign-with-sm3", "SM2 Signature with SM3" },
{ DER_rsasign_with_sm3, 2, "rsasign-with-sm3", "RSA Signature with SM3" },
};
const char *asn1_sm_oid_name(int oid)
{
assert(OID_sm1 <= oid && oid <= OID_rsasign_with_sm3);
return sm_oids[oid - OID_sm1].name;
}
const char *asn1_sm_oid_description(int oid)
{
assert(oid >= OID_sm1 && oid <= OID_rsasign_with_sm3);
return sm_oids[oid - OID_sm1].desc;
}
void asn1_sm_oid_to_octets(int oid, uint8_t *out, size_t *outlen)
{
int i = oid - OID_sm1;
assert(i >= 0 && i < sizeof(sm_oids)/sizeof(sm_oids[0]));
if (out) {
memcpy(out, DER_sm, sizeof(DER_sm));
out += sizeof(DER_sm);
memcpy(out, sm_oids[i].der, sm_oids[i].derlen);
out += sm_oids[i].derlen;
}
*outlen = sizeof(DER_sm) + sm_oids[i].derlen;
}
int asn1_sm_oid_from_octets(const uint8_t *in, size_t inlen)
{
int i;
if (inlen < sizeof(DER_sm)
|| memcmp(in, DER_sm, sizeof(DER_sm)) != 0) {
return -1;
}
in += sizeof(DER_sm);
inlen -= sizeof(DER_sm);
for (i = 0; i < sizeof(sm_oids)/sizeof(sm_oids[0]); i++) {
if (sm_oids[i].derlen == inlen
&& memcmp(sm_oids[i].der, in, inlen) == 0) {
return OID_sm1 + i;
}
}
return OID_undef;
}
int asn1_sm_oid_from_name(const char *name)
{
size_t i;
for (i = 0; i < sizeof(sm_oids)/sizeof(sm_oids[0]); i++) {
if (strcmp(name, sm_oids[i].name) == 0) {
return OID_sm1 + i;
}
}
return OID_undef;
}
// FIXME: 支持所有的公钥类型
static const uint8_t DER_x9_62_ecPublicKey[] = { 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01 };
const char *asn1_pkey_oid_name(int oid)
{
switch (oid) {
case OID_x9_62_ecPublicKey: return "x9_62_ecPublicKey";
}
return NULL;
}
const char *asn1_pkey_oid_description(int oid)
{
switch (oid) {
case OID_x9_62_ecPublicKey: return "x9_62_ecPublicKey";
}
return NULL;
}
void asn1_pkey_oid_to_octets(int oid, uint8_t *out, size_t *outlen)
{
assert(oid == OID_x9_62_ecPublicKey);
if (out) {
memcpy(out, DER_x9_62_ecPublicKey, sizeof(DER_x9_62_ecPublicKey));
}
*outlen = sizeof(DER_x9_62_ecPublicKey);
}
int asn1_pkey_oid_from_octets(const uint8_t *in, size_t inlen)
{
if (inlen == sizeof(DER_x9_62_ecPublicKey)
&& memcmp(DER_x9_62_ecPublicKey, in, inlen) == 0) {
return OID_x9_62_ecPublicKey;
}
return 0;
}
int asn1_pkey_oid_from_name(const char *name)
{
if (strcmp(name, "x9_62_ecPublicKey") == 0) {
return OID_x9_62_ecPublicKey;
}
return 0;
}
// 本组函数不支持 OID_x9_62_ecPublicKey 的 DER 编解码
// 这个类型应该归为公钥类型还包括RSA、DSA、DH等公钥类型
// 这个错误, 03 01 是 curves prime ,而不是x9_62_ecPublicKey
// x9_62_ecPublicKey 是 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01
static const uint8_t DER_x9_62_curve_prime[] = { 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01 };
static const struct {
uint8_t der;
char *name;
} x9_62_curve_oids[] = {
{ 1, "prime192v1" },
{ 2, "prime192v2" },
{ 3, "prime192v3" },
{ 4, "prime239v1" },
{ 5, "prime239v2" },
{ 6, "prime239v3" },
{ 7, "prime256v1" },
};
const char *asn1_x9_62_curve_oid_name(int oid)
{
assert(OID_prime192v1 <= oid && oid <= OID_prime256v1);
return x9_62_curve_oids[oid - OID_prime192v1].name;
}
const char *asn1_x9_62_curve_oid_description(int oid)
{
return asn1_x9_62_curve_oid_name(oid);
}
void asn1_x9_62_curve_oid_to_octets(int oid, uint8_t *out, size_t *outlen)
{
assert(OID_prime192v1 <= oid && oid <= OID_prime256v1);
if (out) {
memcpy(out, DER_x9_62_curve_prime, sizeof(DER_x9_62_curve_prime));
out += sizeof(DER_x9_62_curve_prime);
*out = x9_62_curve_oids[oid - OID_prime192v1].der;
}
(*outlen) = sizeof(DER_x9_62_curve_prime) + 1;
}
int asn1_x9_62_curve_oid_from_octets(const uint8_t *in, size_t inlen)
{
if (inlen < sizeof(DER_x9_62_curve_prime)
|| memcmp(in, DER_x9_62_curve_prime, sizeof(DER_x9_62_curve_prime)) != 0) {
return -1;
}
in += sizeof(DER_x9_62_curve_prime);
inlen -= sizeof(DER_x9_62_curve_prime);
if (inlen == 1 && *in >= 1 && *in <= 7) {
return OID_prime192v1 + *in - 1;
}
return OID_undef;
}
int asn1_x9_62_curve_oid_from_name(const char *name)
{
int i;
for (i = 0; i < sizeof(x9_62_curve_oids)/sizeof(x9_62_curve_oids[0]); i++) {
if (strcmp(name, x9_62_curve_oids[i].name) == 0) {
return OID_prime192v1 + i;
}
}
return OID_undef;
}
static const uint8_t DER_secg_curve[] = { 0x2B, 0x81, 0x04, 0x00 };
static const struct {
uint8_t der;
int oid;
char *name;
} secg_curve_oids[] = {
{ 10, OID_secp256k1, "secp256k1" },
{ 31, OID_secp192k1, "secp192k1" },
{ 32, OID_secp224k1, "secp224k1" },
{ 33, OID_secp224r1, "secp224r1" },
{ 34, OID_secp384r1, "secp384r1" },
{ 35, OID_secp521r1, "secp521r1" },
};
const char *asn1_secg_curve_oid_name(int oid)
{
int i = oid - OID_secp256k1;
if (i < 0 || i >= sizeof(secg_curve_oids)/sizeof(secg_curve_oids[0])) {
fprintf(stderr, "%s %d: i = %d\n", __FILE__, __LINE__, i);
}
assert(i >= 0 && i < sizeof(secg_curve_oids)/sizeof(secg_curve_oids[0]));
return secg_curve_oids[i].name;
}
const char *asn1_secg_curve_oid_description(int oid)
{
return asn1_secg_curve_oid_name(oid);
}
void asn1_secg_curve_oid_to_octets(int oid, uint8_t *out, size_t *outlen)
{
int i = oid - OID_secp256k1;
if (out) {
memcpy(out, DER_secg_curve, sizeof(DER_secg_curve));
out += sizeof(DER_secg_curve);
*out++ = secg_curve_oids[i].der;
}
*outlen = sizeof(DER_secg_curve) + 1;
}
int asn1_secg_curve_oid_from_octets(const uint8_t *in, size_t inlen)
{
if (inlen < sizeof(DER_secg_curve)
|| memcmp(in, DER_secg_curve, sizeof(DER_secg_curve)) != 0) {
return -1;
}
in += sizeof(DER_secg_curve);
inlen -= sizeof(DER_secg_curve);
if (inlen == 1) {
int i;
for (i = 0; i < sizeof(secg_curve_oids)/sizeof(secg_curve_oids[0]); i++) {
if (*in == secg_curve_oids[i].der) {
return secg_curve_oids[i].oid;
}
}
}
return OID_undef;
}
int asn1_secg_curve_oid_from_name(const char *name)
{
uint32_t a;
if (strlen(name) != sizeof("secp256k1")-1
|| *(uint32_t *)name != *(uint32_t *)"secp"
|| name[8] != '1') {
return OID_undef;
}
a = *(uint32_t *)(name + 4);
if (a == *(uint32_t *)"256k") return OID_secp256k1;
else if (a == *(uint32_t *)"192k") return OID_secp192k1;
else if (a == *(uint32_t *)"224k") return OID_secp224k1;
else if (a == *(uint32_t *)"224r") return OID_secp224r1;
else if (a == *(uint32_t *)"384r") return OID_secp384r1;
else if (a == *(uint32_t *)"521r") return OID_secp521r1;
else return OID_undef;
}
static const uint8_t DER_x509[] = { 0x55, 0x04 };
static const struct {
uint8_t der;
char *name;
char *desc;
} x509_oids[] = {
{ 3, "commonName", "Common Name" },
{ 4, "surname", "Surname" },
{ 5, "serialNumber", "Serial Number" },
{ 6, "countryName", "Country" },
{ 7, "localityName", "Locality" },
{ 8, "stateOrProvinceName", "State or Province" },
{ 9, "streetAddress", "Street Address" },
{ 10, "organizationName", "Organization" },
{ 11, "organizationalUnitName", "Organizational Unit" },
{ 12, "title", "Title" },
{ 13, "description", "Description" },
{ 14, "searchGuide", "Search Guide" },
{ 15, "businessCategory", "Business Category" },
{ 16, "postalAddress", "Postal Address" },
{ 17, "postalCode", "Postal Code" },
{ 18, "postOfficeBox", "Post Office Box" },
{ 19, "physicalDeliveryOfficeName", "Physical Delivery Office" },
{ 20, "telephoneNumber", "Telephone Number" },
{ 21, "telexNumber", "Telex Number" },
{ 22, "teletexTerminalIdentifier", "Teletex Terminal Identifier" },
{ 23, "facsimileTelephoneNumber", "Facsimile Telephone Number" },
{ 24, "x121Address", "X121 Address" },
{ 25, "internationaliSDNNumber", "InternationaliSDN Number" },
{ 26, "registeredAddress", "Registered Address" },
{ 27, "destinationIndicator", "Destination Indicator" },
{ 28, "preferredDeliveryMethod", "Preferred Delivery Method" },
{ 29, "presentationAddress", "Presentation Address" },
{ 30, "supportedApplicationContext", "Supported ApplicationContext" },
{ 31, "member", "Member" },
{ 32, "owner", "Owner" },
{ 33, "roleOccupant", "Role Occupant" },
{ 34, "seeAlso", "See Also" },
{ 35, "userPassword", "User Password" },
{ 36, "userCertificate", "User Certificate" },
{ 37, "caCertificate", "CA Certificate" },
{ 38, "authorityRevocationList", "Authority Revocation List" },
{ 39, "certificateRevocationList", "Certificate Revocation List" },
{ 40, "crossCertificatePair", "Cros sCertificate Pair" },
{ 41, "name", "Name" },
{ 42, "givenName", "Given Name" },
{ 43, "initials", "Initials" },
{ 44, "generationQualifier", "Generation Qualifier" },
{ 45, "x500UniqueIdentifier", "X500Unique Identifier" },
{ 46, "dnQualifier", "DN Qualifier" },
{ 47, "enhancedSearchGuide", "Enhanced Search Guide" },
{ 48, "protocolInformation", "Protocol Information" },
{ 49, "distinguishedName", "Distinguished Name" },
{ 50, "uniqueMember", "Unique Member" },
{ 51, "houseIdentifier", "House Identifier" },
{ 52, "supportedAlgorithms", "Supported Algorithms" },
{ 53, "deltaRevocationList", "Delta Revocation List" },
{ 55, "dmdName", "DMD Name" },
{ 65, "pseudonym", "Pseudonym" },
{ 72, "role", "Role" },
};
const char *asn1_x509_oid_name(int oid)
{
int i = oid - OID_at_commonName;
assert(OID_at_role - OID_at_commonName + 1 == sizeof(x509_oids)/sizeof(x509_oids[0]));
if (i < 0 || i >= sizeof(x509_oids)/sizeof(x509_oids[0])) {
fprintf(stderr, "%s %d: oid = %d, i = %d\n", __FILE__, __LINE__, oid, i);
}
assert(i >= 0 && i < sizeof(x509_oids)/sizeof(x509_oids[0]));
return x509_oids[i].name;
}
const char *asn1_x509_oid_description(int oid)
{
int i = oid - OID_at_commonName;
assert(i >= 0 && i < sizeof(x509_oids)/sizeof(x509_oids[0]));
return x509_oids[i].desc;
}
void asn1_x509_oid_to_octets(int oid, uint8_t *out, size_t *outlen)
{
int i = oid - OID_at_commonName;
if (i < 0 || i >= sizeof(x509_oids)/sizeof(x509_oids[0])) {
fprintf(stderr, "%s %d: oid = %d, i = %d\n", __FILE__, __LINE__, oid, i);
}
assert(i >= 0 && i < sizeof(x509_oids)/sizeof(x509_oids[0]));
if (out) {
memcpy(out, DER_x509, sizeof(DER_x509));
out += sizeof(DER_x509);
*out = x509_oids[i].der;
}
*outlen = sizeof(DER_x509) + 1;
}
int asn1_x509_oid_from_octets(const uint8_t *in, size_t inlen)
{
if (inlen < sizeof(DER_x509)
|| memcmp(in, DER_x509, sizeof(DER_x509)) != 0) {
return -1;
}
in += sizeof(DER_x509);
inlen -= sizeof(DER_x509);
if (inlen == 1) {
if (*in >= 3 && *in <= 53)
return OID_at_commonName + *in - 3;
else if (*in == 55)
return OID_at_dmdName;
else if (*in == 65)
return OID_at_pseudonym;
else if (*in == 72)
return OID_at_role;
}
return OID_undef;
}
int asn1_x509_oid_from_name(const char *name)
{
int i;
for (i = 0; i < sizeof(x509_oids)/sizeof(x509_oids[0]); i++) {
if (strcmp(name, x509_oids[i].name) == 0) {
return OID_at_commonName + i;
}
}
return OID_undef;
}
// OIDs for X.509 extension ExtKeyUsage
// kp means "key purpose"
static const uint8_t DER_x509_kp[] = { 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, };
static const struct {
uint8_t der;
char *name;
char *desc;
} x509_kp_oids[] = {
{ 1, "serverAuth", "TLS WWW server authentication" },
{ 2, "clientAuth", "TLS WWW client authentication" },
{ 3, "codeSigning", "Signing of downloadable executable code" },
{ 4, "emailProtection", "Email protection" },
{ 8, "timeStamping", "Binding the hash of an object to a time" },
{ 9, "OCSPSigning", "Signing OCSP responses" },
};
const char *asn1_x509_kp_oid_name(int oid)
{
int i = oid - OID_kp_serverAuth;
assert(i >= 0 && i < sizeof(x509_kp_oids)/sizeof(x509_kp_oids[0]));
return x509_kp_oids[i].name;
}
const char *asn1_x509_kp_oid_description(int oid)
{
int i = oid - OID_kp_serverAuth;
assert(i >= 0 && i < sizeof(x509_kp_oids)/sizeof(x509_kp_oids[0]));
return x509_kp_oids[i].desc;
}
void asn1_x509_kp_oid_to_octets(int oid, uint8_t *out, size_t *outlen)
{
int i = oid - OID_kp_serverAuth;
assert(i >= 0 && i < sizeof(x509_kp_oids)/sizeof(x509_kp_oids[0]));
if (out) {
memcpy(out, DER_x509_kp, sizeof(DER_x509_kp));
out += sizeof(DER_x509_kp);
*out = x509_kp_oids[i].der;
}
*outlen = sizeof(DER_x509_kp) + 1;
}
int asn1_x509_kp_oid_from_octets(const uint8_t *in, size_t inlen)
{
if (inlen < sizeof(DER_x509_kp)
|| memcmp(in, DER_x509_kp, sizeof(DER_x509_kp)) != 0) {
return -1;
}
in += sizeof(DER_x509_kp);
inlen -= sizeof(DER_x509_kp);
if (inlen == 1) {
if (*in >= 1 && *in <= 4)
return OID_kp_serverAuth + *in - 1;
else if (*in == 8)
return OID_kp_timeStamping;
else if (*in == 9)
return OID_kp_OCSPSigning;
}
return OID_undef;
}
int asn1_x509_kp_oid_from_name(const char *name)
{
int i;
for (i = 0; i < sizeof(x509_kp_oids)/sizeof(x509_kp_oids[0]); i++) {
if (strcmp(name, x509_kp_oids[i].name) == 0) {
return OID_kp_serverAuth + i;
}
}
return OID_undef;
}
void asn1_oid_to_octets(int oid, uint8_t *out, size_t *outlen)
{
if (oid <= OID_rsasign_with_sm3) {
asn1_sm_oid_to_octets(oid, out, outlen);
} else if (oid == OID_x9_62_ecPublicKey) {
if (out) // 注意:这里必须验证 out == NULL ?
memcpy(out, DER_x9_62_ecPublicKey, sizeof(DER_x9_62_ecPublicKey));
*outlen = sizeof(DER_x9_62_ecPublicKey);
} else if (oid <= OID_prime256v1) {
asn1_x9_62_curve_oid_to_octets(oid, out, outlen);
} else if (oid <= OID_secp521r1) {
asn1_secg_curve_oid_to_octets(oid, out, outlen);
} else if (oid <= OID_at_role) {
asn1_x509_oid_to_octets(oid, out, outlen);
} else {
error_print();
assert(0);
}
}

View File

@@ -120,8 +120,8 @@
#include <gmssl/digest.h>
#include <gmssl/error.h>
#include <gmssl/oid.h>
#include "endian.h"
#include "mem.h"
#include <gmssl/endian.h>
#include <gmssl/mem.h>
int pbkdf2_genkey(const DIGEST *digest,
const char *pass, size_t passlen,

View File

@@ -48,7 +48,7 @@
#include <string.h>
#include <gmssl/sha1.h>
#include "endian.h"
#include <gmssl/endian.h>
#define F0(B, C, D) (((B) & (C)) | ((~(B)) & (D)))

View File

@@ -48,7 +48,7 @@
#include <string.h>
#include <gmssl/sha2.h>
#include "endian.h"
#include <gmssl/endian.h>
#define Ch(X, Y, Z) (((X) & (Y)) ^ ((~(X)) & (Z)))

View File

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

View File

@@ -53,7 +53,7 @@
#include <gmssl/sm2.h>
#include <gmssl/asn1.h>
#include <gmssl/error.h>
#include "endian.h"
#include <gmssl/endian.h>
#define sm2_print_bn(label,a) sm2_bn_print(stderr,0,0,label,a) // 这个不应该放在这里,应该放在测试文件中

View File

@@ -371,8 +371,8 @@ err:
return -1;
}
/*
#define SM2_PRIVATE_KEY_INFO_MAX_SIZE 512 // 计算长度
#if 0 // 私钥的BASE64编解码可能受到侧信道攻击
#define SM2_PRIVATE_KEY_INFO_MAX_SIZE 512 // TODO计算长度
int sm2_private_key_info_to_pem(const SM2_KEY *key, FILE *fp)
{
@@ -404,7 +404,7 @@ int sm2_private_key_info_from_pem(SM2_KEY *sm2_key, const uint8_t **attrs, size_
}
return 1;
}
*/
#endif
int sm2_public_key_info_to_der(const SM2_KEY *pub_key, uint8_t **out, size_t *outlen)
{
@@ -439,7 +439,7 @@ int sm2_public_key_info_from_der(SM2_KEY *pub_key, const uint8_t **in, size_t *i
return 1;
}
/*
#if 0 // 私钥的BASE64编解码可能受到侧信道攻击
int sm2_private_key_to_pem(const SM2_KEY *a, FILE *fp)
{
uint8_t buf[512];
@@ -474,7 +474,7 @@ int sm2_private_key_from_pem(SM2_KEY *a, FILE *fp)
}
return 1;
}
*/
#endif
int sm2_public_key_info_to_pem(const SM2_KEY *a, FILE *fp)
{

View File

@@ -54,7 +54,7 @@
#include <gmssl/sm3.h>
#include <gmssl/asn1.h>
#include <gmssl/error.h>
#include "endian.h"
#include <gmssl/endian.h>
#define print_bn(str,a) sm2_bn_print(stderr,0,4,str,a)

View File

@@ -48,7 +48,8 @@
#include <string.h>
#include <gmssl/sm3.h>
#include "endian.h"
#include <gmssl/endian.h>
#ifdef SM3_SSE3
# include <x86intrin.h>

View File

@@ -48,7 +48,7 @@
*/
#include <gmssl/sm4.h>
#include "endian.h"
#include <gmssl/endian.h>
#include "sm4_lcl.h"

View File

@@ -1,4 +1,4 @@
/*
/*
* Copyright (c) 2021 - 2021 The GmSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -47,9 +47,9 @@
*/
#include <gmssl/sm4.h>
#include <gmssl/error.h>
#include <gmssl/mem.h>
#include <gmssl/gcm.h>
#include "mem.h"
#include <gmssl/error.h>
void sm4_cbc_encrypt(const SM4_KEY *key, const uint8_t iv[16],
const uint8_t *in, size_t nblocks, uint8_t *out)
@@ -428,12 +428,11 @@ int sm4_ctr_encrypt_update(SM4_CTR_CTX *ctx,
int sm4_ctr_encrypt_finish(SM4_CTR_CTX *ctx, uint8_t *out, size_t *outlen)
{
size_t left;
size_t i;
if (ctx->block_nbytes >= SM4_BLOCK_SIZE) {
error_print();
return -1;
}
sm4_ctr_encrypt(&ctx->sm4_key, ctx->ctr, ctx->block, ctx->block_nbytes, out);
*outlen = ctx->block_nbytes;
return 1;
}

View File

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

View File

@@ -53,7 +53,7 @@
#include <assert.h>
#include <gmssl/hex.h>
#include <gmssl/sm9.h>
#include "endian.h"
#include <gmssl/endian.h>
static const sm9_bn_t SM9_ZERO = {0,0,0,0,0,0,0,0};

View File

@@ -68,7 +68,7 @@
#include <gmssl/gcm.h>
#include <gmssl/hmac.h>
#include <gmssl/hkdf.h>
#include "mem.h"
#include <gmssl/mem.h>

View File

@@ -46,6 +46,12 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
## TODO:
1. 每次发布时,应该将当前的时间戳添加到版本中
2. 将编译信息加入到版本的全部信息中,特别是发布二进制版专有功能时
*/
#include <gmssl/version.h>

View File

@@ -76,7 +76,7 @@ static uint32_t oid_at_serial_number[] = { oid_at,5 };
static uint32_t oid_at_pseudonym[] = { oid_at,65 };
static uint32_t oid_domain_component[] = { 0,9,2342,19200300,100,1,25 };
#define oid_at_cnt (sizeof(oid_at_name)/sizeof(int))
static const size_t oid_at_cnt = sizeof(oid_at_name)/sizeof(int);
static const ASN1_OID_INFO x509_name_types[] = {
{ OID_at_name, "name", oid_at_name, oid_at_cnt },
@@ -167,7 +167,7 @@ static uint32_t oid_ce_inhibit_any_policy[] = { oid_ce,54 };
static uint32_t oid_ce_crl_reasons[] = { oid_ce,21 }; // crl_entry_ext
static uint32_t oid_ce_invalidity_date[] = { oid_ce,24 }; // crl_entry_ext
static uint32_t oid_ce_certificate_issuer[] = { oid_ce,29 }; // crl_entry_ext
#define oid_ce_cnt (sizeof(oid_ce_subject_directory_attributes)/sizeof(int))
static const size_t oid_ce_cnt = sizeof(oid_ce_subject_directory_attributes)/sizeof(int);
static uint32_t oid_netscape_cert_comment[] = { 2,16,840,1,113730,1,13 };
static uint32_t oid_cert_authority_info_access[] = { 1,3,6,1,5,5,7,1,1 };
static uint32_t oid_ct_precertificate_scts[] = { 1,3,6,1,4,1,11129,2,4,2 };
@@ -374,7 +374,7 @@ static uint32_t oid_kp_code_signing[] = { oid_kp,3 };
static uint32_t oid_kp_email_protection[] = { oid_kp,4 };
static uint32_t oid_kp_time_stamping[] = { oid_kp,8 };
static uint32_t oid_kp_ocsp_signing[] = { oid_kp,9 };
#define oid_kp_cnt (sizeof(oid_kp_server_auth)/sizeof(int))
static const size_t oid_kp_cnt = sizeof(oid_kp_server_auth)/sizeof(int);
static const ASN1_OID_INFO x509_key_purposes[] = {

View File

@@ -49,7 +49,9 @@
#include <stdlib.h>
#include <string.h>
#include <gmssl/zuc.h>
#include "endian.h"
#include <gmssl/mem.h>
#include <gmssl/endian.h>
static const ZUC_UINT15 KD[16] = {
0x44D7,0x26BC,0x626B,0x135E,0x5789,0x35E2,0x7135,0x09AF,
@@ -182,9 +184,9 @@ static const uint8_t S1[256] = {
(X0 ^ R1) + R2; \
F_(X1, X2)
void zuc_init(ZUC_STATE *key, const uint8_t *user_key, const uint8_t *iv)
void zuc_init(ZUC_STATE *state, const uint8_t *user_key, const uint8_t *iv)
{
ZUC_UINT31 *LFSR = key->LFSR;
ZUC_UINT31 *LFSR = state->LFSR;
uint32_t R1, R2;
uint32_t X0, X1, X2;
uint32_t W, W1, W2, U, V;
@@ -207,15 +209,15 @@ void zuc_init(ZUC_STATE *key, const uint8_t *user_key, const uint8_t *iv)
F_(X1, X2);
LFSRWithWorkMode();
key->R1 = R1;
key->R2 = R2;
state->R1 = R1;
state->R2 = R2;
}
uint32_t zuc_generate_keyword(ZUC_STATE *key)
uint32_t zuc_generate_keyword(ZUC_STATE *state)
{
ZUC_UINT31 *LFSR = key->LFSR;
uint32_t R1 = key->R1;
uint32_t R2 = key->R2;
ZUC_UINT31 *LFSR = state->LFSR;
uint32_t R1 = state->R1;
uint32_t R2 = state->R2;
uint32_t X0, X1, X2, X3;
uint32_t W1, W2, U, V;
uint32_t Z;
@@ -224,17 +226,17 @@ uint32_t zuc_generate_keyword(ZUC_STATE *key)
Z = X3 ^ F(X0, X1, X2);
LFSRWithWorkMode();
key->R1 = R1;
key->R2 = R2;
state->R1 = R1;
state->R2 = R2;
return Z;
}
void zuc_generate_keystream(ZUC_STATE *key, size_t nwords, uint32_t *keystream)
void zuc_generate_keystream(ZUC_STATE *state, size_t nwords, uint32_t *keystream)
{
ZUC_UINT31 *LFSR = key->LFSR;
uint32_t R1 = key->R1;
uint32_t R2 = key->R2;
ZUC_UINT31 *LFSR = state->LFSR;
uint32_t R1 = state->R1;
uint32_t R2 = state->R2;
uint32_t X0, X1, X2, X3;
uint32_t W1, W2, U, V;
size_t i;
@@ -245,8 +247,42 @@ void zuc_generate_keystream(ZUC_STATE *key, size_t nwords, uint32_t *keystream)
LFSRWithWorkMode();
}
key->R1 = R1;
key->R2 = R2;
state->R1 = R1;
state->R2 = R2;
}
void zuc_encrypt(ZUC_STATE *state, const uint8_t *in, size_t inlen, uint8_t *out)
{
ZUC_UINT31 *LFSR = state->LFSR;
uint32_t R1 = state->R1;
uint32_t R2 = state->R2;
uint32_t X0, X1, X2, X3;
uint32_t W1, W2, U, V;
uint32_t Z;
uint8_t block[4];
size_t nwords = inlen / sizeof(uint32_t);
size_t i;
for (i = 0; i < nwords; i ++) {
BitReconstruction4(X0, X1, X2, X3);
Z = X3 ^ F(X0, X1, X2);
LFSRWithWorkMode();
PUTU32(block, Z);
gmssl_memxor(out, in, block, sizeof(block));
in += sizeof(block);
out += sizeof(block);
}
if (inlen % 4) {
// TODO: use assert to make sure this branch should not be arrived
BitReconstruction4(X0, X1, X2, X3);
Z = X3 ^ F(X0, X1, X2);
LFSRWithWorkMode();
PUTU32(block, Z);
gmssl_memxor(out, in, block, inlen % 4);
}
state->R1 = R1;
state->R2 = R2;
}
void zuc_mac_init(ZUC_MAC_CTX *ctx, const uint8_t key[16], const uint8_t iv[16])

View File

@@ -1,159 +0,0 @@
/* ====================================================================
* Copyright (c) 2015 - 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 <stdlib.h>
#include <string.h>
#include <gmssl/zuc.h>
#include "endian.h"
static void zuc_set_eia_iv(uint8_t iv[16], ZUC_UINT32 count, ZUC_UINT5 bearer,
ZUC_BIT direction)
{
memset(iv, 0, 16);
iv[0] = count >> 24;
iv[1] = iv[9] = count >> 16;
iv[2] = iv[10] = count >> 8;
iv[3] = iv[11] = count;
iv[4] = iv[12] = bearer << 3;
iv[8] = iv[0] ^ (direction << 7);
iv[14] = (direction << 7);
}
#if 1
ZUC_UINT32 zuc_eia_generate_mac(const ZUC_UINT32 *data, size_t nbits,
const uint8_t key[16], ZUC_UINT32 count, ZUC_UINT5 bearer,
ZUC_BIT direction)
{
ZUC_MAC_CTX ctx;
uint8_t iv[16];
uint8_t mac[4];
zuc_set_eia_iv(iv, count, bearer, direction);
zuc_mac_init(&ctx, key, iv);
zuc_mac_finish(&ctx, (uint8_t *)data, nbits, mac);
return GETU32(mac);
}
#else
#define ZUC_MAC_BUF_WORDS 64
#define GET_WORD(p, i) ((i) % 32) \
? ((*((ZUC_UINT32 *)(p) + (i)/32) << ((i) % 32)) \
| (*((ZUC_UINT32 *)(p) + (i)/32 + 1) >> (32 - ((i) % 32)))) \
: *((ZUC_UINT32 *)(p) + (i)/32)
#define GET_BIT(p, i) \
(((*((ZUC_UINT32 *)(p) + (i)/32)) & (1 << (31 - ((i) % 32)))) ? 1 : 0)
ZUC_UINT32 ZUC_eia_generate_mac(const ZUC_UINT32 *data, size_t nbits,
const uint8_t user_key[16], ZUC_UINT32 count, ZUC_UINT5 bearer,
ZUC_BIT direction)
{
ZUC_UINT32 T = 0;
ZUC_STATE key;
uint8_t iv[16];
ZUC_UINT32 buf[ZUC_MAC_BUF_WORDS + 2];
size_t nwords = (nbits + 31)/32;
size_t i;
size_t num = ZUC_MAC_BUF_WORDS;
ZUC_set_eia_iv(iv, count, bearer, direction);
ZUC_set_key(&key, user_key, iv);
if (nwords <= ZUC_MAC_BUF_WORDS) {
ZUC_generate_keystream(&key, nwords + 2, buf);
for (i = 0; i < nbits; i++) {
if (GET_BIT(data, i)) {
T ^= GET_WORD(buf, i);
}
}
T ^= GET_WORD(buf, i);
T ^= buf[nwords + 1];
return T;
} else {
ZUC_generate_keystream(&key, ZUC_MAC_BUF_WORDS + 1, buf);
for (i = 0; i < ZUC_MAC_BUF_WORDS * 32; i++) {
if (GET_BIT(data, i)) {
T ^= GET_WORD(buf, i);
}
}
data += ZUC_MAC_BUF_WORDS;
nwords -= ZUC_MAC_BUF_WORDS;
nbits -= ZUC_MAC_BUF_WORDS * 32;
}
while (nwords > ZUC_MAC_BUF_WORDS) {
buf[0] = buf[ZUC_MAC_BUF_WORDS];
ZUC_generate_keystream(&key, ZUC_MAC_BUF_WORDS, buf + 1);
for (i = 0; i < ZUC_MAC_BUF_WORDS * 32; i ++) {
if (GET_BIT(data, i)) {
T ^= GET_WORD(buf, i);
}
}
data += num;
nwords -= num;
nbits -= ZUC_MAC_BUF_WORDS * 32;
}
buf[0] = buf[ZUC_MAC_BUF_WORDS];
ZUC_generate_keystream(&key, nwords + 1, buf + 1);
for (i = 0; i < nbits; i++) {
if (GET_BIT(data, i)) {
T ^= GET_WORD(buf, i);
}
}
T ^= GET_WORD(buf, i);
T ^= buf[nwords + 1];
return T;
}
#endif

View File

@@ -1,5 +1,5 @@
/* ====================================================================
* Copyright (c) 2015 - 2019 The GmSSL Project. All rights reserved.
/*
* Copyright (c) 2015 - 2022 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
@@ -44,11 +44,16 @@
* 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/zuc.h>
#include <gmssl/error.h>
#include <gmssl/endian.h>
static void zuc_set_eea_key(ZUC_STATE *key, const uint8_t user_key[16],
ZUC_UINT32 count, ZUC_UINT5 bearer, ZUC_BIT direction)
@@ -80,3 +85,96 @@ void zuc_eea_encrypt(const ZUC_UINT32 *in, ZUC_UINT32 *out, size_t nbits,
out[nwords - 1] |= (0xffffffff << (32 - (nbits%32)));
}
}
static void zuc_set_eia_iv(uint8_t iv[16], ZUC_UINT32 count, ZUC_UINT5 bearer,
ZUC_BIT direction)
{
memset(iv, 0, 16);
iv[0] = count >> 24;
iv[1] = iv[9] = count >> 16;
iv[2] = iv[10] = count >> 8;
iv[3] = iv[11] = count;
iv[4] = iv[12] = bearer << 3;
iv[8] = iv[0] ^ (direction << 7);
iv[14] = (direction << 7);
}
ZUC_UINT32 zuc_eia_generate_mac(const ZUC_UINT32 *data, size_t nbits,
const uint8_t key[16], ZUC_UINT32 count, ZUC_UINT5 bearer,
ZUC_BIT direction)
{
ZUC_MAC_CTX ctx;
uint8_t iv[16];
uint8_t mac[4];
zuc_set_eia_iv(iv, count, bearer, direction);
zuc_mac_init(&ctx, key, iv);
zuc_mac_finish(&ctx, (uint8_t *)data, nbits, mac);
return GETU32(mac);
}
#define ZUC_BLOCK_SIZE 4
int zuc_encrypt_init(ZUC_CTX *ctx, const uint8_t key[ZUC_KEY_SIZE], const uint8_t iv[ZUC_IV_SIZE])
{
if (!ctx || !key || !iv) {
error_print();
return -1;
}
zuc_init(&ctx->zuc_state, key, iv);
memset(ctx->block, 0, ZUC_BLOCK_SIZE);
ctx->block_nbytes = 0;
return 1;
}
int zuc_encrypt_update(ZUC_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen)
{
size_t left;
size_t nblocks;
size_t len;
if (ctx->block_nbytes >= ZUC_BLOCK_SIZE) {
error_print();
return -1;
}
*outlen = 0;
if (ctx->block_nbytes) {
left = ZUC_BLOCK_SIZE - ctx->block_nbytes;
if (inlen < left) {
memcpy(ctx->block + ctx->block_nbytes, in, inlen);
ctx->block_nbytes += inlen;
return 1;
}
memcpy(ctx->block + ctx->block_nbytes, in, left);
zuc_encrypt(&ctx->zuc_state, ctx->block, ZUC_BLOCK_SIZE, out);
in += left;
inlen -= left;
out += ZUC_BLOCK_SIZE;
*outlen += ZUC_BLOCK_SIZE;
}
if (inlen >= ZUC_BLOCK_SIZE) {
nblocks = inlen / ZUC_BLOCK_SIZE;
len = nblocks * ZUC_BLOCK_SIZE;
zuc_encrypt(&ctx->zuc_state, in, len, out);
in += len;
inlen -= len;
out += len;
*outlen += len;
}
if (inlen) {
memcpy(ctx->block, in, inlen);
}
ctx->block_nbytes = inlen;
return 1;
}
int zuc_encrypt_finish(ZUC_CTX *ctx, uint8_t *out, size_t *outlen)
{
size_t left;
if (ctx->block_nbytes >= ZUC_BLOCK_SIZE) {
error_print();
return -1;
}
zuc_encrypt(&ctx->zuc_state, ctx->block, ctx->block_nbytes, out);
*outlen = ctx->block_nbytes;
return 1;
}