mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-05-06 16:36:16 +08:00
expose all functions
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -212,6 +212,11 @@ apps/gmca/.ca
|
||||
/engines/sdf
|
||||
/engines/skf
|
||||
|
||||
/sdf/*
|
||||
/skf/*
|
||||
/src/skf*
|
||||
/src/sdf*
|
||||
|
||||
include/openssl/srp.h
|
||||
|
||||
/*.sh
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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] = {
|
||||
|
||||
@@ -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],
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
#include <gmssl/oid.h>
|
||||
#include <gmssl/asn1.h>
|
||||
#include <gmssl/error.h>
|
||||
#include "endian.h"
|
||||
#include <gmssl/endian.h>
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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],
|
||||
|
||||
@@ -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 */
|
||||
|
||||
116
src/endian.h
116
src/endian.h
@@ -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
|
||||
@@ -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}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
46
src/hex.c
46
src/hex.c
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)))
|
||||
|
||||
35
src/nginx.c
35
src/nginx.c
@@ -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
603
src/oid.c
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
@@ -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)))
|
||||
|
||||
@@ -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)))
|
||||
|
||||
@@ -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],
|
||||
|
||||
@@ -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) // 这个不应该放在这里,应该放在测试文件中
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -48,7 +48,8 @@
|
||||
|
||||
#include <string.h>
|
||||
#include <gmssl/sm3.h>
|
||||
#include "endian.h"
|
||||
#include <gmssl/endian.h>
|
||||
|
||||
|
||||
#ifdef SM3_SSE3
|
||||
# include <x86intrin.h>
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
*/
|
||||
|
||||
#include <gmssl/sm4.h>
|
||||
#include "endian.h"
|
||||
#include <gmssl/endian.h>
|
||||
#include "sm4_lcl.h"
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
*/
|
||||
|
||||
#include <gmssl/sm4.h>
|
||||
#include "endian.h"
|
||||
#include <gmssl/endian.h>
|
||||
#include "sm4_lcl.h"
|
||||
|
||||
static uint32_t FK[4] = {
|
||||
|
||||
@@ -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};
|
||||
@@ -68,7 +68,7 @@
|
||||
#include <gmssl/gcm.h>
|
||||
#include <gmssl/hmac.h>
|
||||
#include <gmssl/hkdf.h>
|
||||
#include "mem.h"
|
||||
#include <gmssl/mem.h>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -46,6 +46,12 @@
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
## TODO:
|
||||
1. 每次发布时,应该将当前的时间戳添加到版本中
|
||||
2. 将编译信息加入到版本的全部信息中,特别是发布二进制版专有功能时
|
||||
|
||||
*/
|
||||
|
||||
#include <gmssl/version.h>
|
||||
|
||||
|
||||
@@ -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[] = {
|
||||
|
||||
@@ -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])
|
||||
159
src/zuc_eia.c
159
src/zuc_eia.c
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user