From: Dmitry Belyavskiy Date: Mon, 15 Jul 2019 08:53:47 +0000 (+0300) Subject: Merge branch 'mgm_impl' of https://github.com/gost-engine/engine into mgm_impl X-Git-Url: http://wagner.pp.ru/gitweb/?a=commitdiff_plain;h=361dcb32d8a4b439cdb3cbb85ebd2eebc30f9fbf;hp=291a33c215b36abb43d88bd014f299627ca1824c;p=openssl-gost%2Fengine.git Merge branch 'mgm_impl' of https://github.com/gost-engine/engine into mgm_impl --- diff --git a/.cirrus.yml b/.cirrus.yml new file mode 100644 index 0000000..d4bb0b8 --- /dev/null +++ b/.cirrus.yml @@ -0,0 +1,21 @@ +FreeBSD_task: + freebsd_instance: + image: freebsd-12-0-release-amd64 + env: + ASSUME_ALWAYS_YES: TRUE # required for unattended "pkg" invocation + PREFIX: ${HOME}/opt + LD_LIBRARY_PATH: ${PREFIX}/lib + PATH: ${PREFIX}/bin:${PATH} + OPENSSL_BRANCH: master + script: + - pkg install git cmake p5-App-cpanminus gdb + - sudo cpanm --notest Test2::V0 + - git clone --depth 1 -b ${OPENSSL_BRANCH} https://github.com/openssl/openssl.git + - cd openssl + - ./config shared -d --prefix=${PREFIX} --openssldir=${PREFIX} && make all install_sw > build.log 2>&1 || (cat build.log && exit 1) + - cd .. + - mkdir build + - cd build + - cmake -DOPENSSL_ROOT_DIR=${PREFIX} -DOPENSSL_LIBRARIES=${PREFIX}/lib -DOPENSSL_ENGINES_DIR=${PREFIX}/engines .. + - make + - make test CTEST_OUTPUT_ON_FAILURE=1 diff --git a/.travis.yml b/.travis.yml index 6c1b262..b3c120f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,33 +7,29 @@ language: c addons: apt: - packages: - - cpanminus + packages: [ cpanminus ] + homebrew: + packages: [ cpanminus ] env: global: - PREFIX=${HOME}/opt - - LD_LIBRARY_PATH=${PREFIX}/lib - PATH=${PREFIX}/bin:${PATH} + - OPENSSL_BRANCH=master matrix: include: - - env: OPENSSL_BRANCH=master - os: linux + - os: linux compiler: gcc - - env: - - OPENSSL_BRANCH=master - - ASAN=-DASAN=1 + - env: ASAN=-DASAN=1 os: linux compiler: gcc -# - env: OPENSSL_BRANCH=OpenSSL_1_1_0-stable -# os: linux -# compiler: gcc -# - env: OPENSSL_BRANCH=OpenSSL_1_0_2-stable -# os: linux -# compiler: gcc + - os: osx + compiler: clang + before_script: + - curl -L https://cpanmin.us | sudo perl - --sudo App::cpanminus - sudo cpanm --notest Test2::V0 > build.log 2>&1 || (cat build.log && exit 1) - git clone --depth 1 -b ${OPENSSL_BRANCH} https://github.com/openssl/openssl.git - cd openssl @@ -41,6 +37,8 @@ before_script: - cd .. script: + - if [ "${TRAVIS_OS_NAME}" = "linux" ]; then export LD_LIBRARY_PATH="${PREFIX}/lib:${LD_LIBRARY_PATH:-}"; fi + - if [ "${TRAVIS_OS_NAME}" = "osx" ]; then export DYLD_LIBRARY_PATH="${PREFIX}/lib:${DYLD_LIBRARY_PATH:-}"; fi - mkdir build - cd build - cmake -DOPENSSL_ROOT_DIR=${PREFIX} -DOPENSSL_LIBRARIES=${PREFIX}/lib -DOPENSSL_ENGINES_DIR=${PREFIX}/engines ${ASAN} .. diff --git a/CMakeLists.txt b/CMakeLists.txt index 2ea9574..a85c86e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,6 +44,9 @@ endif() set(BIN_DIRECTORY bin) +# Same soversion as OpenSSL +set(GOST_SOVERSION "${OPENSSL_VERSION_MAJOR}.${OPENSSL_VERSION_MINOR}") + set(OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${BIN_DIRECTORY}) #set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${OUTPUT_DIRECTORY}) @@ -209,8 +212,9 @@ set_property(TARGET ${BINARY_TESTS_TARGETS} APPEND PROPERTY COMPILE_DEFINITIONS add_library(gost_core STATIC ${GOST_LIB_SOURCE_FILES}) set_target_properties(gost_core PROPERTIES POSITION_INDEPENDENT_CODE ON) -add_library(gost_engine MODULE ${GOST_ENGINE_SOURCE_FILES}) +add_library(gost_engine SHARED ${GOST_ENGINE_SOURCE_FILES}) set_target_properties(gost_engine PROPERTIES PREFIX "" OUTPUT_NAME "gost") +set_target_properties(gost_engine PROPERTIES VERSION ${GOST_SOVERSION} SOVERSION ${GOST_SOVERSION}) target_link_libraries(gost_engine gost_core ${OPENSSL_CRYPTO_LIBRARY}) set(GOST_SUM_SOURCE_FILES diff --git a/README.md b/README.md index e994305..aa636d7 100644 --- a/README.md +++ b/README.md @@ -9,3 +9,4 @@ Mailing list: http://www.wagner.pp.ru/list-archives/openssl-gost/ Some useful links: https://www.altlinux.org/OSS-GOST-Crypto +DO NOT TRY BUILDING MASTER BRANCH AGAINST openssl 1.1.1! Use 1_1_0 branch instead! diff --git a/gost_grasshopper_cipher.c b/gost_grasshopper_cipher.c index 529f58a..2249161 100644 --- a/gost_grasshopper_cipher.c +++ b/gost_grasshopper_cipher.c @@ -1184,54 +1184,47 @@ int gost_grasshopper_cipher_ctl(EVP_CIPHER_CTX *ctx, int type, int arg, #ifdef EVP_CTRL_TLS1_2_TLSTREE case EVP_CTRL_TLS1_2_TLSTREE: { - unsigned char newkey[32]; - int mode = EVP_CIPHER_CTX_mode(ctx); - static const unsigned char zeroseq[8]; - gost_grasshopper_cipher_ctx_ctr *ctr_ctx = NULL; - gost_grasshopper_cipher_ctx *c = NULL; - - unsigned char adjusted_iv[16]; - unsigned char seq[8]; - int j; - if (mode != EVP_CIPH_CTR_MODE) - return -1; - - ctr_ctx = (gost_grasshopper_cipher_ctx_ctr *) - EVP_CIPHER_CTX_get_cipher_data(ctx); - c = &(ctr_ctx->c); - - memcpy(seq, ptr, 8); - if (EVP_CIPHER_CTX_encrypting(ctx)) { - /* - * OpenSSL increments seq after mac calculation. - * As we have Mac-Then-Encrypt, we need decrement it here on encryption - * to derive the key correctly. - * */ - if (memcmp(seq, zeroseq, 8) != 0) { - for (j = 7; j >= 0; j--) { - if (seq[j] != 0) { - seq[j]--; - break; - } else - seq[j] = 0xFF; - } - } + unsigned char newkey[32]; + int mode = EVP_CIPHER_CTX_mode(ctx); + static const unsigned char zeroseq[8]; + gost_grasshopper_cipher_ctx_ctr *ctr_ctx = NULL; + gost_grasshopper_cipher_ctx *c = NULL; + + unsigned char adjusted_iv[16]; + unsigned char seq[8]; + int j, carry; + if (mode != EVP_CIPH_CTR_MODE) + return -1; + + ctr_ctx = (gost_grasshopper_cipher_ctx_ctr *) + EVP_CIPHER_CTX_get_cipher_data(ctx); + c = &(ctr_ctx->c); + + memcpy(seq, ptr, 8); + if (EVP_CIPHER_CTX_encrypting(ctx)) { + /* + * OpenSSL increments seq after mac calculation. + * As we have Mac-Then-Encrypt, we need decrement it here on encryption + * to derive the key correctly. + * */ + if (memcmp(seq, zeroseq, 8) != 0) + { + for(j=7; j>=0; j--) + { + if (seq[j] != 0) {seq[j]--; break;} + else seq[j] = 0xFF; + } } - if (gost_tlstree(NID_grasshopper_cbc, c->master_key.k.b, newkey, - (const unsigned char *)seq) > 0) { - memset(adjusted_iv, 0, 16); - memcpy(adjusted_iv, EVP_CIPHER_CTX_original_iv(ctx), 8); - for (j = 7; j >= 0; j--) { - int adj_byte, carry = 0; - adj_byte = adjusted_iv[j] + seq[j] + carry; - carry = (adj_byte > 255) ? 1 : 0; - adjusted_iv[j] = adj_byte & 0xFF; - } - EVP_CIPHER_CTX_set_num(ctx, 0); - memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), adjusted_iv, 16); - - gost_grasshopper_cipher_key(c, newkey); - return 1; + } + if (gost_tlstree(NID_grasshopper_cbc, c->master_key.k.b, newkey, + (const unsigned char *)seq) > 0) { + memset(adjusted_iv, 0, 16); + memcpy(adjusted_iv, EVP_CIPHER_CTX_original_iv(ctx), 8); + for(j=7,carry=0; j>=0; j--) + { + int adj_byte = adjusted_iv[j]+seq[j]+carry; + carry = (adj_byte > 255) ? 1 : 0; + adjusted_iv[j] = adj_byte & 0xFF; } } return -1; diff --git a/gost_keyexpimp.c b/gost_keyexpimp.c index 1f058a1..6df1b2a 100644 --- a/gost_keyexpimp.c +++ b/gost_keyexpimp.c @@ -6,6 +6,7 @@ #include "gost_lcl.h" #include "e_gost_err.h" +int omac_imit_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr); /* * Function expects that out is a preallocated buffer of length * defined as sum of shared_len and mac length defined by mac_nid @@ -44,8 +45,8 @@ int gost_kexp15(const unsigned char *shared_key, const int shared_len, } if (EVP_DigestInit_ex(mac, EVP_get_digestbynid(mac_nid), NULL) <= 0 - || EVP_MD_CTX_ctrl(mac, EVP_MD_CTRL_SET_KEY, 32, mac_key) <= 0 - || EVP_MD_CTX_ctrl(mac, EVP_MD_CTRL_MAC_LEN, mac_len, NULL) <= 0 + || omac_imit_ctrl(mac, EVP_MD_CTRL_SET_KEY, 32, mac_key) <= 0 + || omac_imit_ctrl(mac, EVP_MD_CTRL_MAC_LEN, mac_len, NULL) <= 0 || EVP_DigestUpdate(mac, iv, ivlen) <= 0 || EVP_DigestUpdate(mac, shared_key, shared_len) <= 0 /* As we set MAC length directly, we should not allow overwriting it */ @@ -137,8 +138,8 @@ int gost_kimp15(const unsigned char *expkey, const size_t expkeylen, } if (EVP_DigestInit_ex(mac, EVP_get_digestbynid(mac_nid), NULL) <= 0 - || EVP_MD_CTX_ctrl(mac, EVP_MD_CTRL_SET_KEY, 32, mac_key) <= 0 - || EVP_MD_CTX_ctrl(mac, EVP_MD_CTRL_MAC_LEN, mac_len, NULL) <= 0 + || omac_imit_ctrl(mac, EVP_MD_CTRL_SET_KEY, 32, mac_key) <= 0 + || omac_imit_ctrl(mac, EVP_MD_CTRL_MAC_LEN, mac_len, NULL) <= 0 || EVP_DigestUpdate(mac, iv, ivlen) <= 0 || EVP_DigestUpdate(mac, out, shared_len) <= 0 /* As we set MAC length directly, we should not allow overwriting it */ diff --git a/test_grasshopper.c b/test_grasshopper.c index b148ef1..5329129 100644 --- a/test_grasshopper.c +++ b/test_grasshopper.c @@ -368,6 +368,14 @@ int main(int argc, char **argv) int ret = 0; const struct testcase *t; + setenv("OPENSSL_ENGINES", ENGINE_DIR, 0); + OPENSSL_add_all_algorithms_conf(); + ERR_load_crypto_strings(); + ENGINE *eng; + T(eng = ENGINE_by_id("gost")); + T(ENGINE_init(eng)); + T(ENGINE_set_default(eng, ENGINE_METHOD_ALL)); + for (t = testcases; t->name; t++) { int inplace; const char *standard = t->acpkm? "R 23565.1.017-2018" : "GOST R 34.13-2015"; @@ -383,9 +391,7 @@ int main(int argc, char **argv) t->iv, t->iv_size, t->acpkm); } - /* preload cbc cipher for omac set key */ - EVP_add_cipher(cipher_gost_grasshopper_cbc()); - + printf(cBLUE "# Tests for omac\n" cNORM); ret |= test_mac("OMAC", "GOST R 34.13-2015", grasshopper_omac(), 0, 0, P, sizeof(P), MAC_omac, sizeof(MAC_omac)); ret |= test_mac("OMAC-ACPKM", "R 1323565.1.017-2018 A.4.1", @@ -397,6 +403,9 @@ int main(int argc, char **argv) P_omac_acpkm2, sizeof(P_omac_acpkm2), MAC_omac_acpkm2, sizeof(MAC_omac_acpkm2)); + ENGINE_finish(eng); + ENGINE_free(eng); + if (ret) printf(cDRED "= Some tests FAILED!\n" cNORM); else diff --git a/test_keyexpimp.c b/test_keyexpimp.c index 5e3528d..de7b1fa 100644 --- a/test_keyexpimp.c +++ b/test_keyexpimp.c @@ -9,6 +9,11 @@ #include "e_gost_err.h" #include "gost_grasshopper_cipher.h" +#define T(e) if (!(e)) {\ + ERR_print_errors_fp(stderr);\ + OpenSSLDie(__FILE__, __LINE__, #e);\ + } + static void hexdump(FILE *f, const char *title, const unsigned char *s, int l) { int n = 0; @@ -92,13 +97,15 @@ int main(void) unsigned char tlsseq[8]; unsigned char out[32]; - OpenSSL_add_all_algorithms(); + setenv("OPENSSL_ENGINES", ENGINE_DIR, 0); + OPENSSL_add_all_algorithms_conf(); + ERR_load_crypto_strings(); + ENGINE *eng; + T(eng = ENGINE_by_id("gost")); + T(ENGINE_init(eng)); + T(ENGINE_set_default(eng, ENGINE_METHOD_ALL)); + memset(buf, 0, sizeof(buf)); - /* Make test work without config. */ - EVP_add_cipher(cipher_magma_ctr()); - EVP_add_cipher(cipher_magma_cbc()); - EVP_add_digest(digest_gost2012_256()); - EVP_add_digest(magma_omac()); memset(kroot, 0xFF, 32); memset(tlsseq, 0, 8); @@ -160,5 +167,8 @@ int main(void) } } + ENGINE_finish(eng); + ENGINE_free(eng); + return err; } diff --git a/test_tls.c b/test_tls.c index fa4048c..d137602 100644 --- a/test_tls.c +++ b/test_tls.c @@ -69,7 +69,7 @@ struct certkey { * Simple TLS Server code is based on * https://wiki.openssl.org/index.php/Simple_TLS_Server */ -static int s_server(EVP_PKEY *pkey, X509 *cert, int pipewr) +static int s_server(EVP_PKEY *pkey, X509 *cert, int client) { SSL_CTX *ctx; T(ctx = SSL_CTX_new(TLS_server_method())); @@ -77,34 +77,9 @@ static int s_server(EVP_PKEY *pkey, X509 *cert, int pipewr) T(SSL_CTX_use_PrivateKey(ctx, pkey)); T(SSL_CTX_check_private_key(ctx)); - struct sockaddr_in addr = { .sin_family = AF_INET }; - socklen_t len; - int sock; - sock = socket(AF_INET, SOCK_STREAM, 0); - if (sock < 0) - err(1, "socket"); - if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int)) < 0) - err(1, "setsockopt"); - if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) - err(1, "bind"); - len = sizeof(addr); - if (getsockname(sock, (struct sockaddr *)&addr, &len) < 0) - err(1, "getsockname"); - int port = ntohs(addr.sin_port); - if (listen(sock, 1) < 0) - err(1, "listen"); - /* Signal to client that server is ready. */ - if (write(pipewr, &port, sizeof(port)) != sizeof(port)) - err(1, "write pipe"); - len = sizeof(addr); - alarm(1); - int client = accept(sock, (struct sockaddr *)&addr, &len); - if (client < 0) - err(1, "accept"); - alarm(0); SSL *ssl; - ssl = SSL_new(ctx); - SSL_set_fd(ssl, client); + T(ssl = SSL_new(ctx)); + T(SSL_set_fd(ssl, client)); T(SSL_accept(ssl) == 1); /* Receive data from client */ @@ -127,7 +102,6 @@ static int s_server(EVP_PKEY *pkey, X509 *cert, int pipewr) SSL_free(ssl); close(client); - close(sock); SSL_CTX_free(ctx); return 0; } @@ -136,7 +110,7 @@ static int s_server(EVP_PKEY *pkey, X509 *cert, int pipewr) * Simple TLC Client code is based on man BIO_f_ssl and * https://wiki.openssl.org/index.php/SSL/TLS_Client */ -static int s_client(int piperd) +static int s_client(int server) { SSL_CTX *ctx; T(ctx = SSL_CTX_new(TLS_client_method())); @@ -150,17 +124,8 @@ static int s_client(int piperd) /* Does not work with reneg. */ BIO_set_ssl_renegotiate_bytes(sbio, 100 * 1024); #endif - int port; - alarm(1); - /* Wait for server to be ready. */ - if (read(piperd, &port, sizeof(port)) != sizeof(port)) - err(1, "read pipe"); - char tport[8]; - snprintf(tport, sizeof(tport), "%d", port); - T(BIO_set_conn_port(sbio, tport)); - T(BIO_do_connect(sbio) == 1); + T(SSL_set_fd(ssl, server)); T(BIO_do_handshake(sbio) == 1); - alarm(0); printf("Protocol: %s\n", SSL_get_version(ssl)); printf("Cipher: %s\n", SSL_get_cipher_name(ssl)); @@ -300,9 +265,9 @@ int test(const char *algname, const char *paramset) struct certkey ck; ck = certgen(algname, paramset); - int pipefd[2]; - if (pipe(pipefd)) - err(1, "pipe"); + int sockfd[2]; + if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sockfd) == -1) + err(1, "socketpair"); pid_t pid = fork(); if (pid < 0) @@ -311,13 +276,13 @@ int test(const char *algname, const char *paramset) if (pid > 0) { int status; - ret = s_client(pipefd[0]); + ret = s_client(sockfd[0]); wait(&status); ret |= WIFEXITED(status) && WEXITSTATUS(status); X509_free(ck.cert); EVP_PKEY_free(ck.pkey); } else if (pid == 0) { - ret = s_server(ck.pkey, ck.cert, pipefd[1]); + ret = s_server(ck.pkey, ck.cert, sockfd[1]); X509_free(ck.cert); EVP_PKEY_free(ck.pkey); exit(ret);