mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-09-24 22:33:45 +08:00
tls 1.3 init
This commit is contained in:
@@ -47,13 +47,12 @@
|
||||
*/
|
||||
|
||||
|
||||
#ifndef NO_AES
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <gmssl/aes.h>
|
||||
#include "bswap.h"
|
||||
#include "rotate.h"
|
||||
#include "endian.h"
|
||||
#include "mem.h"
|
||||
|
||||
|
||||
static const uint8_t S[256] = {
|
||||
@@ -479,4 +478,3 @@ void aes_decrypt(const AES_KEY *aes_key, const uint8_t in[16], uint8_t out[16])
|
||||
|
||||
memset(state, 0, sizeof(state));
|
||||
}
|
||||
#endif
|
||||
239
src/aes_modes.c
Normal file
239
src/aes_modes.c
Normal file
@@ -0,0 +1,239 @@
|
||||
/*
|
||||
* Copyright (c) 2014 - 2020 The GmSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project.
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* 4. The name "GmSSL Project" must not be used to endorse or promote
|
||||
* products derived from this software without prior written
|
||||
* permission. For written permission, please contact
|
||||
* guanzhi1980@gmail.com.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "GmSSL"
|
||||
* nor may "GmSSL" appear in their names without prior written
|
||||
* permission of the GmSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <gmssl/aes.h>
|
||||
#include <gmssl/gcm.h>
|
||||
#include <gmssl/error.h>
|
||||
#include "mem.h"
|
||||
|
||||
|
||||
void aes_cbc_encrypt(const AES_KEY *key, const uint8_t iv[16],
|
||||
const uint8_t *in, size_t nblocks, uint8_t *out)
|
||||
{
|
||||
while (nblocks--) {
|
||||
gmssl_memxor(out, in, iv, 16);
|
||||
aes_encrypt(key, out, out);
|
||||
iv = out;
|
||||
in += 16;
|
||||
out += 16;
|
||||
}
|
||||
}
|
||||
|
||||
void aes_cbc_decrypt(const AES_KEY *key, const uint8_t iv[16],
|
||||
const uint8_t *in, size_t nblocks, uint8_t *out)
|
||||
{
|
||||
while (nblocks--) {
|
||||
aes_decrypt(key, in, out);
|
||||
memxor(out, iv, 16);
|
||||
iv = in;
|
||||
in += 16;
|
||||
out += 16;
|
||||
}
|
||||
}
|
||||
|
||||
int aes_cbc_padding_encrypt(const AES_KEY *key, const uint8_t iv[16],
|
||||
const uint8_t *in, size_t inlen,
|
||||
uint8_t *out, size_t *outlen)
|
||||
{
|
||||
uint8_t block[16];
|
||||
size_t rem = inlen % 16;
|
||||
int padding = 16 - rem;
|
||||
|
||||
if (in) {
|
||||
memcpy(block, in + inlen - rem, rem);
|
||||
}
|
||||
memset(block + rem, padding, padding);
|
||||
if (inlen/16) {
|
||||
aes_cbc_encrypt(key, iv, in, inlen/16, out);
|
||||
out += inlen - rem;
|
||||
iv = out - 16;
|
||||
}
|
||||
aes_cbc_encrypt(key, iv, block, 1, out);
|
||||
*outlen = inlen - rem + 16;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int aes_cbc_padding_decrypt(const AES_KEY *key, const uint8_t iv[16],
|
||||
const uint8_t *in, size_t inlen,
|
||||
uint8_t *out, size_t *outlen)
|
||||
{
|
||||
uint8_t block[16];
|
||||
int padding;
|
||||
|
||||
if (inlen == 0) {
|
||||
error_print("warning: input lenght = 0");
|
||||
return 0;
|
||||
}
|
||||
if (inlen%16 != 0 || inlen < 16) {
|
||||
error_print("invalid cbc ciphertext length");
|
||||
return -1;
|
||||
}
|
||||
if (inlen > 16) {
|
||||
aes_cbc_decrypt(key, iv, in, inlen/16 - 1, out);
|
||||
iv = in + inlen - 32;
|
||||
}
|
||||
aes_cbc_decrypt(key, iv, in + inlen - 16, 1, block);
|
||||
padding = block[15];
|
||||
if (padding < 1 || padding > 16) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
memcpy(out + inlen - 16, block, 16 - padding);
|
||||
*outlen = inlen - padding;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void ctr_incr(uint8_t a[16])
|
||||
{
|
||||
int i;
|
||||
for (i = 15; i > 0; i--) {
|
||||
a[i]++;
|
||||
if (a[i]) break;
|
||||
}
|
||||
}
|
||||
|
||||
void aes_ctr_encrypt(const AES_KEY *key, uint8_t ctr[16], const uint8_t *in, size_t inlen, uint8_t *out)
|
||||
{
|
||||
uint8_t block[16];
|
||||
size_t len;
|
||||
|
||||
while (inlen) {
|
||||
len = inlen < 16 ? inlen : 16;
|
||||
aes_encrypt(key, ctr, block);
|
||||
gmssl_memxor(out, in, block, len);
|
||||
ctr_incr(ctr);
|
||||
in += len;
|
||||
out += len;
|
||||
inlen -= len;
|
||||
}
|
||||
}
|
||||
|
||||
int aes_gcm_encrypt(const AES_KEY *key, const uint8_t *iv, size_t ivlen,
|
||||
const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen,
|
||||
uint8_t *out, const size_t taglen, uint8_t *tag)
|
||||
{
|
||||
const uint8_t *pin = in;
|
||||
uint8_t *pout = out;
|
||||
size_t left = inlen;
|
||||
uint8_t H[16] = {0};
|
||||
uint8_t Y[16];
|
||||
uint8_t T[16];
|
||||
|
||||
aes_encrypt(key, H, H);
|
||||
|
||||
if (ivlen == 12) {
|
||||
memcpy(Y, iv, 12);
|
||||
Y[12] = Y[13] = Y[14] = 0;
|
||||
Y[15] = 1;
|
||||
} else {
|
||||
ghash(H, NULL, 0, iv, ivlen, Y);
|
||||
}
|
||||
|
||||
aes_encrypt(key, Y, T);
|
||||
|
||||
while (left) {
|
||||
uint8_t block[16];
|
||||
size_t len = left < 16 ? left : 16;
|
||||
ctr_incr(Y);
|
||||
aes_encrypt(key, Y, block);
|
||||
gmssl_memxor(pout, pin, block, len);
|
||||
pin += len;
|
||||
pout += len;
|
||||
left -= len;
|
||||
}
|
||||
|
||||
ghash(H, aad, aadlen, out, inlen, H);
|
||||
gmssl_memxor(tag, T, H, taglen);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int aes_gcm_decrypt(const AES_KEY *key, const uint8_t *iv, size_t ivlen,
|
||||
const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen,
|
||||
const uint8_t *tag, size_t taglen, uint8_t *out)
|
||||
{
|
||||
const uint8_t *pin = in;
|
||||
uint8_t *pout = out;
|
||||
size_t left = inlen;
|
||||
uint8_t H[16] = {0};
|
||||
uint8_t Y[16];
|
||||
uint8_t T[16];
|
||||
|
||||
aes_encrypt(key, H, H);
|
||||
|
||||
if (ivlen == 12) {
|
||||
memcpy(Y, iv, 12);
|
||||
Y[12] = Y[13] = Y[14] = 0;
|
||||
Y[15] = 1;
|
||||
} else {
|
||||
ghash(H, NULL, 0, iv, ivlen, Y);
|
||||
}
|
||||
|
||||
ghash(H, aad, aadlen, in, inlen, H);
|
||||
aes_encrypt(key, Y, T);
|
||||
gmssl_memxor(T, T, H, taglen);
|
||||
if (memcmp(T, tag, taglen) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (left) {
|
||||
uint8_t block[16];
|
||||
size_t len = left < 16 ? left : 16;
|
||||
ctr_incr(Y);
|
||||
aes_encrypt(key, Y, block);
|
||||
gmssl_memxor(pout, pin, block, len);
|
||||
pin += len;
|
||||
pout += len;
|
||||
left -= len;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -52,152 +52,68 @@
|
||||
#include <stdlib.h>
|
||||
#include <gmssl/oid.h>
|
||||
#include <gmssl/block_cipher.h>
|
||||
#include "internal/endian.h"
|
||||
#include "endian.h"
|
||||
|
||||
|
||||
int block_cipher_encrypt_init(BLOCK_CIPHER_KEY *key, const BLOCK_CIPHER *cipher,
|
||||
const uint8_t *user_key, size_t keylen)
|
||||
|
||||
int block_cipher_set_encrypt_key(BLOCK_CIPHER_KEY *key, const BLOCK_CIPHER *cipher, const uint8_t *raw_key)
|
||||
{
|
||||
memset(key, 0, sizeof(BLOCK_CIPHER_KEY));
|
||||
cipher->set_encrypt_key(key, raw_key);
|
||||
key->cipher = cipher;
|
||||
return key->cipher->set_encrypt_key(key, user_key, keylen);
|
||||
}
|
||||
|
||||
int block_cipher_decrypt_init(BLOCK_CIPHER_KEY *key, const BLOCK_CIPHER *cipher,
|
||||
const uint8_t *user_key, size_t keylen)
|
||||
{
|
||||
memset(key, 0, sizeof(BLOCK_CIPHER_KEY));
|
||||
key->cipher = cipher;
|
||||
return key->cipher->set_decrypt_key(key, user_key, keylen);
|
||||
}
|
||||
|
||||
void block_cipher_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *in, uint8_t *out)
|
||||
{
|
||||
key->cipher->encrypt(key, in, out);
|
||||
}
|
||||
|
||||
void block_cipher_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *in, uint8_t *out)
|
||||
{
|
||||
key->cipher->decrypt(key, in, out);
|
||||
}
|
||||
|
||||
void block_cipher_ecb_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *in, size_t nblocks, uint8_t *out)
|
||||
{
|
||||
while (nblocks--) {
|
||||
key->cipher->encrypt(key, in, out);
|
||||
in += key->cipher->block_size;
|
||||
out += key->cipher->block_size;
|
||||
}
|
||||
}
|
||||
|
||||
void block_cipher_ecb_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *in, size_t nblocks, uint8_t *out)
|
||||
{
|
||||
while (nblocks--) {
|
||||
key->cipher->decrypt(key, in, out);
|
||||
in += key->cipher->block_size;
|
||||
out += key->cipher->block_size;
|
||||
}
|
||||
}
|
||||
|
||||
void block_cipher_cbc_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *iv,
|
||||
const uint8_t *in, size_t nblocks, uint8_t *out)
|
||||
{
|
||||
while (nblocks--) {
|
||||
gmssl_memxor(out, in, iv, key->cipher->block_size);
|
||||
key->cipher->encrypt(key, out, out);
|
||||
iv = out;
|
||||
in += key->cipher->block_size;
|
||||
out += key->cipher->block_size;
|
||||
}
|
||||
}
|
||||
|
||||
void block_cipher_cbc_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *iv,
|
||||
const uint8_t *in, size_t nblocks, uint8_t *out)
|
||||
{
|
||||
while (nblocks--) {
|
||||
key->cipher->decrypt(key, in, out);
|
||||
gmssl_memxor(out, out, iv, key->cipher->block_size);
|
||||
iv = in;
|
||||
in += key->cipher->block_size;
|
||||
out += key->cipher->block_size;
|
||||
}
|
||||
}
|
||||
|
||||
void block_cipher_ctr_encrypt(const BLOCK_CIPHER_KEY *key, uint8_t *counter,
|
||||
const uint8_t *in, size_t nblocks, uint8_t *out)
|
||||
{
|
||||
size_t block_size = key->cipher->block_size;
|
||||
uint8_t block[block_size];
|
||||
uint64_t ctr = GETU64(counter + block_size - sizeof(uint64_t));
|
||||
|
||||
while (nblocks--) {
|
||||
key->cipher->encrypt(key, counter, block);
|
||||
gmssl_memxor(out, in, block, block_size);
|
||||
in += block_size;
|
||||
out += block_size;
|
||||
ctr++;
|
||||
PUTU64(counter + block_size - sizeof(uint64_t), ctr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const BLOCK_CIPHER aes_block_cipher_object = {
|
||||
OID_aes,
|
||||
AES128_KEY_SIZE,
|
||||
AES256_KEY_SIZE,
|
||||
AES_BLOCK_SIZE,
|
||||
(block_cipher_set_encrypt_key_func)aes_set_encrypt_key,
|
||||
(block_cipher_set_decrypt_key_func)aes_set_decrypt_key,
|
||||
(block_cipher_encrypt_func)aes_encrypt,
|
||||
(block_cipher_decrypt_func)aes_encrypt,
|
||||
};
|
||||
|
||||
const BLOCK_CIPHER *BLOCK_CIPHER_aes(void)
|
||||
{
|
||||
return &aes_block_cipher_object;
|
||||
}
|
||||
|
||||
|
||||
static int set_encrypt_key(BLOCK_CIPHER_KEY *key, const uint8_t *user_key, size_t keylen)
|
||||
{
|
||||
if (keylen != SM4_KEY_SIZE) {
|
||||
return -1;
|
||||
}
|
||||
sm4_set_encrypt_key(&key->u.sm4_key, user_key);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int set_decrypt_key(BLOCK_CIPHER_KEY *key, const uint8_t *user_key, size_t keylen)
|
||||
int block_cipher_set_decrypt_key(BLOCK_CIPHER_KEY *key, const BLOCK_CIPHER *cipher, const uint8_t *raw_key)
|
||||
{
|
||||
if (keylen != SM4_KEY_SIZE) {
|
||||
return -1;
|
||||
}
|
||||
sm4_set_decrypt_key(&key->u.sm4_key, user_key);
|
||||
memset(key, 0, sizeof(BLOCK_CIPHER_KEY));
|
||||
cipher->set_decrypt_key(key, raw_key);
|
||||
key->cipher = cipher;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int block_cipher_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *in, uint8_t *out)
|
||||
{
|
||||
key->cipher->encrypt(key, in, out);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int block_cipher_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *in, uint8_t *out)
|
||||
{
|
||||
key->cipher->decrypt(key, in, out);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const BLOCK_CIPHER sm4_block_cipher_object = {
|
||||
OID_sm4,
|
||||
SM4_KEY_SIZE,
|
||||
SM4_KEY_SIZE,
|
||||
SM4_BLOCK_SIZE,
|
||||
set_encrypt_key,
|
||||
set_decrypt_key,
|
||||
(block_cipher_set_encrypt_key_func)sm4_set_encrypt_key,
|
||||
(block_cipher_set_decrypt_key_func)sm4_set_decrypt_key,
|
||||
(block_cipher_encrypt_func)sm4_encrypt,
|
||||
(block_cipher_decrypt_func)sm4_encrypt,
|
||||
};
|
||||
|
||||
const BLOCK_CIPHER *BLOCK_CIPHER_sm4(void)
|
||||
{
|
||||
const BLOCK_CIPHER *BLOCK_CIPHER_sm4(void) {
|
||||
return &sm4_block_cipher_object;
|
||||
}
|
||||
|
||||
const BLOKC_CIPHER *block_cipher_from_name(const char *name)
|
||||
{
|
||||
if (strcmp(name, "aes") == 0) {
|
||||
return BLOCK_CIPHER_aes();
|
||||
} else if (strcmp(name, "sm4") == 0) {
|
||||
return BLOCK_CIPHER_sm4();
|
||||
}
|
||||
return NULL;
|
||||
static int aes128_set_encrypt_key(AES_KEY *aes_key, const uint8_t key[16]) {
|
||||
return aes_set_encrypt_key(aes_key, key, 16);
|
||||
}
|
||||
|
||||
static int aes128_set_decrypt_key(AES_KEY *aes_key, const uint8_t key[16]) {
|
||||
return aes_set_decrypt_key(aes_key, key, 16);
|
||||
}
|
||||
|
||||
static const BLOCK_CIPHER aes128_block_cipher_object = {
|
||||
AES128_KEY_SIZE,
|
||||
AES_BLOCK_SIZE,
|
||||
(block_cipher_set_encrypt_key_func)aes128_set_encrypt_key,
|
||||
(block_cipher_set_decrypt_key_func)aes128_set_decrypt_key,
|
||||
(block_cipher_encrypt_func)aes_encrypt,
|
||||
(block_cipher_decrypt_func)aes_encrypt,
|
||||
};
|
||||
|
||||
const BLOCK_CIPHER *BLOCK_CIPHER_aes128(void) {
|
||||
return &aes128_block_cipher_object;
|
||||
}
|
||||
|
||||
56
src/bswap.h
56
src/bswap.h
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
#ifndef GMSSL_MODES_LCL_H
|
||||
#define GMSSL_MODES_LCL_H
|
||||
|
||||
|
||||
# if defined(__GNUC__) && __GNUC__>=2
|
||||
# if defined(__x86_64) || defined(__x86_64__)
|
||||
# define BSWAP8(x) ({ uint64_t ret_=(x); \
|
||||
asm ("bswapq %0" \
|
||||
: "+r"(ret_)); ret_; })
|
||||
# define BSWAP4(x) ({ uint32_t ret_=(x); \
|
||||
asm ("bswapl %0" \
|
||||
: "+r"(ret_)); ret_; })
|
||||
# elif defined(__aarch64__)
|
||||
# define BSWAP8(x) ({ uint64_t ret_; \
|
||||
asm ("rev %0,%1" \
|
||||
: "=r"(ret_) : "r"(x)); ret_; })
|
||||
# define BSWAP4(x) ({ uint32_t ret_; \
|
||||
asm ("rev %w0,%w1" \
|
||||
: "=r"(ret_) : "r"(x)); ret_; })
|
||||
# endif
|
||||
# elif defined(_MSC_VER)
|
||||
# if _MSC_VER>=1300
|
||||
# pragma intrinsic(_byteswap_uint64,_byteswap_ulong)
|
||||
# define BSWAP8(x) _byteswap_uint64((uint64_t)(x))
|
||||
# define BSWAP4(x) _byteswap_ulong((uint32_t)(x))
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(BSWAP4) && !defined(STRICT_ALIGNMENT)
|
||||
# define GETU32(p) BSWAP4(*(const uint32_t *)(p))
|
||||
# define PUTU32(p,v) *(uint32_t *)(p) = BSWAP4(v)
|
||||
# define GETU64(p) BSWAP8(*(const uint64_t *)(p))
|
||||
# define PUTU64(p,v) *(uint64_t *)(p) = BSWAP8(v)
|
||||
#else
|
||||
# define GETU32(p) ((uint32_t)(p)[0]<<24|(uint32_t)(p)[1]<<16|(uint32_t)(p)[2]<<8|(uint32_t)(p)[3])
|
||||
# define PUTU32(p,v) ((p)[0]=(u8)((v)>>24),(p)[1]=(u8)((v)>>16),(p)[2]=(u8)((v)>>8),(p)[3]=(u8)(v))
|
||||
# define GETU64(p) ((uint64_t)(p)[0]<<56|(uint64_t)(p)[1]<<48|(uint64_t)(p)[2]<<40|(uint64_t)(p)[3]<<32| \
|
||||
(uint64_t)(p)[4]<<24|(uint64_t)(p)[5]<<16|(uint64_t)(p)[6]<<8|(uint64_t)(p)[7])
|
||||
# define PUTU64(p,v) ((p)[0]=(u8)((v)>>56),(p)[1]=(u8)((v)>>48),(p)[2]=(u8)((v)>>40),(p)[3]=(u8)((v)>>32),\
|
||||
(p)[4]=(u8)((v)>>24),(p)[5]=(u8)((v)>>16),(p)[6]=(u8)((v)>>8),(p)[7]=(u8)(v)
|
||||
#endif
|
||||
|
||||
#define GETU32_LE(p) (*(const uint32_t *)(p))
|
||||
#define PUTU32_LE(p,a) *(uint32_t *)(p) = (a)
|
||||
#define PUTU64_LE(p,a) *(uint64_t *)(p) = (a)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -46,14 +46,12 @@
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef NO_CHACHA20
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <gmssl/chacha20.h>
|
||||
#include "bswap.h"
|
||||
#include "rotate.h"
|
||||
#include "endian.h"
|
||||
|
||||
void chacha20_set_key(CHACHA20_STATE *state,
|
||||
const unsigned char key[CHACHA20_KEY_SIZE],
|
||||
@@ -122,4 +120,3 @@ void chacha20_generate_keystream(CHACHA20_STATE *state, unsigned int counts, uns
|
||||
state->d[12]++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
134
src/cmac.c
134
src/cmac.c
@@ -1,134 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014 - 2020 The GmSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project.
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* 4. The name "GmSSL Project" must not be used to endorse or promote
|
||||
* products derived from this software without prior written
|
||||
* permission. For written permission, please contact
|
||||
* guanzhi1980@gmail.com.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "GmSSL"
|
||||
* nor may "GmSSL" appear in their names without prior written
|
||||
* permission of the GmSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <gmssl/cmac.h>
|
||||
#include "internal/gf128.h"
|
||||
|
||||
/*
|
||||
CMAC的主体是CBC-MAC,或者说是CBC模式
|
||||
CMAC初始化的时候需要初始化E_K()中分组密码中的密钥编排
|
||||
用GSK算法通过密钥K生成K1, K2,这两个密钥最后是用来和最后一个分组做异或的
|
||||
*/
|
||||
|
||||
int cmac_init(CMAC_CTX *ctx, const BLOCK_CIPHER *cipher, const uint8_t *key, size_t keylen)
|
||||
{
|
||||
gf128_t L;
|
||||
|
||||
ctx->cipher = cipher;
|
||||
cipher->set_encrypt_key(&ctx->cipher_key, key, keylen);
|
||||
|
||||
/* L = E_K(0^128) */
|
||||
memset(ctx->temp_block, 0, 16);
|
||||
cipher->encrypt(&ctx->cipher_key, ctx->temp_block, ctx->temp_block);
|
||||
L = gf128_from_bytes(ctx->temp_block);
|
||||
|
||||
|
||||
/* K1 = L * 2 over GF(2^128) */
|
||||
L = gf128_mul2(L);
|
||||
gf128_to_bytes(L, ctx->k1);
|
||||
|
||||
|
||||
/* K2 = K1 * 2 over GF(2^128) */
|
||||
L = gf128_mul2(L);
|
||||
gf128_to_bytes(L, ctx->k2);
|
||||
|
||||
memset(&L, 0, sizeof(gf128_t));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cmac_update(CMAC_CTX *ctx, const uint8_t *in, size_t inlen)
|
||||
{
|
||||
if (ctx->last_block_nbytes) {
|
||||
unsigned int left = BLOCK_CIPHER_BLOCK_SIZE - ctx->num;
|
||||
if (inlen < left) {
|
||||
memcpy(ctx->block + ctx->last_block_nbytes, in, inlen);
|
||||
ctx->last_block_nbytes += inlen;
|
||||
return 1;
|
||||
} else {
|
||||
memcpy(ctx->block + ctx->last_block_nbytes, in, inlen);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
while (inlen > 16) {
|
||||
XOR128(block, in);
|
||||
ctx->cipher->encrypt(ctx->cipher_key, block, block);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 在Finish的时候我们不应该清空密钥的内容
|
||||
int cmac_finish(CMAC_CTX *ctx, size_t maclen, uint8_t *mac)
|
||||
{
|
||||
if (ctx->last_block_nbytes == 16) {
|
||||
xor128(ctx->data, ctx->k1);
|
||||
} else {
|
||||
ctx->data[ctx->last_block_nbytes] = 0x01;
|
||||
memset(ctx->data + ctx->last_block_nbytes, 0, 16 - ctx->last_block_nbytes);
|
||||
xor128(ctx->data, ctx->k2);
|
||||
}
|
||||
xor128(cipher, data);
|
||||
|
||||
ctx->cipher->encrypt(ctx->cipher_key, ctx->block, ctx->block);
|
||||
memcpy(out, block, outlen);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cmac_finish_and_verify(CMAC_CTX *ctx, const uint8_t *mac, size_t maclen)
|
||||
{
|
||||
uint8_t buf[16];
|
||||
cmac_finish(ctx, maclen, buf);
|
||||
if (memcmp(buf, mac, maclen) != 0) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
92
src/cms.c
92
src/cms.c
@@ -78,7 +78,6 @@ int cms_public_key_from_certificate(const SM2_KEY **sm2_key,
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int cms_issuer_and_serial_number_to_der(const X509_NAME *issuer,
|
||||
const uint8_t *serial_number, size_t serial_number_len,
|
||||
uint8_t **out, size_t *outlen)
|
||||
@@ -148,12 +147,6 @@ bad:
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static const uint32_t SM2_cms_oid[] = {1,2,156,10197,6,1,4,2};
|
||||
|
||||
const char *cms_content_type_name(int type)
|
||||
@@ -972,8 +965,10 @@ int sm2_recipient_info_decrypt_from_der(const SM2_KEY *sm2_key,
|
||||
sm2_decrypt(sm2_key, enced_key, enced_key_len, key, keylen);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
int cms_enced_content_info_to_der(int enc_algor, const uint8_t enc_iv[16],
|
||||
|
||||
int cms_enced_content_info_to_der(int enc_algor, const uint8_t *enc_iv, size_t enc_iv_len,
|
||||
int content_type, const uint8_t *enced_content, size_t enced_content_len,
|
||||
const uint8_t *shared_info1, size_t shared_info1_len,
|
||||
const uint8_t *shared_info2, size_t shared_info2_len,
|
||||
@@ -982,7 +977,7 @@ int cms_enced_content_info_to_der(int enc_algor, const uint8_t enc_iv[16],
|
||||
size_t len = 0;
|
||||
|
||||
if (cms_content_type_to_der(content_type, NULL, &len) != 1
|
||||
|| x509_encryption_algor_to_der(enc_algor, enc_iv, NULL, &len) != 1
|
||||
|| x509_encryption_algor_to_der(enc_algor, enc_iv, enc_iv_len, NULL, &len) != 1
|
||||
|| asn1_implicit_octet_string_to_der(0, enced_content, enced_content_len, NULL, &len) < 0
|
||||
|| asn1_implicit_octet_string_to_der(1, shared_info1, shared_info1_len, NULL, &len) < 0
|
||||
|| asn1_implicit_octet_string_to_der(2, shared_info2, shared_info2_len, NULL, &len) < 0) {
|
||||
@@ -991,7 +986,7 @@ int cms_enced_content_info_to_der(int enc_algor, const uint8_t enc_iv[16],
|
||||
}
|
||||
if (asn1_sequence_header_to_der(len, out, outlen) != 1
|
||||
|| cms_content_type_to_der(content_type, out, outlen) != 1
|
||||
|| x509_encryption_algor_to_der(enc_algor, enc_iv, out, outlen) != 1
|
||||
|| x509_encryption_algor_to_der(enc_algor, enc_iv, enc_iv_len, out, outlen) != 1
|
||||
|| asn1_implicit_octet_string_to_der(0, enced_content, enced_content_len, out, outlen) < 0
|
||||
|| asn1_implicit_octet_string_to_der(1, shared_info1, shared_info1_len, out, outlen) < 0
|
||||
|| asn1_implicit_octet_string_to_der(2, shared_info2, shared_info2_len, out, outlen) < 0) {
|
||||
@@ -1001,10 +996,8 @@ int cms_enced_content_info_to_der(int enc_algor, const uint8_t enc_iv[16],
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cms_enced_content_info_from_der(
|
||||
int *content_type,
|
||||
int *enc_algor, uint32_t *enc_algor_nodes, size_t *enc_algor_nodes_count,
|
||||
const uint8_t **enc_iv, size_t *enc_iv_len,
|
||||
int cms_enced_content_info_from_der(int *content_type,
|
||||
int *enc_algor, const uint8_t **enc_iv, size_t *enc_iv_len,
|
||||
const uint8_t **enced_content, size_t *enced_content_len,
|
||||
const uint8_t **shared_info1, size_t *shared_info1_len,
|
||||
const uint8_t **shared_info2, size_t *shared_info2_len,
|
||||
@@ -1019,8 +1012,7 @@ int cms_enced_content_info_from_der(
|
||||
return ret;
|
||||
}
|
||||
if (cms_content_type_from_der(content_type, &data, &datalen) != 1
|
||||
|| x509_encryption_algor_from_der(enc_algor, enc_algor_nodes, enc_algor_nodes_count,
|
||||
enc_iv, enc_iv_len, &data, &datalen) != 1
|
||||
|| x509_encryption_algor_from_der(enc_algor, enc_iv, enc_iv_len, &data, &datalen) != 1
|
||||
|| asn1_implicit_octet_string_from_der(0, enced_content, enced_content_len, &data, &datalen) < 0
|
||||
|| asn1_implicit_octet_string_from_der(1, shared_info1, shared_info1_len, &data, &datalen) < 0
|
||||
|| asn1_implicit_octet_string_from_der(1, shared_info2, shared_info2_len, &data, &datalen) < 0
|
||||
@@ -1040,7 +1032,7 @@ int cms_enced_content_info_encrypt_to_der(const SM4_KEY *sm4_key, const uint8_t
|
||||
int content_type, const uint8_t *content, size_t content_len,
|
||||
const uint8_t *shared_info1, size_t shared_info1_len,
|
||||
const uint8_t *shared_info2, size_t shared_info2_len,
|
||||
uint8_t *enced_content_info, size_t *enced_content_info_len)
|
||||
uint8_t **out, size_t *outlen)
|
||||
{
|
||||
uint8_t enced_content[content_len + 256];
|
||||
size_t enced_content_len;
|
||||
@@ -1050,13 +1042,11 @@ int cms_enced_content_info_encrypt_to_der(const SM4_KEY *sm4_key, const uint8_t
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
*enced_content_info_len = 0;
|
||||
if (cms_enced_content_info_to_der(OID_sm4_cbc, iv,
|
||||
if (cms_enced_content_info_to_der(OID_sm4_cbc, iv, 16,
|
||||
content_type, enced_content, enced_content_len,
|
||||
shared_info1, shared_info1_len,
|
||||
shared_info2, shared_info2_len,
|
||||
&enced_content_info, enced_content_info_len) != 1) {
|
||||
out, outlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
@@ -1078,8 +1068,7 @@ int cms_enced_content_info_decrypt_from_der(const SM4_KEY *sm4_key,
|
||||
size_t enced_content_len;
|
||||
|
||||
if (cms_enced_content_info_from_der(content_type,
|
||||
&enc_algor, enc_algor_nodes, &enc_algor_nodes_count,
|
||||
&enc_iv, &enc_iv_len,
|
||||
&enc_algor, &enc_iv, &enc_iv_len,
|
||||
&enced_content, &enced_content_len,
|
||||
shared_info1, shared_info1_len,
|
||||
shared_info2, shared_info2_len,
|
||||
@@ -1096,9 +1085,16 @@ int cms_enced_content_info_decrypt_from_der(const SM4_KEY *sm4_key,
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cms_enveloped_data_to_der()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
|
||||
int cms_enveloped_data_from_der(const uint8_t **rcpt_infos, size_t *rcpt_infos_len,
|
||||
int *content_type,
|
||||
@@ -1272,16 +1268,19 @@ int cms_enveloped_data_decrypt_from_der(const SM2_KEY *sm2_key, const X509_CERTI
|
||||
return -1;
|
||||
}
|
||||
|
||||
int cms_signed_and_enveloped_data_to_der()
|
||||
int cms_signed_and_enveloped_data_to_der(void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int cms_signed_and_enveloped_data_from_der()
|
||||
int cms_signed_and_enveloped_data_from_der(void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int cms_signed_and_enveloped_data_print()
|
||||
int cms_signed_and_enveloped_data_print(void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int cms_signed_and_enveloped_data_sign_encrypt_to_der(
|
||||
@@ -1372,6 +1371,7 @@ int cms_signed_and_enveloped_data_decrypt_verify_from_der()
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -1379,8 +1379,7 @@ int cms_signed_and_enveloped_data_decrypt_verify_from_der()
|
||||
|
||||
|
||||
|
||||
|
||||
int cms_enced_data_to_der(int enc_algor, const uint8_t enc_iv[16],
|
||||
int cms_enced_data_to_der(int enc_algor, const uint8_t *enc_iv, size_t enc_iv_len,
|
||||
int content_type, const uint8_t *enced_content, size_t enced_content_len,
|
||||
const uint8_t *shared_info1, size_t shared_info1_len,
|
||||
const uint8_t *shared_info2, size_t shared_info2_len,
|
||||
@@ -1389,8 +1388,8 @@ int cms_enced_data_to_der(int enc_algor, const uint8_t enc_iv[16],
|
||||
size_t len = 0;
|
||||
|
||||
if (asn1_int_to_der(CMS_version, NULL, &len) != 1
|
||||
|| cms_enced_content_info_to_der(enc_algor, enc_iv,
|
||||
content_type, enced_content, enced_content_len
|
||||
|| cms_enced_content_info_to_der(enc_algor, enc_iv, enc_iv_len,
|
||||
content_type, enced_content, enced_content_len,
|
||||
shared_info1, shared_info1_len,
|
||||
shared_info2, shared_info2_len,
|
||||
NULL, &len) != 1) {
|
||||
@@ -1399,8 +1398,8 @@ int cms_enced_data_to_der(int enc_algor, const uint8_t enc_iv[16],
|
||||
}
|
||||
if (asn1_sequence_header_to_der(len, out, outlen) != 1
|
||||
|| asn1_int_to_der(CMS_version, out, outlen) != 1
|
||||
|| cms_enced_content_info_to_der(enc_algor, enc_iv,
|
||||
content_type, enced_content, enced_content_len
|
||||
|| cms_enced_content_info_to_der(enc_algor, enc_iv, enc_iv_len,
|
||||
content_type, enced_content, enced_content_len,
|
||||
shared_info1, shared_info1_len,
|
||||
shared_info2, shared_info2_len,
|
||||
out, outlen) != 1) {
|
||||
@@ -1410,8 +1409,8 @@ int cms_enced_data_to_der(int enc_algor, const uint8_t enc_iv[16],
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cms_enced_data_from_der(
|
||||
int *content_type,
|
||||
|
||||
int cms_enced_data_from_der(int *content_type,
|
||||
int *enc_algor, uint32_t *enc_algor_nodes, size_t *enc_algor_nodes_count,
|
||||
const uint8_t **enc_iv, size_t *enc_iv_len,
|
||||
const uint8_t **enced_content, size_t *enced_content_len,
|
||||
@@ -1430,8 +1429,7 @@ int cms_enced_data_from_der(
|
||||
}
|
||||
if (asn1_int_from_der(&version, &data, &datalen) != 1
|
||||
|| cms_enced_content_info_from_der(content_type,
|
||||
enc_algor, enc_algor_nodes, enc_algor_nodes_count,
|
||||
enc_iv, enc_iv_len,
|
||||
enc_algor, enc_iv, enc_iv_len,
|
||||
enced_content, enced_content_len,
|
||||
shared_info1, shared_info1_len,
|
||||
shared_info2, shared_info2_len,
|
||||
@@ -1456,7 +1454,7 @@ int cms_encrypted_data_encrypt_to_der(const SM4_KEY *sm4_key, const uint8_t iv[1
|
||||
size_t len = 0;
|
||||
|
||||
if (asn1_int_to_der(CMS_version, NULL, &len) != 1
|
||||
|| cms_encrypted_content_info_to_der(sm4_key, iv,
|
||||
|| cms_enced_content_info_encrypt_to_der(sm4_key, iv,
|
||||
content_type, content, content_len,
|
||||
shared_info1, shared_info1_len,
|
||||
shared_info2, shared_info2_len,
|
||||
@@ -1466,7 +1464,7 @@ int cms_encrypted_data_encrypt_to_der(const SM4_KEY *sm4_key, const uint8_t iv[1
|
||||
}
|
||||
if (asn1_sequence_header_to_der(len, out, outlen) != 1
|
||||
|| asn1_int_to_der(CMS_version, out, outlen) != 1
|
||||
|| cms_encrypted_content_info_to_der(sm4_key, iv,
|
||||
|| cms_enced_content_info_encrypt_to_der(sm4_key, iv,
|
||||
content_type, content, content_len,
|
||||
shared_info1, shared_info1_len,
|
||||
shared_info2, shared_info2_len,
|
||||
@@ -1490,10 +1488,10 @@ int cms_key_agreement_info_to_der(const SM2_KEY *pub_key, const X509_CERTIFICATE
|
||||
return -1;
|
||||
}
|
||||
if (asn1_sequence_header_to_der(len, out, outlen) != 1
|
||||
|| asn1_int_to_der(CMS_version, out, &outlen) != 1
|
||||
|| sm2_public_key_info_to_der(pub_key, out, &outlen) != 1
|
||||
|| x509_certificate_to_der(cert, out, &outlen) != 1
|
||||
|| asn1_octet_string_to_der(user_id, user_id_len, out, &outlen) != 1) {
|
||||
|| asn1_int_to_der(CMS_version, out, outlen) != 1
|
||||
|| sm2_public_key_info_to_der(pub_key, out, outlen) != 1
|
||||
|| x509_certificate_to_der(cert, out, outlen) != 1
|
||||
|| asn1_octet_string_to_der(user_id, user_id_len, out, outlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
@@ -1506,6 +1504,7 @@ int cms_key_agreement_info_from_der(SM2_KEY *pub_key, X509_CERTIFICATE *cert,
|
||||
int ret;
|
||||
const uint8_t *data;
|
||||
size_t datalen;
|
||||
int version;
|
||||
|
||||
if ((ret = asn1_sequence_from_der(&data, &datalen, in, inlen)) != 1) {
|
||||
if (ret < 0) error_print();
|
||||
@@ -1521,6 +1520,3 @@ int cms_key_agreement_info_from_der(SM2_KEY *pub_key, X509_CERTIFICATE *cert,
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
298
src/ctr.c
298
src/ctr.c
@@ -1,298 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014 - 2020 The GmSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project.
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* 4. The name "GmSSL Project" must not be used to endorse or promote
|
||||
* products derived from this software without prior written
|
||||
* permission. For written permission, please contact
|
||||
* guanzhi1980@gmail.com.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "GmSSL"
|
||||
* nor may "GmSSL" appear in their names without prior written
|
||||
* permission of the GmSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
/*
|
||||
* GHASH(H, A, C) = X_{m + n + 1}
|
||||
* A additional authenticated data, A = A_1, ..., A_{m-1}, A_m^*, nbits(A_m^*) = v
|
||||
* C ciphertext, C = C_1, ..., C_{n-1}, C_n^*, nbits(C_n^*) = u
|
||||
* H = E_K(0^128)
|
||||
*
|
||||
* X_i = 0 for i = 0
|
||||
* = (X_{i-1} xor A_i ) * H for i = 1, ..., m-1
|
||||
* = (X_{m-1} xor (A_m^* || 0^{128-v})) * H for i = m
|
||||
* = (X_{i-1} xor C_i ) * H for i = m+1, ..., m + n − 1
|
||||
* = (X_{m+n-1} xor (C_m^* || 0^{128-u})) * H for i = m + n
|
||||
* = (X_{m+n} xor (nbits(A)||nbits(A))) * H for i = m + n + 1
|
||||
*/
|
||||
void ghash_init(GHASH_CTX *ctx, const uint8_t h[16], const uint8_t *aad, size_t aadlen)
|
||||
{
|
||||
__uint128_t H;
|
||||
__uint128_t X;
|
||||
__uint128_t A;
|
||||
|
||||
memset(ctx, 0, sizeof(GHASH_CTX));
|
||||
|
||||
/* get H in GF(2^128) as little endian */
|
||||
ctx->H = H = GETU128_LE(h);
|
||||
ctx->aadlen = aadlen;
|
||||
|
||||
/* process AAD */
|
||||
X = 0;
|
||||
while (aadlen >= 16) {
|
||||
A = GETU128_LE(aad);
|
||||
X = gf128_add(X, A);
|
||||
X = gf128_mul(X, H);
|
||||
aad += 16;
|
||||
aadlen -= 16;
|
||||
}
|
||||
if (aadlen) {
|
||||
memcpy(ctx->buf, aad, aadlen);
|
||||
A = GETU128_LE(ctx->block);
|
||||
X = gf128_add(X, A);
|
||||
X = gf128_mul(X, H);
|
||||
}
|
||||
|
||||
ctx->H = H;
|
||||
ctx->X = X;
|
||||
|
||||
/* this clean ok? */
|
||||
H = X = A = 0;
|
||||
}
|
||||
|
||||
void ghash_update(GHASH_CTX *ctx, const uint8_t *c, size_t clen)
|
||||
{
|
||||
__uint128_t X;
|
||||
__uint128_t H;
|
||||
__uint128_t C;
|
||||
|
||||
if (!c && clen) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ctx->cipherlen += clen;
|
||||
|
||||
X = ctx->X;
|
||||
H = ctx->H;
|
||||
|
||||
if (ctx->num) {
|
||||
unsigned int left = 16 - ctx->num;
|
||||
if (clen < left) {
|
||||
memcpy(ctx->block + ctx->num, c, clen);
|
||||
ctx->num += clen;
|
||||
return 1;
|
||||
} else {
|
||||
memcpy(ctx->block + ctx->num, c, left);
|
||||
C = GETU128_LE(ctx->block);
|
||||
X = GF128_ADD(X, C);
|
||||
X = GF128_MUL(X, H);
|
||||
c += left;
|
||||
clen -= left;
|
||||
}
|
||||
}
|
||||
|
||||
while (clen >= 16) {
|
||||
C = GETU128_LE(c);
|
||||
X = gf128_add(X, C);
|
||||
X = gf128_mul(X, H);
|
||||
c += 16;
|
||||
clen -= 16;
|
||||
}
|
||||
|
||||
ctx->num = clen;
|
||||
if (clen) {
|
||||
memcpy(ctx->block, c, clen);
|
||||
}
|
||||
|
||||
ctx->X = X;
|
||||
X = H = C = 0;
|
||||
}
|
||||
|
||||
void ghash_finish(GHASH_CTX *ctx, uint8_t out[16])
|
||||
{
|
||||
__uint128_t X = ctx->X;
|
||||
__uint128_t H = ctx->H;
|
||||
__uint128_t C;
|
||||
|
||||
if (ctx->num < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ctx->num) {
|
||||
memset(ctx->block + ctx->num, 0, 16 - ctx->num);
|
||||
C = GETU128_LE(ctx->block);
|
||||
X = GF128_ADD(X, C);
|
||||
X = GF128_MUL(X, H);
|
||||
}
|
||||
|
||||
PUTU64_LE(ctx->block, (uint64_t)ctx->aadlen << 3);
|
||||
PUTU64_LE(ctx->block + sizeof(uint64_t), (uint64_t)ctx->cipherlen << 3);
|
||||
C = GETU128_LE(ctx->block);
|
||||
X = GF128_ADD(X, C);
|
||||
X = GF128_MUL(X, H);
|
||||
|
||||
PUTU128_LE(out, X);
|
||||
|
||||
memset(ctx, 0, sizeof(GHASH_CTX));
|
||||
X = H = C = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* GCM(K, IV, A, P)
|
||||
*
|
||||
* H = E_K(0^128)
|
||||
* Y_0 = IV || 0^{31}1 if nbits(IV) == 96
|
||||
* = GHASH(H, {}, IV) otherwise
|
||||
* Y_i = Y_{i-1} + 1 for i = 1, ..., n
|
||||
* C_i = P_i xor E_K(Y_i) for i = 1, ..., n
|
||||
* C_n^* = P_n^* xor MSB_u(E_K(Y_n))
|
||||
* T = MSB_t(GHASH(H, A, C) xor E_K(Y_0))
|
||||
*/
|
||||
int gcm_init(GCM_CTX *ctx, const BLOCK_CIPEHR *cipher,
|
||||
const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen,
|
||||
const uint8_t *aad, size_t aadlen)
|
||||
{
|
||||
memset(ctx, 0, sizeof(GCM_CTX));
|
||||
ctx->cipher = cipher;
|
||||
|
||||
/* H = E_K(0^128) */
|
||||
if (!cipher->set_encrypt_key(ctx->key, key, keylen)) {
|
||||
return 0;
|
||||
}
|
||||
cipher->encrypt(ctx->key, ctx->block, ctx->block);
|
||||
|
||||
/* init counter as Y_0 */
|
||||
if (ivlen == GCM_DEFAULT_IV_SIZE) {
|
||||
memcpy(ctx->counter, iv, ivlen);
|
||||
PUTU32(ctx->counter + 12, 1);
|
||||
} else {
|
||||
ghash_init(&ctx->ghash_ctx, ctx->block, NULL, 0);
|
||||
ghash_update(&ctx->ghash_ctx, iv, ivlen);
|
||||
ghash_finish(&ctx->ghash_ctx, ctx->counter);
|
||||
}
|
||||
|
||||
ghash_init(&ctx->ghash-ctx, ctx->block, aad, aadlen);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// gcm 加密解密显然是不一样的
|
||||
int gcm_update(GCM_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out)
|
||||
{
|
||||
uint32_t r;
|
||||
size_t i;
|
||||
|
||||
uint8_t *c = out;
|
||||
size_t clen = inlen;
|
||||
|
||||
if (ctx->num) {
|
||||
uint8_t *k = ctx->block + 16 - ctx->num;
|
||||
size_t len = inlen < ctx->num ? inlen : ctx->num;
|
||||
for (i = 0; i < len; i++) {
|
||||
out[i] = in[i] ^ k[i];
|
||||
}
|
||||
in += len;
|
||||
out += len;
|
||||
inlen -= len;
|
||||
ctx->num -= len;
|
||||
}
|
||||
|
||||
/* gcm only use the last 32 bits as counter */
|
||||
r = GETU32(ctx->counter + 12);
|
||||
|
||||
while (inlen >= 16) {
|
||||
r++;
|
||||
PUTU32(ctx->counter + 12, r);
|
||||
ctx->cipher->encrypt(ctx->key, ctx->counter, out);
|
||||
for (i = 0; i < 16; i++) {
|
||||
out[i] ^= in[i];
|
||||
}
|
||||
|
||||
in += 16;
|
||||
out += 16;
|
||||
inlen -= 16;
|
||||
}
|
||||
|
||||
if (inlen) {
|
||||
r++;
|
||||
PUTU32(ctx->counter + 12, r);
|
||||
ctx->cipher->encrypt(ctx->key, ctx->counter, ctx->block);
|
||||
for (i = 0; i < inlen; i++) {
|
||||
out[i] = in[i] ^ ctx->block[i];
|
||||
}
|
||||
ctx->num = 16 - inlen;
|
||||
}
|
||||
|
||||
ghash_update(ctx->ghash_ctx, c, inlen);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int gcm_encrypt_update(GCM_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out)
|
||||
{
|
||||
ctr_update(ctx->ctr_ctx, in, inlen, out);
|
||||
ghash_update(ctx->ghash_ctx, out, inlen);
|
||||
}
|
||||
|
||||
int gcm_encrypt_finish(GCM_CTX *ctx, size_t taglen, uint8_t *tag)
|
||||
{
|
||||
int i;
|
||||
ghash_finish(ctx->ghash_ctx, ctx->block);
|
||||
|
||||
for (i = 0; i < ctx->taglen; i++) {
|
||||
tag[i] = ctx->block[i] ^ ctx->enced_iv[i];
|
||||
}
|
||||
|
||||
memset(ctx, 0, sizeof(GCM_CTX));
|
||||
}
|
||||
|
||||
int gcm_decrypt_finish(GCM_CTX *ctx, const uint8_t *tag, size_t taglen)
|
||||
{
|
||||
uint8_t buf[16];
|
||||
if (taglen != ctx->taglen) {
|
||||
return 0;
|
||||
}
|
||||
gcm_finish(ctx, buf);
|
||||
if (memcmp(buf, tag, taglen) != 0) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -46,13 +46,11 @@
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef NO_DES
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <gmssl/des.h>
|
||||
#include "bswap.h"
|
||||
#include "endian.h"
|
||||
|
||||
|
||||
/* permuted choice 1 for key schedule, 64 bits to 56 bits */
|
||||
@@ -205,7 +203,7 @@ static uint32_t substitution(const uint64_t A)
|
||||
(((uint32_t)S8[(A ) & 0x3f]) );
|
||||
}
|
||||
|
||||
#define ROL32(A,Si) (((A)<<(Si))|((A)>>(32-(Si))))
|
||||
//#define ROL32(A,Si) (((A)<<(Si))|((A)>>(32-(Si))))
|
||||
|
||||
void des_set_encrypt_key(DES_KEY *key, const unsigned char user_key[8])
|
||||
{
|
||||
@@ -267,4 +265,3 @@ void des_encrypt(DES_KEY *key, const unsigned char in[DES_BLOCK_SIZE],
|
||||
|
||||
PUTU64(out, T);
|
||||
}
|
||||
#endif
|
||||
351
src/ffx.c
351
src/ffx.c
@@ -1,351 +0,0 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2014 - 2017 The GmSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project.
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* 4. The name "GmSSL Project" must not be used to endorse or promote
|
||||
* products derived from this software without prior written
|
||||
* permission. For written permission, please contact
|
||||
* guanzhi1980@gmail.com.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "GmSSL"
|
||||
* nor may "GmSSL" appear in their names without prior written
|
||||
* permission of the GmSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/ffx.h>
|
||||
#include <openssl/e_os2.h>
|
||||
#include "../modes/modes_lcl.h"
|
||||
|
||||
|
||||
static uint32_t modulo[] = {
|
||||
1,
|
||||
10,
|
||||
100,
|
||||
1000,
|
||||
10000,
|
||||
100000,
|
||||
1000000,
|
||||
10000000,
|
||||
100000000,
|
||||
1000000000,
|
||||
1000000000,
|
||||
};
|
||||
|
||||
struct FFX_CTX_st {
|
||||
EVP_CIPHER_CTX *cctx;
|
||||
int flag;
|
||||
};
|
||||
|
||||
FFX_CTX *FFX_CTX_new(void)
|
||||
{
|
||||
FFX_CTX *ret = NULL;
|
||||
ret = OPENSSL_zalloc(sizeof(*ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
void FFX_CTX_free(FFX_CTX *ctx)
|
||||
{
|
||||
if (ctx) {
|
||||
EVP_CIPHER_CTX_free(ctx->cctx);
|
||||
}
|
||||
OPENSSL_free(ctx);
|
||||
}
|
||||
|
||||
int FFX_init(FFX_CTX *ctx, const EVP_CIPHER *cipher, const unsigned char *key,
|
||||
int flag)
|
||||
{
|
||||
int ret = 0;
|
||||
EVP_CIPHER_CTX *cctx = NULL;
|
||||
|
||||
if (!ctx || !cipher || !key) {
|
||||
FFXerr(FFX_F_FFX_INIT, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
if (EVP_CIPHER_mode(cipher) != EVP_CIPH_ECB_MODE) {
|
||||
FFXerr(FFX_F_FFX_INIT, FFX_R_INVALID_CIPHER_MODE);
|
||||
return 0;
|
||||
}
|
||||
if (EVP_CIPHER_block_size(cipher) != 16) {
|
||||
FFXerr(FFX_F_FFX_INIT, FFX_R_INVALID_BLOCK_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ctx->cctx) {
|
||||
if (!(cctx = EVP_CIPHER_CTX_new())) {
|
||||
FFXerr(FFX_F_FFX_INIT, ERR_R_MALLOC_FAILURE);
|
||||
goto end;
|
||||
}
|
||||
ctx->cctx = cctx;
|
||||
cctx = NULL;
|
||||
}
|
||||
ctx->flag = flag;
|
||||
|
||||
if (!EVP_EncryptInit_ex(ctx->cctx, cipher, NULL, key, NULL)) {
|
||||
FFXerr(FFX_F_FFX_INIT, FFX_R_ENCRYPT_INIT_FAILURE);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
end:
|
||||
EVP_CIPHER_CTX_free(cctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int FFX_encrypt(FFX_CTX *ctx, const char *in, char *out, size_t iolen,
|
||||
unsigned char *tweak, size_t tweaklen)
|
||||
{
|
||||
int llen, rlen;
|
||||
uint32_t lval, rval;
|
||||
unsigned char pblock[16] = {
|
||||
0x01, 0x02, 0x01, 0x0a, 0x00, 0x00, 0x0a, 0xff,
|
||||
0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00};
|
||||
unsigned char qblock[16];
|
||||
char lbuf[FFX_MAX_DIGITS/2 + 2];
|
||||
uint64_t yval;
|
||||
size_t i;
|
||||
|
||||
if (!ctx || !in || !out || !tweak) {
|
||||
FFXerr(FFX_F_FFX_ENCRYPT, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (iolen < FFX_MIN_DIGITS || iolen > FFX_MAX_DIGITS) {
|
||||
FFXerr(FFX_F_FFX_ENCRYPT, FFX_R_INVALID_INPUT_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < iolen; i++) {
|
||||
if (!isdigit(in[i])) {
|
||||
FFXerr(FFX_F_FFX_ENCRYPT, FFX_R_INVALID_INPUT_DIGIT);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
llen = iolen / 2;
|
||||
rlen = iolen - llen;
|
||||
|
||||
if (tweaklen < FFX_MIN_TWEAKLEN || tweaklen > FFX_MAX_TWEAKLEN) {
|
||||
FFXerr(FFX_F_FFX_ENCRYPT, FFX_R_INVALID_TWEAK_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(lbuf, in, llen);
|
||||
lbuf[llen] = 0;
|
||||
lval = atoi(lbuf);
|
||||
rval = atoi(in + llen);
|
||||
|
||||
pblock[7] = llen & 0xff;
|
||||
pblock[8] = iolen & 0xff;
|
||||
pblock[12] = tweaklen & 0xff;
|
||||
|
||||
if (!EVP_Cipher(ctx->cctx, pblock, pblock,
|
||||
EVP_CIPHER_CTX_block_size(ctx->cctx))) {
|
||||
FFXerr(FFX_F_FFX_ENCRYPT, ERR_R_EVP_LIB);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(qblock, 0, sizeof(qblock));
|
||||
memcpy(qblock, tweak, tweaklen);
|
||||
|
||||
for (i = 0; i < FFX_NUM_ROUNDS; i += 2) {
|
||||
|
||||
unsigned char rblock[16];
|
||||
size_t j;
|
||||
|
||||
qblock[11] = i & 0xff;
|
||||
memcpy(qblock + 12, &rval, sizeof(rval));
|
||||
for (j = 0; j < sizeof(rblock); j++) {
|
||||
rblock[j] = pblock[j] ^ qblock[j];
|
||||
}
|
||||
if (!EVP_Cipher(ctx->cctx, rblock, rblock,
|
||||
EVP_CIPHER_CTX_block_size(ctx->cctx))) {
|
||||
FFXerr(FFX_F_FFX_ENCRYPT, ERR_R_EVP_LIB);
|
||||
return 0;
|
||||
}
|
||||
|
||||
yval = *((uint64_t *)rblock) % modulo[llen];
|
||||
lval = (lval + yval) % modulo[llen];
|
||||
|
||||
qblock[11] = (i + 1) & 0xff;
|
||||
memcpy(qblock + 12, &lval, sizeof(lval));
|
||||
for (j = 0; j < sizeof(rblock); j++) {
|
||||
rblock[j] = pblock[j] ^ qblock[j];
|
||||
}
|
||||
if (!EVP_Cipher(ctx->cctx, rblock, rblock,
|
||||
EVP_CIPHER_CTX_block_size(ctx->cctx))) {
|
||||
FFXerr(FFX_F_FFX_ENCRYPT, ERR_R_EVP_LIB);
|
||||
return 0;
|
||||
}
|
||||
yval = *((uint64_t *)rblock) % modulo[rlen];
|
||||
rval = (rval + yval) % modulo[rlen];
|
||||
}
|
||||
|
||||
memset(out, '0', iolen);
|
||||
sprintf(lbuf, "%d", rval);
|
||||
memcpy(out + rlen - strlen(lbuf), lbuf, strlen(lbuf));
|
||||
sprintf(lbuf, "%d", lval);
|
||||
strcpy(out + iolen - strlen(lbuf), lbuf);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int FFX_decrypt(FFX_CTX *ctx, const char *in, char *out, size_t iolen,
|
||||
unsigned char *tweak, size_t tweaklen)
|
||||
{
|
||||
int llen, rlen;
|
||||
uint32_t lval, rval;
|
||||
unsigned char pblock[16] = {
|
||||
0x01, 0x02, 0x01, 0x0a, 0x00, 0x00, 0x0a, 0xff,
|
||||
0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00};
|
||||
unsigned char qblock[16];
|
||||
char lbuf[FFX_MAX_DIGITS/2 + 2];
|
||||
uint64_t yval;
|
||||
size_t i;
|
||||
|
||||
if (!ctx || !in || !out || !tweak) {
|
||||
FFXerr(FFX_F_FFX_DECRYPT, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (iolen < FFX_MIN_DIGITS || iolen > FFX_MAX_DIGITS) {
|
||||
FFXerr(FFX_F_FFX_DECRYPT, FFX_R_INVALID_INPUT_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < iolen; i++) {
|
||||
if (!isdigit(in[i])) {
|
||||
FFXerr(FFX_F_FFX_DECRYPT, FFX_R_INVALID_INPUT_DIGIT);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
rlen = iolen / 2;
|
||||
llen = iolen - rlen;
|
||||
|
||||
|
||||
if (tweaklen < FFX_MIN_TWEAKLEN || tweaklen > FFX_MAX_TWEAKLEN) {
|
||||
FFXerr(FFX_F_FFX_DECRYPT, FFX_R_INVALID_TWEAK_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(lbuf, in, llen);
|
||||
lbuf[llen] = 0;
|
||||
lval = atoi(lbuf);
|
||||
rval = atoi(in + llen);
|
||||
|
||||
pblock[7] = rlen & 0xff;
|
||||
pblock[8] = iolen & 0xff;
|
||||
pblock[12] = tweaklen & 0xff;
|
||||
|
||||
if (!EVP_Cipher(ctx->cctx, pblock, pblock,
|
||||
EVP_CIPHER_CTX_block_size(ctx->cctx))) {
|
||||
FFXerr(FFX_F_FFX_DECRYPT, ERR_R_EVP_LIB);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(qblock, 0, sizeof(qblock));
|
||||
memcpy(qblock, tweak, tweaklen);
|
||||
|
||||
for (i = FFX_NUM_ROUNDS - 1; i > 0; i -= 2) {
|
||||
|
||||
unsigned char rblock[16];
|
||||
size_t j;
|
||||
|
||||
qblock[11] = i & 0xff;
|
||||
memcpy(qblock + 12, &rval, sizeof(rval));
|
||||
for (j = 0; j < sizeof(rblock); j++) {
|
||||
rblock[j] = pblock[j] ^ qblock[j];
|
||||
}
|
||||
if (!EVP_Cipher(ctx->cctx, rblock, rblock,
|
||||
EVP_CIPHER_CTX_block_size(ctx->cctx))) {
|
||||
FFXerr(FFX_F_FFX_DECRYPT, ERR_R_EVP_LIB);
|
||||
return 0;
|
||||
}
|
||||
|
||||
yval = *((uint64_t *)rblock) % modulo[llen];
|
||||
lval = (lval >= yval) ? (lval - yval) : lval + modulo[llen] - yval;
|
||||
|
||||
qblock[11] = (i - 1) & 0xff;
|
||||
memcpy(qblock + 12, &lval, sizeof(lval));
|
||||
for (j = 0; j < sizeof(rblock); j++) {
|
||||
rblock[j] = pblock[j] ^ qblock[j];
|
||||
}
|
||||
if (!EVP_Cipher(ctx->cctx, rblock, rblock,
|
||||
EVP_CIPHER_CTX_block_size(ctx->cctx))) {
|
||||
FFXerr(FFX_F_FFX_DECRYPT, ERR_R_EVP_LIB);
|
||||
return 0;
|
||||
}
|
||||
|
||||
yval = *((uint64_t *)rblock) % modulo[rlen];
|
||||
rval = (rval >= yval) ? (rval - yval) : rval + modulo[rlen] - yval;
|
||||
}
|
||||
|
||||
memset(out, '0', iolen);
|
||||
sprintf(lbuf, "%d", rval);
|
||||
memcpy(out + rlen - strlen(lbuf), lbuf, strlen(lbuf));
|
||||
sprintf(lbuf, "%d", lval);
|
||||
strcpy(out + iolen - strlen(lbuf), lbuf);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int luhn_table[10] = {0, 2, 4, 6, 8, 1, 3, 5, 7, 9};
|
||||
|
||||
int FFX_compute_luhn(const char *in, size_t inlen)
|
||||
{
|
||||
int r = 0;
|
||||
int i;
|
||||
|
||||
for (i = inlen - 1; i >= 0; i--) {
|
||||
int a;
|
||||
if (!isdigit(in[i])) {
|
||||
return -2;
|
||||
}
|
||||
a = in[i] - '0';
|
||||
if (i % 2 != inlen % 2)
|
||||
a = luhn_table[a];
|
||||
r += a;
|
||||
}
|
||||
|
||||
r = ((r * 9) % 10) + '0';
|
||||
return r;
|
||||
}
|
||||
|
||||
226
src/gcm.c
226
src/gcm.c
@@ -49,12 +49,17 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <gmssl/gf128.h>
|
||||
#include <gmssl/gcm.h>
|
||||
#include <gmssl/oid.h>
|
||||
#include <gmssl/error.h>
|
||||
#include <gmssl/aes.h>
|
||||
#include "endian.h"
|
||||
|
||||
/*
|
||||
* GHASH(H, A, C) = X_{m + n + 1}
|
||||
* A additional authenticated data, A = A_1, ..., A_{m-1}, A_m^*, nbits(A_m^*) = v
|
||||
* C ciphertext, C = C_1, ..., C_{n-1}, C_n^*, nbits(C_n^*) = u
|
||||
* A additional authenticated data, A = A_1, ..., A_{m-1}, A_{m^*}, nbits(A_{m^*}) = v
|
||||
* C ciphertext, C = C_1, ..., C_{n-1}, C_{n^*}, nbits(C_{n^*}) = u
|
||||
* H = E_K(0^128)
|
||||
*
|
||||
* X_i = 0 for i = 0
|
||||
@@ -62,189 +67,74 @@
|
||||
* = (X_{m-1} xor (A_m^* || 0^{128-v})) * H for i = m
|
||||
* = (X_{i-1} xor C_i ) * H for i = m+1, ..., m + n − 1
|
||||
* = (X_{m+n-1} xor (C_m^* || 0^{128-u})) * H for i = m + n
|
||||
* = (X_{m+n} xor (nbits(A)||nbits(A))) * H for i = m + n + 1
|
||||
* = (X_{m+n} xor (nbits(A)||nbits(C))) * H for i = m + n + 1
|
||||
*/
|
||||
void ghash_init(GHASH_CTX *ctx, const uint8_t h[16], const uint8_t *aad, size_t aadlen)
|
||||
void ghash(const uint8_t h[16], const uint8_t *aad, size_t aadlen, const uint8_t *c, size_t clen, uint8_t out[16])
|
||||
{
|
||||
__uint128_t H;
|
||||
__uint128_t X;
|
||||
__uint128_t A;
|
||||
gf128_t H = gf128_from_bytes(h);
|
||||
gf128_t X = gf128_zero();
|
||||
gf128_t L;
|
||||
|
||||
memset(ctx, 0, sizeof(GHASH_CTX));
|
||||
PUTU64(out, (uint64_t)aadlen << 3);
|
||||
PUTU64(out + 8, (uint64_t)clen << 3);
|
||||
L = gf128_from_bytes(out);
|
||||
|
||||
/* get H in GF(2^128) as little endian */
|
||||
ctx->H = H = GETU128_LE(h);
|
||||
ctx->aadlen = aadlen;
|
||||
|
||||
/* process AAD */
|
||||
X = 0;
|
||||
while (aadlen >= 16) {
|
||||
A = GETU128_LE(aad);
|
||||
X = gf128_add(X, A);
|
||||
X = gf128_mul(X, H);
|
||||
aad += 16;
|
||||
aadlen -= 16;
|
||||
}
|
||||
if (aadlen) {
|
||||
memcpy(ctx->buf, aad, aadlen);
|
||||
A = GETU128_LE(ctx->block);
|
||||
X = gf128_add(X, A);
|
||||
X = gf128_mul(X, H);
|
||||
}
|
||||
|
||||
ctx->H = H;
|
||||
ctx->X = X;
|
||||
|
||||
/* this clean ok? */
|
||||
H = X = A = 0;
|
||||
}
|
||||
|
||||
void ghash_update(GHASH_CTX *ctx, const uint8_t *c, size_t clen)
|
||||
{
|
||||
__uint128_t X;
|
||||
__uint128_t H;
|
||||
__uint128_t C;
|
||||
|
||||
if (!c && clen) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ctx->cipherlen += clen;
|
||||
|
||||
X = ctx->X;
|
||||
H = ctx->H;
|
||||
|
||||
if (ctx->num) {
|
||||
unsigned int left = 16 - ctx->num;
|
||||
if (clen < left) {
|
||||
memcpy(ctx->block + ctx->num, c, clen);
|
||||
ctx->num += clen;
|
||||
return 1;
|
||||
while (aadlen) {
|
||||
gf128_t A;
|
||||
if (aadlen >= 16) {
|
||||
A = gf128_from_bytes(aad);
|
||||
aad += 16;
|
||||
aadlen -= 16;
|
||||
} else {
|
||||
memcpy(ctx->block + ctx->num, c, left);
|
||||
C = GETU128_LE(ctx->block);
|
||||
X = GF128_ADD(X, C);
|
||||
X = GF128_MUL(X, H);
|
||||
c += left;
|
||||
clen -= left;
|
||||
memset(out, 0, 16);
|
||||
memcpy(out, aad, aadlen);
|
||||
A = gf128_from_bytes(out);
|
||||
aadlen = 0;
|
||||
}
|
||||
X = gf128_add(X, A);
|
||||
X = gf128_mul(X, H);
|
||||
}
|
||||
|
||||
while (clen >= 16) {
|
||||
C = GETU128_LE(c);
|
||||
while (clen) {
|
||||
gf128_t C;
|
||||
if (clen >= 16) {
|
||||
C = gf128_from_bytes(c);
|
||||
c += 16;
|
||||
clen -= 16;
|
||||
} else {
|
||||
memset(out, 0, 16);
|
||||
memcpy(out, c, clen);
|
||||
C = gf128_from_bytes(out);
|
||||
clen = 0;
|
||||
}
|
||||
X = gf128_add(X, C);
|
||||
X = gf128_mul(X, H);
|
||||
c += 16;
|
||||
clen -= 16;
|
||||
}
|
||||
|
||||
ctx->num = clen;
|
||||
if (clen) {
|
||||
memcpy(ctx->block, c, clen);
|
||||
}
|
||||
|
||||
ctx->X = X;
|
||||
X = H = C = 0;
|
||||
X = gf128_add(X, L);
|
||||
H = gf128_mul(X, H);
|
||||
gf128_to_bytes(H, out);
|
||||
}
|
||||
|
||||
void ghash_finish(GHASH_CTX *ctx, uint8_t out[16])
|
||||
int gcm_encrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *iv, size_t ivlen,
|
||||
const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen,
|
||||
uint8_t *out, size_t taglen, uint8_t *tag)
|
||||
{
|
||||
__uint128_t X = ctx->X;
|
||||
__uint128_t H = ctx->H;
|
||||
__uint128_t C;
|
||||
|
||||
if (ctx->num < 0) {
|
||||
return 0;
|
||||
if (key->cipher == BLOCK_CIPHER_sm4()) {
|
||||
sm4_gcm_encrypt(&(key->u.sm4_key), iv, ivlen, aad, aadlen, in, inlen, out, taglen, tag);
|
||||
return 1;
|
||||
} else if (key->cipher == BLOCK_CIPHER_aes128()) {
|
||||
aes_gcm_encrypt(&(key->u.aes_key), iv, ivlen, aad, aadlen, in, inlen, out, taglen, tag);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ctx->num) {
|
||||
memset(ctx->block + ctx->num, 0, 16 - ctx->num);
|
||||
C = GETU128_LE(ctx->block);
|
||||
X = GF128_ADD(X, C);
|
||||
X = GF128_MUL(X, H);
|
||||
}
|
||||
|
||||
PUTU64_LE(ctx->block, (uint64_t)ctx->aadlen << 3);
|
||||
PUTU64_LE(ctx->block + sizeof(uint64_t), (uint64_t)ctx->cipherlen << 3);
|
||||
C = GETU128_LE(ctx->block);
|
||||
X = GF128_ADD(X, C);
|
||||
X = GF128_MUL(X, H);
|
||||
|
||||
PUTU128_LE(out, X);
|
||||
|
||||
memset(ctx, 0, sizeof(GHASH_CTX));
|
||||
X = H = C = 0;
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* GCM(K, IV, A, P)
|
||||
*
|
||||
* H = E_K(0^128)
|
||||
* Y_0 = IV || 0^{31}1 if nbits(IV) == 96
|
||||
* = GHASH(H, {}, IV) otherwise
|
||||
* Y_i = Y_{i-1} + 1 for i = 1, ..., n
|
||||
* C_i = P_i xor E_K(Y_i) for i = 1, ..., n
|
||||
* C_n^* = P_n^* xor MSB_u(E_K(Y_n))
|
||||
* T = MSB_t(GHASH(H, A, C) xor E_K(Y_0))
|
||||
*/
|
||||
int gcm_init(GCM_CTX *ctx, const BLOCK_CIPEHR *cipher,
|
||||
const uint8_t *key, size_t keylen, const uint8_t *iv, size_t ivlen,
|
||||
const uint8_t *aad, size_t aadlen)
|
||||
int gcm_decrypt(const BLOCK_CIPHER_KEY *key, const uint8_t *iv, size_t ivlen,
|
||||
const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen,
|
||||
const uint8_t *tag, size_t taglen, uint8_t *out)
|
||||
{
|
||||
memset(ctx, 0, sizeof(GCM_CTX));
|
||||
ctx->cipher = cipher;
|
||||
|
||||
/* H = E_K(0^128) */
|
||||
if (!cipher->set_encrypt_key(ctx->key, key, keylen)) {
|
||||
return 0;
|
||||
}
|
||||
cipher->encrypt(ctx->key, ctx->block, ctx->block);
|
||||
|
||||
/* init counter as Y_0 */
|
||||
if (ivlen == GCM_DEFAULT_IV_SIZE) {
|
||||
memcpy(ctx->counter, iv, ivlen);
|
||||
PUTU32(ctx->counter + 12, 1);
|
||||
} else {
|
||||
ghash_init(&ctx->ghash_ctx, ctx->block, NULL, 0);
|
||||
ghash_update(&ctx->ghash_ctx, iv, ivlen);
|
||||
ghash_finish(&ctx->ghash_ctx, ctx->counter);
|
||||
}
|
||||
|
||||
ghash_init(&ctx->ghash-ctx, ctx->block, aad, aadlen);
|
||||
return 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int gcm_encrypt_update(GCM_CTX *ctx, const uint8_t *in, size_t iolen, uint8_t *out)
|
||||
{
|
||||
ctr_update(&ctx->ctr_ctx, in, iolen, out);
|
||||
ghash_update(&ctx->ghash_ctx, out, iolen);
|
||||
}
|
||||
|
||||
int gcm_decrypt_update(GCM_CTX *ctx, const uint8_t *in, size_t iolen, uint8_t *out)
|
||||
{
|
||||
ghash_update(&ctx->ghash_ctx, in, iolen);
|
||||
|
||||
}
|
||||
|
||||
int gcm_encrypt_finish(GCM_CTX *ctx, size_t taglen, uint8_t *tag)
|
||||
{
|
||||
int i;
|
||||
ghash_finish(ctx->ghash_ctx, ctx->block);
|
||||
for (i = 0; i < ctx->taglen; i++) {
|
||||
tag[i] = ctx->block[i] ^ ctx->enced_iv[i];
|
||||
}
|
||||
memset(ctx, 0, sizeof(GCM_CTX));
|
||||
}
|
||||
|
||||
int gcm_decrypt_finish(GCM_CTX *ctx, const uint8_t *tag, size_t taglen)
|
||||
{
|
||||
uint8_t buf[16];
|
||||
if (taglen != ctx->taglen) {
|
||||
return 0;
|
||||
}
|
||||
gcm_finish(ctx, buf);
|
||||
if (memcmp(buf, tag, taglen) != 0) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
91
src/gf128.c
91
src/gf128.c
@@ -51,30 +51,78 @@
|
||||
* A * 2 mod f(x)
|
||||
*/
|
||||
|
||||
#include "internal/endian.h"
|
||||
#include "internal/gf128.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <gmssl/hex.h>
|
||||
#include <gmssl/gf128.h>
|
||||
#include "endian.h"
|
||||
|
||||
gf128_t gf128_zero(void)
|
||||
{
|
||||
uint8_t zero[16] = {0};
|
||||
return gf128_from_bytes(zero);
|
||||
}
|
||||
|
||||
gf128_t gf128_from_hex(const char *s)
|
||||
{
|
||||
uint8_t bin[16];
|
||||
hex2bin(s, strlen(s), bin);
|
||||
return gf128_from_bytes(bin);
|
||||
}
|
||||
|
||||
int gf128_equ_hex(gf128_t a, const char *s)
|
||||
{
|
||||
uint8_t bin1[16];
|
||||
uint8_t bin2[16];
|
||||
hex2bin(s, strlen(s), bin1);
|
||||
gf128_to_bytes(a, bin2);
|
||||
return memcmp(bin1, bin2, sizeof(bin1)) == 0;
|
||||
}
|
||||
|
||||
void gf128_print_bits(gf128_t a)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 128; i++) {
|
||||
printf("%d", (int)(a % 2));
|
||||
a >>= 1;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void gf128_print(const char *s, gf128_t a)
|
||||
{
|
||||
uint8_t be[16];
|
||||
int i;
|
||||
|
||||
printf("%s", s);
|
||||
gf128_to_bytes(a, be);
|
||||
for (i = 0; i < 16; i++) {
|
||||
printf("%02X", be[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
#ifdef GMSSL_HAVE_UINT128
|
||||
gf128_t gf128_mul(gf128_t a, gf128_t b)
|
||||
{
|
||||
const gf128_t mask = (gf128_t)1 << 127;
|
||||
|
||||
gf128_t r = 0;
|
||||
gf128_t mask = (gf128_t)1 << 127;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 128; i++) {
|
||||
// r = r * 2 over gf(2^128)
|
||||
// r = r * 2
|
||||
if (r & mask)
|
||||
r = (r << 1) ^ 0x87;
|
||||
else r <<= 1;
|
||||
|
||||
// if b[i] == 1, r = r + a
|
||||
// if b[127-i] == 1, r = r + a
|
||||
if (b & mask)
|
||||
r ^= a;
|
||||
|
||||
b <<= 1;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -90,21 +138,37 @@ gf128_t gf128_mul2(gf128_t a)
|
||||
else return (a << 1);
|
||||
}
|
||||
|
||||
gf128_t gf128_reverse(gf128_t a)
|
||||
{
|
||||
gf128_t r = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 128; i++) {
|
||||
r = (r << 1) | (a & 1);
|
||||
a >>= 1;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
gf128_t gf128_from_bytes(const uint8_t p[16])
|
||||
{
|
||||
uint64_t hi = GETU64(p);
|
||||
uint64_t lo = GETU64(p + 8);
|
||||
return (gf128_t)hi << 64 | lo;
|
||||
gf128_t r = (gf128_t)hi << 64 | lo;
|
||||
r = gf128_reverse(r);
|
||||
return r;
|
||||
}
|
||||
|
||||
void gf128_to_bytes(gf128_t a, uint8_t p[16])
|
||||
{
|
||||
a = gf128_reverse(a);
|
||||
uint64_t hi = a >> 64;
|
||||
uint64_t lo = a;
|
||||
PUTU64(p, hi);
|
||||
PUTU64(p + 8, lo);
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
gf128_t gf128_from_bytes(const uint8_t p[16])
|
||||
{
|
||||
@@ -137,10 +201,11 @@ gf128_t gf128_mul(gf128_t a, gf128_t b)
|
||||
for (i = 0; i < 64; i++) {
|
||||
if (r.hi & mask) {
|
||||
r.hi = r.hi << 1 | r.lo >> 63;
|
||||
r.lo = (r.lo << 1) ^ 0x87;
|
||||
r.lo = (r.lo << 1);
|
||||
r.lo ^= 0x87;
|
||||
} else {
|
||||
r.hi = a.hi << 1 | a.lo >> 63;
|
||||
r.lo = a.lo << 1;
|
||||
r.hi = r.hi << 1 | r.lo >> 63;
|
||||
r.lo = r.lo << 1;
|
||||
}
|
||||
|
||||
if (b.hi & mask) {
|
||||
@@ -155,8 +220,8 @@ gf128_t gf128_mul(gf128_t a, gf128_t b)
|
||||
r.hi = r.hi << 1 | r.lo >> 63;
|
||||
r.lo = (r.lo << 1) ^ 0x87;
|
||||
} else {
|
||||
r.hi = a.hi << 1 | a.lo >> 63;
|
||||
r.lo = a.lo << 1;
|
||||
r.hi = r.hi << 1 | r.lo >> 63;
|
||||
r.lo = r.lo << 1;
|
||||
}
|
||||
|
||||
if (b.lo & mask) {
|
||||
|
||||
75
src/gf128.h
75
src/gf128.h
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014 - 2020 The GmSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project.
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* 4. The name "GmSSL Project" must not be used to endorse or promote
|
||||
* products derived from this software without prior written
|
||||
* permission. For written permission, please contact
|
||||
* guanzhi1980@gmail.com.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "GmSSL"
|
||||
* nor may "GmSSL" appear in their names without prior written
|
||||
* permission of the GmSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* GF(2^128) defined by f(x) = x^128 + x^7 + x^2 + x + 1
|
||||
* A + B mod f(x) = a xor b
|
||||
* A * 2 mod f(x)
|
||||
*/
|
||||
|
||||
#ifndef GMSSL_GF128_H
|
||||
#define GMSSL_GF128_H
|
||||
|
||||
#ifdef GMSSL_HAVE_UINT128
|
||||
typedef unsigned __int128 gf128_t;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct {
|
||||
uint64_t hi;
|
||||
uint64_t lo;
|
||||
} gf128_t;
|
||||
#endif
|
||||
|
||||
gf128_t gf128_add(gf128_t a, gf128_t b);
|
||||
gf128_t gf128_mul(gf128_t a, gf128_t b);
|
||||
gf128_t gf128_mul2(gf128_t a);
|
||||
gf128_t gf128_from_bytes(const uint8_t p[16]);
|
||||
void gf128_to_bytes(gf128_t a, uint8_t p[16]);
|
||||
|
||||
|
||||
#endif
|
||||
@@ -51,7 +51,7 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <gmssl/hash_drbg.h>
|
||||
#include "bswap.h"
|
||||
#include "endian.h"
|
||||
|
||||
static int hash_df(const DIGEST *digest, const uint8_t *in, size_t inlen,
|
||||
size_t outlen, uint8_t *out)
|
||||
|
||||
@@ -143,7 +143,7 @@ int hex2bin(const char *in, size_t inlen, uint8_t *out)
|
||||
{
|
||||
int c;
|
||||
if (inlen % 2) {
|
||||
error_print();
|
||||
error_print("hex %s len = %zu\n", in, inlen);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -164,6 +164,13 @@ int hex2bin(const char *in, size_t inlen, uint8_t *out)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int hex_to_bytes(const char *in, size_t inlen, uint8_t *out, size_t *outlen)
|
||||
{
|
||||
*outlen = inlen/2;
|
||||
return hex2bin(in, inlen, out);
|
||||
}
|
||||
|
||||
|
||||
void memxor(void *r, const void *a, size_t len)
|
||||
{
|
||||
uint8_t *pr = r;
|
||||
|
||||
52
src/md5.c
52
src/md5.c
@@ -46,58 +46,10 @@
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2014 - 2017 The GmSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project.
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* 4. The name "GmSSL Project" must not be used to endorse or promote
|
||||
* products derived from this software without prior written
|
||||
* permission. For written permission, please contact
|
||||
* guanzhi1980@gmail.com.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "GmSSL"
|
||||
* nor may "GmSSL" appear in their names without prior written
|
||||
* permission of the GmSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <gmssl/md5.h>
|
||||
#include "bswap.h"
|
||||
#include "endian.h"
|
||||
|
||||
|
||||
static void md5_compress_blocks(uint32_t state[4],
|
||||
@@ -166,7 +118,7 @@ void md5_finish(MD5_CTX *ctx, unsigned char *dgst)
|
||||
}
|
||||
}
|
||||
|
||||
#define ROL32(X, n) (((X) << (n)) | ((X) >> (32-(n))))
|
||||
//#define ROL32(X, n) (((X) << (n)) | ((X) >> (32-(n))))
|
||||
#define F(B, C, D) (((B) & (C)) | ((~(B)) & (D)))
|
||||
#define G(B, C, D) (((B) & (D)) | ((C) & (~(D))))
|
||||
#define H(B, C, D) ((B) ^ (C) ^ (D))
|
||||
|
||||
@@ -45,13 +45,10 @@
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef NO_RC4
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
#include <gmssl/rc4.h>
|
||||
|
||||
void rc4_set_key(RC4_STATE *state, const unsigned char *key, size_t keylen)
|
||||
@@ -118,5 +115,3 @@ unsigned char rc4_generate_keybyte(RC4_STATE *state)
|
||||
rc4_generate_keystream(state, 1, out);
|
||||
return out[0];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
68
src/rotate.h
68
src/rotate.h
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/*
|
||||
* 应该看看Intel Intrisics中是否支持这个指令,以及VS是否也支持这个指令
|
||||
* 这样我们就不需要内联汇编了
|
||||
*/
|
||||
|
||||
/*
|
||||
* Engage compiler specific rotate intrinsic function if available.
|
||||
*/
|
||||
#undef ROL32
|
||||
#ifndef PEDANTIC
|
||||
# if defined(_MSC_VER)
|
||||
# define ROL32(a,n) _lrotl(a,n)
|
||||
# elif defined(__ICC)
|
||||
# define ROL32(a,n) _rotl(a,n)
|
||||
# elif defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
|
||||
/*
|
||||
* Some GNU C inline assembler templates. Note that these are
|
||||
* rotates by *constant* number of bits! But that's exactly
|
||||
* what we need here...
|
||||
* <appro@fy.chalmers.se>
|
||||
*/
|
||||
# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
|
||||
# define ROL32(a,n) ({ register unsigned int ret; \
|
||||
asm ( \
|
||||
"roll %1,%0" \
|
||||
: "=r"(ret) \
|
||||
: "I"(n), "0"((unsigned int)(a)) \
|
||||
: "cc"); \
|
||||
ret; \
|
||||
})
|
||||
# elif defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \
|
||||
defined(__powerpc) || defined(__ppc__) || defined(__powerpc64__)
|
||||
# define ROL32(a,n) ({ register unsigned int ret; \
|
||||
asm ( \
|
||||
"rlwinm %0,%1,%2,0,31" \
|
||||
: "=r"(ret) \
|
||||
: "r"(a), "I"(n)); \
|
||||
ret; \
|
||||
})
|
||||
# elif defined(__s390x__)
|
||||
# define ROL32(a,n) ({ register unsigned int ret; \
|
||||
asm ("rll %0,%1,%2" \
|
||||
: "=r"(ret) \
|
||||
: "r"(a), "I"(n)); \
|
||||
ret; \
|
||||
})
|
||||
# endif
|
||||
# endif
|
||||
#endif /* PEDANTIC */
|
||||
|
||||
#ifndef ROL32
|
||||
# define ROL32(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
|
||||
#endif
|
||||
|
||||
#define ROR32(a,n) ROL32((a),32-(n))
|
||||
#define ROL64(a,n) (((a)<<(n))|((a)>>(64-(n))))
|
||||
#define ROR64(a,n) ROL64(a,64-n)
|
||||
|
||||
|
||||
@@ -49,8 +49,7 @@
|
||||
|
||||
#include <string.h>
|
||||
#include <gmssl/sha1.h>
|
||||
#include "bswap.h"
|
||||
#include "rotate.h"
|
||||
#include "endian.h"
|
||||
|
||||
|
||||
static void sha1_compress_blocks(uint32_t dgst[5],
|
||||
|
||||
@@ -51,8 +51,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <gmssl/sha2.h>
|
||||
#include "bswap.h"
|
||||
#include "rotate.h"
|
||||
#include "endian.h"
|
||||
|
||||
|
||||
static void sha256_compress_blocks(uint32_t state[8],
|
||||
const unsigned char *data, size_t blocks);
|
||||
|
||||
@@ -51,8 +51,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <gmssl/sha2.h>
|
||||
#include "bswap.h"
|
||||
#include "rotate.h"
|
||||
#include "endian.h"
|
||||
|
||||
|
||||
static void sha512_compress_blocks(uint64_t state[8],
|
||||
|
||||
@@ -49,8 +49,9 @@
|
||||
|
||||
#include <string.h>
|
||||
#include <gmssl/sm3.h>
|
||||
#include "bswap.h"
|
||||
#include "rotate.h"
|
||||
//#include "bswap.h"
|
||||
//#include "rotate.h"
|
||||
#include "endian.h"
|
||||
|
||||
#ifdef SM3_SSE3
|
||||
# include <x86intrin.h>
|
||||
|
||||
208
src/sm4_avx2.c
208
src/sm4_avx2.c
@@ -1,208 +0,0 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2014 - 2019 The GmSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project.
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* 4. The name "GmSSL Project" must not be used to endorse or promote
|
||||
* products derived from this software without prior written
|
||||
* permission. For written permission, please contact
|
||||
* guanzhi1980@gmail.com.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "GmSSL"
|
||||
* nor may "GmSSL" appear in their names without prior written
|
||||
* permission of the GmSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
#include <gmssl/sm4.h>
|
||||
#include "internal/bswap.h"
|
||||
#include "internal/rotate.h"
|
||||
#include "sm4_lcl.h"
|
||||
|
||||
#ifdef SMS4_AVX2
|
||||
# include <immintrin.h>
|
||||
|
||||
# define GET_BLKS(x0, x1, x2, x3, in) \
|
||||
t0 = _mm256_i32gather_epi32((int *)(in+4*0), vindex_4i, 4); \
|
||||
t1 = _mm256_i32gather_epi32((int *)(in+4*1), vindex_4i, 4); \
|
||||
t2 = _mm256_i32gather_epi32((int *)(in+4*2), vindex_4i, 4); \
|
||||
t3 = _mm256_i32gather_epi32((int *)(in+4*3), vindex_4i, 4); \
|
||||
x0 = _mm256_shuffle_epi8(t0, vindex_swap); \
|
||||
x1 = _mm256_shuffle_epi8(t1, vindex_swap); \
|
||||
x2 = _mm256_shuffle_epi8(t2, vindex_swap); \
|
||||
x3 = _mm256_shuffle_epi8(t3, vindex_swap)
|
||||
|
||||
# define PUT_BLKS(out, x0, x1, x2, x3) \
|
||||
t0 = _mm256_shuffle_epi8(x0, vindex_swap); \
|
||||
t1 = _mm256_shuffle_epi8(x1, vindex_swap); \
|
||||
t2 = _mm256_shuffle_epi8(x2, vindex_swap); \
|
||||
t3 = _mm256_shuffle_epi8(x3, vindex_swap); \
|
||||
_mm256_storeu_si256((__m256i *)(out+32*0), t0); \
|
||||
_mm256_storeu_si256((__m256i *)(out+32*1), t1); \
|
||||
_mm256_storeu_si256((__m256i *)(out+32*2), t2); \
|
||||
_mm256_storeu_si256((__m256i *)(out+32*3), t3); \
|
||||
x0 = _mm256_i32gather_epi32((int *)(out+8*0), vindex_read, 4); \
|
||||
x1 = _mm256_i32gather_epi32((int *)(out+8*1), vindex_read, 4); \
|
||||
x2 = _mm256_i32gather_epi32((int *)(out+8*2), vindex_read, 4); \
|
||||
x3 = _mm256_i32gather_epi32((int *)(out+8*3), vindex_read, 4); \
|
||||
_mm256_storeu_si256((__m256i *)(out+32*0), x0); \
|
||||
_mm256_storeu_si256((__m256i *)(out+32*1), x1); \
|
||||
_mm256_storeu_si256((__m256i *)(out+32*2), x2); \
|
||||
_mm256_storeu_si256((__m256i *)(out+32*3), x3)
|
||||
|
||||
# define _mm256_rotl_epi32(a, i) _mm256_xor_si256( \
|
||||
_mm256_slli_epi32(a, i), _mm256_srli_epi32(a, 32 - i))
|
||||
|
||||
# define INDEX_MASK_TBOX 0xff
|
||||
|
||||
# define ROUND_TBOX(x0, x1, x2, x3, x4, i) \
|
||||
t0 = _mm256_set1_epi32(*(rk + i)); \
|
||||
t1 = _mm256_xor_si256(x1, x2); \
|
||||
t2 = _mm256_xor_si256(x3, t0); \
|
||||
x4 = _mm256_xor_si256(t1, t2); \
|
||||
t0 = _mm256_and_si256(x4, vindex_mask); \
|
||||
t0 = _mm256_i32gather_epi32((int *)SMS4_T, t0, 4); \
|
||||
t0 = _mm256_rotl_epi32(t0, 8); \
|
||||
x4 = _mm256_srli_epi32(x4, 8); \
|
||||
x0 = _mm256_xor_si256(x0, t0); \
|
||||
t0 = _mm256_and_si256(x4, vindex_mask); \
|
||||
t0 = _mm256_i32gather_epi32((int *)SMS4_T, t0, 4); \
|
||||
t0 = _mm256_rotl_epi32(t0, 16); \
|
||||
x4 = _mm256_srli_epi32(x4, 8); \
|
||||
x0 = _mm256_xor_si256(x0, t0); \
|
||||
t0 = _mm256_and_si256(x4, vindex_mask); \
|
||||
t0 = _mm256_i32gather_epi32((int *)SMS4_T, t0, 4); \
|
||||
t0 = _mm256_rotl_epi32(t0, 24); \
|
||||
x4 = _mm256_srli_epi32(x4, 8); \
|
||||
x0 = _mm256_xor_si256(x0, t0); \
|
||||
t1 = _mm256_i32gather_epi32((int *)SMS4_T, x4, 4); \
|
||||
x4 = _mm256_xor_si256(x0, t1)
|
||||
|
||||
# define INDEX_MASK_DBOX 0xffff
|
||||
|
||||
# define ROUND_DBOX(x0, x1, x2, x3, x4, i) \
|
||||
t0 = _mm256_set1_epi32(*(rk + i)); \
|
||||
t1 = _mm256_xor_si256(x1, x2); \
|
||||
t2 = _mm256_xor_si256(x3, t0); \
|
||||
x4 = _mm256_xor_si256(t1, t2); \
|
||||
t0 = _mm256_srli_epi32(x4, 16); \
|
||||
t1 = _mm256_i32gather_epi32((int *)SMS4_D, t0, 4); \
|
||||
t2 = _mm256_and_si256(x4, vindex_mask); \
|
||||
t3 = _mm256_i32gather_epi32((int *)SMS4_D, t2, 4); \
|
||||
t0 = _mm256_rotl_epi32(t3, 16); \
|
||||
x4 = _mm256_xor_si256(x0, t1); \
|
||||
x4 = _mm256_xor_si256(x4, t0)
|
||||
|
||||
# define ROUND ROUND_TBOX
|
||||
# define INDEX_MASK INDEX_MASK_TBOX
|
||||
|
||||
|
||||
void sm4_avx2_ecb_encrypt_blocks(const unsigned char *in, unsigned char *out,
|
||||
size_t blocks, const SM4_KEY *key)
|
||||
{
|
||||
const int *rk = (int *)key->rk;
|
||||
__m256i x0, x1, x2, x3, x4;
|
||||
__m256i t0, t1, t2, t3;
|
||||
__m256i vindex_4i = _mm256_setr_epi32(0,4,8,12,16,20,24,28);
|
||||
__m256i vindex_mask = _mm256_set1_epi32(INDEX_MASK);
|
||||
__m256i vindex_read = _mm256_setr_epi32(0,8,16,24,1,9,17,25);
|
||||
__m256i vindex_swap = _mm256_setr_epi8(
|
||||
3,2,1,0,7,6,5,4,11,10,9,8,15,14,13,12,
|
||||
3,2,1,0,7,6,5,4,11,10,9,8,15,14,13,12
|
||||
);
|
||||
|
||||
while (blocks >= 8) {
|
||||
GET_BLKS(x0, x1, x2, x3, in);
|
||||
ROUNDS(x0, x1, x2, x3, x4);
|
||||
PUT_BLKS(out, x0, x4, x3, x2);
|
||||
in += 128;
|
||||
out += 128;
|
||||
blocks -= 8;
|
||||
}
|
||||
|
||||
while (blocks--) {
|
||||
sm4_encrypt(in, out, key);
|
||||
in += 16;
|
||||
out += 16;
|
||||
}
|
||||
}
|
||||
|
||||
void sm4_avx2_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out,
|
||||
size_t blocks, const SM4_KEY *key, const unsigned char iv[16])
|
||||
{
|
||||
const int *rk = (int *)key->rk;
|
||||
__m256i x0, x1, x2, x3, x4;
|
||||
__m256i t0, t1, t2, t3;
|
||||
__m256i vindex_4i = _mm256_setr_epi32(0,4,8,12,16,20,24,28);
|
||||
__m256i vindex_mask = _mm256_set1_epi32(INDEX_MASK);
|
||||
__m256i vindex_read = _mm256_setr_epi32(0,8,16,24,1,9,17,25);
|
||||
__m256i vindex_swap = _mm256_setr_epi8(
|
||||
3,2,1,0,7,6,5,4,11,10,9,8,15,14,13,12,
|
||||
3,2,1,0,7,6,5,4,11,10,9,8,15,14,13,12
|
||||
);
|
||||
__m256i incr = _mm256_setr_epi32(0, 1, 2, 3, 4, 5, 6, 7);
|
||||
int c0 = (int)GETU32(iv );
|
||||
int c1 = (int)GETU32(iv + 4);
|
||||
int c2 = (int)GETU32(iv + 8);
|
||||
int c3 = (int)GETU32(iv + 12);
|
||||
|
||||
while (blocks >= 8) {
|
||||
x0 = _mm256_set1_epi32(c0);
|
||||
x1 = _mm256_set1_epi32(c1);
|
||||
x2 = _mm256_set1_epi32(c2);
|
||||
x3 = _mm256_set1_epi32(c3);
|
||||
x3 = _mm256_add_epi32(x3, incr);
|
||||
ROUNDS(x0, x1, x2, x3, x4);
|
||||
GET_BLKS(t0, t1, t2, t3, in);
|
||||
x0 = _mm256_xor_si256(x0, t0);
|
||||
x4 = _mm256_xor_si256(x4, t1);
|
||||
x3 = _mm256_xor_si256(x3, t2);
|
||||
x2 = _mm256_xor_si256(x2, t3);
|
||||
PUT_BLKS(out, x0, x4, x3, x2);
|
||||
c3 += 8;
|
||||
in += 128;
|
||||
out += 128;
|
||||
blocks -= 8;
|
||||
}
|
||||
|
||||
if (blocks) {
|
||||
unsigned char ctr[16];
|
||||
memcpy(ctr, iv, 12);
|
||||
PUTU32(ctr + 12, c3);
|
||||
sm4_ctr32_encrypt_blocks(in, out, blocks, key, ctr);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
16387
src/sm4_common.c
16387
src/sm4_common.c
File diff suppressed because it is too large
Load Diff
@@ -48,8 +48,7 @@
|
||||
*/
|
||||
|
||||
#include <gmssl/sm4.h>
|
||||
#include "bswap.h"
|
||||
#include "rotate.h"
|
||||
#include "endian.h"
|
||||
#include "sm4_lcl.h"
|
||||
|
||||
|
||||
@@ -79,11 +78,6 @@
|
||||
t1 = SM4_T[x4]; \
|
||||
x4 = x0 ^ t1
|
||||
|
||||
#define ROUND_DBOX(x0, x1, x2, x3, x4, i) \
|
||||
x4 = x1 ^ x2 ^ x3 ^ *(rk + i); \
|
||||
x4 = x0 ^ SM4_D[(uint16_t)(x4 >> 16)] ^ \
|
||||
ROL32(SM4_D[(uint16_t)x4], 16)
|
||||
|
||||
#define ROUND ROUND_TBOX
|
||||
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
|
||||
#include <gmssl/sm4.h>
|
||||
#include <gmssl/error.h>
|
||||
#include <gmssl/gcm.h>
|
||||
#include "mem.h"
|
||||
|
||||
void sm4_cbc_encrypt(const SM4_KEY *key, const uint8_t iv[16],
|
||||
@@ -125,3 +126,109 @@ int sm4_cbc_padding_decrypt(const SM4_KEY *key, const uint8_t iv[16],
|
||||
*outlen = inlen - padding;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void ctr_incr(uint8_t a[16])
|
||||
{
|
||||
int i;
|
||||
for (i = 15; i > 0; i--) {
|
||||
a[i]++;
|
||||
if (a[i]) break;
|
||||
}
|
||||
}
|
||||
|
||||
void sm4_ctr_encrypt(const SM4_KEY *key, uint8_t ctr[16], const uint8_t *in, size_t inlen, uint8_t *out)
|
||||
{
|
||||
uint8_t block[16];
|
||||
size_t len;
|
||||
|
||||
while (inlen) {
|
||||
len = inlen < 16 ? inlen : 16;
|
||||
sm4_encrypt(key, ctr, block);
|
||||
gmssl_memxor(out, in, block, len);
|
||||
ctr_incr(ctr);
|
||||
in += len;
|
||||
out += len;
|
||||
inlen -= len;
|
||||
}
|
||||
}
|
||||
|
||||
int sm4_gcm_encrypt(const SM4_KEY *key, const uint8_t *iv, size_t ivlen,
|
||||
const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen,
|
||||
uint8_t *out, const size_t taglen, uint8_t *tag)
|
||||
{
|
||||
const uint8_t *pin = in;
|
||||
uint8_t *pout = out;
|
||||
size_t left = inlen;
|
||||
uint8_t H[16] = {0};
|
||||
uint8_t Y[16];
|
||||
uint8_t T[16];
|
||||
|
||||
sm4_encrypt(key, H, H);
|
||||
|
||||
if (ivlen == 12) {
|
||||
memcpy(Y, iv, 12);
|
||||
Y[12] = Y[13] = Y[14] = 0;
|
||||
Y[15] = 1;
|
||||
} else {
|
||||
ghash(H, NULL, 0, iv, ivlen, Y);
|
||||
}
|
||||
|
||||
sm4_encrypt(key, Y, T);
|
||||
|
||||
while (left) {
|
||||
uint8_t block[16];
|
||||
size_t len = left < 16 ? left : 16;
|
||||
ctr_incr(Y);
|
||||
sm4_encrypt(key, Y, block);
|
||||
gmssl_memxor(pout, pin, block, len);
|
||||
pin += len;
|
||||
pout += len;
|
||||
left -= len;
|
||||
}
|
||||
|
||||
ghash(H, aad, aadlen, out, inlen, H);
|
||||
gmssl_memxor(tag, T, H, taglen);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int sm4_gcm_decrypt(const SM4_KEY *key, const uint8_t *iv, size_t ivlen,
|
||||
const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen,
|
||||
const uint8_t *tag, size_t taglen, uint8_t *out)
|
||||
{
|
||||
const uint8_t *pin = in;
|
||||
uint8_t *pout = out;
|
||||
size_t left = inlen;
|
||||
uint8_t H[16] = {0};
|
||||
uint8_t Y[16];
|
||||
uint8_t T[16];
|
||||
|
||||
sm4_encrypt(key, H, H);
|
||||
|
||||
if (ivlen == 12) {
|
||||
memcpy(Y, iv, 12);
|
||||
Y[12] = Y[13] = Y[14] = 0;
|
||||
Y[15] = 1;
|
||||
} else {
|
||||
ghash(H, NULL, 0, iv, ivlen, Y);
|
||||
}
|
||||
|
||||
ghash(H, aad, aadlen, in, inlen, H);
|
||||
sm4_encrypt(key, Y, T);
|
||||
gmssl_memxor(T, T, H, taglen);
|
||||
if (memcmp(T, tag, taglen) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (left) {
|
||||
uint8_t block[16];
|
||||
size_t len = left < 16 ? left : 16;
|
||||
ctr_incr(Y);
|
||||
sm4_encrypt(key, Y, block);
|
||||
gmssl_memxor(pout, pin, block, len);
|
||||
pin += len;
|
||||
pout += len;
|
||||
left -= len;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -48,8 +48,7 @@
|
||||
*/
|
||||
|
||||
#include <gmssl/sm4.h>
|
||||
#include "bswap.h"
|
||||
#include "rotate.h"
|
||||
#include "endian.h"
|
||||
#include "sm4_lcl.h"
|
||||
|
||||
static uint32_t FK[4] = {
|
||||
|
||||
@@ -322,6 +322,8 @@ int tls_record_length(const uint8_t *record)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// 这个函数应该是处理的,这个函数是不应该用的,通常我们在加密的时候,header ,明文数据是分离的,但是输出的record是一个
|
||||
int tls_record_encrypt(const SM3_HMAC_CTX *hmac_ctx, const SM4_KEY *cbc_key,
|
||||
const uint8_t seq_num[8], const uint8_t *in, size_t inlen,
|
||||
@@ -683,6 +685,9 @@ int tls_record_get_handshake_server_hello(const uint8_t *record,
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int tls_record_set_handshake_certificate(uint8_t *record, size_t *recordlen,
|
||||
const uint8_t *data, size_t datalen)
|
||||
{
|
||||
@@ -1024,7 +1029,6 @@ int tls_record_get_handshake_client_key_exchange_pke(const uint8_t *record,
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int tls_record_set_handshake_certificate_verify(uint8_t *record, size_t *recordlen,
|
||||
const uint8_t *sig, size_t siglen)
|
||||
{
|
||||
@@ -1050,6 +1054,8 @@ int tls_record_get_handshake_certificate_verify(const uint8_t *record,
|
||||
return 1;
|
||||
}
|
||||
|
||||
//FIXME: TLS 1.3 中的verify_data长度和hashLen一样,并且长度是不单独编码的,
|
||||
// 因此这个函数应该改一下了
|
||||
int tls_record_set_handshake_finished(uint8_t *record, size_t *recordlen,
|
||||
const uint8_t verify_data[12])
|
||||
{
|
||||
|
||||
1860
src/tls13.c
1860
src/tls13.c
File diff suppressed because it is too large
Load Diff
@@ -55,6 +55,10 @@
|
||||
#include <gmssl/x509.h>
|
||||
#include <gmssl/rand.h>
|
||||
#include <gmssl/error.h>
|
||||
#include <gmssl/digest.h>
|
||||
#include <gmssl/hkdf.h>
|
||||
#include "mem.h"
|
||||
|
||||
|
||||
|
||||
int tls_prf(const uint8_t *secret, size_t secretlen, const char *label,
|
||||
@@ -114,6 +118,65 @@ int tls_prf(const uint8_t *secret, size_t secretlen, const char *label,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
HKDF-Expand-Label(Secret, Label, Context, Length) =
|
||||
HKDF-Expand(Secret, HkdfLabel, Length);
|
||||
|
||||
HkdfLabel = struct {
|
||||
uint16 length = Length;
|
||||
opaque label<7..255> = "tls13 " + Label;
|
||||
opaque context<0..255> = Context; }
|
||||
|
||||
Derive-Secret(Secret, Label, Messages) =
|
||||
HKDF-Expand-Label(Secret, Label, Hash(Messages), Hash.length)
|
||||
|
||||
*/
|
||||
|
||||
int tls13_hkdf_extract(const DIGEST *digest, const uint8_t salt[32], const uint8_t in[32], uint8_t out[32])
|
||||
{
|
||||
size_t dgstlen;
|
||||
if (hkdf_extract(digest, salt, 32, in, 32, out, &dgstlen) != 1
|
||||
|| dgstlen != 32) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int tls13_hkdf_expand_label(const DIGEST *digest, const uint8_t secret[32],
|
||||
const char *label, const uint8_t *context, size_t context_len,
|
||||
size_t outlen, uint8_t *out)
|
||||
{
|
||||
uint8_t label_len;
|
||||
uint8_t hkdf_label[2 + 256 + 256];
|
||||
uint8_t *p = hkdf_label;
|
||||
size_t hkdf_label_len = 0;
|
||||
|
||||
label_len = strlen("tls13") + strlen(label);
|
||||
tls_uint16_to_bytes((uint16_t)outlen, &p, &hkdf_label_len);
|
||||
tls_uint8_to_bytes(label_len, &p, &hkdf_label_len);
|
||||
tls_array_to_bytes((uint8_t *)"tls13", strlen("tls13"), &p, &hkdf_label_len);
|
||||
tls_array_to_bytes((uint8_t *)label, strlen(label), &p, &hkdf_label_len);
|
||||
tls_uint8array_to_bytes(context, context_len, &p, &hkdf_label_len);
|
||||
|
||||
hkdf_expand(digest, secret, 32, hkdf_label, hkdf_label_len, outlen, out);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int tls13_derive_secret(const uint8_t secret[32], const char *label, const DIGEST_CTX *dgst_ctx, uint8_t out[32])
|
||||
{
|
||||
DIGEST_CTX ctx = *dgst_ctx;
|
||||
uint8_t dgst[64];
|
||||
size_t dgstlen;
|
||||
|
||||
if (digest_finish(&ctx, dgst, &dgstlen) != 1
|
||||
|| tls13_hkdf_expand_label(dgst_ctx->digest, secret, label, dgst, 32, dgstlen, out) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int tls_cbc_encrypt(const SM3_HMAC_CTX *inited_hmac_ctx, const SM4_KEY *enc_key,
|
||||
const uint8_t seq_num[8], const uint8_t header[5],
|
||||
const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen)
|
||||
@@ -250,6 +313,7 @@ int tls_sign_server_ecdh_params(const SM2_KEY *server_sign_key,
|
||||
sm2_sign_update(&sign_ctx, server_random, 32);
|
||||
sm2_sign_update(&sign_ctx, server_ecdh_params, 69);
|
||||
sm2_sign_finish(&sign_ctx, sig, siglen);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -292,6 +292,8 @@ const char *tls_curve_type_name(int type)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// FIXME: 是否应该将函数名改为 tls_curve_name() 这样和 TLS_curve_xxx 保持一致
|
||||
const char *tls_named_curve_name(int curve)
|
||||
{
|
||||
switch (curve) {
|
||||
@@ -417,6 +419,27 @@ int tls_extension_print(FILE *fp, int type, const uint8_t *data, size_t datalen,
|
||||
tls_signature_scheme_name(sig_alg), sig_alg);
|
||||
}
|
||||
break;
|
||||
case TLS_extension_key_share:
|
||||
if (tls_uint16array_from_bytes(&p, &len, &data, &datalen) != 1
|
||||
|| datalen) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
while (len) {
|
||||
uint16_t group;
|
||||
const uint8_t *key_exch;
|
||||
size_t key_exch_len;
|
||||
|
||||
if (tls_uint16_from_bytes(&group, &p, &len) != 1
|
||||
|| tls_uint16array_from_bytes(&key_exch, &key_exch_len, &p, &len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
format_print(fp, format, indent, "group : %s\n", tls_named_curve_name(group));
|
||||
format_bytes(fp, format, indent, "key_exchange : ", key_exch, key_exch_len);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
format_bytes(fp, format, indent, "raw_data : ", data, datalen);
|
||||
}
|
||||
@@ -524,7 +547,8 @@ int tls_server_hello_print(FILE *fp, const uint8_t *data, size_t datalen, int fo
|
||||
tls_compression_method_name(comp_meth), comp_meth);
|
||||
if (datalen > 0) {
|
||||
if (tls_uint16array_from_bytes(&exts, &exts_len, &data, &datalen) != 1) goto bad;
|
||||
format_bytes(fp, format, indent, "Extensions : ", exts, exts_len); // FIXME: extensions_print
|
||||
//format_bytes(fp, format, indent, "Extensions : ", exts, exts_len); // FIXME: extensions_print
|
||||
tls_extensions_print(fp, exts, exts_len, format, indent);
|
||||
}
|
||||
return 1;
|
||||
bad:
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <gmssl/zuc.h>
|
||||
#include "bswap.h"
|
||||
#include "endian.h"
|
||||
|
||||
static const ZUC_UINT15 KD[16] = {
|
||||
0x44D7,0x26BC,0x626B,0x135E,0x5789,0x35E2,0x7135,0x09AF,
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <gmssl/zuc.h>
|
||||
#include "bswap.h"
|
||||
#include "endian.h"
|
||||
|
||||
static void zuc_set_eia_iv(unsigned char iv[16], ZUC_UINT32 count, ZUC_UINT5 bearer,
|
||||
ZUC_BIT direction)
|
||||
|
||||
Reference in New Issue
Block a user