diff --git a/.gitignore b/.gitignore index 24705f33..4cb35b62 100644 --- a/.gitignore +++ b/.gitignore @@ -212,6 +212,11 @@ apps/gmca/.ca /engines/sdf /engines/skf +/sdf/* +/skf/* +/src/skf* +/src/sdf* + include/openssl/srp.h /*.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index 2a4fa961..dbec4ca6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/src/mem.h b/include/gmssl/mem.h similarity index 93% rename from src/mem.h rename to include/gmssl/mem.h index 0b210440..2cb2cf98 100644 --- a/src/mem.h +++ b/include/gmssl/mem.h @@ -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 + diff --git a/src/aes.c b/src/aes.c index 31bfd866..c90d0656 100644 --- a/src/aes.c +++ b/src/aes.c @@ -51,8 +51,8 @@ #include #include #include -#include "endian.h" -#include "mem.h" +#include +#include static const uint8_t S[256] = { diff --git a/src/aes_modes.c b/src/aes_modes.c index ad10b134..951640f9 100644 --- a/src/aes_modes.c +++ b/src/aes_modes.c @@ -53,7 +53,7 @@ #include #include #include -#include "mem.h" +#include void aes_cbc_encrypt(const AES_KEY *key, const uint8_t iv[16], diff --git a/src/asn1.c b/src/asn1.c index 5a6b2929..f05ca18a 100644 --- a/src/asn1.c +++ b/src/asn1.c @@ -56,7 +56,7 @@ #include #include #include -#include "endian.h" +#include /* diff --git a/src/block_cipher.c b/src/block_cipher.c index b6ca65bf..8a937fc4 100644 --- a/src/block_cipher.c +++ b/src/block_cipher.c @@ -52,8 +52,7 @@ #include #include #include -#include "endian.h" - +#include int block_cipher_set_encrypt_key(BLOCK_CIPHER_KEY *key, const BLOCK_CIPHER *cipher, const uint8_t *raw_key) diff --git a/src/chacha20.c b/src/chacha20.c index de6f37cb..2e36eb73 100644 --- a/src/chacha20.c +++ b/src/chacha20.c @@ -51,7 +51,8 @@ #include #include #include -#include "endian.h" +#include + void chacha20_init(CHACHA20_STATE *state, const uint8_t key[CHACHA20_KEY_SIZE], diff --git a/src/des.c b/src/des.c index 98df6f43..03655630 100644 --- a/src/des.c +++ b/src/des.c @@ -50,7 +50,7 @@ #include #include #include -#include "endian.h" +#include /* permuted choice 1 for key schedule, 64 bits to 56 bits */ diff --git a/src/endian.h b/src/endian.h deleted file mode 100644 index 590dccfc..00000000 --- a/src/endian.h +++ /dev/null @@ -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 diff --git a/src/gcm.c b/src/gcm.c index 0fba87d1..6c746cf8 100644 --- a/src/gcm.c +++ b/src/gcm.c @@ -54,7 +54,8 @@ #include #include #include -#include "endian.h" +#include + /* * GHASH(H, A, C) = X_{m + n + 1} diff --git a/src/gf128.c b/src/gf128.c index 109ac71b..db4da42b 100644 --- a/src/gf128.c +++ b/src/gf128.c @@ -57,7 +57,7 @@ #include #include #include -#include "endian.h" +#include gf128_t gf128_zero(void) diff --git a/src/hash_drbg.c b/src/hash_drbg.c index 3595254a..72335b57 100644 --- a/src/hash_drbg.c +++ b/src/hash_drbg.c @@ -52,7 +52,8 @@ #include #include #include -#include "endian.h" +#include + static int hash_df(const DIGEST *digest, const uint8_t *in, size_t inlen, size_t outlen, uint8_t *out) diff --git a/src/hex.c b/src/hex.c index ea59bd06..563bed4c 100644 --- a/src/hex.c +++ b/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); +} diff --git a/src/md5.c b/src/md5.c index fcab99e4..ef8a2809 100644 --- a/src/md5.c +++ b/src/md5.c @@ -49,7 +49,7 @@ #include #include -#include "endian.h" +#include #define F(B, C, D) (((B) & (C)) | ((~(B)) & (D))) diff --git a/src/nginx.c b/src/nginx.c deleted file mode 100644 index 08a08ce0..00000000 --- a/src/nginx.c +++ /dev/null @@ -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 diff --git a/src/oid.c b/src/oid.c deleted file mode 100644 index 8c6ac13a..00000000 --- a/src/oid.c +++ /dev/null @@ -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 -#include -#include -#include -#include -#include -#include - - -/* - 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); - } -} diff --git a/src/pbkdf2.c b/src/pbkdf2.c index 8777ee55..55d5df91 100644 --- a/src/pbkdf2.c +++ b/src/pbkdf2.c @@ -120,8 +120,8 @@ #include #include #include -#include "endian.h" -#include "mem.h" +#include +#include int pbkdf2_genkey(const DIGEST *digest, const char *pass, size_t passlen, diff --git a/src/sha1.c b/src/sha1.c index 1514eaf1..0b31f84a 100644 --- a/src/sha1.c +++ b/src/sha1.c @@ -48,7 +48,7 @@ #include #include -#include "endian.h" +#include #define F0(B, C, D) (((B) & (C)) | ((~(B)) & (D))) diff --git a/src/sha256.c b/src/sha256.c index 37fc9fd3..5fb19259 100644 --- a/src/sha256.c +++ b/src/sha256.c @@ -48,7 +48,7 @@ #include #include -#include "endian.h" +#include #define Ch(X, Y, Z) (((X) & (Y)) ^ ((~(X)) & (Z))) diff --git a/src/sha512.c b/src/sha512.c index e278cfc3..cf98ffea 100644 --- a/src/sha512.c +++ b/src/sha512.c @@ -51,7 +51,7 @@ #include #include #include -#include "endian.h" +#include static void sha512_compress_blocks(uint64_t state[8], diff --git a/src/sm2_alg.c b/src/sm2_alg.c index 7f69a5c2..702038ce 100644 --- a/src/sm2_alg.c +++ b/src/sm2_alg.c @@ -53,7 +53,7 @@ #include #include #include -#include "endian.h" +#include #define sm2_print_bn(label,a) sm2_bn_print(stderr,0,0,label,a) // 这个不应该放在这里,应该放在测试文件中 diff --git a/src/sm2_key.c b/src/sm2_key.c index 66eb22d7..cd54661e 100644 --- a/src/sm2_key.c +++ b/src/sm2_key.c @@ -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) { diff --git a/src/sm2_lib.c b/src/sm2_lib.c index d496259b..5f58add4 100644 --- a/src/sm2_lib.c +++ b/src/sm2_lib.c @@ -54,7 +54,7 @@ #include #include #include -#include "endian.h" +#include #define print_bn(str,a) sm2_bn_print(stderr,0,4,str,a) diff --git a/src/sm3.c b/src/sm3.c index b279d777..534aa785 100644 --- a/src/sm3.c +++ b/src/sm3.c @@ -48,7 +48,8 @@ #include #include -#include "endian.h" +#include + #ifdef SM3_SSE3 # include diff --git a/src/sm4_enc.c b/src/sm4_enc.c index 0efb53ac..3731779e 100644 --- a/src/sm4_enc.c +++ b/src/sm4_enc.c @@ -48,7 +48,7 @@ */ #include -#include "endian.h" +#include #include "sm4_lcl.h" diff --git a/src/sm4_modes.c b/src/sm4_modes.c index 7b35ae81..318626b5 100644 --- a/src/sm4_modes.c +++ b/src/sm4_modes.c @@ -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 -#include +#include #include -#include "mem.h" +#include 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; } diff --git a/src/sm4_setkey.c b/src/sm4_setkey.c index a8757cdb..5b89145d 100644 --- a/src/sm4_setkey.c +++ b/src/sm4_setkey.c @@ -48,7 +48,7 @@ */ #include -#include "endian.h" +#include #include "sm4_lcl.h" static uint32_t FK[4] = { diff --git a/src/sm9_math.c b/src/sm9_alg.c similarity index 99% rename from src/sm9_math.c rename to src/sm9_alg.c index be3856e2..84776ec3 100644 --- a/src/sm9_math.c +++ b/src/sm9_alg.c @@ -53,7 +53,7 @@ #include #include #include -#include "endian.h" +#include static const sm9_bn_t SM9_ZERO = {0,0,0,0,0,0,0,0}; diff --git a/src/sm9_keygen.c b/src/sm9_key.c similarity index 100% rename from src/sm9_keygen.c rename to src/sm9_key.c diff --git a/src/sm9_sign.c b/src/sm9_lib.c similarity index 100% rename from src/sm9_sign.c rename to src/sm9_lib.c diff --git a/src/tls13.c b/src/tls13.c index 96159098..17f53c2a 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -68,7 +68,7 @@ #include #include #include -#include "mem.h" +#include diff --git a/src/version.c b/src/version.c index 223c5a56..7dca9a6b 100644 --- a/src/version.c +++ b/src/version.c @@ -46,6 +46,12 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* +## TODO: + 1. 每次发布时,应该将当前的时间戳添加到版本中 + 2. 将编译信息加入到版本的全部信息中,特别是发布二进制版专有功能时 + +*/ #include diff --git a/src/x509_oid.c b/src/x509_oid.c index 4322fb39..ce482536 100644 --- a/src/x509_oid.c +++ b/src/x509_oid.c @@ -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[] = { diff --git a/src/zuc_core.c b/src/zuc.c similarity index 91% rename from src/zuc_core.c rename to src/zuc.c index 7b529f07..f1fd225a 100644 --- a/src/zuc_core.c +++ b/src/zuc.c @@ -49,7 +49,9 @@ #include #include #include -#include "endian.h" +#include +#include + 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]) diff --git a/src/zuc_eia.c b/src/zuc_eia.c deleted file mode 100644 index 47509e80..00000000 --- a/src/zuc_eia.c +++ /dev/null @@ -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 -#include -#include -#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 diff --git a/src/zuc_eea.c b/src/zuc_modes.c similarity index 56% rename from src/zuc_eea.c rename to src/zuc_modes.c index cc3ca54a..2883f837 100644 --- a/src/zuc_eea.c +++ b/src/zuc_modes.c @@ -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 +#include #include #include +#include +#include + 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; +}