diff --git a/Configure b/Configure index c47b4360..4d939424 100755 --- a/Configure +++ b/Configure @@ -311,7 +311,7 @@ $config{sdirs} = [ "buffer", "bio", "stack", "lhash", "rand", "err", "evp", "asn1", "pem", "x509", "x509v3", "conf", "txt_db", "pkcs7", "pkcs12", "comp", "ocsp", "ui", "cms", "ts", "srp", "cmac", "ct", "async", "kdf", - "sm3", "sms4", "kdf2", "ecies" + "sm3", "sms4", "kdf2", "ecies", "ffx" ]; # Known TLS and DTLS protocols diff --git a/crypto/err/err.c b/crypto/err/err.c index 609dfb56..1f827e1a 100644 --- a/crypto/err/err.c +++ b/crypto/err/err.c @@ -60,6 +60,7 @@ static ERR_STRING_DATA ERR_str_libraries[] = { {ERR_PACK(ERR_LIB_ASYNC, 0, 0), "ASYNC routines"}, {ERR_PACK(ERR_LIB_KDF, 0, 0), "KDF routines"}, {ERR_PACK(ERR_LIB_KDF2, 0, 0), "KDF2 routines"}, + {ERR_PACK(ERR_LIB_FFX, 0, 0), "FFX routines"}, {0, NULL}, }; @@ -105,6 +106,7 @@ static ERR_STRING_DATA ERR_str_reasons[] = { {ERR_R_ENGINE_LIB, "ENGINE lib"}, {ERR_R_ECDSA_LIB, "ECDSA lib"}, {ERR_R_KDF2_LIB, "KDF2 lib"}, + {ERR_R_FFX_LIB, "FFX lib"}, {ERR_R_NESTED_ASN1_ERROR, "nested asn1 error"}, {ERR_R_MISSING_ASN1_EOS, "missing asn1 eos"}, diff --git a/crypto/err/err_all.c b/crypto/err/err_all.c index 5dd78738..de6bb245 100644 --- a/crypto/err/err_all.c +++ b/crypto/err/err_all.c @@ -40,6 +40,7 @@ #include #include #include +#include int err_load_crypto_strings_int(void) { @@ -105,6 +106,9 @@ int err_load_crypto_strings_int(void) # ifndef OPENSSL_NO_KDF2 ERR_load_KDF2_strings() == 0 || # endif +# ifndef OPENSSL_NO_FFX + ERR_load_FFX_strings() == 0 || +# endif #endif ERR_load_KDF_strings() == 0) return 0; diff --git a/crypto/err/openssl.ec b/crypto/err/openssl.ec index db382380..408eff2a 100644 --- a/crypto/err/openssl.ec +++ b/crypto/err/openssl.ec @@ -36,6 +36,7 @@ L CT include/openssl/ct.h crypto/ct/ct_err.c L ASYNC include/openssl/async.h crypto/async/async_err.c L KDF include/openssl/kdf.h crypto/kdf/kdf_err.c L KDF2 include/openssl/kdf2.h crypto/kdf2/kdf2_err.c +L FFX include/openssl/ffx.h crypto/ffx/ffx_err.c # additional header files to be scanned for function names L NONE crypto/x509/x509_vfy.h NONE diff --git a/crypto/ffx/build.info b/crypto/ffx/build.info new file mode 100644 index 00000000..0f9604f0 --- /dev/null +++ b/crypto/ffx/build.info @@ -0,0 +1,2 @@ +LIBS=../../libcrypto +SOURCE[../../libcrypto]=ffx.c ffx_err.c diff --git a/crypto/ffx/ffx.c b/crypto/ffx/ffx.c new file mode 100644 index 00000000..ff2a9170 --- /dev/null +++ b/crypto/ffx/ffx.c @@ -0,0 +1,351 @@ +/* ==================================================================== + * 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 +#include +#include +#include +#include +#include +#include +#include "../modes/modes_lcl.h" + + +static uint32_t modulo[] = { + 1, + 10, + 100, + 1000, + 10000, + 100000, + 1000000, + 10000000, + 100000000, + 1000000000, + 1000000000, +}; + +typedef struct FFX_CTX_st { + EVP_CIPHER_CTX *cctx; + int flag; +} FFX_CTX; + +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; + int 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]; + int 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; + int 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]; + int 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; +} + diff --git a/crypto/ffx/ffx_err.c b/crypto/ffx/ffx_err.c new file mode 100644 index 00000000..327bf27d --- /dev/null +++ b/crypto/ffx/ffx_err.c @@ -0,0 +1,50 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2017 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 + */ + +#include +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_FFX,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_FFX,0,reason) + +static ERR_STRING_DATA FFX_str_functs[] = { + {ERR_FUNC(FFX_F_FFX_DECRYPT), "FFX_decrypt"}, + {ERR_FUNC(FFX_F_FFX_ENCRYPT), "FFX_encrypt"}, + {ERR_FUNC(FFX_F_FFX_INIT), "FFX_init"}, + {0, NULL} +}; + +static ERR_STRING_DATA FFX_str_reasons[] = { + {ERR_REASON(FFX_R_ENCRYPT_INIT_FAILURE), "encrypt init failure"}, + {ERR_REASON(FFX_R_INVALID_BLOCK_SIZE), "invalid block size"}, + {ERR_REASON(FFX_R_INVALID_CIPHER_MODE), "invalid cipher mode"}, + {ERR_REASON(FFX_R_INVALID_INPUT_DIGIT), "invalid input digit"}, + {ERR_REASON(FFX_R_INVALID_INPUT_LENGTH), "invalid input length"}, + {ERR_REASON(FFX_R_INVALID_TWEAK_LENGTH), "invalid tweak length"}, + {0, NULL} +}; + +#endif + +int ERR_load_FFX_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(FFX_str_functs[0].error) == NULL) { + ERR_load_strings(0, FFX_str_functs); + ERR_load_strings(0, FFX_str_reasons); + } +#endif + return 1; +} diff --git a/include/openssl/err.h b/include/openssl/err.h index 0afc7fd1..812b09ca 100644 --- a/include/openssl/err.h +++ b/include/openssl/err.h @@ -94,6 +94,7 @@ typedef struct err_state_st { # define ERR_LIB_ASYNC 51 # define ERR_LIB_KDF 52 # define ERR_LIB_KDF2 53 +# define ERR_LIB_FFX 54 # define ERR_LIB_USER 128 @@ -133,6 +134,7 @@ typedef struct err_state_st { # define ASYNCerr(f,r) ERR_PUT_error(ERR_LIB_ASYNC,(f),(r),OPENSSL_FILE,OPENSSL_LINE) # define KDFerr(f,r) ERR_PUT_error(ERR_LIB_KDF,(f),(r),OPENSSL_FILE,OPENSSL_LINE) # define KDF2err(f,r) ERR_PUT_error(ERR_LIB_KDF2,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define FFXerr(f,r) ERR_PUT_error(ERR_LIB_FFX,(f),(r),OPENSSL_FILE,OPENSSL_LINE) # define ERR_PACK(l,f,r) ( \ (((unsigned int)(l) & 0x0FF) << 24L) | \ @@ -181,6 +183,7 @@ typedef struct err_state_st { # define ERR_R_ENGINE_LIB ERR_LIB_ENGINE/* 38 */ # define ERR_R_ECDSA_LIB ERR_LIB_ECDSA/* 42 */ # define ERR_R_KDF2_LIB ERR_LIB_KDF2/* 53 */ +# define ERR_R_FFX_LIB ERR_LIB_FFX/* 54 */ # define ERR_R_NESTED_ASN1_ERROR 58 # define ERR_R_MISSING_ASN1_EOS 63 diff --git a/include/openssl/ffx.h b/include/openssl/ffx.h new file mode 100644 index 00000000..a0445973 --- /dev/null +++ b/include/openssl/ffx.h @@ -0,0 +1,116 @@ +/* ==================================================================== + * Copyright (c) 2015 - 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. + * ==================================================================== + */ + +#ifndef HEADER_FFX_H +#define HEADER_FFX_H + +#include +#include + + +#define FFX_MIN_DIGITS 6 +#define FFX_MAX_DIGITS 18 +#define FFX_MIN_TWEAKLEN 4 +#define FFX_MAX_TWEAKLEN 11 +#define FFX_NUM_ROUNDS 10 + +#define FFX_TYPE_BINARY 0x04 +#define FFX_TYPE_KEYWORD 0x05 +#define FFX_TYPE_PASSWORD 0x08 +#define FFX_TYPE_TEXT 0x09 +#define FFX_TYPE_INTEGER 0x0a +#define FFX_TYPE_DIGITS 0x00 +#define FFX_TYPE_CELLPHONE 0x01 +#define FFX_TYPE_BANKCARD 0x02 +#define FFX_TYPE_IDCARD 0x03 + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct FFX_CTX_st FFX_CTX; + +FFX_CTX *FFX_CTX_new(void); +void FFX_CTX_free(FFX_CTX *ctx); +int FFX_init(FFX_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, int flag); +int FFX_encrypt(FFX_CTX *ctx, const char *in, char *out, size_t iolen, + unsigned char *tweak, size_t tweaklen); +int FFX_decrypt(FFX_CTX *ctx, const char *in, char *out, size_t iolen, + unsigned char *tweak, size_t tweaklen); +int FFX_compute_luhn(const char *in, size_t inlen); + + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ + +int ERR_load_FFX_strings(void); + +/* Error codes for the FFX functions. */ + +/* Function codes. */ +# define FFX_F_FFX_DECRYPT 100 +# define FFX_F_FFX_ENCRYPT 101 +# define FFX_F_FFX_INIT 102 + +/* Reason codes. */ +# define FFX_R_ENCRYPT_INIT_FAILURE 100 +# define FFX_R_INVALID_BLOCK_SIZE 101 +# define FFX_R_INVALID_CIPHER_MODE 102 +# define FFX_R_INVALID_INPUT_DIGIT 103 +# define FFX_R_INVALID_INPUT_LENGTH 104 +# define FFX_R_INVALID_TWEAK_LENGTH 105 + +# ifdef __cplusplus +} +# endif +#endif diff --git a/test/build.info b/test/build.info index 8b0723d0..9c812344 100644 --- a/test/build.info +++ b/test/build.info @@ -17,7 +17,7 @@ IF[{- !$disabled{tests} -}] dtlsv1listentest ct_test threadstest afalgtest d2i_test \ ssl_test_ctx_test ssl_test x509aux cipherlist_test asynciotest \ bioprinttest sslapitest dtlstest sslcorrupttest bio_enc_test \ - sm3test sms4test kdf2test eciestest + sm3test sms4test kdf2test eciestest ffxtest SOURCE[aborttest]=aborttest.c INCLUDE[aborttest]=../include @@ -300,6 +300,10 @@ IF[{- !$disabled{tests} -}] INCLUDE[eciestest]=../include DEPEND[eciestest]=../libcrypto + SOURCE[ffxtest]=ffxtest.c + INCLUDE[ffxtest]=../include + DEPEND[ffxtest]=../libcrypto + IF[{- !$disabled{shared} -}] PROGRAMS_NO_INST=shlibloadtest SOURCE[shlibloadtest]=shlibloadtest.c diff --git a/test/ffxtest.c b/test/ffxtest.c new file mode 100644 index 00000000..12c13aa2 --- /dev/null +++ b/test/ffxtest.c @@ -0,0 +1,163 @@ +/* ==================================================================== + * Copyright (c) 2014 - 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include + +#include "../e_os.h" + +#ifdef OPENSSL_NO_FFX +int main(int argc, char **argv) +{ + printf("No FFX support\n"); + return 0; +} +#else +# include +# include +# include + +static int test_ffx(int verbose) +{ + int ret = 0; + FFX_CTX *ctx = NULL; + char *in = "99999999999999999"; + const EVP_CIPHER *cipher[] = { + EVP_sms4_ecb(), + EVP_aes_128_ecb(), + EVP_aes_256_ecb(), + }; + unsigned char key[32] = {0}; + unsigned char tweak[8] = { + 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38 + }; + char buf1[100]; + char buf2[100]; + int i; + + if (!(ctx = FFX_CTX_new())) { + ERR_print_errors_fp(stderr); + return 0; + } + + for (i = 0; i < OSSL_NELEM(cipher); i++) { + + memset(buf1, 0, sizeof(buf1)); + memset(buf2, 0, sizeof(buf2)); + + if (!FFX_init(ctx, cipher[i], key, 0)) { + ERR_print_errors_fp(stderr); + goto end; + } + if (!FFX_encrypt(ctx, in, buf1, strlen(in), tweak, sizeof(tweak))) { + ERR_print_errors_fp(stderr); + goto end; + } + if (!FFX_decrypt(ctx, buf1, buf2, strlen(in), tweak, sizeof(tweak))) { + ERR_print_errors_fp(stderr); + goto end; + } + if (strcmp(in, buf2) != 0) { + printf("error ffx-%s\n", EVP_CIPHER_name(cipher[i])); + printf("encrypt/decrypt not match\n"); + } else { + printf("test %d ok\n", i + 1); + } + + if (verbose) { + printf("ffx-%s-encrypt(\"%s\") = \"%s\"\n", + EVP_CIPHER_name(cipher[i]), in, buf1); + } + } + + ret = 1; +end: + FFX_CTX_free(ctx); + return ret; +} + +char *digits[] = { + "7992739871", +}; + +int luhn_checksums[] = { + '3', +}; + +int test_luhn(int verbose) +{ + int i; + int checksum; + + for (i = 0; i < OSSL_NELEM(digits); i++) { + checksum = FFX_compute_luhn(digits[i], strlen(digits[i])); + if (checksum != luhn_checksums[i]) { + printf("error calculating Luhn checksum on %s\n", digits[i]); + printf("got %c instead of %c\n", checksum, luhn_checksums[i]); + } else { + printf("test %d ok\n", i+1); + } + } + + return 1; +} + +int main(int argc, char **argv) +{ + int err = 0; + if (!test_ffx(1)) { + err = 1; + } + if (!test_luhn(1)) { + err = 1; + } + return err; +} +#endif diff --git a/test/recipes/30-test_ffx.t b/test/recipes/30-test_ffx.t new file mode 100644 index 00000000..c783d062 --- /dev/null +++ b/test/recipes/30-test_ffx.t @@ -0,0 +1,12 @@ +#! /usr/bin/env perl +# Copyright 2015-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 + + +use OpenSSL::Test::Simple; + +simple_test("test_ffx", "ffxtest", "ffx"); diff --git a/test/x509-f.p b/test/x509-f.p deleted file mode 100644 index 0da253d5..00000000 --- a/test/x509-f.p +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICjTCCAfigAwIBAgIEMaYgRzALBgkqhkiG9w0BAQQwRTELMAkGA1UEBhMCVVMx -NjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFuZCBTcGFjZSBBZG1pbmlz -dHJhdGlvbjAmFxE5NjA1MjgxMzQ5MDUrMDgwMBcROTgwNTI4MTM0OTA1KzA4MDAw -ZzELMAkGA1UEBhMCVVMxNjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFu -ZCBTcGFjZSBBZG1pbmlzdHJhdGlvbjEgMAkGA1UEBRMCMTYwEwYDVQQDEwxTdGV2 -ZSBTY2hvY2gwWDALBgkqhkiG9w0BAQEDSQAwRgJBALrAwyYdgxmzNP/ts0Uyf6Bp -miJYktU/w4NG67ULaN4B5CnEz7k57s9o3YY3LecETgQ5iQHmkwlYDTL2fTgVfw0C -AQOjgaswgagwZAYDVR0ZAQH/BFowWDBWMFQxCzAJBgNVBAYTAlVTMTYwNAYDVQQK -Ey1OYXRpb25hbCBBZXJvbmF1dGljcyBhbmQgU3BhY2UgQWRtaW5pc3RyYXRpb24x -DTALBgNVBAMTBENSTDEwFwYDVR0BAQH/BA0wC4AJODMyOTcwODEwMBgGA1UdAgQR -MA8ECTgzMjk3MDgyM4ACBSAwDQYDVR0KBAYwBAMCBkAwCwYJKoZIhvcNAQEEA4GB -AH2y1VCEw/A4zaXzSYZJTTUi3uawbbFiS2yxHvgf28+8Js0OHXk1H1w2d6qOHH21 -X82tZXd/0JtG0g1T9usFFBDvYK8O0ebgz/P5ELJnBL2+atObEuJy1ZZ0pBDWINR3 -WkDNLCGiTkCKp0F5EWIrVDwh54NNevkCQRZita+z4IBO ------END CERTIFICATE----- diff --git a/test/x509-fff.p b/test/x509-fff.p deleted file mode 100644 index 0da253d5..00000000 --- a/test/x509-fff.p +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICjTCCAfigAwIBAgIEMaYgRzALBgkqhkiG9w0BAQQwRTELMAkGA1UEBhMCVVMx -NjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFuZCBTcGFjZSBBZG1pbmlz -dHJhdGlvbjAmFxE5NjA1MjgxMzQ5MDUrMDgwMBcROTgwNTI4MTM0OTA1KzA4MDAw -ZzELMAkGA1UEBhMCVVMxNjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFu -ZCBTcGFjZSBBZG1pbmlzdHJhdGlvbjEgMAkGA1UEBRMCMTYwEwYDVQQDEwxTdGV2 -ZSBTY2hvY2gwWDALBgkqhkiG9w0BAQEDSQAwRgJBALrAwyYdgxmzNP/ts0Uyf6Bp -miJYktU/w4NG67ULaN4B5CnEz7k57s9o3YY3LecETgQ5iQHmkwlYDTL2fTgVfw0C -AQOjgaswgagwZAYDVR0ZAQH/BFowWDBWMFQxCzAJBgNVBAYTAlVTMTYwNAYDVQQK -Ey1OYXRpb25hbCBBZXJvbmF1dGljcyBhbmQgU3BhY2UgQWRtaW5pc3RyYXRpb24x -DTALBgNVBAMTBENSTDEwFwYDVR0BAQH/BA0wC4AJODMyOTcwODEwMBgGA1UdAgQR -MA8ECTgzMjk3MDgyM4ACBSAwDQYDVR0KBAYwBAMCBkAwCwYJKoZIhvcNAQEEA4GB -AH2y1VCEw/A4zaXzSYZJTTUi3uawbbFiS2yxHvgf28+8Js0OHXk1H1w2d6qOHH21 -X82tZXd/0JtG0g1T9usFFBDvYK8O0ebgz/P5ELJnBL2+atObEuJy1ZZ0pBDWINR3 -WkDNLCGiTkCKp0F5EWIrVDwh54NNevkCQRZita+z4IBO ------END CERTIFICATE----- diff --git a/util/mkdef.pl b/util/mkdef.pl index e5715fc7..aeed80cf 100755 --- a/util/mkdef.pl +++ b/util/mkdef.pl @@ -132,7 +132,7 @@ my @known_algorithms = ( "RC2", "RC4", "RC5", "IDEA", "DES", "BF", "CMAC", # APPLINK (win build feature?) "APPLINK", - "SM3", "SMS4", "KDF2", "ECIES" + "SM3", "SMS4", "KDF2", "ECIES", "FFX" ); my %disabled_algorithms;