diff --git a/.gitignore b/.gitignore index f128c70a93..a9fcf4ef66 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,12 @@ # Object files *.o +# editor artefacts +*.swp +.#* +#*# +*~ + # Top level excludes /Makefile.bak /Makefile @@ -19,6 +25,12 @@ !/test/r160test.c !/test/fips_algvs.c +/test/*.ss +/test/*.srl +/test/.rnd +/test/test*.pem +/test/newkey.pem + # Certificate symbolic links *.0 diff --git a/CHANGES b/CHANGES index 34dc69b0f0..7d332674db 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,13 @@ Changes between 1.0.1 and 1.0.2 [xx XXX xxxx] + *) New option -crl_download in several openssl utilities to download CRLs + from CRLDP extension in certificates. + [Steve Henson] + + *) New options -CRL and -CRLform for s_client and s_server for CRLs. + [Steve Henson] + *) New function X509_CRL_diff to generate a delta CRL from the difference of two full CRLs. Add support to "crl" utility. [Steve Henson] diff --git a/apps/apps.c b/apps/apps.c index 391a4d10b5..ae5b00f2c2 100644 --- a/apps/apps.c +++ b/apps/apps.c @@ -929,6 +929,55 @@ end: return(x); } +X509_CRL *load_crl(const char *infile, int format) + { + X509_CRL *x=NULL; + BIO *in=NULL; + + if (format == FORMAT_HTTP) + { + load_cert_crl_http(infile, bio_err, NULL, &x); + return x; + } + + in=BIO_new(BIO_s_file()); + if (in == NULL) + { + ERR_print_errors(bio_err); + goto end; + } + + if (infile == NULL) + BIO_set_fp(in,stdin,BIO_NOCLOSE); + else + { + if (BIO_read_filename(in,infile) <= 0) + { + perror(infile); + goto end; + } + } + if (format == FORMAT_ASN1) + x=d2i_X509_CRL_bio(in,NULL); + else if (format == FORMAT_PEM) + x=PEM_read_bio_X509_CRL(in,NULL,NULL,NULL); + else { + BIO_printf(bio_err,"bad input format specified for input crl\n"); + goto end; + } + if (x == NULL) + { + BIO_printf(bio_err,"unable to load CRL\n"); + ERR_print_errors(bio_err); + goto end; + } + +end: + BIO_free(in); + return(x); + } + + EVP_PKEY *load_key(BIO *err, const char *file, int format, int maybe_stdin, const char *pass, ENGINE *e, const char *key_descrip) { @@ -2914,6 +2963,83 @@ void print_cert_checks(BIO *bio, X509 *x, } } +/* Get first http URL from a DIST_POINT structure */ + +static const char *get_dp_url(DIST_POINT *dp) + { + GENERAL_NAMES *gens; + GENERAL_NAME *gen; + int i, gtype; + ASN1_STRING *uri; + if (!dp->distpoint || dp->distpoint->type != 0) + return NULL; + gens = dp->distpoint->name.fullname; + for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) + { + gen = sk_GENERAL_NAME_value(gens, i); + uri = GENERAL_NAME_get0_value(gen, >ype); + if (gtype == GEN_URI && ASN1_STRING_length(uri) > 6) + { + char *uptr = (char *)ASN1_STRING_data(uri); + if (!strncmp(uptr, "http://", 7)) + return uptr; + } + } + return NULL; + } + + +/* Look through a CRLDP structure and attempt to find an http URL to downloads + * a CRL from. + */ + +static X509_CRL *load_crl_crldp(STACK_OF(DIST_POINT) *crldp) + { + int i; + const char *urlptr = NULL; + for (i = 0; i < sk_DIST_POINT_num(crldp); i++) + { + DIST_POINT *dp = sk_DIST_POINT_value(crldp, i); + urlptr = get_dp_url(dp); + if (urlptr) + return load_crl(urlptr, FORMAT_HTTP); + } + return NULL; + } + +/* Example of downloading CRLs from CRLDP: not usable for real world + * as it always downloads, doesn't support non-blocking I/O and doesn't + * cache anything. + */ + +static STACK_OF(X509_CRL) *crls_http_cb(X509_STORE_CTX *ctx, X509_NAME *nm) + { + X509 *x; + STACK_OF(X509_CRL) *crls = NULL; + X509_CRL *crl; + STACK_OF(DIST_POINT) *crldp; + x = X509_STORE_CTX_get_current_cert(ctx); + crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, NULL, NULL); + crl = load_crl_crldp(crldp); + sk_DIST_POINT_pop_free(crldp, DIST_POINT_free); + if (!crl) + return NULL; + crls = sk_X509_CRL_new_null(); + sk_X509_CRL_push(crls, crl); + /* Try to download delta CRL */ + crldp = X509_get_ext_d2i(x, NID_freshest_crl, NULL, NULL); + crl = load_crl_crldp(crldp); + sk_DIST_POINT_pop_free(crldp, DIST_POINT_free); + if (crl) + sk_X509_CRL_push(crls, crl); + return crls; + } + +void store_setup_crl_download(X509_STORE *st) + { + X509_STORE_set_lookup_crls_cb(st, crls_http_cb); + } + /* * Platform-specific sections */ diff --git a/apps/apps.h b/apps/apps.h index cc20466cf0..6a71b8323a 100644 --- a/apps/apps.h +++ b/apps/apps.h @@ -245,6 +245,7 @@ int app_passwd(BIO *err, char *arg1, char *arg2, char **pass1, char **pass2); int add_oid_section(BIO *err, CONF *conf); X509 *load_cert(BIO *err, const char *file, int format, const char *pass, ENGINE *e, const char *cert_descrip); +X509_CRL *load_crl(const char *infile, int format); int load_cert_crl_http(const char *url, BIO *err, X509 **pcert, X509_CRL **pcrl); EVP_PKEY *load_key(BIO *err, const char *file, int format, int maybe_stdin, @@ -342,6 +343,8 @@ void print_cert_checks(BIO *bio, X509 *x, const unsigned char *checkemail, const char *checkip); +void store_setup_crl_download(X509_STORE *st); + #define FORMAT_UNDEF 0 #define FORMAT_ASN1 1 #define FORMAT_TEXT 2 diff --git a/apps/crl.c b/apps/crl.c index 50e7d95a6f..3520c4cbb8 100644 --- a/apps/crl.c +++ b/apps/crl.c @@ -93,7 +93,6 @@ static const char *crl_usage[]={ NULL }; -static X509_CRL *load_crl(char *file, int format); static BIO *bio_out=NULL; int MAIN(int, char **); @@ -452,52 +451,3 @@ end: apps_shutdown(); OPENSSL_EXIT(ret); } - -static X509_CRL *load_crl(char *infile, int format) - { - X509_CRL *x=NULL; - BIO *in=NULL; - - if (format == FORMAT_HTTP) - { - load_cert_crl_http(infile, bio_err, NULL, &x); - return x; - } - - in=BIO_new(BIO_s_file()); - if (in == NULL) - { - ERR_print_errors(bio_err); - goto end; - } - - if (infile == NULL) - BIO_set_fp(in,stdin,BIO_NOCLOSE); - else - { - if (BIO_read_filename(in,infile) <= 0) - { - perror(infile); - goto end; - } - } - if (format == FORMAT_ASN1) - x=d2i_X509_CRL_bio(in,NULL); - else if (format == FORMAT_PEM) - x=PEM_read_bio_X509_CRL(in,NULL,NULL,NULL); - else { - BIO_printf(bio_err,"bad input format specified for input crl\n"); - goto end; - } - if (x == NULL) - { - BIO_printf(bio_err,"unable to load CRL\n"); - ERR_print_errors(bio_err); - goto end; - } - -end: - BIO_free(in); - return(x); - } - diff --git a/apps/s_apps.h b/apps/s_apps.h index 9bc61cea3a..0a150b791e 100644 --- a/apps/s_apps.h +++ b/apps/s_apps.h @@ -196,7 +196,9 @@ int args_ssl(char ***pargs, int *pargc, SSL_CONF_CTX *cctx, int *badarg, BIO *err, STACK_OF(OPENSSL_STRING) **pstr); int args_ssl_call(SSL_CTX *ctx, BIO *err, SSL_CONF_CTX *cctx, STACK_OF(OPENSSL_STRING) *str, int no_ecdhe, int no_jpake); -int ssl_load_stores(SSL_CTX *sctx, +int ssl_ctx_add_crls(SSL_CTX *ctx, STACK_OF(X509_CRL) *crls, int crl_download); +int ssl_load_stores(SSL_CTX *ctx, const char *vfyCApath, const char *vfyCAfile, - const char *chCApath, const char *chCAfile); + const char *chCApath, const char *chCAfile, + STACK_OF(X509_CRL) *crls, int crl_download); #endif diff --git a/apps/s_cb.c b/apps/s_cb.c index c876adf3e9..865aa383e8 100644 --- a/apps/s_cb.c +++ b/apps/s_cb.c @@ -288,7 +288,6 @@ int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key, ERR_print_errors(bio_err); return 0; } - return 1; } @@ -1600,9 +1599,32 @@ int args_ssl_call(SSL_CTX *ctx, BIO *err, SSL_CONF_CTX *cctx, return 1; } +static int add_crls_store(X509_STORE *st, STACK_OF(X509_CRL) *crls) + { + X509_CRL *crl; + int i; + for (i = 0; i < sk_X509_CRL_num(crls); i++) + { + crl = sk_X509_CRL_value(crls, i); + X509_STORE_add_crl(st, crl); + } + return 1; + } + +int ssl_ctx_add_crls(SSL_CTX *ctx, STACK_OF(X509_CRL) *crls, int crl_download) + { + X509_STORE *st; + st = SSL_CTX_get_cert_store(ctx); + add_crls_store(st, crls); + if (crl_download) + store_setup_crl_download(st); + return 1; + } + int ssl_load_stores(SSL_CTX *ctx, const char *vfyCApath, const char *vfyCAfile, - const char *chCApath, const char *chCAfile) + const char *chCApath, const char *chCAfile, + STACK_OF(X509_CRL) *crls, int crl_download) { X509_STORE *vfy = NULL, *ch = NULL; int rv = 0; @@ -1611,7 +1633,10 @@ int ssl_load_stores(SSL_CTX *ctx, vfy = X509_STORE_new(); if (!X509_STORE_load_locations(vfy, vfyCAfile, vfyCApath)) goto err; + add_crls_store(vfy, crls); SSL_CTX_set1_verify_cert_store(ctx, vfy); + if (crl_download) + store_setup_crl_download(vfy); } if (chCApath || chCAfile) { diff --git a/apps/s_client.c b/apps/s_client.c index 1be3028cfc..8fe2c56f2a 100644 --- a/apps/s_client.c +++ b/apps/s_client.c @@ -636,6 +636,11 @@ static char *jpake_secret = NULL; SSL_CONF_CTX *cctx = NULL; STACK_OF(OPENSSL_STRING) *ssl_args = NULL; + char *crl_file = NULL; + int crl_format = FORMAT_PEM; + int crl_download = 0; + STACK_OF(X509_CRL) *crls = NULL; + meth=SSLv23_client_method(); apps_startup(); @@ -705,6 +710,13 @@ static char *jpake_secret = NULL; if (--argc < 1) goto bad; cert_file= *(++argv); } + else if (strcmp(*argv,"-CRL") == 0) + { + if (--argc < 1) goto bad; + crl_file= *(++argv); + } + else if (strcmp(*argv,"-crl_download") == 0) + crl_download = 1; else if (strcmp(*argv,"-sess_out") == 0) { if (--argc < 1) goto bad; @@ -720,6 +732,11 @@ static char *jpake_secret = NULL; if (--argc < 1) goto bad; cert_format = str2fmt(*(++argv)); } + else if (strcmp(*argv,"-CRLform") == 0) + { + if (--argc < 1) goto bad; + crl_format = str2fmt(*(++argv)); + } else if (args_verify(&argv, &argc, &badarg, bio_err, &vpm)) { if (badarg) @@ -1108,6 +1125,26 @@ bad: goto end; } + if (crl_file) + { + X509_CRL *crl; + crl = load_crl(crl_file, crl_format); + if (!crl) + { + BIO_puts(bio_err, "Error loading CRL\n"); + ERR_print_errors(bio_err); + goto end; + } + crls = sk_X509_CRL_new_null(); + if (!crls || !sk_X509_CRL_push(crls, crl)) + { + BIO_puts(bio_err, "Error adding CRL\n"); + ERR_print_errors(bio_err); + X509_CRL_free(crl); + goto end; + } + } + if (!load_excert(&exc, bio_err)) goto end; @@ -1159,7 +1196,8 @@ bad: goto end; } - if (!ssl_load_stores(ctx, vfyCApath, vfyCAfile, chCApath, chCAfile)) + if (!ssl_load_stores(ctx, vfyCApath, vfyCAfile, chCApath, chCAfile, + crls, crl_download)) { BIO_printf(bio_err, "Error loading store locations\n"); ERR_print_errors(bio_err); @@ -1221,6 +1259,7 @@ bad: /* goto end; */ } + ssl_ctx_add_crls(ctx, crls, crl_download); if (!set_cert_key_stuff(ctx,cert,key,chain,build_chain)) goto end; @@ -1955,6 +1994,8 @@ end: if (ctx != NULL) SSL_CTX_free(ctx); if (cert) X509_free(cert); + if (crls) + sk_X509_CRL_pop_free(crls, X509_CRL_free); if (key) EVP_PKEY_free(key); if (chain) diff --git a/apps/s_server.c b/apps/s_server.c index 2b8754bbf5..9acc374c01 100644 --- a/apps/s_server.c +++ b/apps/s_server.c @@ -264,7 +264,6 @@ static int accept_socket= -1; extern int verify_depth, verify_return_error; -static char *cipher=NULL; static int s_server_verify=SSL_VERIFY_NONE; static int s_server_session_id_context = 1; /* anything will do */ static const char *s_cert_file=TEST_CERT,*s_key_file=NULL, *s_chain_file=NULL; @@ -431,7 +430,6 @@ static int MS_CALLBACK ssl_srp_server_param_cb(SSL *s, int *ad, void *arg) static void s_server_init(void) { accept_socket=-1; - cipher=NULL; s_server_verify=SSL_VERIFY_NONE; s_dcert_file=NULL; s_dkey_file=NULL; @@ -946,9 +944,6 @@ int MAIN(int argc, char *argv[]) char *vfyCApath=NULL,*vfyCAfile=NULL; unsigned char *context = NULL; char *dhfile = NULL; -#ifndef OPENSSL_NO_ECDH - char *named_curve = NULL; -#endif int badop=0; int ret=1; int build_chain = 0; @@ -986,6 +981,12 @@ int MAIN(int argc, char *argv[]) SSL_EXCERT *exc = NULL; SSL_CONF_CTX *cctx = NULL; STACK_OF(OPENSSL_STRING) *ssl_args = NULL; + + char *crl_file = NULL; + int crl_format = FORMAT_PEM; + int crl_download = 0; + STACK_OF(X509_CRL) *crls = NULL; + meth=SSLv23_server_method(); local_argc=argc; @@ -1051,6 +1052,13 @@ int MAIN(int argc, char *argv[]) if (--argc < 1) goto bad; s_cert_file= *(++argv); } + else if (strcmp(*argv,"-CRL") == 0) + { + if (--argc < 1) goto bad; + crl_file= *(++argv); + } + else if (strcmp(*argv,"-crl_download") == 0) + crl_download = 1; #ifndef OPENSSL_NO_TLSEXT else if (strcmp(*argv,"-authz") == 0) { @@ -1088,13 +1096,6 @@ int MAIN(int argc, char *argv[]) if (--argc < 1) goto bad; dhfile = *(++argv); } -#ifndef OPENSSL_NO_ECDH - else if (strcmp(*argv,"-named_curve") == 0) - { - if (--argc < 1) goto bad; - named_curve = *(++argv); - } -#endif else if (strcmp(*argv,"-dcertform") == 0) { if (--argc < 1) goto bad; @@ -1146,6 +1147,11 @@ int MAIN(int argc, char *argv[]) } else if (strcmp(*argv,"-no_cache") == 0) no_cache = 1; + else if (strcmp(*argv,"-CRLform") == 0) + { + if (--argc < 1) goto bad; + crl_format = str2fmt(*(++argv)); + } else if (args_verify(&argv, &argc, &badarg, bio_err, &vpm)) { if (badarg) @@ -1508,6 +1514,26 @@ bad: } #endif + if (crl_file) + { + X509_CRL *crl; + crl = load_crl(crl_file, crl_format); + if (!crl) + { + BIO_puts(bio_err, "Error loading CRL\n"); + ERR_print_errors(bio_err); + goto end; + } + crls = sk_X509_CRL_new_null(); + if (!crls || !sk_X509_CRL_push(crls, crl)) + { + BIO_puts(bio_err, "Error adding CRL\n"); + ERR_print_errors(bio_err); + X509_CRL_free(crl); + goto end; + } + } + if (s_dcert_file) { @@ -1641,10 +1667,13 @@ bad: if (vpm) SSL_CTX_set1_param(ctx, vpm); + ssl_ctx_add_crls(ctx, crls, 0); + if (!args_ssl_call(ctx, bio_err, cctx, ssl_args, no_ecdhe, no_jpake)) goto end; - if (!ssl_load_stores(ctx, vfyCApath, vfyCAfile, chCApath, chCAfile)) + if (!ssl_load_stores(ctx, vfyCApath, vfyCAfile, chCApath, chCAfile, + crls, crl_download)) { BIO_printf(bio_err, "Error loading store locations\n"); ERR_print_errors(bio_err); @@ -1705,8 +1734,11 @@ bad: if (vpm) SSL_CTX_set1_param(ctx2, vpm); + ssl_ctx_add_crls(ctx2, crls, 0); + if (!args_ssl_call(ctx2, bio_err, cctx, ssl_args, no_ecdhe, no_jpake)) goto end; + } # ifndef OPENSSL_NO_NEXTPROTONEG @@ -1759,58 +1791,6 @@ bad: } #endif -#ifndef OPENSSL_NO_ECDH - if (!no_ecdhe) - { - EC_KEY *ecdh=NULL; - - if (named_curve && strcmp(named_curve, "auto")) - { - int nid = EC_curve_nist2nid(named_curve); - if (nid == NID_undef) - nid = OBJ_sn2nid(named_curve); - if (nid == 0) - { - BIO_printf(bio_err, "unknown curve name (%s)\n", - named_curve); - goto end; - } - ecdh = EC_KEY_new_by_curve_name(nid); - if (ecdh == NULL) - { - BIO_printf(bio_err, "unable to create curve (%s)\n", - named_curve); - goto end; - } - } - - if (ecdh != NULL) - { - BIO_printf(bio_s_out,"Setting temp ECDH parameters\n"); - } - else if (named_curve) - SSL_CTX_set_ecdh_auto(ctx, 1); - else - { - BIO_printf(bio_s_out,"Using default temp ECDH parameters\n"); - ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); - if (ecdh == NULL) - { - BIO_printf(bio_err, "unable to create curve (nistp256)\n"); - goto end; - } - } - (void)BIO_flush(bio_s_out); - - SSL_CTX_set_tmp_ecdh(ctx,ecdh); -#ifndef OPENSSL_NO_TLSEXT - if (ctx2) - SSL_CTX_set_tmp_ecdh(ctx2,ecdh); -#endif - EC_KEY_free(ecdh); - } -#endif - if (!set_cert_key_stuff(ctx, s_cert, s_key, s_chain, build_chain)) goto end; #ifndef OPENSSL_NO_TLSEXT @@ -1888,23 +1868,6 @@ bad: } #endif - if (cipher != NULL) - { - if(!SSL_CTX_set_cipher_list(ctx,cipher)) - { - BIO_printf(bio_err,"error setting cipher list\n"); - ERR_print_errors(bio_err); - goto end; - } -#ifndef OPENSSL_NO_TLSEXT - if (ctx2 && !SSL_CTX_set_cipher_list(ctx2,cipher)) - { - BIO_printf(bio_err,"error setting cipher list\n"); - ERR_print_errors(bio_err); - goto end; - } -#endif - } SSL_CTX_set_verify(ctx,s_server_verify,verify_callback); SSL_CTX_set_session_id_context(ctx,(void*)&s_server_session_id_context, sizeof s_server_session_id_context); @@ -1968,6 +1931,8 @@ end: if (ctx != NULL) SSL_CTX_free(ctx); if (s_cert) X509_free(s_cert); + if (crls) + sk_X509_CRL_pop_free(crls, X509_CRL_free); if (s_dcert) X509_free(s_dcert); if (s_key) diff --git a/apps/verify.c b/apps/verify.c index 893670ff41..18fba46545 100644 --- a/apps/verify.c +++ b/apps/verify.c @@ -88,6 +88,7 @@ int MAIN(int argc, char **argv) X509_STORE *cert_ctx=NULL; X509_LOOKUP *lookup=NULL; X509_VERIFY_PARAM *vpm = NULL; + int crl_download = 0; #ifndef OPENSSL_NO_ENGINE char *engine=NULL; #endif @@ -145,6 +146,8 @@ int MAIN(int argc, char **argv) if (argc-- < 1) goto end; crlfile= *(++argv); } + else if (strcmp(*argv,"-crl_download") == 0) + crl_download = 1; #ifndef OPENSSL_NO_ENGINE else if (strcmp(*argv,"-engine") == 0) { @@ -223,6 +226,9 @@ int MAIN(int argc, char **argv) } ret = 0; + + if (crl_download) + store_setup_crl_download(cert_ctx); if (argc < 1) { if (1 != check(cert_ctx, NULL, untrusted, trusted, crls, e)) diff --git a/engines/ccgost/gost89.c b/engines/ccgost/gost89.c index 7ebae0f71f..b0568c6b3c 100644 --- a/engines/ccgost/gost89.c +++ b/engines/ccgost/gost89.c @@ -369,7 +369,13 @@ int gost_mac(gost_ctx *ctx,int mac_len,const unsigned char *data, memset(buf2,0,8); memcpy(buf2,data+i,data_len-i); mac_block(ctx,buffer,buf2); - } + i+=8; + } + if (i==8) + { + memset(buf2,0,8); + mac_block(ctx,buffer,buf2); + } get_mac(buffer,mac_len,mac); return 1; } @@ -389,7 +395,13 @@ int gost_mac_iv(gost_ctx *ctx,int mac_len,const unsigned char *iv,const unsigned memset(buf2,0,8); memcpy(buf2,data+i,data_len-i); mac_block(ctx,buffer,buf2); + i+=8; } + if (i==8) + { + memset(buf2,0,8); + mac_block(ctx,buffer,buf2); + } get_mac(buffer,mac_len,mac); return 1; } diff --git a/engines/ccgost/gost_crypt.c b/engines/ccgost/gost_crypt.c index cde58c0e9b..52aef15acf 100644 --- a/engines/ccgost/gost_crypt.c +++ b/engines/ccgost/gost_crypt.c @@ -11,6 +11,14 @@ #include #include "e_gost_err.h" #include "gost_lcl.h" + +#if !defined(CCGOST_DEBUG) && !defined(DEBUG) +# ifndef NDEBUG +# define NDEBUG +# endif +#endif +#include + static int gost_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc); static int gost_cipher_init_cpa(EVP_CIPHER_CTX *ctx, const unsigned char *key, @@ -206,12 +214,13 @@ int gost_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, static void gost_crypt_mesh (void *ctx,unsigned char *iv,unsigned char *buf) { struct ossl_gost_cipher_ctx *c = ctx; - if (c->count&&c->key_meshing && c->count%1024==0) + assert(c->count%8 == 0 && c->count <= 1024); + if (c->key_meshing && c->count==1024) { cryptopro_key_meshing(&(c->cctx),iv); } gostcrypt(&(c->cctx),iv,buf); - c->count+=8; + c->count = c->count%1024 + 8; } static void gost_cnt_next (void *ctx, unsigned char *iv, unsigned char *buf) @@ -219,7 +228,8 @@ static void gost_cnt_next (void *ctx, unsigned char *iv, unsigned char *buf) struct ossl_gost_cipher_ctx *c = ctx; word32 g,go; unsigned char buf1[8]; - if (c->count && c->key_meshing && c->count %1024 ==0) + assert(c->count%8 == 0 && c->count <= 1024); + if (c->key_meshing && c->count==1024) { cryptopro_key_meshing(&(c->cctx),iv); } @@ -248,7 +258,7 @@ static void gost_cnt_next (void *ctx, unsigned char *iv, unsigned char *buf) buf1[7]=(unsigned char)((g>>24)&0xff); memcpy(iv,buf1,8); gostcrypt(&(c->cctx),buf1,buf); - c->count +=8; + c->count = c->count%1024 + 8; } /* GOST encryption in CFB mode */ @@ -511,12 +521,13 @@ static void mac_block_mesh(struct ossl_gost_imit_ctx *c,const unsigned char *dat * interpret internal state of MAC algorithm as iv during keymeshing * (but does initialize internal state from iv in key transport */ - if (c->key_meshing&& c->count && c->count %1024 ==0) + assert(c->count%8 == 0 && c->count <= 1024); + if (c->key_meshing && c->count==1024) { cryptopro_key_meshing(&(c->cctx),buffer); } mac_block(&(c->cctx),c->buffer,data); - c->count +=8; + c->count = c->count%1024 + 8; } int gost_imit_update(EVP_MD_CTX *ctx, const void *data, size_t count) @@ -565,6 +576,12 @@ int gost_imit_final(EVP_MD_CTX *ctx,unsigned char *md) GOSTerr(GOST_F_GOST_IMIT_FINAL, GOST_R_MAC_KEY_NOT_SET); return 0; } + if (c->count==0 && c->bytes_left) + { + unsigned char buffer[8]; + memset(buffer, 0, 8); + gost_imit_update(ctx, buffer, 8); + } if (c->bytes_left) { int i; diff --git a/engines/ccgost/gost_lcl.h b/engines/ccgost/gost_lcl.h index 437a48cc86..00aa42cea4 100644 --- a/engines/ccgost/gost_lcl.h +++ b/engines/ccgost/gost_lcl.h @@ -136,7 +136,7 @@ extern EVP_MD imit_gost_cpa; /* Cipher context used for EVP_CIPHER operation */ struct ossl_gost_cipher_ctx { int paramNID; - off_t count; + unsigned int count; int key_meshing; gost_ctx cctx; }; @@ -151,7 +151,7 @@ struct ossl_gost_imit_ctx { gost_ctx cctx; unsigned char buffer[8]; unsigned char partial_block[8]; - off_t count; + unsigned int count; int key_meshing; int bytes_left; int key_set;