diff --git a/Configure b/Configure index 0b6ffa73..72b304c3 100755 --- a/Configure +++ b/Configure @@ -480,7 +480,6 @@ our %disabled = ( # "what" => "comment" "weak-ssl-ciphers" => "default", "zlib" => "default", "zlib-dynamic" => "default", - "zuc" => "default", "skfeng" => "default", "sdfeng" => "default", "gmieng" => "default", diff --git a/crypto/evp/build.info b/crypto/evp/build.info index ced2ce9d..646f04c0 100644 --- a/crypto/evp/build.info +++ b/crypto/evp/build.info @@ -15,6 +15,7 @@ SOURCE[../../libcrypto]=\ e_chacha20_poly1305.c cmeth_lib.c \ m_sm3.c \ e_sms4.c e_sms4_ccm.c e_sms4_gcm.c e_sms4_ocb.c e_sms4_wrap.c e_sms4_xts.c \ + e_zuc.c \ evp_ctxt.c names2.c INCLUDE[e_aes.o]=.. ../modes diff --git a/crypto/evp/c_allc.c b/crypto/evp/c_allc.c index ea9b7a05..70eb122a 100644 --- a/crypto/evp/c_allc.c +++ b/crypto/evp/c_allc.c @@ -1,3 +1,51 @@ +/* ==================================================================== + * Copyright (c) 2014 - 2018 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. + * ==================================================================== + */ /* * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. * @@ -243,4 +291,7 @@ void openssl_add_all_ciphers_int(void) EVP_add_cipher_alias(SN_sms4_cbc,"SMS4"); EVP_add_cipher_alias(SN_sms4_cbc,"sms4"); #endif +#ifndef OPENSSL_NO_ZUC + EVP_add_cipher(EVP_zuc()); +#endif } diff --git a/crypto/zuc/zuc.c b/crypto/evp/e_zuc.c old mode 100755 new mode 100644 similarity index 65% rename from crypto/zuc/zuc.c rename to crypto/evp/e_zuc.c index 92d88319..950ebabc --- a/crypto/zuc/zuc.c +++ b/crypto/evp/e_zuc.c @@ -1,5 +1,5 @@ /* ==================================================================== - * Copyright (c) 2015 - 2016 The GmSSL Project. All rights reserved. + * Copyright (c) 2014 - 2018 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 @@ -45,26 +45,68 @@ * 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 "evp_locl.h" +# include "internal/evp_int.h" + +#ifndef OPENSSL_NO_ZUC + +# include + +typedef struct { + ZUC_KEY ks; +} EVP_ZUC_KEY; -void zuc_set_key(zuc_key_t *key, const unsigned char *user_key, const unsigned char *iv) +static int zuc_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) { + EVP_ZUC_KEY *dctx = EVP_C_DATA(EVP_ZUC_KEY, ctx); + ZUC_set_key(&dctx->ks, key, iv); + return 1; } -void zuc_generate_keystream(zuc_key_t *key, size_t nwords, uint32_t *words) +static int zuc_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) { + EVP_ZUC_KEY *dctx = EVP_C_DATA(EVP_ZUC_KEY, ctx); + unsigned char *buf = EVP_CIPHER_CTX_buf_noconst(ctx); + unsigned int n = EVP_CIPHER_CTX_num(ctx); + size_t l = 0; + + while (l < len) { + if (n == 0) { + ZUC_generate_keystream(&dctx->ks, 4, (uint32_t *)buf); + } + out[l] = in[l] ^ buf[n]; + ++l; + n = (n + 1) % 16; + } + + EVP_CIPHER_CTX_set_num(ctx, n); + return 1; } -void zuc_ctx_init(zuc_ctx_t *ctx, const unsigned char *user_key, const unsigned char *iv) -{ -} +const EVP_CIPHER zuc_cipher = { + NID_zuc, + 1, + ZUC_KEY_LENGTH, + ZUC_IV_LENGTH, + 0, + zuc_init_key, + zuc_do_cipher, + NULL, + sizeof(EVP_ZUC_KEY), + NULL,NULL,NULL,NULL, +}; -void zuc_encrypt(zuc_ctx_t *ctx, size_t len, const unsigned char *in, unsigned char *out) +const EVP_CIPHER *EVP_zuc(void) { - memcpy(out, in, len); + return &zuc_cipher; } +#endif /* OPENSSL_NO_ZUC */ diff --git a/crypto/zuc/build.info b/crypto/zuc/build.info index 016d75fb..2d9acb1c 100644 --- a/crypto/zuc/build.info +++ b/crypto/zuc/build.info @@ -1,2 +1,2 @@ LIBS=../../libcrypto -SOURCE[../../libcrypto]=zuc.c zuc_spec.c +SOURCE[../../libcrypto]=zuc_core.c zuc_128eea3.c zuc_128eia3.c zuc_spec.c diff --git a/crypto/zuc/zuc_128eea3.c b/crypto/zuc/zuc_128eea3.c index 9e88fe86..5c4504d3 100644 --- a/crypto/zuc/zuc_128eea3.c +++ b/crypto/zuc/zuc_128eea3.c @@ -1,5 +1,5 @@ /* ==================================================================== - * Copyright (c) 2015 - 2017 The GmSSL Project. All rights reserved. + * Copyright (c) 2015 - 2018 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 @@ -48,28 +48,22 @@ */ #include -#include "zuc_lcl.h" -void zuc_128eea3_init(zuc_128eea3_t *ctx, const unsigned char *user_key, - uint32_t count, uint32_t bearer, int direction) +void ZUC_128eea3_set_key(ZUC_128EEA3 *ctx, const unsigned char user_key[16], + ZUC_UINT32 count, ZUC_UINT5 bearer, ZUC_UINT1 direction) { - unsigned char iv[16] = {0}; - iv[0] = iv[8] = (count >> 24) & 0xff; - iv[1] = iv[9] = (count >> 16) & 0xff; - iv[2] = iv[10] = (count >> 8) & 0xff; - iv[3] = iv[11] = count & 0xff; - iv[4] = iv[12] = ((bearer << 3) | ((direction & 1) << 2)) & 0xfc; - - zuc_ctx_init(ctx->zuc_ctx, user_key, iv); + //TODO } -void zuc_128eea3_encrypt(zuc_128eea3_t *eea3, size_t len, +void ZUC_128eea3_encrypt(ZUC_128EEA3 *ctx, size_t len, const unsigned char *in, unsigned char *out) { - return zuc_encrypt(); + //TODO } -void zuc_128eea3(const unsigned char *key, uint32_t count, uint32_t bearer, int direction, +void ZUC_128eea3(const unsigned char key[ZUC_KEY_LENGTH], + ZUC_UINT32 count, ZUC_UINT5 bearer, ZUC_UINT1 direction, size_t len, const unsigned char *in, unsigned char *out) { + //TODO } diff --git a/crypto/zuc/zuc_128eia3.c b/crypto/zuc/zuc_128eia3.c index 949c65b4..d7da975a 100644 --- a/crypto/zuc/zuc_128eia3.c +++ b/crypto/zuc/zuc_128eia3.c @@ -1,5 +1,5 @@ /* ==================================================================== - * Copyright (c) 2015 - 2016 The GmSSL Project. All rights reserved. + * Copyright (c) 2015 - 2018 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 @@ -48,85 +48,27 @@ */ #include -#include "zuc_lcl.h" -void eea3_init(eea3_ctx_t *ctx, const unsigned char *user_key, - uint32_t count, uint32_t bearer, int direction) +void ZUC_128eia3_set_key(ZUC_128EIA3 *ctx, const unsigned char *user_key, + ZUC_UINT32 count, ZUC_UINT5 bearer, ZUC_UINT1 direction) { - unsigned char iv[16] = {0}; - iv[0] = iv[8] = (count >> 24) & 0xff; - iv[1] = iv[9] = (count >> 16) & 0xff; - iv[2] = iv[10] = (count >> 8) & 0xff; - iv[3] = iv[11] = count & 0xff; - iv[4] = iv[12] = ((bearer << 3) | ((direction & 1) << 2)) & 0xfc; - - zuc_ctx_init(ctx->zuc_ctx, user_key, iv); + //TODO } -void eea3_encrypt(eea3_ctx_t *ctx, size_t len, const unsigned char *in, unsigned char *out); - - - -void eea3(const unsigned char *key, uint32_t count, uint32_t bearer, int direction, - size_t len, const unsigned char *in, unsigned char *out); - - - -u32 GET_WORD(u32 * DATA, u32 i) +void ZUC_128eia3_update(ZUC_128EIA3 *ctx, const unsigned char *data, + size_t datalen) { - u32 WORD, ti; - ti = i % 32; - - if (ti == 0) { - WORD = DATA[i/32]; - } - else { - WORD = (DATA[i/32]<>(32-ti)); - } - return WORD; + //TODO } -u8 GET_BIT(u32 * DATA, u32 i) +void ZUC_128eia3_final(ZUC_128EIA3 *ctx, uint32_t *mac) { - return (DATA[i/32] & (1<<(31-(i%32)))) ? 1 : 0; + //TODO } -void EIA3(u8* IK, u32 count, u32 DIRECTION, u32 BEARER, u32 LENGTH, u32* M, u32* MAC) +void ZUC_128eia3(const unsigned char key[ZUC_KEY_LENGTH], + ZUC_UINT32 count, ZUC_UINT5 bearer, ZUC_UINT1 direction, + const unsigned char *data, size_t dlen, uint32_t *mac) { - u32 *z, N, L, T, i; - u8 iv[16]; - - iv[0] = (count>>24) & 0xFF; - iv[1] = (count>>16) & 0xFF; - iv[2] = (count>>8) & 0xFF; - iv[3] = count & 0xFF; - - iv[4] = (BEARER << 3) & 0xF8; - iv[5] = iv[6] = iv[7] = 0; - - iv[8] = ((count>>24) & 0xFF) ^ ((DIRECTION&1)<<7); - iv[9] = (count>>16) & 0xFF; - iv[10] = (count>>8) & 0xFF; - iv[11] = count & 0xFF; - - iv[12] = iv[4]; - iv[13] = iv[5]; - iv[14] = iv[6] ^ ((DIRECTION&1)<<7); - iv[15] = iv[7]; - - N = LENGTH + 64; - L = (N + 31) / 32; - z = (u32 *) malloc(L*sizeof(u32)); - ZUC(IK, iv, z, L); - - T = 0; - for (i = 0; i < LENGTH; i++) { - if (GET_BIT(M,i)) { - T ^= GET_WORD(z,i); - } - } - T ^= GET_WORD(z,LENGTH); - - *MAC = T ^ z[L-1]; - free(z); + //TODO } diff --git a/crypto/zuc/zuc_core.c b/crypto/zuc/zuc_core.c index f401adc2..a4cc8367 100644 --- a/crypto/zuc/zuc_core.c +++ b/crypto/zuc/zuc_core.c @@ -1,5 +1,5 @@ /* ==================================================================== - * Copyright (c) 2015 - 2016 The GmSSL Project. All rights reserved. + * Copyright (c) 2015 - 2018 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 @@ -47,19 +47,16 @@ * ==================================================================== */ -/* code from ZUC 3GPP Specifications, version 1.6 - */ - #include +#include #include "zuc_spec.h" -typedef struct { - uint32_t S[16]; - uint32_t R1; - uint32_t R2; -} zuc_key_t; +static const ZUC_UINT15 KD[16] = { + 0x44D7,0x26BC,0x626B,0x135E,0x5789,0x35E2,0x7135,0x09AF, + 0x4D78,0x2F13,0x6BC4,0x1AF1,0x5E26,0x3C4D,0x789A,0x47AC, +}; -static const unsigned char S0[256] = { +static const uint8_t S0[256] = { 0x3e,0x72,0x5b,0x47,0xca,0xe0,0x00,0x33,0x04,0xd1,0x54,0x98,0x09,0xb9,0x6d,0xcb, 0x7b,0x1b,0xf9,0x32,0xaf,0x9d,0x6a,0xa5,0xb8,0x2d,0xfc,0x1d,0x08,0x53,0x03,0x90, 0x4d,0x4e,0x84,0x99,0xe4,0xce,0xd9,0x91,0xdd,0xb6,0x85,0x48,0x8b,0x29,0x6e,0xac, @@ -78,7 +75,7 @@ static const unsigned char S0[256] = { 0x8d,0x27,0x1a,0xdb,0x81,0xb3,0xa0,0xf4,0x45,0x7a,0x19,0xdf,0xee,0x78,0x34,0x60, }; -static const unsigned char S1[256] = { +static const uint8_t S1[256] = { 0x55,0xc2,0x63,0x71,0x3b,0xc8,0x47,0x86,0x9f,0x3c,0xda,0x5b,0x29,0xaa,0xfd,0x77, 0x8c,0xc5,0x94,0x0c,0xa6,0x1a,0x13,0x00,0xe3,0xa8,0x16,0x72,0x40,0xf9,0xf8,0x42, 0x44,0x26,0x68,0x96,0x81,0xd9,0x45,0x3e,0x10,0x76,0xc6,0xa7,0x8b,0x39,0x43,0xe1, @@ -97,130 +94,63 @@ static const unsigned char S1[256] = { 0x64,0xbe,0x85,0x9b,0x2f,0x59,0x8a,0xd7,0xb0,0x25,0xac,0xaf,0x12,0x03,0xe2,0xf2, }; -static uint32_t const EK_d[16] = { - 0x44D7,0x26BC,0x626B,0x135E,0x5789,0x35E2,0x7135,0x09AF, - 0x4D78,0x2F13,0x6BC4,0x1AF1,0x5E26,0x3C4D,0x789A,0x47AC, -}; -inline uint32_t zuc_madd(uint32_t a, uint32_t b) -{ - uint32_t c = a + b; - return (c & 0x7FFFFFFF) + (c >> 31); -} +#define ADD31(a,b) a += (b); a = (a & 0x7fffffff) + (a >> 31) +#define ROT31(a,k) ((((a) << (k)) | ((a) >> (31 - (k)))) & 0x7FFFFFFF) +#define ROT32(a,k) (((a) << (k)) | ((a) >> (32 - (k)))) + +#define L1(X) \ + ((X) ^ \ + ROT32((X), 2) ^ \ + ROT32((X), 10) ^ \ + ROT32((X), 18) ^ \ + ROT32((X), 24)) + +#define L2(X) \ + ((X) ^ \ + ROT32((X), 8) ^ \ + ROT32((X), 14) ^ \ + ROT32((X), 22) ^ \ + ROT32((X), 30)) + +#define LFSRWithInitialisationMode(u) \ + V = LFSR[0]; \ + ADD31(V, ROT31(LFSR[0], 8)); \ + ADD31(V, ROT31(LFSR[4], 20)); \ + ADD31(V, ROT31(LFSR[10], 21)); \ + ADD31(V, ROT31(LFSR[13], 17)); \ + ADD31(V, ROT31(LFSR[15], 15)); \ + ADD31(V, (u)); \ + {int j; for (j=0; j<15;j++) LFSR[j]=LFSR[j+1];} \ + LFSR[15] = V + +#define LFSRWithWorkMode() \ + V = LFSR[0]; \ + ADD31(V, ROT31(LFSR[0], 8)); \ + ADD31(V, ROT31(LFSR[4], 20)); \ + ADD31(V, ROT31(LFSR[10], 21)); \ + ADD31(V, ROT31(LFSR[13], 17)); \ + ADD31(V, ROT31(LFSR[15], 15)); \ + {int j; for (j=0; j<15;j++) LFSR[j]=LFSR[j+1];} \ + LFSR[15] = V + +#define BitReconstruction2(X1,X2) \ + X1 = ((LFSR[11] & 0xFFFF) << 16) | (LFSR[9] >> 15); \ + X2 = ((LFSR[7] & 0xFFFF) << 16) | (LFSR[5] >> 15) + +#define BitReconstruction3(X0,X1,X2) \ + X0 = ((LFSR[15] & 0x7FFF8000) << 1) | (LFSR[14] & 0xFFFF); \ + BitReconstruction2(X1,X2) + +#define BitReconstruction4(X0,X1,X2,X3) \ + BitReconstruction3(X0,X1,X2); \ + X3 = ((LFSR[2] & 0xFFFF) << 16) | (LFSR[0] >> 15) -/* LFSR with initialization mode */ -#define MulByPow2(x, k) ((((x) << (k)) | ((x) >> (31 - (k)))) & 0x7FFFFFFF) - -void zuc_lfsr_init(zuc_key_t *key, uint32_t u) -{ - uint32_t f, v; - f = key->lfsr_s[0]; - - v = MulByPow2(key->lfsr_s[0], 8); - f = AddM(f, v); - v = MulByPow2(key->lfsr_s[4], 20); - f = AddM(f, v); - v = MulByPow2(key->lfsr_s[10], 21); - f = AddM(f, v); - v = MulByPow2(key->lfsr_s[13], 17); - f = AddM(f, v); - v = MulByPow2(key->lfsr_s[15], 15); - f = AddM(f, v); - f = AddM(f, u); - - /* update the state */ - key->lfsr_s[0] = key->lfsr_s[1]; - key->lfsr_s[1] = key->lfsr_s[2]; - key->lfsr_s[2] = key->lfsr_s[3]; - key->lfsr_s[3] = key->lfsr_s[4]; - key->lfsr_s[4] = key->lfsr_s[5]; - key->lfsr_s[5] = key->lfsr_s[6]; - key->lfsr_s[6] = key->lfsr_s[7]; - key->lfsr_s[7] = key->lfsr_s[8]; - key->lfsr_s[8] = key->lfsr_s[9]; - key->lfsr_s[9] = key->lfsr_s[10]; - key->lfsr_s[10] = key->lfsr_s[11]; - key->lfsr_s[11] = key->lfsr_s[12]; - key->lfsr_s[12] = key->lfsr_s[13]; - key->lfsr_s[13] = key->lfsr_s[14]; - key->lfsr_s[14] = key->lfsr_s[15]; - key->lfsr_s[15] = f; -} - -void zuc_lfst_word(zuc_key_t *key) -{ - u32 f, v; - f = key->lfsr_s[0]; - v = MulByPow2(key->lfsr_s[0], 8); - f = AddM(f, v); - v = MulByPow2(key->lfsr_s[4], 20); - f = AddM(f, v); - v = MulByPow2(key->lfsr_s[10], 21); - f = AddM(f, v); - v = MulByPow2(key->lfsr_s[13], 17); - f = AddM(f, v); - v = MulByPow2(key->lfsr_s[15], 15); - f = AddM(f, v); - - key->lfsr_s[0] = key->lfsr_s[1]; - key->lfsr_s[1] = key->lfsr_s[2]; - key->lfsr_s[2] = key->lfsr_s[3]; - key->lfsr_s[3] = key->lfsr_s[4]; - key->lfsr_s[4] = key->lfsr_s[5]; - key->lfsr_s[5] = key->lfsr_s[6]; - key->lfsr_s[6] = key->lfsr_s[7]; - key->lfsr_s[7] = key->lfsr_s[8]; - key->lfsr_s[8] = key->lfsr_s[9]; - key->lfsr_s[9] = key->lfsr_s[10]; - key->lfsr_s[10] = key->lfsr_s[11]; - key->lfsr_s[11] = key->lfsr_s[12]; - key->lfsr_s[12] = key->lfsr_s[13]; - key->lfsr_s[13] = key->lfsr_s[14]; - key->lfsr_s[14] = key->lfsr_s[15]; - key->lfsr_s[15] = f; -} - -void zuc_bit_reorganization(zuc_key_t *key) -{ - key->brc_x[0] = ((key->lfsr_s[15] & 0x7FFF8000) << 1) | (key->lfsr_s[14] & 0xFFFF); - key->brc_x[1] = ((key->lfsr_s[11] & 0xFFFF) << 16) | (key->lfsr_s[9] >> 15); - key->brc_x[2] = ((key->lfsr_s[7] & 0xFFFF) << 16) | (key->lfsr_s[5] >> 15); - key->brc_x[3] = ((key->lfsr_s[2] & 0xFFFF) << 16) | (key->lfsr_s[0] >> 15); -} - -#define ZUC_BIT_REORG(x,x0,x1,x2,x3) \ - x0 = ((s[15] & 0x7FFF8000) << 1) | (s[14] & 0xFFFF); \ - x1 = ((s[11] & 0xFFFF) << 16) | (s[9] >> 15); \ - x2 = ((s[7] & 0xFFFF) << 16) | (s[5] >> 15); \ - x3 = ((s[2] & 0xFFFF) << 16) | (s[0] >> 15) - -#define ROT32(a, k) (((a) << k) | ((a) >> (32 - k))) - -#define L1(x) \ - ((x) ^ \ - ROT32((x), 2) ^ \ - ROT32((x), 10) ^ \ - ROT32((x), 18) ^ \ - ROT32((x), 24)) - -#define L2(x) \ - ((x) ^ \ - ROT32((x), 8) ^ \ - ROT32((x), 14) ^ \ - ROT32((x), 22) ^ \ - ROT32((x), 30)) - -#define GET32(pc) ( \ - ((uint32_t)(pc)[0] << 24) ^ \ - ((uint32_t)(pc)[1] << 16) ^ \ - ((uint32_t)(pc)[2] << 8) ^ \ - ((uint32_t)(pc)[3])) - -#define PUT32(st, ct) \ - (ct)[0] = (uint8_t)((st) >> 24); \ - (ct)[1] = (uint8_t)((st) >> 16); \ - (ct)[2] = (uint8_t)((st) >> 8); \ +#define MAKEU31(k,d,iv) \ + (((uint32_t)(k) << 23) | \ + ((uint32_t)(d) << 8) | \ + (uint32_t)(iv)) #define MAKEU32(a, b, c, d) \ (((uint32_t)(a) << 24) | \ @@ -228,74 +158,86 @@ void zuc_bit_reorganization(zuc_key_t *key) ((uint32_t)(c) << 8) | \ ((uint32_t)(d))) -#define MAKEU31(a, b, c) \ - (((uint32_t)(a) << 23) | \ - ((uint32_t)(b) << 8) | \ - (uint32_t)(c)) +#define F_(X1,X2) \ + W1 = R1 + X1; \ + W2 = R2 ^ X2; \ + U = L1((W1 << 16) | (W2 >> 16)); \ + V = L2((W2 << 16) | (W1 >> 16)); \ + R1 = MAKEU32( S0[U >> 24], \ + S1[(U >> 16) & 0xFF], \ + S0[(U >> 8) & 0xFF], \ + S1[U & 0xFF]); \ + R2 = MAKEU32( S0[V >> 24], \ + S1[(V >> 16) & 0xFF], \ + S0[(V >> 8) & 0xFF], \ + S1[V & 0xFF]) +#define F(X0,X1,X2) \ + (X0 ^ R1) + R2; \ + F_(X1, X2) -uint32_t F(zuc_key_t *key) +void ZUC_set_key(ZUC_KEY *key, const unsigned char *user_key, const unsigned char *iv) { - uint32_t W, W1, W2, u, v; - - W = (key->brc_x[0] ^ key->f_r[1]) + key->f_r[2]; - W1 = key->f_r[1] + key->brc_x[1]; - W2 = key->f_r[2] ^ key->brc_x[2]; - u = L1((W1 << 16) | (W2 >> 16)); - v = L2((W2 << 16) | (W1 >> 16)); - - key->f_r[1] = MAKEU32( - S0[u >> 24], - S1[(u >> 16) & 0xFF], - S0[(u >> 8) & 0xFF], - S1[u & 0xFF]); - - key->f_r[2] = MAKEU32( - S0[v >> 24], - S1[(v >> 16) & 0xFF], - S0[(v >> 8) & 0xFF], - S1[v & 0xFF]); - - return W; -} - -void zuc_set_key(zuc_key_t *key, const unsigned char *user_key, const unsigned char *iv) -{ - uint32_t w; + ZUC_UINT31 *LFSR = key->LFSR; + uint32_t R1, R2; + uint32_t X0, X1, X2; + uint32_t W, W1, W2, U, V; + int i; for (i = 0; i < 16; i++) { - key->lfsr_s[i] = MAKEU31(user_key[i], EK_d[i], iv[i]); + LFSR[i] = MAKEU31(user_key[i], KD[i], iv[i]); } - - key->f_r[1] = 0; - key->f_r[2] = 0; + R1 = 0; + R2 = 0; for (i = 0; i < 32; i++) { - zuc_bit_reorganization(key); - w = F(key); - zuc_lfsr_init(w >> 1); + BitReconstruction3(X0, X1, X2); + W = F(X0, X1, X2); + LFSRWithInitialisationMode(W >> 1); } + BitReconstruction2(X1, X2); + F_(X1, X2); + LFSRWithWorkMode(); + + key->R1 = R1; + key->R2 = R2; } -void zuc_generate_keystream(zuc_key_t *key, size_t num, uint32_t *keystream) +uint32_t ZUC_generate_keyword(ZUC_KEY *key) { + ZUC_UINT31 *LFSR = key->LFSR; + uint32_t R1 = key->R1; + uint32_t R2 = key->R2; + uint32_t X0, X1, X2, X3; + uint32_t W1, W2, U, V; + uint32_t Z; + + BitReconstruction4(X0, X1, X2, X3); + Z = X3 ^ F(X0, X1, X2); + LFSRWithWorkMode(); + + key->R1 = R1; + key->R2 = R2; + + return Z; +} + +void ZUC_generate_keystream(ZUC_KEY *key, size_t nwords, uint32_t *keystream) +{ + ZUC_UINT31 *LFSR = key->LFSR; + uint32_t R1 = key->R1; + uint32_t R2 = key->R2; + uint32_t X0, X1, X2, X3; + uint32_t W1, W2, U, V; size_t i; - zuc_bit_reorg(key); - (void)F(key); - zuc_lfsr_work(key); - - for (i = 0; i < num; i ++) { - zuc_bit_reorg(key); - keystream[i] = F(key) ^ key->brc_x[3]; - zuc_lfsr_work(key); + for (i = 0; i < nwords; i ++) { + BitReconstruction4(X0, X1, X2, X3); + keystream[i] = X3 ^ F(X0, X1, X2); + LFSRWithWorkMode(); } -} -void ZUC(const unsigned char *key, const unsigned char *iv, uint32_t *keystream, int num) -{ - zuc_key_t zuc; - zuc_key_init(&zuc, key, iv); - zuc_generate_keystream(&zuc, keystream, num); + key->R1 = R1; + key->R2 = R2; } diff --git a/crypto/zuc/zuc_spec.c b/crypto/zuc/zuc_spec.c index ceb2d17c..85e37a5c 100644 --- a/crypto/zuc/zuc_spec.c +++ b/crypto/zuc/zuc_spec.c @@ -1,5 +1,5 @@ /* ==================================================================== - * Copyright (c) 2015 - 2016 The GmSSL Project. All rights reserved. + * Copyright (c) 2015 - 2018 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 @@ -404,16 +404,3 @@ void EIA3(u8* IK, u32 COUNT, u32 DIRECTION, u32 BEARER, u32 LENGTH, u32* M, u32* *MAC = T ^ z[L-1]; free(z); } - -int main(int argc, char **argv) -{ - unsigned char key[16] = {0}; - unsigned char iv[16] = {0}; - u32 z[3]; - - Initialization(key, iv); - GenerateKeystream(z, 3); - printf("%08x, %08x, %08x\n", z[0], z[1], z[2]); - - return 0; -} diff --git a/include/openssl/evp.h b/include/openssl/evp.h index b7855589..73e75fde 100644 --- a/include/openssl/evp.h +++ b/include/openssl/evp.h @@ -1,5 +1,5 @@ /* ==================================================================== - * Copyright (c) 2014 - 2017 The GmSSL Project. All rights reserved. + * Copyright (c) 2014 - 2018 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 @@ -920,6 +920,10 @@ const EVP_CIPHER *EVP_sms4_wrap_pad(void); # define EVP_sm4_ofb EVP_sms4_ofb # endif +# ifndef OPENSSL_NO_ZUC +const EVP_CIPHER *EVP_zuc(void); +# endif + # if OPENSSL_API_COMPAT < 0x10100000L # define OPENSSL_add_all_algorithms_conf() \ OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS \ diff --git a/include/openssl/zuc.h b/include/openssl/zuc.h index 8bd0478e..ba2ed935 100755 --- a/include/openssl/zuc.h +++ b/include/openssl/zuc.h @@ -1,5 +1,5 @@ /* ==================================================================== - * Copyright (c) 2015 - 2016 The GmSSL Project. All rights reserved. + * Copyright (c) 2015 - 2018 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 @@ -51,73 +51,82 @@ #define HEADER_ZUC_H #include -#ifndef OPENSSL_NO_ZUC +# ifndef OPENSSL_NO_ZUC -#include -#include +# include +# include -#ifdef __cplusplus +# define ZUC_IV_LENGTH 16 +# define ZUC_KEY_LENGTH 16 + +typedef uint32_t ZUC_UINT1; +typedef uint32_t ZUC_UINT5; +typedef uint32_t ZUC_UINT15; +typedef uint32_t ZUC_UINT31; +typedef uint32_t ZUC_UINT32; + +# ifdef __cplusplus extern "C" { -#endif +# endif -typedef struct { - uint32_t state[22]; -} zuc_key_t; +/* ZUC stream cipher */ -void zuc_set_key(zuc_key_t *key, const unsigned char *user_key, const unsigned char *iv); -void zuc_generate_keystream(zuc_key_t *key, size_t nwords, uint32_t *words); +typedef struct zuc_key_st { + ZUC_UINT31 LFSR[16]; + uint32_t R1; + uint32_t R2; +} ZUC_KEY; -typedef struct { - zuc_key_t key; - unsigned char buf[4]; - size_t buflen; -} zuc_ctx_t; +void ZUC_set_key(ZUC_KEY *key, const unsigned char *user_key, const unsigned char *iv); +void ZUC_generate_keystream(ZUC_KEY *key, size_t nwords, uint32_t *words); +uint32_t ZUC_generate_keyword(ZUC_KEY *key); -void zuc_ctx_init(zuc_ctx_t *ctx, const unsigned char *user_key, const unsigned char *iv); -void zuc_encrypt(zuc_ctx_t *ctx, size_t len, const unsigned char *in, unsigned char *out); -#define zuc_decrypt(ctx,len,in,out) zuc_encrypt(ctx,len,in,out) +# define ZUC_128EEA3_MIN_BITS 1 +# define ZUC_128EEA3_MAX_BITS 65504 +# define ZUC_128EEA3_MIN_BYTES ((ZUC_128EEA3_MIN_BITS + 7)/8) +# define ZUC_128EEA3_MAX_BYTES ((ZUC_128EEA3_MAX_BITS + 7)/8) -#define ZUC_128EEA3_MIN_BITS 1 -#define ZUC_128EEA3_MAX_BITS 65504 -#define ZUC_128EEA3_MIN_BYTES ((ZUC_128EEA3_MIN_BITS + 7)/8) -#define ZUC_128EEA3_MAX_BYTES ((ZUC_128EEA3_MAX_BITS + 7)/8) +/* ZUC 128-EEA3 */ -typedef struct { - zuc_ctx_t zuc; - size_t length; - /* maybe buffer */ -} eea3_ctx_t; +typedef struct zuc_128eea3_st { + ZUC_KEY ks; +} ZUC_128EEA3; -void zuc_128eea3_init(zuc_128eea3_t *eea3, const unsigned char *user_key, - uint32_t count, uint32_t bearer, int direction); -void zuc_128eea3_encrypt(zuc_128eea3_t *ctx, size_t len, +void ZUC_128eea3_set_key(ZUC_128EEA3 *ctx, const unsigned char user_key[16], + ZUC_UINT32 count, ZUC_UINT5 bearer, ZUC_UINT1 direction); +void ZUC_128eea3_encrypt(ZUC_128EEA3 *ctx, size_t len, const unsigned char *in, unsigned char *out); -#define eea3_decrypt(ctx,len,in,out) eea3_encrypt(ctx,len,in,out) -void eea3(const unsigned char *key, uint32_t count, uint32_t bearer, - int direction, size_t len, const unsigned char *in, unsigned char *out); +# define ZUC_128eea3_decrypt(ctx,len,in,out) \ + ZUC_128eea3_encrypt(ctx,len,in,out) +void ZUC_128eea3(const unsigned char key[ZUC_KEY_LENGTH], + ZUC_UINT32 count, ZUC_UINT5 bearer, ZUC_UINT1 direction, + size_t len, const unsigned char *in, unsigned char *out); -#define ZUC_128EIA3_MIN_BYTES EEA3_MIN_BYTES -#define ZUC_128EIA3_MAX_BYTES EEA3_MAX_BYTES -#define ZUC_128EIA3_MAC_SIZE 4 +/* ZUC 128-EIA3 */ -typedef struct { - zuc_ctx_t zuc; - size_t length; - /* maybe buffer */ -} eia3_ctx_t; +# define ZUC_128EIA3_MIN_BYTES EEA3_MIN_BYTES +# define ZUC_128EIA3_MAX_BYTES EEA3_MAX_BYTES +# define ZUC_128EIA3_MAC_SIZE 4 -void zuc_128eia3_init(zuc_128eia3_t *eia3, const unsigned char *user_key, - uint32_t count, uint32_t bearer, int direction); -void zuc_128eia3_update(zuc_128eia3_t *eia3, const unsigned char *data, +typedef struct zuc_128eia3_st { + ZUC_KEY ks; + unsigned char buf[4]; + size_t num; +} ZUC_128EIA3; + +void ZUC_128eia3_set_key(ZUC_128EIA3 *ctx, const unsigned char *user_key, + ZUC_UINT32 count, ZUC_UINT5 bearer, ZUC_UINT1 direction); +void ZUC_128eia3_update(ZUC_128EIA3 *ctx, const unsigned char *data, size_t datalen); -void zuc_128eia3_final(zuc_128eia3_t *eia3, uint32_t *mac); -void zuc_128eia3(const unsigned char *key, uint32_t count, uint32_t bearer, - int direction, const unsigned char *data, size_t len, uint32_t *mac); +void ZUC_128eia3_final(ZUC_128EIA3 *ctx, uint32_t *mac); +void ZUC_128eia3(const unsigned char key[ZUC_KEY_LENGTH], + ZUC_UINT32 count, ZUC_UINT5 bearer, ZUC_UINT1 direction, + const unsigned char *data, size_t dlen, uint32_t *mac); -#ifdef __cplusplus +# ifdef __cplusplus } -#endif -#endif +# endif +# endif #endif diff --git a/test/zuctest.c b/test/zuctest.c index 958ebca2..b376c280 100644 --- a/test/zuctest.c +++ b/test/zuctest.c @@ -1,5 +1,5 @@ /* ==================================================================== - * Copyright (c) 2014 - 2016 The GmSSL Project. All rights reserved. + * Copyright (c) 2014 - 2018 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 @@ -62,6 +62,20 @@ int main(int argc, char **argv) # include # include +/* +static int zuc_128eea3_test1(void) +{ + unsigned char ck[] = { + 0x17,0x3d,0x14,0xba,0x50,0x03,0x73,0x1d,0x7a,0x60,0x04,0x94,0x70,0xf0,0x0a,0x29, + }; + uint32_t count = 0x66035492; + uint8_t bearer = 0x0f; + uint8_t direction = 0; + uint32_t length = c1; + unsigned char ibs[] = { + 0x6cf65340, 735552ab, +} + static int zuc_eia3_test1(void) { unsigned char key[16] = {0}; @@ -103,24 +117,43 @@ static int zuc_eia3_test2(int verbose) return 1; } +*/ int main(int argc, char **argv) { int err = 0; + int i; - unsigned char key[][] = { + unsigned char key[][16] = { {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}, {0x3d,0x4c,0x4b,0xe9,0x6a,0x82,0xfd,0xae,0xb5,0x8f,0x64,0x1d,0xb1,0x7b,0x45,0x5b}, }; - unsigned char iv[][] = { + unsigned char iv[][16] = { {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}, {0x84,0x31,0x9a,0xa8,0xde,0x69,0x15,0xca,0x1f,0x6b,0xda,0x6b,0xfb,0xd8,0xc7,0x66}, }; - uint32_t z0[] = {0x286dafe5,0x668b56df,0x3ead461d}; - uint32_t z1[] = {0x27bedc74,0x0657cfa0,0x14f1c272}; - uint32_t z2[] = {0x018082da,0x7096398b,0x3279c419}; + uint32_t ciphertext[][2] = { + {0x27bede74, 0x018082da}, + {0x0657cfa0, 0x7096398b}, + {0x14f1c272, 0x3279c419}, + }; + + for (i = 0; i < 3; i++) { + ZUC_KEY zuc = {{0}}; + uint32_t buf[3] = {0}; + ZUC_set_key(&zuc, key[i], iv[i]); + ZUC_generate_keystream(&zuc, 2, buf); + printf("%08x %08x\n", buf[0], buf[1]); + printf("%08x %08x\n", ciphertext[i][0], ciphertext[i][1]); + if (buf[0] != ciphertext[i][0] || buf[1] != ciphertext[i][1]) { + fprintf(stderr, "error generating ZUC key stream on test vector %d\n", i); + err++; + } else { + fprintf(stderr, "ZUC test vector %d success\n", i); + } + } return err; }