From 72a51d0b15de931b1fd3624763e3565915915925 Mon Sep 17 00:00:00 2001 From: purplerain Date: Sat, 30 Dec 2023 04:25:26 +0000 Subject: [PATCH] sync with OpenBSD -current --- distrib/sets/lists/comp/mi | 4 +- lib/libcrypto/Makefile | 10 +- lib/libcrypto/asn1/ameth_lib.c | 166 +-- lib/libcrypto/asn1/asn1_local.h | 66 +- lib/libcrypto/asn1/t_x509.c | 4 +- lib/libcrypto/ec/ec_ameth.c | 169 +-- lib/libcrypto/evp/cipher_method_lib.c | 185 ---- lib/libcrypto/evp/{evp_enc.c => evp_cipher.c} | 475 ++++++++- lib/libcrypto/evp/{digest.c => evp_digest.c} | 341 ++++-- lib/libcrypto/evp/{encode.c => evp_encode.c} | 4 +- lib/libcrypto/evp/evp_lib.c | 565 ---------- lib/libcrypto/evp/evp_local.h | 64 +- lib/libcrypto/evp/p_lib.c | 198 +++- lib/libcrypto/man/BN_generate_prime.3 | 6 +- lib/libcrypto/man/DSA_generate_key.3 | 6 +- ...ameters.3 => DSA_generate_parameters_ex.3} | 64 +- lib/libcrypto/man/DSA_get0_pqg.3 | 6 +- lib/libcrypto/man/DSA_new.3 | 6 +- lib/libcrypto/man/Makefile | 4 +- lib/libcrypto/x509/by_dir.c | 12 +- lib/libcrypto/x509/x509_local.h | 5 +- lib/libssl/ssl_clnt.c | 7 +- lib/libssl/ssl_lib.c | 6 +- lib/libssl/ssl_local.h | 5 +- lib/libssl/ssl_srvr.c | 8 +- lib/libutil/imsg_init.3 | 14 +- regress/lib/libutil/imsg/ibuf_test.c | 3 +- regress/sys/sys/tree/rb/Makefile | 23 +- regress/sys/sys/tree/rb/rb-test.c | 988 ++++++++++++++++-- regress/sys/sys/tree/rb/rbt-test.c | 975 +++++++++++++++++ share/man/man5/login.conf.5 | 6 +- sys/arch/amd64/amd64/pmap.c | 8 +- sys/arch/amd64/include/pmap.h | 4 +- sys/dev/pci/drm/drm_drv.c | 15 +- sys/net/if.c | 15 +- sys/net/if_loop.c | 5 +- usr.bin/openssl/openssl.1 | 7 +- usr.bin/openssl/s_client.c | 12 +- usr.bin/openssl/s_server.c | 4 +- usr.sbin/rpki-client/parser.c | 9 +- usr.sbin/rpki-client/version.h | 4 +- 41 files changed, 3131 insertions(+), 1347 deletions(-) delete mode 100644 lib/libcrypto/evp/cipher_method_lib.c rename lib/libcrypto/evp/{evp_enc.c => evp_cipher.c} (62%) rename lib/libcrypto/evp/{digest.c => evp_digest.c} (77%) rename lib/libcrypto/evp/{encode.c => evp_encode.c} (99%) delete mode 100644 lib/libcrypto/evp/evp_lib.c rename lib/libcrypto/man/{DSA_generate_parameters.3 => DSA_generate_parameters_ex.3} (78%) create mode 100644 regress/sys/sys/tree/rb/rbt-test.c diff --git a/distrib/sets/lists/comp/mi b/distrib/sets/lists/comp/mi index 0ea4fabe8..b63e163b7 100644 --- a/distrib/sets/lists/comp/mi +++ b/distrib/sets/lists/comp/mi @@ -354,6 +354,8 @@ ./usr/include/dev/ic/qlavar.h ./usr/include/dev/ic/qlwreg.h ./usr/include/dev/ic/qlwvar.h +./usr/include/dev/ic/qwxreg.h +./usr/include/dev/ic/qwxvar.h ./usr/include/dev/ic/r92creg.h ./usr/include/dev/ic/ramdac.h ./usr/include/dev/ic/revar.h @@ -1875,7 +1877,7 @@ ./usr/share/man/man3/DSA_do_sign.3 ./usr/share/man/man3/DSA_dup_DH.3 ./usr/share/man/man3/DSA_generate_key.3 -./usr/share/man/man3/DSA_generate_parameters.3 +./usr/share/man/man3/DSA_generate_parameters_ex.3 ./usr/share/man/man3/DSA_get0_pqg.3 ./usr/share/man/man3/DSA_get_ex_new_index.3 ./usr/share/man/man3/DSA_meth_new.3 diff --git a/lib/libcrypto/Makefile b/lib/libcrypto/Makefile index 6329d309e..2a12e43a7 100644 --- a/lib/libcrypto/Makefile +++ b/lib/libcrypto/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.159 2023/12/20 13:52:17 tb Exp $ +# $OpenBSD: Makefile,v 1.162 2023/12/29 06:56:38 tb Exp $ LIB= crypto LIBREBUILD=y @@ -349,8 +349,6 @@ SRCS+= bio_b64.c SRCS+= bio_enc.c SRCS+= bio_md.c SRCS+= c_all.c -SRCS+= cipher_method_lib.c -SRCS+= digest.c SRCS+= e_aes.c SRCS+= e_aes_cbc_hmac_sha1.c SRCS+= e_bf.c @@ -368,12 +366,12 @@ SRCS+= e_rc4.c SRCS+= e_rc4_hmac_md5.c SRCS+= e_sm4.c SRCS+= e_xcbc_d.c -SRCS+= encode.c SRCS+= evp_aead.c -SRCS+= evp_enc.c +SRCS+= evp_cipher.c +SRCS+= evp_digest.c +SRCS+= evp_encode.c SRCS+= evp_err.c SRCS+= evp_key.c -SRCS+= evp_lib.c SRCS+= evp_pbe.c SRCS+= evp_pkey.c SRCS+= m_gost2814789.c diff --git a/lib/libcrypto/asn1/ameth_lib.c b/lib/libcrypto/asn1/ameth_lib.c index 656d9036f..ccde1e8ec 100644 --- a/lib/libcrypto/asn1/ameth_lib.c +++ b/lib/libcrypto/asn1/ameth_lib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ameth_lib.c,v 1.37 2023/12/15 21:55:47 tb Exp $ */ +/* $OpenBSD: ameth_lib.c,v 1.41 2023/12/29 19:00:31 tb Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2006. */ @@ -62,159 +62,11 @@ #include #include -#include "asn1_local.h" #include "evp_local.h" -extern const EVP_PKEY_ASN1_METHOD cmac_asn1_meth; -extern const EVP_PKEY_ASN1_METHOD dh_asn1_meth; -extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[]; -extern const EVP_PKEY_ASN1_METHOD eckey_asn1_meth; -extern const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth; -extern const EVP_PKEY_ASN1_METHOD gostimit_asn1_meth; -extern const EVP_PKEY_ASN1_METHOD gostr01_asn1_meths[]; -extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth; -extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[]; -extern const EVP_PKEY_ASN1_METHOD rsa_pss_asn1_meth; -extern const EVP_PKEY_ASN1_METHOD x25519_asn1_meth; - -static const EVP_PKEY_ASN1_METHOD *asn1_methods[] = { - &cmac_asn1_meth, - &dh_asn1_meth, - &dsa_asn1_meths[0], - &dsa_asn1_meths[1], - &dsa_asn1_meths[2], - &dsa_asn1_meths[3], - &dsa_asn1_meths[4], - &eckey_asn1_meth, - &ed25519_asn1_meth, - &gostimit_asn1_meth, - &gostr01_asn1_meths[0], - &gostr01_asn1_meths[1], - &gostr01_asn1_meths[2], - &hmac_asn1_meth, - &rsa_asn1_meths[0], - &rsa_asn1_meths[1], - &rsa_pss_asn1_meth, - &x25519_asn1_meth, -}; - -#define N_ASN1_METHODS (sizeof(asn1_methods) / sizeof(asn1_methods[0])) - -int -EVP_PKEY_asn1_get_count(void) -{ - return N_ASN1_METHODS; -} - -const EVP_PKEY_ASN1_METHOD * -EVP_PKEY_asn1_get0(int idx) -{ - if (idx < 0 || idx >= N_ASN1_METHODS) - return NULL; - - return asn1_methods[idx]; -} - -static const EVP_PKEY_ASN1_METHOD * -pkey_asn1_find(int pkey_id) -{ - const EVP_PKEY_ASN1_METHOD *ameth; - int i; - - for (i = EVP_PKEY_asn1_get_count() - 1; i >= 0; i--) { - ameth = EVP_PKEY_asn1_get0(i); - if (ameth->pkey_id == pkey_id) - return ameth; - } - - return NULL; -} - /* - * Find an implementation of an ASN1 algorithm. If 'pe' is not NULL - * also search through engines and set *pe to a functional reference - * to the engine implementing 'type' or NULL if no engine implements - * it. + * XXX - remove all the API below here in the next major bump. */ -const EVP_PKEY_ASN1_METHOD * -EVP_PKEY_asn1_find(ENGINE **pe, int type) -{ - const EVP_PKEY_ASN1_METHOD *mp; - - if (pe != NULL) - *pe = NULL; - - for (;;) { - if ((mp = pkey_asn1_find(type)) == NULL) - break; - if ((mp->pkey_flags & ASN1_PKEY_ALIAS) == 0) - break; - type = mp->pkey_base_id; - } - - return mp; -} - -const EVP_PKEY_ASN1_METHOD * -EVP_PKEY_asn1_find_str(ENGINE **pe, const char *str, int len) -{ - const EVP_PKEY_ASN1_METHOD *ameth; - int i; - - if (len == -1) - len = strlen(str); - if (pe != NULL) - *pe = NULL; - for (i = EVP_PKEY_asn1_get_count() - 1; i >= 0; i--) { - ameth = EVP_PKEY_asn1_get0(i); - if (ameth->pkey_flags & ASN1_PKEY_ALIAS) - continue; - if (((int)strlen(ameth->pem_str) == len) && - !strncasecmp(ameth->pem_str, str, len)) - return ameth; - } - return NULL; -} - -int -EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth) -{ - EVPerror(ERR_R_DISABLED); - return 0; -} - -int -EVP_PKEY_asn1_add_alias(int to, int from) -{ - EVPerror(ERR_R_DISABLED); - return 0; -} - -int -EVP_PKEY_asn1_get0_info(int *ppkey_id, int *ppkey_base_id, int *ppkey_flags, - const char **pinfo, const char **ppem_str, - const EVP_PKEY_ASN1_METHOD *ameth) -{ - if (!ameth) - return 0; - if (ppkey_id) - *ppkey_id = ameth->pkey_id; - if (ppkey_base_id) - *ppkey_base_id = ameth->pkey_base_id; - if (ppkey_flags) - *ppkey_flags = ameth->pkey_flags; - if (pinfo) - *pinfo = ameth->info; - if (ppem_str) - *ppem_str = ameth->pem_str; - return 1; -} - -const EVP_PKEY_ASN1_METHOD* -EVP_PKEY_get0_asn1(const EVP_PKEY *pkey) -{ - return pkey->ameth; -} EVP_PKEY_ASN1_METHOD* EVP_PKEY_asn1_new(int id, int flags, const char *pem_str, const char *info) @@ -364,3 +216,17 @@ EVP_PKEY_asn1_set_param_check(EVP_PKEY_ASN1_METHOD *ameth, { ameth->pkey_param_check = pkey_param_check; } + +int +EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth) +{ + EVPerror(ERR_R_DISABLED); + return 0; +} + +int +EVP_PKEY_asn1_add_alias(int to, int from) +{ + EVPerror(ERR_R_DISABLED); + return 0; +} diff --git a/lib/libcrypto/asn1/asn1_local.h b/lib/libcrypto/asn1/asn1_local.h index 566ace798..c1dfa6f68 100644 --- a/lib/libcrypto/asn1/asn1_local.h +++ b/lib/libcrypto/asn1/asn1_local.h @@ -1,4 +1,4 @@ -/* $OpenBSD: asn1_local.h,v 1.4 2023/07/28 10:00:10 tb Exp $ */ +/* $OpenBSD: asn1_local.h,v 1.5 2023/12/29 10:59:00 tb Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2006. */ @@ -89,70 +89,6 @@ struct asn1_pctx_st { unsigned long str_flags; } /* ASN1_PCTX */; -/* ASN1 public key method structure */ - -struct evp_pkey_asn1_method_st { - int pkey_id; - int pkey_base_id; - unsigned long pkey_flags; - - char *pem_str; - char *info; - - int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub); - int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk); - int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b); - int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *pctx); - - int (*priv_decode)(EVP_PKEY *pk, const PKCS8_PRIV_KEY_INFO *p8inf); - int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk); - int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *pctx); - - int (*pkey_size)(const EVP_PKEY *pk); - int (*pkey_bits)(const EVP_PKEY *pk); - int (*pkey_security_bits)(const EVP_PKEY *pk); - - int (*param_decode)(EVP_PKEY *pkey, const unsigned char **pder, - int derlen); - int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder); - int (*param_missing)(const EVP_PKEY *pk); - int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from); - int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b); - int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *pctx); - int (*sig_print)(BIO *out, const X509_ALGOR *sigalg, - const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx); - - void (*pkey_free)(EVP_PKEY *pkey); - int (*pkey_ctrl)(EVP_PKEY *pkey, int op, long arg1, void *arg2); - - /* Legacy functions for old PEM */ - - int (*old_priv_decode)(EVP_PKEY *pkey, const unsigned char **pder, - int derlen); - int (*old_priv_encode)(const EVP_PKEY *pkey, unsigned char **pder); - /* Custom ASN1 signature verification */ - int (*item_verify)(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, - X509_ALGOR *a, ASN1_BIT_STRING *sig, EVP_PKEY *pkey); - int (*item_sign)(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, - X509_ALGOR *alg1, X509_ALGOR *alg2, ASN1_BIT_STRING *sig); - - int (*pkey_check)(const EVP_PKEY *pk); - int (*pkey_public_check)(const EVP_PKEY *pk); - int (*pkey_param_check)(const EVP_PKEY *pk); - - int (*set_priv_key)(EVP_PKEY *pk, const unsigned char *private_key, - size_t len); - int (*set_pub_key)(EVP_PKEY *pk, const unsigned char *public_key, - size_t len); - int (*get_priv_key)(const EVP_PKEY *pk, unsigned char *out_private_key, - size_t *out_len); - int (*get_pub_key)(const EVP_PKEY *pk, unsigned char *out_public_key, - size_t *out_len); -} /* EVP_PKEY_ASN1_METHOD */; - /* Method to handle CRL access. * In general a CRL could be very large (several Mb) and can consume large * amounts of resources if stored in memory by multiple processes. diff --git a/lib/libcrypto/asn1/t_x509.c b/lib/libcrypto/asn1/t_x509.c index cd98997f6..6f7bdc79f 100644 --- a/lib/libcrypto/asn1/t_x509.c +++ b/lib/libcrypto/asn1/t_x509.c @@ -1,4 +1,4 @@ -/* $OpenBSD: t_x509.c,v 1.43 2023/07/07 19:37:52 beck Exp $ */ +/* $OpenBSD: t_x509.c,v 1.44 2023/12/29 10:59:00 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -77,7 +77,7 @@ #include #endif -#include "asn1_local.h" +#include "evp_local.h" #include "x509_local.h" int diff --git a/lib/libcrypto/ec/ec_ameth.c b/lib/libcrypto/ec/ec_ameth.c index 324865870..c22f38b34 100644 --- a/lib/libcrypto/ec/ec_ameth.c +++ b/lib/libcrypto/ec/ec_ameth.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ec_ameth.c,v 1.45 2023/09/24 08:08:54 tb Exp $ */ +/* $OpenBSD: ec_ameth.c,v 1.50 2023/12/29 18:49:06 tb Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2006. */ @@ -264,8 +264,8 @@ eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) goto err; - X509_ALGOR_get0(NULL, &ptype, &pval, palg); + X509_ALGOR_get0(NULL, &ptype, &pval, palg); if (!eckey_from_params(ptype, pval, &eckey)) goto err; @@ -301,69 +301,73 @@ eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) return -2; } +static int +eckey_compute_pubkey(EC_KEY *eckey) +{ + const BIGNUM *priv_key; + const EC_GROUP *group; + EC_POINT *pub_key = NULL; + int ret = 0; + + if ((priv_key = EC_KEY_get0_private_key(eckey)) == NULL) + goto err; + if ((group = EC_KEY_get0_group(eckey)) == NULL) + goto err; + if ((pub_key = EC_POINT_new(group)) == NULL) + goto err; + if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL)) + goto err; + if (!EC_KEY_set_public_key(eckey, pub_key)) + goto err; + pub_key = NULL; + + ret = 1; + + err: + EC_POINT_free(pub_key); + + return ret; +} + static int eckey_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8) { - const unsigned char *p = NULL; + const unsigned char *priv = NULL; + int priv_len; const void *pval; - int ptype, pklen; + int ptype; EC_KEY *eckey = NULL; const X509_ALGOR *palg; + int ret = 0; + + if (!PKCS8_pkey_get0(NULL, &priv, &priv_len, &palg, p8)) + goto err; - if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) - return 0; X509_ALGOR_get0(NULL, &ptype, &pval, palg); - if (!eckey_from_params(ptype, pval, &eckey)) - goto ecliberr; + goto err; - /* We have parameters now set private key */ - if (!d2i_ECPrivateKey(&eckey, &p, pklen)) { + /* Decode private key into eckey. */ + if (d2i_ECPrivateKey(&eckey, &priv, priv_len) == NULL) { ECerror(EC_R_DECODE_ERROR); - goto ecerr; + goto err; } - /* calculate public key (if necessary) */ + /* If public key was missing from SEC1 key, compute it. */ if (EC_KEY_get0_public_key(eckey) == NULL) { - const BIGNUM *priv_key; - const EC_GROUP *group; - EC_POINT *pub_key; - /* - * the public key was not included in the SEC1 private key => - * calculate the public key - */ - group = EC_KEY_get0_group(eckey); - pub_key = EC_POINT_new(group); - if (pub_key == NULL) { - ECerror(ERR_R_EC_LIB); - goto ecliberr; - } - if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) { - EC_POINT_free(pub_key); - ECerror(ERR_R_EC_LIB); - goto ecliberr; - } - priv_key = EC_KEY_get0_private_key(eckey); - if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL)) { - EC_POINT_free(pub_key); - ECerror(ERR_R_EC_LIB); - goto ecliberr; - } - if (EC_KEY_set_public_key(eckey, pub_key) == 0) { - EC_POINT_free(pub_key); - ECerror(ERR_R_EC_LIB); - goto ecliberr; - } - EC_POINT_free(pub_key); + if (!eckey_compute_pubkey(eckey)) + goto err; } - EVP_PKEY_assign_EC_KEY(pkey, eckey); - return 1; - ecliberr: - ECerror(ERR_R_EC_LIB); - ecerr: - if (eckey) - EC_KEY_free(eckey); - return 0; + if (!EVP_PKEY_assign_EC_KEY(pkey, eckey)) + goto err; + eckey = NULL; + + ret = 1; + + err: + EC_KEY_free(eckey); + + return ret; } static int @@ -547,63 +551,74 @@ do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) } static int -eckey_param_decode(EVP_PKEY *pkey, - const unsigned char **pder, int derlen) +eckey_param_decode(EVP_PKEY *pkey, const unsigned char **param, int param_len) { EC_KEY *eckey; - if (!(eckey = d2i_ECParameters(NULL, pder, derlen))) { - ECerror(ERR_R_EC_LIB); - return 0; - } - EVP_PKEY_assign_EC_KEY(pkey, eckey); - return 1; + int ret = 0; + + if ((eckey = d2i_ECParameters(NULL, param, param_len)) == NULL) + goto err; + if (!EVP_PKEY_assign_EC_KEY(pkey, eckey)) + goto err; + eckey = NULL; + + ret = 1; + + err: + EC_KEY_free(eckey); + + return ret; } static int -eckey_param_encode(const EVP_PKEY *pkey, unsigned char **pder) +eckey_param_encode(const EVP_PKEY *pkey, unsigned char **param) { - return i2d_ECParameters(pkey->pkey.ec, pder); + return i2d_ECParameters(pkey->pkey.ec, param); } static int -eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *ctx) +eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx) { return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0); } static int -eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *ctx) +eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx) { return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1); } static int -eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *ctx) +eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx) { return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2); } static int -old_ec_priv_decode(EVP_PKEY *pkey, - const unsigned char **pder, int derlen) +old_ec_priv_decode(EVP_PKEY *pkey, const unsigned char **priv, int priv_len) { - EC_KEY *ec; - if (!(ec = d2i_ECPrivateKey(NULL, pder, derlen))) { - ECerror(EC_R_DECODE_ERROR); - return 0; - } - EVP_PKEY_assign_EC_KEY(pkey, ec); - return 1; + EC_KEY *eckey; + int ret = 0; + + if ((eckey = d2i_ECPrivateKey(NULL, priv, priv_len)) == NULL) + goto err; + if (!EVP_PKEY_assign_EC_KEY(pkey, eckey)) + goto err; + eckey = NULL; + + ret = 1; + + err: + EC_KEY_free(eckey); + + return ret; } static int -old_ec_priv_encode(const EVP_PKEY *pkey, unsigned char **pder) +old_ec_priv_encode(const EVP_PKEY *pkey, unsigned char **priv) { - return i2d_ECPrivateKey(pkey->pkey.ec, pder); + return i2d_ECPrivateKey(pkey->pkey.ec, priv); } static int diff --git a/lib/libcrypto/evp/cipher_method_lib.c b/lib/libcrypto/evp/cipher_method_lib.c deleted file mode 100644 index d3931522d..000000000 --- a/lib/libcrypto/evp/cipher_method_lib.c +++ /dev/null @@ -1,185 +0,0 @@ -/* $OpenBSD: cipher_method_lib.c,v 1.11 2023/12/20 14:05:58 tb Exp $ */ -/* - * Written by Richard Levitte (levitte@openssl.org) for the OpenSSL project - * 2015. - */ -/* ==================================================================== - * Copyright (c) 2015 The OpenSSL 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 OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL 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 OpenSSL 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. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include - -#include - -#include "evp_local.h" - -EVP_CIPHER * -EVP_CIPHER_meth_new(int cipher_type, int block_size, int key_len) -{ - EVP_CIPHER *cipher; - - if (cipher_type < 0 || key_len < 0) - return NULL; - - /* EVP_CipherInit() will fail for any other value. */ - if (block_size != 1 && block_size != 8 && block_size != 16) - return NULL; - - if ((cipher = calloc(1, sizeof(*cipher))) == NULL) - return NULL; - - cipher->nid = cipher_type; - cipher->block_size = block_size; - cipher->key_len = key_len; - - return cipher; -} - -EVP_CIPHER * -EVP_CIPHER_meth_dup(const EVP_CIPHER *cipher) -{ - EVP_CIPHER *copy; - - if ((copy = calloc(1, sizeof(*copy))) == NULL) - return NULL; - - *copy = *cipher; - - return copy; -} - -void -EVP_CIPHER_meth_free(EVP_CIPHER *cipher) -{ - free(cipher); -} - -int -EVP_CIPHER_meth_set_iv_length(EVP_CIPHER *cipher, int iv_len) -{ - cipher->iv_len = iv_len; - - return 1; -} - -int -EVP_CIPHER_meth_set_flags(EVP_CIPHER *cipher, unsigned long flags) -{ - cipher->flags = flags; - - return 1; -} - -int -EVP_CIPHER_meth_set_impl_ctx_size(EVP_CIPHER *cipher, int ctx_size) -{ - cipher->ctx_size = ctx_size; - - return 1; -} - -int -EVP_CIPHER_meth_set_init(EVP_CIPHER *cipher, - int (*init)(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc)) -{ - cipher->init = init; - - return 1; -} - -int -EVP_CIPHER_meth_set_do_cipher(EVP_CIPHER *cipher, - int (*do_cipher)(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl)) -{ - cipher->do_cipher = do_cipher; - - return 1; -} - -int -EVP_CIPHER_meth_set_cleanup(EVP_CIPHER *cipher, - int (*cleanup)(EVP_CIPHER_CTX *)) -{ - cipher->cleanup = cleanup; - - return 1; -} - -int -EVP_CIPHER_meth_set_set_asn1_params(EVP_CIPHER *cipher, - int (*set_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *)) -{ - cipher->set_asn1_parameters = set_asn1_parameters; - - return 1; -} - -int -EVP_CIPHER_meth_set_get_asn1_params(EVP_CIPHER *cipher, - int (*get_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *)) -{ - cipher->get_asn1_parameters = get_asn1_parameters; - - return 1; -} - -int -EVP_CIPHER_meth_set_ctrl(EVP_CIPHER *cipher, - int (*ctrl)(EVP_CIPHER_CTX *, int type, int arg, void *ptr)) -{ - cipher->ctrl = ctrl; - - return 1; -} diff --git a/lib/libcrypto/evp/evp_enc.c b/lib/libcrypto/evp/evp_cipher.c similarity index 62% rename from lib/libcrypto/evp/evp_enc.c rename to lib/libcrypto/evp/evp_cipher.c index 3eef53c2d..751360cd7 100644 --- a/lib/libcrypto/evp/evp_enc.c +++ b/lib/libcrypto/evp/evp_cipher.c @@ -1,4 +1,4 @@ -/* $OpenBSD: evp_enc.c,v 1.81 2023/12/26 09:04:30 tb Exp $ */ +/* $OpenBSD: evp_cipher.c,v 1.3 2023/12/29 06:56:38 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -55,17 +55,70 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ +/* ==================================================================== + * Copyright (c) 2015 The OpenSSL 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 OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL 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 OpenSSL 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. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ #include #include #include #include -#include - +#include #include #include +#include "asn1_local.h" #include "evp_local.h" int @@ -685,3 +738,419 @@ EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in) return 1; } + +int +EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type) +{ + int ret; + + if (c->cipher->set_asn1_parameters != NULL) + ret = c->cipher->set_asn1_parameters(c, type); + else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) + ret = EVP_CIPHER_set_asn1_iv(c, type); + else + ret = -1; + return (ret); +} + +int +EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type) +{ + int ret; + + if (c->cipher->get_asn1_parameters != NULL) + ret = c->cipher->get_asn1_parameters(c, type); + else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) + ret = EVP_CIPHER_get_asn1_iv(c, type); + else + ret = -1; + return (ret); +} + +int +EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) +{ + int i = 0; + int l; + + if (type != NULL) { + l = EVP_CIPHER_CTX_iv_length(c); + if (l < 0 || l > sizeof(c->iv)) { + EVPerror(EVP_R_IV_TOO_LARGE); + return 0; + } + i = ASN1_TYPE_get_octetstring(type, c->oiv, l); + if (i != l) + return (-1); + else if (i > 0) + memcpy(c->iv, c->oiv, l); + } + return (i); +} + +int +EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) +{ + int i = 0; + int j; + + if (type != NULL) { + j = EVP_CIPHER_CTX_iv_length(c); + if (j < 0 || j > sizeof(c->iv)) { + EVPerror(EVP_R_IV_TOO_LARGE); + return 0; + } + i = ASN1_TYPE_set_octetstring(type, c->oiv, j); + } + return (i); +} + +/* Convert the various cipher NIDs and dummies to a proper OID NID */ +int +EVP_CIPHER_type(const EVP_CIPHER *ctx) +{ + int nid; + ASN1_OBJECT *otmp; + nid = EVP_CIPHER_nid(ctx); + + switch (nid) { + case NID_rc2_cbc: + case NID_rc2_64_cbc: + case NID_rc2_40_cbc: + return NID_rc2_cbc; + + case NID_rc4: + case NID_rc4_40: + return NID_rc4; + + case NID_aes_128_cfb128: + case NID_aes_128_cfb8: + case NID_aes_128_cfb1: + return NID_aes_128_cfb128; + + case NID_aes_192_cfb128: + case NID_aes_192_cfb8: + case NID_aes_192_cfb1: + return NID_aes_192_cfb128; + + case NID_aes_256_cfb128: + case NID_aes_256_cfb8: + case NID_aes_256_cfb1: + return NID_aes_256_cfb128; + + case NID_des_cfb64: + case NID_des_cfb8: + case NID_des_cfb1: + return NID_des_cfb64; + + case NID_des_ede3_cfb64: + case NID_des_ede3_cfb8: + case NID_des_ede3_cfb1: + return NID_des_cfb64; + + default: + /* Check it has an OID and it is valid */ + otmp = OBJ_nid2obj(nid); + if (!otmp || !otmp->data) + nid = NID_undef; + ASN1_OBJECT_free(otmp); + return nid; + } +} + +int +EVP_CIPHER_block_size(const EVP_CIPHER *e) +{ + return e->block_size; +} + +int +EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx) +{ + return ctx->cipher->block_size; +} + +const EVP_CIPHER * +EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx) +{ + return ctx->cipher; +} + +int +EVP_CIPHER_CTX_encrypting(const EVP_CIPHER_CTX *ctx) +{ + return ctx->encrypt; +} + +unsigned long +EVP_CIPHER_flags(const EVP_CIPHER *cipher) +{ + return cipher->flags; +} + +unsigned long +EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx) +{ + return ctx->cipher->flags; +} + +void * +EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx) +{ + return ctx->app_data; +} + +void +EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data) +{ + ctx->app_data = data; +} + +void * +EVP_CIPHER_CTX_get_cipher_data(const EVP_CIPHER_CTX *ctx) +{ + return ctx->cipher_data; +} + +void * +EVP_CIPHER_CTX_set_cipher_data(EVP_CIPHER_CTX *ctx, void *cipher_data) +{ + void *old_cipher_data; + + old_cipher_data = ctx->cipher_data; + ctx->cipher_data = cipher_data; + + return old_cipher_data; +} + +int +EVP_CIPHER_iv_length(const EVP_CIPHER *cipher) +{ + return cipher->iv_len; +} + +int +EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx) +{ + int iv_length = 0; + + if ((ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_IV_LENGTH) == 0) + return ctx->cipher->iv_len; + + /* + * XXX - sanity would suggest to pass the size of the pointer along, + * but unfortunately we have to match the other crowd. + */ + if (EVP_CIPHER_CTX_ctrl((EVP_CIPHER_CTX *)ctx, EVP_CTRL_GET_IVLEN, 0, + &iv_length) != 1) + return -1; + + return iv_length; +} + +unsigned char * +EVP_CIPHER_CTX_buf_noconst(EVP_CIPHER_CTX *ctx) +{ + return ctx->buf; +} + +int +EVP_CIPHER_key_length(const EVP_CIPHER *cipher) +{ + return cipher->key_len; +} + +int +EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx) +{ + return ctx->key_len; +} + +int +EVP_CIPHER_nid(const EVP_CIPHER *cipher) +{ + return cipher->nid; +} + +int +EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx) +{ + return ctx->cipher->nid; +} + +int +EVP_CIPHER_CTX_get_iv(const EVP_CIPHER_CTX *ctx, unsigned char *iv, size_t len) +{ + if (ctx == NULL || len != EVP_CIPHER_CTX_iv_length(ctx)) + return 0; + if (len > EVP_MAX_IV_LENGTH) + return 0; /* sanity check; shouldn't happen */ + /* + * Skip the memcpy entirely when the requested IV length is zero, + * since the iv pointer may be NULL or invalid. + */ + if (len != 0) { + if (iv == NULL) + return 0; + memcpy(iv, ctx->iv, len); + } + return 1; +} + +int +EVP_CIPHER_CTX_set_iv(EVP_CIPHER_CTX *ctx, const unsigned char *iv, size_t len) +{ + if (ctx == NULL || len != EVP_CIPHER_CTX_iv_length(ctx)) + return 0; + if (len > EVP_MAX_IV_LENGTH) + return 0; /* sanity check; shouldn't happen */ + /* + * Skip the memcpy entirely when the requested IV length is zero, + * since the iv pointer may be NULL or invalid. + */ + if (len != 0) { + if (iv == NULL) + return 0; + memcpy(ctx->iv, iv, len); + } + return 1; +} + +void +EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags) +{ + ctx->flags |= flags; +} + +void +EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags) +{ + ctx->flags &= ~flags; +} + +int +EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags) +{ + return (ctx->flags & flags); +} + +EVP_CIPHER * +EVP_CIPHER_meth_new(int cipher_type, int block_size, int key_len) +{ + EVP_CIPHER *cipher; + + if (cipher_type < 0 || key_len < 0) + return NULL; + + /* EVP_CipherInit() will fail for any other value. */ + if (block_size != 1 && block_size != 8 && block_size != 16) + return NULL; + + if ((cipher = calloc(1, sizeof(*cipher))) == NULL) + return NULL; + + cipher->nid = cipher_type; + cipher->block_size = block_size; + cipher->key_len = key_len; + + return cipher; +} + +EVP_CIPHER * +EVP_CIPHER_meth_dup(const EVP_CIPHER *cipher) +{ + EVP_CIPHER *copy; + + if ((copy = calloc(1, sizeof(*copy))) == NULL) + return NULL; + + *copy = *cipher; + + return copy; +} + +void +EVP_CIPHER_meth_free(EVP_CIPHER *cipher) +{ + free(cipher); +} + +int +EVP_CIPHER_meth_set_iv_length(EVP_CIPHER *cipher, int iv_len) +{ + cipher->iv_len = iv_len; + + return 1; +} + +int +EVP_CIPHER_meth_set_flags(EVP_CIPHER *cipher, unsigned long flags) +{ + cipher->flags = flags; + + return 1; +} + +int +EVP_CIPHER_meth_set_impl_ctx_size(EVP_CIPHER *cipher, int ctx_size) +{ + cipher->ctx_size = ctx_size; + + return 1; +} + +int +EVP_CIPHER_meth_set_init(EVP_CIPHER *cipher, + int (*init)(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc)) +{ + cipher->init = init; + + return 1; +} + +int +EVP_CIPHER_meth_set_do_cipher(EVP_CIPHER *cipher, + int (*do_cipher)(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl)) +{ + cipher->do_cipher = do_cipher; + + return 1; +} + +int +EVP_CIPHER_meth_set_cleanup(EVP_CIPHER *cipher, + int (*cleanup)(EVP_CIPHER_CTX *)) +{ + cipher->cleanup = cleanup; + + return 1; +} + +int +EVP_CIPHER_meth_set_set_asn1_params(EVP_CIPHER *cipher, + int (*set_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *)) +{ + cipher->set_asn1_parameters = set_asn1_parameters; + + return 1; +} + +int +EVP_CIPHER_meth_set_get_asn1_params(EVP_CIPHER *cipher, + int (*get_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *)) +{ + cipher->get_asn1_parameters = get_asn1_parameters; + + return 1; +} + +int +EVP_CIPHER_meth_set_ctrl(EVP_CIPHER *cipher, + int (*ctrl)(EVP_CIPHER_CTX *, int type, int arg, void *ptr)) +{ + cipher->ctrl = ctrl; + + return 1; +} diff --git a/lib/libcrypto/evp/digest.c b/lib/libcrypto/evp/evp_digest.c similarity index 77% rename from lib/libcrypto/evp/digest.c rename to lib/libcrypto/evp/evp_digest.c index 56decc231..166b04562 100644 --- a/lib/libcrypto/evp/digest.c +++ b/lib/libcrypto/evp/evp_digest.c @@ -1,4 +1,4 @@ -/* $OpenBSD: digest.c,v 1.41 2023/12/24 22:17:05 tb Exp $ */ +/* $OpenBSD: evp_digest.c,v 1.7 2023/12/29 07:22:47 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -217,6 +217,72 @@ EVP_Digest(const void *data, size_t count, return ret; } +EVP_MD_CTX * +EVP_MD_CTX_new(void) +{ + return calloc(1, sizeof(EVP_MD_CTX)); +} + +void +EVP_MD_CTX_free(EVP_MD_CTX *ctx) +{ + if (ctx == NULL) + return; + + EVP_MD_CTX_cleanup(ctx); + + free(ctx); +} + +EVP_MD_CTX * +EVP_MD_CTX_create(void) +{ + return EVP_MD_CTX_new(); +} + +void +EVP_MD_CTX_destroy(EVP_MD_CTX *ctx) +{ + EVP_MD_CTX_free(ctx); +} + +void +EVP_MD_CTX_init(EVP_MD_CTX *ctx) +{ + memset(ctx, 0, sizeof(*ctx)); +} + +int +EVP_MD_CTX_reset(EVP_MD_CTX *ctx) +{ + return EVP_MD_CTX_cleanup(ctx); +} + +/* This call frees resources associated with the context */ +int +EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) +{ + /* + * Don't assume ctx->md_data was cleaned in EVP_Digest_Final, + * because sometimes only copies of the context are ever finalised. + */ + if (ctx->digest && ctx->digest->cleanup && + !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_CLEANED)) + ctx->digest->cleanup(ctx); + if (ctx->digest && ctx->digest->ctx_size && ctx->md_data && + !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) + freezero(ctx->md_data, ctx->digest->ctx_size); + /* + * If EVP_MD_CTX_FLAG_KEEP_PKEY_CTX is set, EVP_MD_CTX_set_pkey() was + * called and its strange API contract implies we don't own ctx->pctx. + */ + if (!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX)) + EVP_PKEY_CTX_free(ctx->pctx); + memset(ctx, 0, sizeof(*ctx)); + + return 1; +} + int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in) { @@ -279,72 +345,6 @@ EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) return 1; } -EVP_MD_CTX * -EVP_MD_CTX_new(void) -{ - return calloc(1, sizeof(EVP_MD_CTX)); -} - -void -EVP_MD_CTX_free(EVP_MD_CTX *ctx) -{ - if (ctx == NULL) - return; - - EVP_MD_CTX_cleanup(ctx); - - free(ctx); -} - -void -EVP_MD_CTX_init(EVP_MD_CTX *ctx) -{ - memset(ctx, 0, sizeof(*ctx)); -} - -int -EVP_MD_CTX_reset(EVP_MD_CTX *ctx) -{ - return EVP_MD_CTX_cleanup(ctx); -} - -EVP_MD_CTX * -EVP_MD_CTX_create(void) -{ - return EVP_MD_CTX_new(); -} - -void -EVP_MD_CTX_destroy(EVP_MD_CTX *ctx) -{ - EVP_MD_CTX_free(ctx); -} - -/* This call frees resources associated with the context */ -int -EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) -{ - /* - * Don't assume ctx->md_data was cleaned in EVP_Digest_Final, - * because sometimes only copies of the context are ever finalised. - */ - if (ctx->digest && ctx->digest->cleanup && - !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_CLEANED)) - ctx->digest->cleanup(ctx); - if (ctx->digest && ctx->digest->ctx_size && ctx->md_data && - !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) - freezero(ctx->md_data, ctx->digest->ctx_size); - /* - * If EVP_MD_CTX_FLAG_KEEP_PKEY_CTX is set, EVP_MD_CTX_set_pkey() was - * called and its strange API contract implies we don't own ctx->pctx. - */ - if (!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX)) - EVP_PKEY_CTX_free(ctx->pctx); - memset(ctx, 0, sizeof(*ctx)); - - return 1; -} - int EVP_MD_CTX_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr) { @@ -367,3 +367,210 @@ EVP_MD_CTX_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr) } return ret; } + +const EVP_MD * +EVP_MD_CTX_md(const EVP_MD_CTX *ctx) +{ + if (!ctx) + return NULL; + return ctx->digest; +} + +void +EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags) +{ + ctx->flags &= ~flags; +} + +void +EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags) +{ + ctx->flags |= flags; +} + +int +EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, int flags) +{ + return (ctx->flags & flags); +} + +void * +EVP_MD_CTX_md_data(const EVP_MD_CTX *ctx) +{ + return ctx->md_data; +} + +EVP_PKEY_CTX * +EVP_MD_CTX_pkey_ctx(const EVP_MD_CTX *ctx) +{ + return ctx->pctx; +} + +void +EVP_MD_CTX_set_pkey_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pctx) +{ + if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX)) { + EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX); + } else { + EVP_PKEY_CTX_free(ctx->pctx); + } + + ctx->pctx = pctx; + + if (pctx != NULL) { + /* + * For unclear reasons it was decided that the caller keeps + * ownership of pctx. So a flag was invented to make sure we + * don't free it in EVP_MD_CTX_cleanup(). We also need to + * unset it in EVP_MD_CTX_copy_ex(). Fortunately, the flag + * isn't public... + */ + EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX); + } +} + +int +EVP_MD_type(const EVP_MD *md) +{ + return md->type; +} + +int +EVP_MD_pkey_type(const EVP_MD *md) +{ + return md->pkey_type; +} + +int +EVP_MD_size(const EVP_MD *md) +{ + if (!md) { + EVPerror(EVP_R_MESSAGE_DIGEST_IS_NULL); + return -1; + } + return md->md_size; +} + +unsigned long +EVP_MD_flags(const EVP_MD *md) +{ + return md->flags; +} + +int +EVP_MD_block_size(const EVP_MD *md) +{ + return md->block_size; +} + +/* + * XXX - remove everything below in the next bump. + */ + +EVP_MD * +EVP_MD_meth_new(int md_type, int pkey_type) +{ + EVP_MD *md; + + if ((md = calloc(1, sizeof(*md))) == NULL) + return NULL; + + md->type = md_type; + md->pkey_type = pkey_type; + + return md; +} + +EVP_MD * +EVP_MD_meth_dup(const EVP_MD *md) +{ + EVP_MD *to; + + if ((to = EVP_MD_meth_new(md->type, md->pkey_type)) == NULL) + return NULL; + + memcpy(to, md, sizeof(*to)); + + return to; +} + +void +EVP_MD_meth_free(EVP_MD *md) +{ + freezero(md, sizeof(*md)); +} + +int +EVP_MD_meth_set_input_blocksize(EVP_MD *md, int blocksize) +{ + md->block_size = blocksize; + return 1; +} + +int +EVP_MD_meth_set_result_size(EVP_MD *md, int result_size) +{ + md->md_size = result_size; + return 1; +} + +int +EVP_MD_meth_set_app_datasize(EVP_MD *md, int datasize) +{ + md->ctx_size = datasize; + return 1; +} + +int +EVP_MD_meth_set_flags(EVP_MD *md, unsigned long flags) +{ + md->flags = flags; + return 1; +} + +int +EVP_MD_meth_set_init(EVP_MD *md, int (*init)(EVP_MD_CTX *ctx)) +{ + md->init = init; + return 1; +} + +int +EVP_MD_meth_set_update(EVP_MD *md, + int (*update)(EVP_MD_CTX *ctx, const void *data, size_t count)) +{ + md->update = update; + return 1; +} + +int +EVP_MD_meth_set_final(EVP_MD *md, + int (*final)(EVP_MD_CTX *ctx, unsigned char *md)) +{ + md->final = final; + return 1; +} + +int +EVP_MD_meth_set_copy(EVP_MD *md, + int (*copy)(EVP_MD_CTX *to, const EVP_MD_CTX *from)) +{ + md->copy = copy; + return 1; +} + +int +EVP_MD_meth_set_cleanup(EVP_MD *md, + int (*cleanup)(EVP_MD_CTX *ctx)) +{ + md->cleanup = cleanup; + return 1; +} + +int +EVP_MD_meth_set_ctrl(EVP_MD *md, + int (*ctrl)(EVP_MD_CTX *ctx, int cmd, int p1, void *p2)) +{ + md->md_ctrl = ctrl; + return 1; +} diff --git a/lib/libcrypto/evp/encode.c b/lib/libcrypto/evp/evp_encode.c similarity index 99% rename from lib/libcrypto/evp/encode.c rename to lib/libcrypto/evp/evp_encode.c index c62a1dea8..199bdfa27 100644 --- a/lib/libcrypto/evp/encode.c +++ b/lib/libcrypto/evp/evp_encode.c @@ -1,4 +1,4 @@ -/* $OpenBSD: encode.c,v 1.32 2023/07/07 19:37:53 beck Exp $ */ +/* $OpenBSD: evp_encode.c,v 1.2 2023/12/29 10:31:50 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -92,7 +92,7 @@ abcdefghijklmnopqrstuvwxyz0123456789+/"; #define B64_CR 0xF1 #define B64_EOF 0xF2 #define B64_WS 0xE0 -#define B64_ERROR 0xFF +#define B64_ERROR 0xFF #define B64_NOT_BASE64(a) (((a)|0x13) == 0xF3) #define B64_BASE64(a) !B64_NOT_BASE64(a) diff --git a/lib/libcrypto/evp/evp_lib.c b/lib/libcrypto/evp/evp_lib.c deleted file mode 100644 index 622d40dbd..000000000 --- a/lib/libcrypto/evp/evp_lib.c +++ /dev/null @@ -1,565 +0,0 @@ -/* $OpenBSD: evp_lib.c,v 1.30 2023/12/15 13:28:30 tb Exp $ */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include - -#include -#include -#include - -#include "asn1_local.h" -#include "evp_local.h" - -int -EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type) -{ - int ret; - - if (c->cipher->set_asn1_parameters != NULL) - ret = c->cipher->set_asn1_parameters(c, type); - else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) - ret = EVP_CIPHER_set_asn1_iv(c, type); - else - ret = -1; - return (ret); -} - -int -EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type) -{ - int ret; - - if (c->cipher->get_asn1_parameters != NULL) - ret = c->cipher->get_asn1_parameters(c, type); - else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) - ret = EVP_CIPHER_get_asn1_iv(c, type); - else - ret = -1; - return (ret); -} - -int -EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) -{ - int i = 0; - int l; - - if (type != NULL) { - l = EVP_CIPHER_CTX_iv_length(c); - if (l < 0 || l > sizeof(c->iv)) { - EVPerror(EVP_R_IV_TOO_LARGE); - return 0; - } - i = ASN1_TYPE_get_octetstring(type, c->oiv, l); - if (i != l) - return (-1); - else if (i > 0) - memcpy(c->iv, c->oiv, l); - } - return (i); -} - -int -EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) -{ - int i = 0; - int j; - - if (type != NULL) { - j = EVP_CIPHER_CTX_iv_length(c); - if (j < 0 || j > sizeof(c->iv)) { - EVPerror(EVP_R_IV_TOO_LARGE); - return 0; - } - i = ASN1_TYPE_set_octetstring(type, c->oiv, j); - } - return (i); -} - -/* Convert the various cipher NIDs and dummies to a proper OID NID */ -int -EVP_CIPHER_type(const EVP_CIPHER *ctx) -{ - int nid; - ASN1_OBJECT *otmp; - nid = EVP_CIPHER_nid(ctx); - - switch (nid) { - case NID_rc2_cbc: - case NID_rc2_64_cbc: - case NID_rc2_40_cbc: - return NID_rc2_cbc; - - case NID_rc4: - case NID_rc4_40: - return NID_rc4; - - case NID_aes_128_cfb128: - case NID_aes_128_cfb8: - case NID_aes_128_cfb1: - return NID_aes_128_cfb128; - - case NID_aes_192_cfb128: - case NID_aes_192_cfb8: - case NID_aes_192_cfb1: - return NID_aes_192_cfb128; - - case NID_aes_256_cfb128: - case NID_aes_256_cfb8: - case NID_aes_256_cfb1: - return NID_aes_256_cfb128; - - case NID_des_cfb64: - case NID_des_cfb8: - case NID_des_cfb1: - return NID_des_cfb64; - - case NID_des_ede3_cfb64: - case NID_des_ede3_cfb8: - case NID_des_ede3_cfb1: - return NID_des_cfb64; - - default: - /* Check it has an OID and it is valid */ - otmp = OBJ_nid2obj(nid); - if (!otmp || !otmp->data) - nid = NID_undef; - ASN1_OBJECT_free(otmp); - return nid; - } -} - -int -EVP_CIPHER_block_size(const EVP_CIPHER *e) -{ - return e->block_size; -} - -int -EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx) -{ - return ctx->cipher->block_size; -} - -const EVP_CIPHER * -EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx) -{ - return ctx->cipher; -} - -int -EVP_CIPHER_CTX_encrypting(const EVP_CIPHER_CTX *ctx) -{ - return ctx->encrypt; -} - -unsigned long -EVP_CIPHER_flags(const EVP_CIPHER *cipher) -{ - return cipher->flags; -} - -unsigned long -EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx) -{ - return ctx->cipher->flags; -} - -void * -EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx) -{ - return ctx->app_data; -} - -void -EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data) -{ - ctx->app_data = data; -} - -void * -EVP_CIPHER_CTX_get_cipher_data(const EVP_CIPHER_CTX *ctx) -{ - return ctx->cipher_data; -} - -void * -EVP_CIPHER_CTX_set_cipher_data(EVP_CIPHER_CTX *ctx, void *cipher_data) -{ - void *old_cipher_data; - - old_cipher_data = ctx->cipher_data; - ctx->cipher_data = cipher_data; - - return old_cipher_data; -} - -int -EVP_CIPHER_iv_length(const EVP_CIPHER *cipher) -{ - return cipher->iv_len; -} - -int -EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx) -{ - int iv_length = 0; - - if ((ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_IV_LENGTH) == 0) - return ctx->cipher->iv_len; - - /* - * XXX - sanity would suggest to pass the size of the pointer along, - * but unfortunately we have to match the other crowd. - */ - if (EVP_CIPHER_CTX_ctrl((EVP_CIPHER_CTX *)ctx, EVP_CTRL_GET_IVLEN, 0, - &iv_length) != 1) - return -1; - - return iv_length; -} - -unsigned char * -EVP_CIPHER_CTX_buf_noconst(EVP_CIPHER_CTX *ctx) -{ - return ctx->buf; -} - -int -EVP_CIPHER_key_length(const EVP_CIPHER *cipher) -{ - return cipher->key_len; -} - -int -EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx) -{ - return ctx->key_len; -} - -int -EVP_CIPHER_nid(const EVP_CIPHER *cipher) -{ - return cipher->nid; -} - -int -EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx) -{ - return ctx->cipher->nid; -} - -int -EVP_CIPHER_CTX_get_iv(const EVP_CIPHER_CTX *ctx, unsigned char *iv, size_t len) -{ - if (ctx == NULL || len != EVP_CIPHER_CTX_iv_length(ctx)) - return 0; - if (len > EVP_MAX_IV_LENGTH) - return 0; /* sanity check; shouldn't happen */ - /* - * Skip the memcpy entirely when the requested IV length is zero, - * since the iv pointer may be NULL or invalid. - */ - if (len != 0) { - if (iv == NULL) - return 0; - memcpy(iv, ctx->iv, len); - } - return 1; -} - -int -EVP_CIPHER_CTX_set_iv(EVP_CIPHER_CTX *ctx, const unsigned char *iv, size_t len) -{ - if (ctx == NULL || len != EVP_CIPHER_CTX_iv_length(ctx)) - return 0; - if (len > EVP_MAX_IV_LENGTH) - return 0; /* sanity check; shouldn't happen */ - /* - * Skip the memcpy entirely when the requested IV length is zero, - * since the iv pointer may be NULL or invalid. - */ - if (len != 0) { - if (iv == NULL) - return 0; - memcpy(ctx->iv, iv, len); - } - return 1; -} - -int -EVP_MD_block_size(const EVP_MD *md) -{ - return md->block_size; -} - -int -EVP_MD_type(const EVP_MD *md) -{ - return md->type; -} - -int -EVP_MD_pkey_type(const EVP_MD *md) -{ - return md->pkey_type; -} - -int -EVP_MD_size(const EVP_MD *md) -{ - if (!md) { - EVPerror(EVP_R_MESSAGE_DIGEST_IS_NULL); - return -1; - } - return md->md_size; -} - -unsigned long -EVP_MD_flags(const EVP_MD *md) -{ - return md->flags; -} - -EVP_MD * -EVP_MD_meth_new(int md_type, int pkey_type) -{ - EVP_MD *md; - - if ((md = calloc(1, sizeof(*md))) == NULL) - return NULL; - - md->type = md_type; - md->pkey_type = pkey_type; - - return md; -} - -EVP_MD * -EVP_MD_meth_dup(const EVP_MD *md) -{ - EVP_MD *to; - - if ((to = EVP_MD_meth_new(md->type, md->pkey_type)) == NULL) - return NULL; - - memcpy(to, md, sizeof(*to)); - - return to; -} - -void -EVP_MD_meth_free(EVP_MD *md) -{ - freezero(md, sizeof(*md)); -} - -int -EVP_MD_meth_set_input_blocksize(EVP_MD *md, int blocksize) -{ - md->block_size = blocksize; - return 1; -} - -int -EVP_MD_meth_set_result_size(EVP_MD *md, int result_size) -{ - md->md_size = result_size; - return 1; -} - -int -EVP_MD_meth_set_app_datasize(EVP_MD *md, int datasize) -{ - md->ctx_size = datasize; - return 1; -} - -int -EVP_MD_meth_set_flags(EVP_MD *md, unsigned long flags) -{ - md->flags = flags; - return 1; -} - -int -EVP_MD_meth_set_init(EVP_MD *md, int (*init)(EVP_MD_CTX *ctx)) -{ - md->init = init; - return 1; -} - -int -EVP_MD_meth_set_update(EVP_MD *md, - int (*update)(EVP_MD_CTX *ctx, const void *data, size_t count)) -{ - md->update = update; - return 1; -} - -int -EVP_MD_meth_set_final(EVP_MD *md, - int (*final)(EVP_MD_CTX *ctx, unsigned char *md)) -{ - md->final = final; - return 1; -} - -int -EVP_MD_meth_set_copy(EVP_MD *md, - int (*copy)(EVP_MD_CTX *to, const EVP_MD_CTX *from)) -{ - md->copy = copy; - return 1; -} - -int -EVP_MD_meth_set_cleanup(EVP_MD *md, - int (*cleanup)(EVP_MD_CTX *ctx)) -{ - md->cleanup = cleanup; - return 1; -} - -int -EVP_MD_meth_set_ctrl(EVP_MD *md, - int (*ctrl)(EVP_MD_CTX *ctx, int cmd, int p1, void *p2)) -{ - md->md_ctrl = ctrl; - return 1; -} - -const EVP_MD * -EVP_MD_CTX_md(const EVP_MD_CTX *ctx) -{ - if (!ctx) - return NULL; - return ctx->digest; -} - -void * -EVP_MD_CTX_md_data(const EVP_MD_CTX *ctx) -{ - return ctx->md_data; -} - -EVP_PKEY_CTX * -EVP_MD_CTX_pkey_ctx(const EVP_MD_CTX *ctx) -{ - return ctx->pctx; -} - -void -EVP_MD_CTX_set_pkey_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pctx) -{ - if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX)) { - EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX); - } else { - EVP_PKEY_CTX_free(ctx->pctx); - } - - ctx->pctx = pctx; - - if (pctx != NULL) { - /* - * For unclear reasons it was decided that the caller keeps - * ownership of pctx. So a flag was invented to make sure we - * don't free it in EVP_MD_CTX_cleanup(). We also need to - * unset it in EVP_MD_CTX_copy_ex(). Fortunately, the flag - * isn't public... - */ - EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX); - } -} - -void -EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags) -{ - ctx->flags |= flags; -} - -void -EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags) -{ - ctx->flags &= ~flags; -} - -int -EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, int flags) -{ - return (ctx->flags & flags); -} - -void -EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags) -{ - ctx->flags |= flags; -} - -void -EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags) -{ - ctx->flags &= ~flags; -} - -int -EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags) -{ - return (ctx->flags & flags); -} diff --git a/lib/libcrypto/evp/evp_local.h b/lib/libcrypto/evp/evp_local.h index 1034b88a1..d21919ac9 100644 --- a/lib/libcrypto/evp/evp_local.h +++ b/lib/libcrypto/evp/evp_local.h @@ -1,4 +1,4 @@ -/* $OpenBSD: evp_local.h,v 1.9 2023/12/22 17:25:47 tb Exp $ */ +/* $OpenBSD: evp_local.h,v 1.10 2023/12/29 10:59:00 tb Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2000. */ @@ -89,6 +89,68 @@ struct ecx_key_st { size_t pub_key_len; }; +struct evp_pkey_asn1_method_st { + int pkey_id; + int pkey_base_id; + unsigned long pkey_flags; + + char *pem_str; + char *info; + + int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub); + int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk); + int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b); + int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx); + + int (*priv_decode)(EVP_PKEY *pk, const PKCS8_PRIV_KEY_INFO *p8inf); + int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk); + int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx); + + int (*pkey_size)(const EVP_PKEY *pk); + int (*pkey_bits)(const EVP_PKEY *pk); + int (*pkey_security_bits)(const EVP_PKEY *pk); + + int (*param_decode)(EVP_PKEY *pkey, const unsigned char **pder, + int derlen); + int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder); + int (*param_missing)(const EVP_PKEY *pk); + int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from); + int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b); + int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx); + int (*sig_print)(BIO *out, const X509_ALGOR *sigalg, + const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx); + + void (*pkey_free)(EVP_PKEY *pkey); + int (*pkey_ctrl)(EVP_PKEY *pkey, int op, long arg1, void *arg2); + + /* Legacy functions for old PEM */ + + int (*old_priv_decode)(EVP_PKEY *pkey, const unsigned char **pder, + int derlen); + int (*old_priv_encode)(const EVP_PKEY *pkey, unsigned char **pder); + /* Custom ASN1 signature verification */ + int (*item_verify)(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, + X509_ALGOR *a, ASN1_BIT_STRING *sig, EVP_PKEY *pkey); + int (*item_sign)(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, + X509_ALGOR *alg1, X509_ALGOR *alg2, ASN1_BIT_STRING *sig); + + int (*pkey_check)(const EVP_PKEY *pk); + int (*pkey_public_check)(const EVP_PKEY *pk); + int (*pkey_param_check)(const EVP_PKEY *pk); + + int (*set_priv_key)(EVP_PKEY *pk, const unsigned char *private_key, + size_t len); + int (*set_pub_key)(EVP_PKEY *pk, const unsigned char *public_key, + size_t len); + int (*get_priv_key)(const EVP_PKEY *pk, unsigned char *out_private_key, + size_t *out_len); + int (*get_pub_key)(const EVP_PKEY *pk, unsigned char *out_public_key, + size_t *out_len); +} /* EVP_PKEY_ASN1_METHOD */; + /* Type needs to be a bit field * Sub-type needs to be for variations on the method, as in, can it do * arbitrary encryption.... */ diff --git a/lib/libcrypto/evp/p_lib.c b/lib/libcrypto/evp/p_lib.c index f92684fdd..24e1dbb14 100644 --- a/lib/libcrypto/evp/p_lib.c +++ b/lib/libcrypto/evp/p_lib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: p_lib.c,v 1.50 2023/12/25 22:41:50 tb Exp $ */ +/* $OpenBSD: p_lib.c,v 1.51 2023/12/29 10:59:00 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -55,13 +55,62 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL 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 OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL 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 OpenSSL 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 +#include #include #include #include @@ -73,13 +122,152 @@ #ifndef OPENSSL_NO_DSA #include #endif +#ifndef OPENSSL_NO_EC +#include +#endif #ifndef OPENSSL_NO_RSA #include #endif -#include "asn1_local.h" #include "evp_local.h" +extern const EVP_PKEY_ASN1_METHOD cmac_asn1_meth; +extern const EVP_PKEY_ASN1_METHOD dh_asn1_meth; +extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[]; +extern const EVP_PKEY_ASN1_METHOD eckey_asn1_meth; +extern const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth; +extern const EVP_PKEY_ASN1_METHOD gostimit_asn1_meth; +extern const EVP_PKEY_ASN1_METHOD gostr01_asn1_meths[]; +extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth; +extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[]; +extern const EVP_PKEY_ASN1_METHOD rsa_pss_asn1_meth; +extern const EVP_PKEY_ASN1_METHOD x25519_asn1_meth; + +static const EVP_PKEY_ASN1_METHOD *asn1_methods[] = { + &cmac_asn1_meth, + &dh_asn1_meth, + &dsa_asn1_meths[0], + &dsa_asn1_meths[1], + &dsa_asn1_meths[2], + &dsa_asn1_meths[3], + &dsa_asn1_meths[4], + &eckey_asn1_meth, + &ed25519_asn1_meth, + &gostimit_asn1_meth, + &gostr01_asn1_meths[0], + &gostr01_asn1_meths[1], + &gostr01_asn1_meths[2], + &hmac_asn1_meth, + &rsa_asn1_meths[0], + &rsa_asn1_meths[1], + &rsa_pss_asn1_meth, + &x25519_asn1_meth, +}; + +#define N_ASN1_METHODS (sizeof(asn1_methods) / sizeof(asn1_methods[0])) + +int +EVP_PKEY_asn1_get_count(void) +{ + return N_ASN1_METHODS; +} + +const EVP_PKEY_ASN1_METHOD * +EVP_PKEY_asn1_get0(int idx) +{ + if (idx < 0 || idx >= N_ASN1_METHODS) + return NULL; + + return asn1_methods[idx]; +} + +static const EVP_PKEY_ASN1_METHOD * +pkey_asn1_find(int pkey_id) +{ + const EVP_PKEY_ASN1_METHOD *ameth; + int i; + + for (i = EVP_PKEY_asn1_get_count() - 1; i >= 0; i--) { + ameth = EVP_PKEY_asn1_get0(i); + if (ameth->pkey_id == pkey_id) + return ameth; + } + + return NULL; +} + +/* + * XXX - fix this. In what looks like an infinite loop, this API only makes two + * calls to pkey_asn1_find(): If the type resolves to an aliased ASN.1 method, + * the second call will find the method it aliases. Codify this in regress and + * make this explicit in code. + */ +const EVP_PKEY_ASN1_METHOD * +EVP_PKEY_asn1_find(ENGINE **pe, int type) +{ + const EVP_PKEY_ASN1_METHOD *mp; + + if (pe != NULL) + *pe = NULL; + + for (;;) { + if ((mp = pkey_asn1_find(type)) == NULL) + break; + if ((mp->pkey_flags & ASN1_PKEY_ALIAS) == 0) + break; + type = mp->pkey_base_id; + } + + return mp; +} + +const EVP_PKEY_ASN1_METHOD * +EVP_PKEY_asn1_find_str(ENGINE **pe, const char *str, int len) +{ + const EVP_PKEY_ASN1_METHOD *ameth; + int i; + + if (len == -1) + len = strlen(str); + if (pe != NULL) + *pe = NULL; + for (i = EVP_PKEY_asn1_get_count() - 1; i >= 0; i--) { + ameth = EVP_PKEY_asn1_get0(i); + if (ameth->pkey_flags & ASN1_PKEY_ALIAS) + continue; + if (((int)strlen(ameth->pem_str) == len) && + !strncasecmp(ameth->pem_str, str, len)) + return ameth; + } + return NULL; +} + +int +EVP_PKEY_asn1_get0_info(int *ppkey_id, int *ppkey_base_id, int *ppkey_flags, + const char **pinfo, const char **ppem_str, + const EVP_PKEY_ASN1_METHOD *ameth) +{ + if (!ameth) + return 0; + if (ppkey_id) + *ppkey_id = ameth->pkey_id; + if (ppkey_base_id) + *ppkey_base_id = ameth->pkey_base_id; + if (ppkey_flags) + *ppkey_flags = ameth->pkey_flags; + if (pinfo) + *pinfo = ameth->info; + if (ppem_str) + *ppem_str = ameth->pem_str; + return 1; +} + +const EVP_PKEY_ASN1_METHOD* +EVP_PKEY_get0_asn1(const EVP_PKEY *pkey) +{ + return pkey->ameth; +} + int EVP_PKEY_bits(const EVP_PKEY *pkey) { diff --git a/lib/libcrypto/man/BN_generate_prime.3 b/lib/libcrypto/man/BN_generate_prime.3 index a7551390e..d9144155c 100644 --- a/lib/libcrypto/man/BN_generate_prime.3 +++ b/lib/libcrypto/man/BN_generate_prime.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: BN_generate_prime.3,v 1.24 2023/05/12 08:18:13 jsg Exp $ +.\" $OpenBSD: BN_generate_prime.3,v 1.25 2023/12/29 19:12:46 tb Exp $ .\" full merge up to: OpenSSL f987a4dd Jun 27 10:12:08 2019 +0200 .\" .\" This file is a derived work. @@ -67,7 +67,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED .\" OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: May 12 2023 $ +.Dd $Mdocdate: December 29 2023 $ .Dt BN_GENERATE_PRIME 3 .Os .Sh NAME @@ -354,7 +354,7 @@ In some cases, error codes can be obtained by .Sh SEE ALSO .Xr BN_new 3 , .Xr DH_generate_parameters 3 , -.Xr DSA_generate_parameters 3 , +.Xr DSA_generate_parameters_ex 3 , .Xr RSA_generate_key 3 .Sh HISTORY .Fn BN_generate_prime_ex , diff --git a/lib/libcrypto/man/DSA_generate_key.3 b/lib/libcrypto/man/DSA_generate_key.3 index 97e185e0b..37d8ec1c0 100644 --- a/lib/libcrypto/man/DSA_generate_key.3 +++ b/lib/libcrypto/man/DSA_generate_key.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: DSA_generate_key.3,v 1.10 2019/06/10 14:58:48 schwarze Exp $ +.\" $OpenBSD: DSA_generate_key.3,v 1.11 2023/12/29 19:12:47 tb Exp $ .\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 .\" .\" This file was written by Ulf Moeller . @@ -48,7 +48,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED .\" OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: June 10 2019 $ +.Dd $Mdocdate: December 29 2023 $ .Dt DSA_GENERATE_KEY 3 .Os .Sh NAME @@ -75,7 +75,7 @@ returns 1 on success or 0 otherwise. The error codes can be obtained by .Xr ERR_get_error 3 . .Sh SEE ALSO -.Xr DSA_generate_parameters 3 , +.Xr DSA_generate_parameters_ex 3 , .Xr DSA_get0_key 3 , .Xr DSA_new 3 .Sh HISTORY diff --git a/lib/libcrypto/man/DSA_generate_parameters.3 b/lib/libcrypto/man/DSA_generate_parameters_ex.3 similarity index 78% rename from lib/libcrypto/man/DSA_generate_parameters.3 rename to lib/libcrypto/man/DSA_generate_parameters_ex.3 index 07fa5acf9..a318bf829 100644 --- a/lib/libcrypto/man/DSA_generate_parameters.3 +++ b/lib/libcrypto/man/DSA_generate_parameters_ex.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: DSA_generate_parameters.3,v 1.13 2023/05/14 09:27:15 tb Exp $ +.\" $OpenBSD: DSA_generate_parameters_ex.3,v 1.1 2023/12/29 19:15:15 tb Exp $ .\" OpenSSL 9b86974e Aug 7 22:14:47 2015 -0400 .\" .\" This file was written by Ulf Moeller , @@ -49,12 +49,13 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED .\" OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: May 14 2023 $ -.Dt DSA_GENERATE_PARAMETERS 3 +.Dd $Mdocdate: December 29 2023 $ +.Dt DSA_GENERATE_PARAMETERS_EX 3 .Os .Sh NAME -.Nm DSA_generate_parameters_ex , -.Nm DSA_generate_parameters +.\" .Nm DSA_generate_parameters is intentionally undocumented +.\" because it will be removed in the next major bump +.Nm DSA_generate_parameters_ex .Nd generate DSA parameters .Sh SYNOPSIS .In openssl/dsa.h @@ -68,19 +69,6 @@ .Fa "unsigned long *h_ret" .Fa "BN_GENCB *cb" .Fc -.Pp -Deprecated: -.Pp -.Ft DSA * -.Fo DSA_generate_parameters -.Fa "int bits" -.Fa "unsigned char *seed" -.Fa "int seed_len" -.Fa "int *counter_ret" -.Fa "unsigned long *h_ret" -.Fa "void (*callback)(int, int, void *)" -.Fa "void *cb_arg" -.Fc .Sh DESCRIPTION .Fn DSA_generate_parameters_ex generates primes p and q and a generator g for use in the DSA and stores @@ -168,32 +156,10 @@ When the generator has been found, .Fn BN_GENCB_call cb 3 1 is called. .El -.Pp -.Fn DSA_generate_parameters -(deprecated) works in much the same way as for -.Fn DSA_generate_parameters_ex , -except that no -.Fa dsa -parameter is passed and instead a newly allocated -.Vt DSA -structure is returned. -Additionally "old style" callbacks are used instead of the newer -.Vt BN_GENCB -based approach. -Refer to -.Xr BN_generate_prime 3 -for further information. .Sh RETURN VALUES .Fn DSA_generate_parameters_ex returns a 1 on success, or 0 otherwise. .Pp -.Fn DSA_generate_parameters -returns a pointer to the -.Vt DSA -structure, or -.Dv NULL -if the parameter generation fails. -.Pp The error codes can be obtained by .Xr ERR_get_error 3 . .Sh SEE ALSO @@ -201,24 +167,6 @@ The error codes can be obtained by .Xr DSA_get0_pqg 3 , .Xr DSA_new 3 .Sh HISTORY -.Fn DSA_generate_parameters -first appeared in SSLeay 0.8.0 and had its -.Fa cb_arg -argument added in SSLeay 0.9.0. -It has been available since -.Ox 2.4 . -.Pp -In versions up to OpenSSL 0.9.4, -.Fn callback 1 ...\& -was called in the inner loop of the Miller-Rabin test whenever it -reached the squaring step (the parameters to -.Fn callback -did not reveal how many witnesses had been tested); since OpenSSL 0.9.5, -.Fn callback 1 ...\& -is called as in -.Xr BN_is_prime_ex 3 , -i.e. once for each witness. -.Pp .Fn DSA_generate_parameters_ex first appeared in OpenSSL 0.9.8 and has been available since .Ox 4.5 . diff --git a/lib/libcrypto/man/DSA_get0_pqg.3 b/lib/libcrypto/man/DSA_get0_pqg.3 index b5250d9f9..8639b0115 100644 --- a/lib/libcrypto/man/DSA_get0_pqg.3 +++ b/lib/libcrypto/man/DSA_get0_pqg.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: DSA_get0_pqg.3,v 1.7 2023/03/07 06:15:07 tb Exp $ +.\" $OpenBSD: DSA_get0_pqg.3,v 1.10 2023/12/29 22:37:47 tb Exp $ .\" full merge up to: OpenSSL e90fc053 Jul 15 09:39:45 2017 -0400 .\" .\" This file was written by Matt Caswell . @@ -48,7 +48,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED .\" OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: March 7 2023 $ +.Dd $Mdocdate: December 29 2023 $ .Dt DSA_GET0_PQG 3 .Os .Sh NAME @@ -296,7 +296,7 @@ if no engine was set for this object. .Xr DSA_do_sign 3 , .Xr DSA_dup_DH 3 , .Xr DSA_generate_key 3 , -.Xr DSA_generate_parameters 3 , +.Xr DSA_generate_parameters_ex 3 , .Xr DSA_new 3 , .Xr DSA_print 3 , .Xr DSA_security_bits 3 , diff --git a/lib/libcrypto/man/DSA_new.3 b/lib/libcrypto/man/DSA_new.3 index 8e3160117..5a958b58c 100644 --- a/lib/libcrypto/man/DSA_new.3 +++ b/lib/libcrypto/man/DSA_new.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: DSA_new.3,v 1.13 2022/07/13 21:51:35 schwarze Exp $ +.\" $OpenBSD: DSA_new.3,v 1.14 2023/12/29 19:12:47 tb Exp $ .\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100 .\" .\" This file was written by Ulf Moeller . @@ -48,7 +48,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED .\" OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: July 13 2022 $ +.Dd $Mdocdate: December 29 2023 $ .Dt DSA_NEW 3 .Os .Sh NAME @@ -114,7 +114,7 @@ returns 1 for success or 0 for failure. .Xr DSA_do_sign 3 , .Xr DSA_dup_DH 3 , .Xr DSA_generate_key 3 , -.Xr DSA_generate_parameters 3 , +.Xr DSA_generate_parameters_ex 3 , .Xr DSA_get0_pqg 3 , .Xr DSA_get_ex_new_index 3 , .Xr DSA_meth_new 3 , diff --git a/lib/libcrypto/man/Makefile b/lib/libcrypto/man/Makefile index 544495207..72ddcd343 100644 --- a/lib/libcrypto/man/Makefile +++ b/lib/libcrypto/man/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.279 2023/12/16 10:26:10 tb Exp $ +# $OpenBSD: Makefile,v 1.280 2023/12/29 19:15:15 tb Exp $ .include @@ -123,7 +123,7 @@ MAN= \ DSA_do_sign.3 \ DSA_dup_DH.3 \ DSA_generate_key.3 \ - DSA_generate_parameters.3 \ + DSA_generate_parameters_ex.3 \ DSA_get0_pqg.3 \ DSA_get_ex_new_index.3 \ DSA_meth_new.3 \ diff --git a/lib/libcrypto/x509/by_dir.c b/lib/libcrypto/x509/by_dir.c index 88c06513a..7e6949e21 100644 --- a/lib/libcrypto/x509/by_dir.c +++ b/lib/libcrypto/x509/by_dir.c @@ -1,4 +1,4 @@ -/* $OpenBSD: by_dir.c,v 1.45 2023/12/25 22:14:23 tb Exp $ */ +/* $OpenBSD: by_dir.c,v 1.46 2023/12/29 05:33:32 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -118,10 +118,8 @@ static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, char **retp) { + BY_DIR *ld = ctx->method_data; int ret = 0; - BY_DIR *ld; - - ld = (BY_DIR *)ctx->method_data; switch (cmd) { case X509_L_ADD_DIR: @@ -153,7 +151,7 @@ new_dir(X509_LOOKUP *lu) return 0; } a->dirs = NULL; - lu->method_data = (char *)a; + lu->method_data = a; return 1; } @@ -187,7 +185,7 @@ free_dir(X509_LOOKUP *lu) { BY_DIR *a; - a = (BY_DIR *)lu->method_data; + a = lu->method_data; sk_BY_DIR_ENTRY_pop_free(a->dirs, by_dir_entry_free); BUF_MEM_free(a->buffer); free(a); @@ -300,7 +298,7 @@ get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name, goto finish; } - ctx = (BY_DIR *)xl->method_data; + ctx = xl->method_data; h = X509_NAME_hash(name); for (i = 0; i < sk_BY_DIR_ENTRY_num(ctx->dirs); i++) { diff --git a/lib/libcrypto/x509/x509_local.h b/lib/libcrypto/x509/x509_local.h index d4197e66c..6285370b2 100644 --- a/lib/libcrypto/x509/x509_local.h +++ b/lib/libcrypto/x509/x509_local.h @@ -1,4 +1,4 @@ -/* $OpenBSD: x509_local.h,v 1.15 2023/12/25 22:14:23 tb Exp $ */ +/* $OpenBSD: x509_local.h,v 1.17 2023/12/29 05:33:32 tb Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2013. */ @@ -299,9 +299,8 @@ struct x509_store_st { /* This is the functions plus an instance of the local variables. */ struct x509_lookup_st { - int init; /* have we been started */ X509_LOOKUP_METHOD *method; /* the functions */ - char *method_data; /* method data */ + void *method_data; /* method data */ X509_STORE *store_ctx; /* who owns us */ } /* X509_LOOKUP */; diff --git a/lib/libssl/ssl_clnt.c b/lib/libssl/ssl_clnt.c index 6813081f8..ae90d6f52 100644 --- a/lib/libssl/ssl_clnt.c +++ b/lib/libssl/ssl_clnt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl_clnt.c,v 1.162 2023/11/19 15:50:29 tb Exp $ */ +/* $OpenBSD: ssl_clnt.c,v 1.163 2023/12/29 12:24:33 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -631,11 +631,6 @@ ssl3_connect(SSL *s) /* did we do anything */ if (!s->s3->hs.tls12.reuse_message && !skip) { - if (s->debug) { - if ((ret = BIO_flush(s->wbio)) <= 0) - goto end; - } - if (s->s3->hs.state != state) { new_state = s->s3->hs.state; s->s3->hs.state = state; diff --git a/lib/libssl/ssl_lib.c b/lib/libssl/ssl_lib.c index ce14ce710..c97441c9c 100644 --- a/lib/libssl/ssl_lib.c +++ b/lib/libssl/ssl_lib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl_lib.c,v 1.317 2023/11/29 13:39:34 tb Exp $ */ +/* $OpenBSD: ssl_lib.c,v 1.318 2023/12/29 12:24:33 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -2933,8 +2933,6 @@ SSL_dup(SSL *s) SSL_set_info_callback(ret, SSL_get_info_callback(s)); - ret->debug = s->debug; - /* copy app data, a little dangerous perhaps */ if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL, &ret->ex_data, &s->ex_data)) @@ -3488,7 +3486,7 @@ LSSL_ALIAS(SSL_set_msg_callback); void SSL_set_debug(SSL *s, int debug) { - s->debug = debug; + SSLerror(s, ERR_R_DISABLED); } LSSL_ALIAS(SSL_set_debug); diff --git a/lib/libssl/ssl_local.h b/lib/libssl/ssl_local.h index a2c2588c3..bd6275fac 100644 --- a/lib/libssl/ssl_local.h +++ b/lib/libssl/ssl_local.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl_local.h,v 1.11 2023/11/29 13:39:34 tb Exp $ */ +/* $OpenBSD: ssl_local.h,v 1.12 2023/12/29 12:24:33 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -1074,9 +1074,6 @@ struct ssl_st { /* for server side, keep the list of CA_dn we can use */ STACK_OF(X509_NAME) *client_CA; - /* set this flag to 1 and a sleep(1) is put into all SSL_read() - * and SSL_write() calls, good for nbio debugging :-) */ - int debug; long max_cert_list; int first_packet; diff --git a/lib/libssl/ssl_srvr.c b/lib/libssl/ssl_srvr.c index a571549b6..f26fde506 100644 --- a/lib/libssl/ssl_srvr.c +++ b/lib/libssl/ssl_srvr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl_srvr.c,v 1.157 2023/11/18 10:51:09 tb Exp $ */ +/* $OpenBSD: ssl_srvr.c,v 1.158 2023/12/29 12:24:33 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -740,12 +740,6 @@ ssl3_accept(SSL *s) } if (!s->s3->hs.tls12.reuse_message && !skip) { - if (s->debug) { - if ((ret = BIO_flush(s->wbio)) <= 0) - goto end; - } - - if (s->s3->hs.state != state) { new_state = s->s3->hs.state; s->s3->hs.state = state; diff --git a/lib/libutil/imsg_init.3 b/lib/libutil/imsg_init.3 index c581f3a6e..d61610151 100644 --- a/lib/libutil/imsg_init.3 +++ b/lib/libutil/imsg_init.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: imsg_init.3,v 1.32 2023/12/13 00:37:42 jsg Exp $ +.\" $OpenBSD: imsg_init.3,v 1.33 2023/12/29 11:48:47 claudio Exp $ .\" .\" Copyright (c) 2023 Claudio Jeker .\" Copyright (c) 2010 Nicholas Marriott @@ -15,7 +15,7 @@ .\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING .\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: December 13 2023 $ +.Dd $Mdocdate: December 29 2023 $ .Dt IMSG_INIT 3 .Os .Sh NAME @@ -41,10 +41,7 @@ .Nm imsg_clear .Nd IPC messaging functions .Sh SYNOPSIS -.In sys/types.h .In sys/queue.h -.In sys/uio.h -.In stdint.h .In imsg.h .Ft void .Fn imsg_init "struct imsgbuf *imsgbuf" "int fd" @@ -70,9 +67,6 @@ .Fn imsg_compose "struct imsgbuf *imsgbuf" "uint32_t type" "uint32_t id" \ "pid_t pid" "int fd" "const void *data" "size_t datalen" .Ft int -.Fn imsg_composev "struct imsgbuf *imsgbuf" "uint32_t type" "uint32_t id" \ - "pid_t pid" "int fd" "const struct iovec *iov" "int iovcnt" -.Ft int .Fn imsg_compose_ibuf "struct imsgbuf *imsgbuf" "uint32_t type" \ "uint32_t id" "pid_t pid" "struct ibuf *buf" .Ft "struct ibuf *" @@ -90,6 +84,10 @@ .Fn imsg_flush "struct imsgbuf *imsgbuf" .Ft void .Fn imsg_clear "struct imsgbuf *imsgbuf" +.In sys/uio.h +.Ft int +.Fn imsg_composev "struct imsgbuf *imsgbuf" "uint32_t type" "uint32_t id" \ + "pid_t pid" "int fd" "const struct iovec *iov" "int iovcnt" .Sh DESCRIPTION The .Nm imsg diff --git a/regress/lib/libutil/imsg/ibuf_test.c b/regress/lib/libutil/imsg/ibuf_test.c index c8c481d5b..d952b5cb3 100644 --- a/regress/lib/libutil/imsg/ibuf_test.c +++ b/regress/lib/libutil/imsg/ibuf_test.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ibuf_test.c,v 1.4 2023/06/19 17:22:46 claudio Exp $ */ +/* $OpenBSD: ibuf_test.c,v 1.5 2023/12/29 16:02:29 claudio Exp $ */ /* * Copyright (c) Tobias Stoeckmann * @@ -17,7 +17,6 @@ #include #include -#include #include #include diff --git a/regress/sys/sys/tree/rb/Makefile b/regress/sys/sys/tree/rb/Makefile index 61695ac22..161969890 100644 --- a/regress/sys/sys/tree/rb/Makefile +++ b/regress/sys/sys/tree/rb/Makefile @@ -1,5 +1,24 @@ -# $OpenBSD: Makefile,v 1.1 2002/06/11 22:10:22 provos Exp $ +# $OpenBSD: Makefile,v 1.2 2023/12/29 02:37:39 aisha Exp $ -PROG= rb-test +NAMED_TESTS = random-inserts sequential-inserts \ + sequential-removes random-removes remove-nfind \ + remove-pfind node-iterations iteration-macros insert-next \ + insert-prev benchmarks + +REGRESS_TARGETS = all-tests ${NAMED_TESTS} + +PROGS = rb-test rbt-test + +all-tests: rb-test rbt-test + @echo "===== testing RB macros =====" + ./rb-test + @echo "===== testing RBT macros =====" + ./rbt-test + +${NAMED_TESTS}: rb-test rbt-test + @echo "===== testing RB macros =====" + ./rb-test $@ + @echo "===== testing RBT macros =====" + ./rbt-test $@ .include diff --git a/regress/sys/sys/tree/rb/rb-test.c b/regress/sys/sys/tree/rb/rb-test.c index 409cc2239..c26b549d5 100644 --- a/regress/sys/sys/tree/rb/rb-test.c +++ b/regress/sys/sys/tree/rb/rb-test.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rb-test.c,v 1.4 2008/04/13 00:22:17 djm Exp $ */ +/* $OpenBSD: rb-test.c,v 1.5 2023/12/29 02:37:39 aisha Exp $ */ /* * Copyright 2002 Niels Provos * All rights reserved. @@ -25,82 +25,952 @@ * (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 +#include +#include +#include +#include +#include +#include + +struct timespec start, end, diff, rstart, rend, rdiff, rtot = {0, 0}; +#ifndef timespecsub +#define timespecsub(tsp, usp, vsp) \ + do { \ + (vsp)->tv_sec = (tsp)->tv_sec - (usp)->tv_sec; \ + (vsp)->tv_nsec = (tsp)->tv_nsec - (usp)->tv_nsec; \ + if ((vsp)->tv_nsec < 0) { \ + (vsp)->tv_sec--; \ + (vsp)->tv_nsec += 1000000000L; \ + } \ + } while (0) +#endif +#ifndef timespecadd +#define timespecadd(tsp, usp, vsp) \ + do { \ + (vsp)->tv_sec = (tsp)->tv_sec + (usp)->tv_sec; \ + (vsp)->tv_nsec = (tsp)->tv_nsec + (usp)->tv_nsec; \ + if ((vsp)->tv_nsec >= 1000000000L) { \ + (vsp)->tv_sec++; \ + (vsp)->tv_nsec -= 1000000000L; \ + } \ + } while (0) +#endif + +//#define RB_SMALL +//#define RB_TEST_RANK +//#define RB_TEST_DIAGNOSTIC +//#define _RB_DIAGNOSTIC + +#ifdef DOAUGMENT +#define RB_AUGMENT(elm) tree_augment(elm) +#endif + +#include + +#define TDEBUGF(fmt, ...) \ + fprintf(stderr, "%s:%d:%s(): " fmt "\n", \ + __FILE__, __LINE__, __func__, ##__VA_ARGS__) + + +#ifdef __OpenBSD__ +#define SEED_RANDOM srandom_deterministic +#else +#define SEED_RANDOM srandom +#endif + +int ITER=150000; +int RANK_TEST_ITERATIONS=10000; + +#define MAX(a, b) ((a) > (b) ? (a) : (b)) + +/* declarations */ +struct node; +struct tree; +static int compare(const struct node *, const struct node *); +static void mix_operations(int *, int, struct node *, int, int, int, int); + +#ifdef DOAUGMENT +static int tree_augment(struct node *); +#else +#define tree_augment(x) (0) +#endif + +#ifdef RB_TEST_DIAGNOSTIC +static void print_helper(const struct node *, int); +static void print_tree(const struct tree *); +#else +#define print_helper(x, y) do {} while (0) +#define print_tree(x) do {} while (0) +#endif + +/* definitions */ struct node { - RB_ENTRY(node) node; - int key; + RB_ENTRY(node) node_link; + int key; + size_t height; + size_t size; }; -RB_HEAD(tree, node) root; +RB_HEAD(tree, node); +struct tree root = RB_INITIALIZER(&root); -static int -compare(struct node *a, struct node *b) -{ - if (a->key < b->key) return (-1); - else if (a->key > b->key) return (1); - return (0); -} +RB_PROTOTYPE(tree, node, node_link, compare) -RB_PROTOTYPE(tree, node, node, compare); +RB_GENERATE(tree, node, node_link, compare) -RB_GENERATE(tree, node, node, compare); - -#define ITER 150 -#define MIN 5 -#define MAX 5000 +#ifndef RB_RANK +#define RB_RANK(x, y) 0 +#endif +#ifndef _RB_GET_RDIFF +#define _RB_GET_RDIFF(x, y, z) 0 +#endif int main(int argc, char **argv) { - struct node *tmp, *ins; - int i, max, min; + char *test_target = NULL; + struct node *tmp, *ins, *nodes; + int i, r, rank, *perm, *nums; + + if (argc > 1) + test_target = argv[1]; + + nodes = calloc((ITER + 5), sizeof(struct node)); + perm = calloc(ITER, sizeof(int)); + nums = calloc(ITER, sizeof(int)); + + // for determinism + SEED_RANDOM(4201); + + TDEBUGF("generating a 'random' permutation"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + perm[0] = 0; + nums[0] = 0; + for(i = 1; i < ITER; i++) { + r = random() % i; // arc4random_uniform(i); + perm[i] = perm[r]; + perm[r] = i; + nums[i] = i; + } + /* + fprintf(stderr, "{"); + for(int i = 0; i < ITER; i++) { + fprintf(stderr, "%d, ", perm[i]); + } + fprintf(stderr, "}\n"); + int nperm[10] = {2, 4, 9, 7, 8, 3, 0, 1, 6, 5}; + int nperm[6] = {2, 6, 1, 4, 5, 3}; + int nperm[10] = {10, 3, 7, 8, 6, 1, 9, 2, 5, 4}; + int nperm[2] = {0, 1}; + + int nperm[100] = { + 54, 47, 31, 35, 40, 73, 29, 66, 15, 45, 9, 71, 51, 32, 28, 62, + 12, 46, 50, 26, 36, 91, 10, 76, 33, 43, 34, 58, 55, 72, 37, 24, + 75, 4, 90, 88, 30, 25, 82, 18, 67, 81, 80, 65, 23, 41, 61, 86, + 20, 99, 59, 14, 79, 21, 68, 27, 1, 7, 94, 44, 89, 64, 96, 2, 49, + 53, 74, 13, 48, 42, 60, 52, 95, 17, 11, 0, 22, 97, 77, 69, 6, + 16, 84, 78, 8, 83, 98, 93, 39, 38, 85, 70, 3, 19, 57, 5, 87, + 92, 63, 56 + }; + ITER = 100; + for(int i = 0; i < ITER; i++){ + perm[i] = nperm[i]; + } + */ + + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done generating a 'random' permutation in: %llu.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); RB_INIT(&root); - for (i = 0; i < ITER; i++) { - tmp = malloc(sizeof(struct node)); - if (tmp == NULL) err(1, "malloc"); - do { - tmp->key = arc4random_uniform(MAX-MIN); - tmp->key += MIN; - } while (RB_FIND(tree, &root, tmp) != NULL); - if (i == 0) - max = min = tmp->key; - else { - if (tmp->key > max) - max = tmp->key; - if (tmp->key < min) - min = tmp->key; + // testing random inserts + // due to codependency between inserts and removals, this also tests + // root removals + if (test_target == NULL || + strcmp(test_target, "random-inserts") == 0 + ) { + TDEBUGF("starting random insertions"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + mix_operations(perm, ITER, nodes, ITER, ITER, 0, 0); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done random insertions in: %llu.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + +#ifdef DOAUGMENT + ins = RB_ROOT(&root); + assert(ITER + 1 == ins->size); +#endif + + TDEBUGF("getting min"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + ins = RB_MIN(tree, &root); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done getting min in: %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + assert(0 == ins->key); + + TDEBUGF("getting max"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + ins = RB_MAX(tree, &root); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done getting max in: %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + assert(ITER + 5 == ins->key); + + ins = RB_ROOT(&root); + TDEBUGF("getting root"); + assert(RB_REMOVE(tree, &root, ins) == ins); + +#ifdef DOAUGMENT + assert(ITER == (RB_ROOT(&root))->size); +#endif + + TDEBUGF("doing root removals"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + for (i = 0; i < ITER; i++) { + tmp = RB_ROOT(&root); + assert(NULL != tmp); + assert(RB_REMOVE(tree, &root, tmp) == tmp); +#ifdef RB_TEST_RANK + if (i % RANK_TEST_ITERATIONS == 0) { + rank = RB_RANK(tree, RB_ROOT(&root)); + assert(-2 != rank); + print_tree(&root); + } +#endif + +#ifdef DOAUGMENT + if (!(RB_EMPTY(&root)) && (RB_ROOT(&root))->size != ITER - 1 - i) + errx(1, "RB_REMOVE size error"); +#endif + } + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done root removals in: %llu.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + } + + // testing insertions in increasing sequential order + // removals are done using root removals (separate test) + if (test_target == NULL || + strcmp(test_target, "sequential-inserts") == 0 + ) { + TDEBUGF("starting sequential insertions"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + mix_operations(nums, ITER, nodes, ITER, ITER, 0, 0); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done sequential insertions in: %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + TDEBUGF("doing root removals"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + for (i = 0; i < ITER + 1; i++) { + tmp = RB_ROOT(&root); + assert(NULL != tmp); + assert(RB_REMOVE(tree, &root, tmp) == tmp); +#ifdef RB_TEST_RANK + if (i % RANK_TEST_ITERATIONS == 0) { + rank = RB_RANK(tree, RB_ROOT(&root)); + if (rank == -2) + errx(1, "rank error"); + } +#endif + } + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done root removals in: %llu.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + } + + // testing the RB_FIND function and using it to do removals in + // sequential order + // insertions are done using sequential insertions (separate test) + if (test_target == NULL || + strcmp(test_target, "sequential-removes") == 0 + ) { + TDEBUGF("starting sequential insertions"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + mix_operations(nums, ITER, nodes, ITER, ITER, 0, 0); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done sequential insertions in: %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + TDEBUGF("doing find and remove in sequential order"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + tmp = malloc(sizeof(struct node)); + for(i = 0; i < ITER; i++) { + tmp->key = i; + ins = RB_FIND(tree, &root, tmp); + assert(NULL != tmp); + assert(RB_REMOVE(tree, &root, ins) == ins); +#ifdef RB_TEST_RANK + if (i % RANK_TEST_ITERATIONS == 0) { + rank = RB_RANK(tree, RB_ROOT(&root)); + if (rank == -2) + errx(1, "rank error"); + } +#endif + } + free(tmp); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done removals in: %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + ins = RB_ROOT(&root); + if (ins == NULL) + errx(1, "RB_ROOT error"); + if (RB_REMOVE(tree, &root, ins) != ins) + errx(1, "RB_REMOVE failed"); + } + + // testing removals in random order + // the elements are found using RB_FIND + // insertions are done using sequential insertions (separate test) + if (test_target == NULL || + strcmp(test_target, "random-removes") == 0 + ) { + TDEBUGF("starting sequential insertions"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + mix_operations(nums, ITER, nodes, ITER, ITER, 0, 0); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done sequential insertions in: %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + + TDEBUGF("doing find and remove in random order"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + tmp = malloc(sizeof(struct node)); + for(i = 0; i < ITER; i++) { + tmp->key = perm[i]; + ins = RB_FIND(tree, &root, tmp); + if (ins == NULL) { + errx(1, "RB_FIND %d failed: %d", i, perm[i]); + } + if (RB_REMOVE(tree, &root, ins) == NULL) + errx(1, "RB_REMOVE failed: %d", i); +#ifdef RB_TEST_RANK + if (i % RANK_TEST_ITERATIONS == 0) { + rank = RB_RANK(tree, RB_ROOT(&root)); + if (rank == -2) + errx(1, "rank error"); + } +#endif + } + free(tmp); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done removals in: %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + ins = RB_ROOT(&root); + if (ins == NULL) + errx(1, "RB_ROOT error"); + if (RB_REMOVE(tree, &root, ins) != ins) + errx(1, "RB_REMOVE failed"); + } + + // testing removals by finding the next largest element + // this is testing the RB_NFIND macro + // insertions are done using sequential insertions (separate test) + if (test_target == NULL || + strcmp(test_target, "remove-nfind") == 0 + ) { + TDEBUGF("starting sequential insertions"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + mix_operations(nums, ITER, nodes, ITER, ITER, 0, 0); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done sequential insertions in: %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + TDEBUGF("doing nfind and remove"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + tmp = malloc(sizeof(struct node)); + for(i = 0; i < ITER + 1; i++) { + tmp->key = i; + ins = RB_NFIND(tree, &root, tmp); + if (ins == NULL) + errx(1, "RB_NFIND failed"); + if (RB_REMOVE(tree, &root, ins) == NULL) + errx(1, "RB_REMOVE failed: %d", i); +#ifdef RB_TEST_RANK + if (i % RANK_TEST_ITERATIONS == 0) { + rank = RB_RANK(tree, RB_ROOT(&root)); + if (rank == -2) + errx(1, "rank error"); + } +#endif + } + free(tmp); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done removals in: %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + } + +#ifdef RB_PFIND + // testing removals by finding the previous element + // this is testing the RB_PFIND macro + // insertions are done using sequential insertions (separate test) + if (test_target == NULL || + strcmp(test_target, "remove-pfind") == 0 + ) { + TDEBUGF("starting sequential insertions"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + mix_operations(nums, ITER, nodes, ITER, ITER, 0, 0); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done sequential insertions in: %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + TDEBUGF("doing pfind and remove"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + tmp = malloc(sizeof(struct node)); + for(i = 0; i < ITER + 1; i++) { + tmp->key = ITER + 6; + ins = RB_PFIND(tree, &root, tmp); + if (ins == NULL) + errx(1, "RB_PFIND failed"); + if (RB_REMOVE(tree, &root, ins) == NULL) + errx(1, "RB_REMOVE failed: %d", i); +#ifdef RB_TEST_RANK + if (i % RANK_TEST_ITERATIONS == 0) { + rank = RB_RANK(tree, RB_ROOT(&root)); + if (rank == -2) + errx(1, "rank error"); + } +#endif + } + free(tmp); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done removals in: %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + } +#endif + + // iterate over the tree using RB_NEXT/RB_PREV + // insertions and removals have separate tests + if (test_target == NULL || + strcmp(test_target, "node-iterations") == 0 + ) { + TDEBUGF("starting sequential insertions"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + mix_operations(nums, ITER, nodes, ITER, ITER, 0, 0); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done sequential insertions in: %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + TDEBUGF("iterating over tree with RB_NEXT"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + tmp = RB_MIN(tree, &root); + assert(tmp != NULL); + assert(tmp->key == 0); + for(i = 1; i < ITER; i++) { + tmp = RB_NEXT(tree, &root, tmp); + assert(tmp != NULL); + assert(tmp->key == i); + } + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done iterations in %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + TDEBUGF("iterating over tree with RB_PREV"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + tmp = RB_MAX(tree, &root); + assert(tmp != NULL); + assert(tmp->key == ITER + 5); + for(i = 0; i < ITER; i++) { + tmp = RB_PREV(tree, &root, tmp); + assert(tmp != NULL); + assert(tmp->key == ITER - 1 - i); + } + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done iterations in %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + TDEBUGF("doing root removals"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + for (i = 0; i < ITER + 1; i++) { + tmp = RB_ROOT(&root); + assert(NULL != tmp); + assert(RB_REMOVE(tree, &root, tmp) == tmp); +#ifdef RB_TEST_RANK + if (i % RANK_TEST_ITERATIONS == 0) { + rank = RB_RANK(tree, RB_ROOT(&root)); + if (rank == -2) + errx(1, "rank error"); + } +#endif + } + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done root removals in: %llu.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + } + + // iterate over the tree using RB_FOREACH* macros + // the *_SAFE macros are tested by using them to clear the tree + // insertions and removals have separate tests + if (test_target == NULL || + strcmp(test_target, "iteration-macros") == 0 + ) { + TDEBUGF("starting sequential insertions"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + mix_operations(nums, ITER, nodes, ITER, ITER, 0, 0); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done sequential insertions in: %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + +#ifdef RB_FOREACH + TDEBUGF("iterating over tree with RB_FOREACH"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + i = 0; + RB_FOREACH(ins, tree, &root) { + if (i < ITER) + assert(ins->key == i); + else + assert(ins->key == ITER + 5); + i++; + } + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done iterations in %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); +#endif + +#ifdef RB_FOREACH_REVERSE + TDEBUGF("iterating over tree with RB_FOREACH_REVERSE"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + i = ITER + 5; + RB_FOREACH_REVERSE(ins, tree, &root) { + assert(ins->key == i); + if (i > ITER) + i = ITER - 1; + else + i--; + } + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done iterations in %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); +#endif + + TDEBUGF("doing root removals"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + for (i = 0; i < ITER + 1; i++) { + tmp = RB_ROOT(&root); + assert(NULL != tmp); + assert(RB_REMOVE(tree, &root, tmp) == tmp); +#ifdef RB_TEST_RANK + if (i % RANK_TEST_ITERATIONS == 0) { + rank = RB_RANK(tree, RB_ROOT(&root)); + if (rank == -2) + errx(1, "rank error"); + } +#endif + } + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done root removals in: %llu.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + +#ifdef RB_FOREACH_SAFE + TDEBUGF("starting sequential insertions"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + mix_operations(nums, ITER, nodes, ITER, ITER, 0, 0); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done sequential insertions in: %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + TDEBUGF("iterating over tree and clearing with RB_FOREACH_SAFE"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + i = 0; + RB_FOREACH_SAFE(ins, tree, &root, tmp) { + if (i < ITER) + assert(ins->key == i); + else + assert(ins->key == ITER + 5); + i++; + assert(RB_REMOVE(tree, &root, ins) == ins); + } + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done iterations in %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); +#endif + +#ifdef RB_FOREACH_REVERSE_SAFE + TDEBUGF("starting sequential insertions"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + mix_operations(nums, ITER, nodes, ITER, ITER, 0, 0); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done sequential insertions in: %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + TDEBUGF("iterating over tree and clearing with RB_FOREACH_REVERSE_SAFE"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + i = ITER + 5; + RB_FOREACH_REVERSE_SAFE(ins, tree, &root, tmp) { + assert(ins->key == i); + if (i > ITER) + i = ITER - 1; + else + i--; + assert(RB_REMOVE(tree, &root, ins) == ins); + } + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done iterations in %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); +#endif + } + +#ifdef RB_INSERT_NEXT + // testing insertions at specific points in the tree + // the insertions are done at the next position in the tree at a give node + // this assumes that the location is correct for the given ordering + if (test_target == NULL || + strcmp(test_target, "insert-next") == 0 + ) { + TDEBUGF("starting sequential insertions using INSERT_NEXT"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + tmp = &(nodes[0]); + tmp->size = 1; + tmp->height = 1; + tmp->key = 0; if (RB_INSERT(tree, &root, tmp) != NULL) errx(1, "RB_INSERT failed"); + ins = tmp; + for(i = 1; i < ITER; i++) { + tmp = &(nodes[i]); + tmp->size = 1; + tmp->height = 1; + tmp->key = i; + if (RB_INSERT_NEXT(tree, &root, ins, tmp) != NULL) + errx(1, "RB_INSERT failed"); + ins = tmp; +#ifdef RB_TEST_RANK + if (i % RANK_TEST_ITERATIONS == 0) { + rank = RB_RANK(tree, RB_ROOT(&root)); + if (rank == -2) + errx(1, "rank error"); + } +#endif + } + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done insertions in %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + TDEBUGF("iterating over tree and clearing with RB_FOREACH_REVERSE_SAFE"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + RB_FOREACH_REVERSE_SAFE(ins, tree, &root, tmp) { + assert(RB_REMOVE(tree, &root, ins) == ins); + } + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done iterations in %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + } +#endif + +#ifdef RB_INSERT_PREV + // testing insertions at specific points in the tree + // the insertions are done at the next position in the tree at a give node + // this assumes that the location is correct for the given ordering + if (test_target == NULL || + strcmp(test_target, "insert-prev") == 0 + ) { + TDEBUGF("starting sequential insertions using INSERT_PREV"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + tmp = &(nodes[ITER]); + tmp->size = 1; + tmp->height = 1; + tmp->key = ITER; + if (RB_INSERT(tree, &root, tmp) != NULL) + errx(1, "RB_INSERT failed"); + ins = tmp; + for(i = ITER - 1; i >= 0; i--) { + tmp = &(nodes[i]); + tmp->size = 1; + tmp->height = 1; + tmp->key = i; + if (RB_INSERT_PREV(tree, &root, ins, tmp) != NULL) + errx(1, "RB_INSERT failed"); + ins = tmp; +#ifdef RB_TEST_RANK + if (i % RANK_TEST_ITERATIONS == 0) { + rank = RB_RANK(tree, RB_ROOT(&root)); + if (rank == -2) + errx(1, "rank error"); + } +#endif + } + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done insertions in %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + TDEBUGF("iterating over tree and clearing with RB_FOREACH_REVERSE_SAFE"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + RB_FOREACH_REVERSE_SAFE(ins, tree, &root, tmp) { + assert(RB_REMOVE(tree, &root, ins) == ins); + } + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done iterations in %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + } +#endif + + if (test_target == NULL || + strcmp(test_target, "benchmarks") == 0 + ) { + TDEBUGF("doing 50%% insertions, 50%% lookups"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + mix_operations(perm, ITER, nodes, ITER, ITER / 2, ITER / 2, 1); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done operations in: %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + TDEBUGF("doing root removals"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + for (i = 0; i < ITER / 2 + 1; i++) { + tmp = RB_ROOT(&root); + if (tmp == NULL) + errx(1, "RB_ROOT error"); + if (RB_REMOVE(tree, &root, tmp) != tmp) + errx(1, "RB_REMOVE error"); + } + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done root removals in: %llu.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + TDEBUGF("doing 20%% insertions, 80%% lookups"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + mix_operations(perm, ITER, nodes, ITER, ITER / 5, 4 * (ITER / 5), 1); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done operations in: %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + TDEBUGF("doing root removals"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + for (i = 0; i < ITER / 5 + 1; i++) { + tmp = RB_ROOT(&root); + if (tmp == NULL) + errx(1, "RB_ROOT error"); + if (RB_REMOVE(tree, &root, tmp) != tmp) + errx(1, "RB_REMOVE error"); + } + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done root removals in: %llu.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + TDEBUGF("doing 10%% insertions, 90%% lookups"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + mix_operations(perm, ITER, nodes, ITER, ITER / 10, 9 * (ITER / 10), 1); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done operations in: %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + TDEBUGF("doing root removals"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + for (i = 0; i < ITER / 10 + 1; i++) { + tmp = RB_ROOT(&root); + if (tmp == NULL) + errx(1, "RB_ROOT error"); + if (RB_REMOVE(tree, &root, tmp) != tmp) + errx(1, "RB_REMOVE error"); + } + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done root removals in: %llu.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + TDEBUGF("doing 5%% insertions, 95%% lookups"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + mix_operations(perm, ITER, nodes, + ITER, 5 * (ITER / 100), + 95 * (ITER / 100), 1); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done operations in: %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + TDEBUGF("doing root removals"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + for (i = 0; i < 5 * (ITER / 100) + 1; i++) { + tmp = RB_ROOT(&root); + if (tmp == NULL) + errx(1, "RB_ROOT error"); + if (RB_REMOVE(tree, &root, tmp) != tmp) + errx(1, "RB_REMOVE error"); + } + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done root removals in: %llu.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + TDEBUGF("doing 2%% insertions, 98%% lookups"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + mix_operations(perm, ITER, nodes, ITER, + 2 * (ITER / 100), + 98 * (ITER / 100), 1); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done operations in: %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + TDEBUGF("doing root removals"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + for (i = 0; i < 2 * (ITER / 100) + 1; i++) { + tmp = RB_ROOT(&root); + if (tmp == NULL) + errx(1, "RB_ROOT error"); + if (RB_REMOVE(tree, &root, tmp) != tmp) + errx(1, "RB_REMOVE error"); + } + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done root removals in: %llu.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); } - ins = RB_MIN(tree, &root); - if (ins->key != min) - errx(1, "min does not match"); - tmp = ins; - ins = RB_MAX(tree, &root); - if (ins->key != max) - errx(1, "max does not match"); + free(nodes); + free(perm); + free(nums); - if (RB_REMOVE(tree, &root, tmp) != tmp) - errx(1, "RB_REMOVE failed"); - - for (i = 0; i < ITER - 1; i++) { - tmp = RB_ROOT(&root); - if (tmp == NULL) - errx(1, "RB_ROOT error"); - if (RB_REMOVE(tree, &root, tmp) != tmp) - errx(1, "RB_REMOVE error"); - free(tmp); - } - - exit(0); + return 0; +} + + +static int +compare(const struct node *a, const struct node *b) +{ + return a->key - b->key; +} + +#ifdef RB_TEST_DIAGNOSTIC +static void +print_helper(const struct node *n, int indent) +{ + if (RB_RIGHT(n, node_link)) + print_helper(RB_RIGHT(n, node_link), indent + 4); + TDEBUGF("%*s key=%d :: size=%zu :: rank=%d :: rdiff %lu:%lu", + indent, "", n->key, n->size, RB_RANK(tree, n), + _RB_GET_RDIFF(n, _RB_LDIR, node_link), + _RB_GET_RDIFF(n, _RB_RDIR, node_link)); + if (RB_LEFT(n, node_link)) + print_helper(RB_LEFT(n, node_link), indent + 4); +} + +static void +print_tree(const struct tree *t) +{ + if (RB_ROOT(t)) print_helper(RB_ROOT(t), 0); +} +#endif + +#ifdef DOAUGMENT +static int +tree_augment(struct node *elm) +{ + size_t newsize = 1, newheight = 0; + if ((RB_LEFT(elm, node_link))) { + newsize += (RB_LEFT(elm, node_link))->size; + newheight = MAX((RB_LEFT(elm, node_link))->height, newheight); + } + if ((RB_RIGHT(elm, node_link))) { + newsize += (RB_RIGHT(elm, node_link))->size; + newheight = MAX((RB_RIGHT(elm, node_link))->height, newheight); + } + newheight += 1; + if (elm->size != newsize || elm->height != newheight) { + elm->size = newsize; + elm->height = newheight; + return 1; + } + return 0; +} +#endif + + +void +mix_operations(int *perm, int psize, struct node *nodes, int nsize, + int insertions, int reads, int do_reads) +{ + int i, rank; + struct node *tmp, *ins; + struct node it; + assert(psize == nsize); + assert(insertions + reads <= psize); + + for(i = 0; i < insertions; i++) { + //TDEBUGF("iteration %d", i); + tmp = &(nodes[i]); + if (tmp == NULL) err(1, "malloc"); + tmp->size = 1; + tmp->height = 1; + tmp->key = perm[i]; + //TDEBUGF("inserting %d", tmp->key); + if (RB_INSERT(tree, &root, tmp) != NULL) + errx(1, "RB_INSERT failed"); + print_tree(&root); +#ifdef DOAUGMENT + //TDEBUGF("size = %zu", RB_ROOT(&root)->size); + assert(RB_ROOT(&root)->size == i + 1); +#endif + +#ifdef RB_TEST_RANK + if (i % RANK_TEST_ITERATIONS == 0) { + rank = RB_RANK(tree, RB_ROOT(&root)); + if (rank == -2) + errx(1, "rank error"); + } +#endif + } + tmp = &(nodes[insertions]); + tmp->key = ITER + 5; + tmp->size = 1; + tmp->height = 1; + RB_INSERT(tree, &root, tmp); + if (do_reads) { + for (i = 0; i < insertions; i++) { + it.key = perm[i]; + ins = RB_FIND(tree, &root, &it); + if ((ins == NULL) || ins->key != it.key) + errx(1, "RB_FIND failed"); + } + for (i = insertions; i < insertions + reads; i++) { + it.key = perm[i]; + ins = RB_NFIND(tree, &root, &it); + if (ins->key < it.key) + errx(1, "RB_NFIND failed"); + } + } } diff --git a/regress/sys/sys/tree/rb/rbt-test.c b/regress/sys/sys/tree/rb/rbt-test.c new file mode 100644 index 000000000..006f3d3f7 --- /dev/null +++ b/regress/sys/sys/tree/rb/rbt-test.c @@ -0,0 +1,975 @@ +/* + * Copyright 2002 Niels Provos + * 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. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 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 AUTHOR 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 + +struct timespec start, end, diff, rstart, rend, rdiff, rtot = {0, 0}; +#ifndef timespecsub +#define timespecsub(tsp, usp, vsp) \ + do { \ + (vsp)->tv_sec = (tsp)->tv_sec - (usp)->tv_sec; \ + (vsp)->tv_nsec = (tsp)->tv_nsec - (usp)->tv_nsec; \ + if ((vsp)->tv_nsec < 0) { \ + (vsp)->tv_sec--; \ + (vsp)->tv_nsec += 1000000000L; \ + } \ + } while (0) +#endif +#ifndef timespecadd +#define timespecadd(tsp, usp, vsp) \ + do { \ + (vsp)->tv_sec = (tsp)->tv_sec + (usp)->tv_sec; \ + (vsp)->tv_nsec = (tsp)->tv_nsec + (usp)->tv_nsec; \ + if ((vsp)->tv_nsec >= 1000000000L) { \ + (vsp)->tv_sec++; \ + (vsp)->tv_nsec -= 1000000000L; \ + } \ + } while (0) +#endif + +//#define RBT_SMALL +//#define RBT_TEST_RANK +//#define RBT_TEST_DIAGNOSTIC +//#define _RBT_DIAGNOSTIC + +#ifdef DOAUGMENT +#define RBT_AUGMENT(elm) tree_augment(elm) +#endif + +#include + +#define TDEBUGF(fmt, ...) \ + fprintf(stderr, "%s:%d:%s(): " fmt "\n", \ + __FILE__, __LINE__, __func__, ##__VA_ARGS__) + + +#ifdef __OpenBSD__ +#define SEED_RANDOM srandom_deterministic +#else +#define SEED_RANDOM srandom +#endif + +int ITER=150000; +int RANK_TEST_ITERATIONS=10000; + +#define MAX(a, b) ((a) > (b) ? (a) : (b)) + +/* declarations */ +struct node; +struct tree; +static int compare(const struct node *, const struct node *); +static void mix_operations(int *, int, struct node *, int, int, int, int); + +#ifdef DOAUGMENT +static int tree_augment(struct node *); +#else +#define tree_augment(x) (0) +#endif + +#ifdef RBT_TEST_DIAGNOSTIC +static void print_helper(const struct node *, int); +static void print_tree(const struct tree *); +#else +#define print_helper(x, y) do {} while (0) +#define print_tree(x) do {} while (0) +#endif + +/* definitions */ +struct node { + RBT_ENTRY(node) node_link; + int key; + size_t height; + size_t size; +}; + +RBT_HEAD(tree, node); +struct tree root = RBT_INITIALIZER(&root); + +RBT_PROTOTYPE(tree, node, node_link, compare) + +RBT_GENERATE(tree, node, node_link, compare); + +#ifndef RBT_RANK +#define RBT_RANK(x, y) 0 +#endif +#ifndef _RBT_GET_RDIFF +#define _RBT_GET_RDIFF(x, y, z) 0 +#endif + +int +main(int argc, char **argv) +{ + char *test_target = NULL; + struct node *tmp, *ins, *nodes; + int i, r, rank, *perm, *nums; + + if (argc > 1) + test_target = argv[1]; + + nodes = calloc((ITER + 5), sizeof(struct node)); + perm = calloc(ITER, sizeof(int)); + nums = calloc(ITER, sizeof(int)); + + // for determinism + SEED_RANDOM(4201); + + TDEBUGF("generating a 'random' permutation"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + perm[0] = 0; + nums[0] = 0; + for(i = 1; i < ITER; i++) { + r = random() % i; // arc4random_uniform(i); + perm[i] = perm[r]; + perm[r] = i; + nums[i] = i; + } + /* + fprintf(stderr, "{"); + for(int i = 0; i < ITER; i++) { + fprintf(stderr, "%d, ", perm[i]); + } + fprintf(stderr, "}\n"); + int nperm[10] = {2, 4, 9, 7, 8, 3, 0, 1, 6, 5}; + int nperm[6] = {2, 6, 1, 4, 5, 3}; + int nperm[10] = {10, 3, 7, 8, 6, 1, 9, 2, 5, 4}; + int nperm[2] = {0, 1}; + + int nperm[100] = { + 54, 47, 31, 35, 40, 73, 29, 66, 15, 45, 9, 71, 51, 32, 28, 62, + 12, 46, 50, 26, 36, 91, 10, 76, 33, 43, 34, 58, 55, 72, 37, 24, + 75, 4, 90, 88, 30, 25, 82, 18, 67, 81, 80, 65, 23, 41, 61, 86, + 20, 99, 59, 14, 79, 21, 68, 27, 1, 7, 94, 44, 89, 64, 96, 2, 49, + 53, 74, 13, 48, 42, 60, 52, 95, 17, 11, 0, 22, 97, 77, 69, 6, + 16, 84, 78, 8, 83, 98, 93, 39, 38, 85, 70, 3, 19, 57, 5, 87, + 92, 63, 56 + }; + ITER = 100; + for(int i = 0; i < ITER; i++){ + perm[i] = nperm[i]; + } + */ + + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done generating a 'random' permutation in: %llu.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + RBT_INIT(tree, &root); + + // testing random inserts + // due to codependency between inserts and removals, this also tests + // root removals + if (test_target == NULL || + strcmp(test_target, "random-inserts") == 0 + ) { + TDEBUGF("starting random insertions"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + mix_operations(perm, ITER, nodes, ITER, ITER, 0, 0); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done random insertions in: %llu.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + +#ifdef DOAUGMENT + ins = RBT_ROOT(tree, &root); + assert(ITER + 1 == ins->size); +#endif + + TDEBUGF("getting min"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + ins = RBT_MIN(tree, &root); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done getting min in: %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + assert(0 == ins->key); + + TDEBUGF("getting max"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + ins = RBT_MAX(tree, &root); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done getting max in: %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + assert(ITER + 5 == ins->key); + + ins = RBT_ROOT(tree, &root); + TDEBUGF("getting root"); + assert(RBT_REMOVE(tree, &root, ins) == ins); + +#ifdef DOAUGMENT + assert(ITER == (RBT_ROOT(tree, &root))->size); +#endif + + TDEBUGF("doing root removals"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + for (i = 0; i < ITER; i++) { + tmp = RBT_ROOT(tree, &root); + assert(NULL != tmp); + assert(RBT_REMOVE(tree, &root, tmp) == tmp); +#ifdef RBT_TEST_RANK + if (i % RANK_TEST_ITERATIONS == 0) { + rank = RBT_RANK(tree, RBT_ROOT(tree, &root)); + assert(-2 != rank); + print_tree(&root); + } +#endif + +#ifdef DOAUGMENT + if (!(RBT_EMPTY(&root)) && (RBT_ROOT(tree, &root))->size != ITER - 1 - i) + errx(1, "RBT_REMOVE size error"); +#endif + + } + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done root removals in: %llu.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + } + + // testing insertions in increasing sequential order + // removals are done using root removals (separate test) + if (test_target == NULL || + strcmp(test_target, "sequential-inserts") == 0 + ) { + TDEBUGF("starting sequential insertions"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + mix_operations(nums, ITER, nodes, ITER, ITER, 0, 0); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done sequential insertions in: %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + TDEBUGF("doing root removals"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + for (i = 0; i < ITER + 1; i++) { + tmp = RBT_ROOT(tree, &root); + assert(NULL != tmp); + assert(RBT_REMOVE(tree, &root, tmp) == tmp); +#ifdef RBT_TEST_RANK + if (i % RANK_TEST_ITERATIONS == 0) { + rank = RBT_RANK(tree, RBT_ROOT(tree, &root)); + if (rank == -2) + errx(1, "rank error"); + } +#endif + } + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done root removals in: %llu.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + } + + // testing the RBT_FIND function and using it to do removals in + // sequential order + // insertions are done using sequential insertions (separate test) + if (test_target == NULL || + strcmp(test_target, "sequential-removes") == 0 + ) { + TDEBUGF("starting sequential insertions"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + mix_operations(nums, ITER, nodes, ITER, ITER, 0, 0); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done sequential insertions in: %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + TDEBUGF("doing find and remove in sequential order"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + tmp = malloc(sizeof(struct node)); + for(i = 0; i < ITER; i++) { + tmp->key = i; + ins = RBT_FIND(tree, &root, tmp); + assert(NULL != tmp); + assert(RBT_REMOVE(tree, &root, ins) == ins); +#ifdef RBT_TEST_RANK + if (i % RANK_TEST_ITERATIONS == 0) { + rank = RBT_RANK(tree, RBT_ROOT(tree, &root)); + if (rank == -2) + errx(1, "rank error"); + } +#endif + } + free(tmp); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done removals in: %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + ins = RBT_ROOT(tree, &root); + if (ins == NULL) + errx(1, "RBT_ROOT error"); + if (RBT_REMOVE(tree, &root, ins) != ins) + errx(1, "RBT_REMOVE failed"); + } + + // testing removals in random order + // the elements are found using RBT_FIND + // insertions are done using sequential insertions (separate test) + if (test_target == NULL || + strcmp(test_target, "random-removes") == 0 + ) { + TDEBUGF("starting sequential insertions"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + mix_operations(nums, ITER, nodes, ITER, ITER, 0, 0); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done sequential insertions in: %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + + TDEBUGF("doing find and remove in random order"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + tmp = malloc(sizeof(struct node)); + for(i = 0; i < ITER; i++) { + tmp->key = perm[i]; + ins = RBT_FIND(tree, &root, tmp); + if (ins == NULL) { + errx(1, "RBT_FIND %d failed: %d", i, perm[i]); + } + if (RBT_REMOVE(tree, &root, ins) == NULL) + errx(1, "RBT_REMOVE failed: %d", i); +#ifdef RBT_TEST_RANK + if (i % RANK_TEST_ITERATIONS == 0) { + rank = RBT_RANK(tree, RBT_ROOT(tree, &root)); + if (rank == -2) + errx(1, "rank error"); + } +#endif + } + free(tmp); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done removals in: %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + ins = RBT_ROOT(tree, &root); + if (ins == NULL) + errx(1, "RBT_ROOT error"); + if (RBT_REMOVE(tree, &root, ins) != ins) + errx(1, "RBT_REMOVE failed"); + } + + // testing removals by finding the next largest element + // this is testing the RBT_NFIND macro + // insertions are done using sequential insertions (separate test) + if (test_target == NULL || + strcmp(test_target, "remove-nfind") == 0 + ) { + TDEBUGF("starting sequential insertions"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + mix_operations(nums, ITER, nodes, ITER, ITER, 0, 0); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done sequential insertions in: %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + TDEBUGF("doing nfind and remove"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + tmp = malloc(sizeof(struct node)); + for(i = 0; i < ITER + 1; i++) { + tmp->key = i; + ins = RBT_NFIND(tree, &root, tmp); + if (ins == NULL) + errx(1, "RBT_NFIND failed"); + if (RBT_REMOVE(tree, &root, ins) == NULL) + errx(1, "RBT_REMOVE failed: %d", i); +#ifdef RBT_TEST_RANK + if (i % RANK_TEST_ITERATIONS == 0) { + rank = RBT_RANK(tree, RBT_ROOT(tree, &root)); + if (rank == -2) + errx(1, "rank error"); + } +#endif + } + free(tmp); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done removals in: %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + } + +#ifdef RBT_PFIND + // testing removals by finding the previous element + // this is testing the RBT_PFIND macro + // insertions are done using sequential insertions (separate test) + if (test_target == NULL || + strcmp(test_target, "remove-pfind") == 0 + ) { + TDEBUGF("starting sequential insertions"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + mix_operations(nums, ITER, nodes, ITER, ITER, 0, 0); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done sequential insertions in: %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + TDEBUGF("doing pfind and remove"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + tmp = malloc(sizeof(struct node)); + for(i = 0; i < ITER + 1; i++) { + tmp->key = ITER + 6; + ins = RBT_PFIND(tree, &root, tmp); + if (ins == NULL) + errx(1, "RBT_PFIND failed"); + if (RBT_REMOVE(tree, &root, ins) == NULL) + errx(1, "RBT_REMOVE failed: %d", i); +#ifdef RBT_TEST_RANK + if (i % RANK_TEST_ITERATIONS == 0) { + rank = RBT_RANK(tree, RBT_ROOT(tree, &root)); + if (rank == -2) + errx(1, "rank error"); + } +#endif + } + free(tmp); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done removals in: %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + } +#endif + + // iterate over the tree using RBT_NEXT/RBT_PREV + // insertions and removals have separate tests + if (test_target == NULL || + strcmp(test_target, "node-iterations") == 0 + ) { + TDEBUGF("starting sequential insertions"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + mix_operations(nums, ITER, nodes, ITER, ITER, 0, 0); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done sequential insertions in: %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + TDEBUGF("iterating over tree with RBT_NEXT"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + tmp = RBT_MIN(tree, &root); + assert(tmp != NULL); + assert(tmp->key == 0); + for(i = 1; i < ITER; i++) { + tmp = RBT_NEXT(tree, tmp); + assert(tmp != NULL); + assert(tmp->key == i); + } + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done iterations in %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + TDEBUGF("iterating over tree with RBT_PREV"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + tmp = RBT_MAX(tree, &root); + assert(tmp != NULL); + assert(tmp->key == ITER + 5); + for(i = 0; i < ITER; i++) { + tmp = RBT_PREV(tree, tmp); + assert(tmp != NULL); + assert(tmp->key == ITER - 1 - i); + } + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done iterations in %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + TDEBUGF("doing root removals"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + for (i = 0; i < ITER + 1; i++) { + tmp = RBT_ROOT(tree, &root); + assert(NULL != tmp); + assert(RBT_REMOVE(tree, &root, tmp) == tmp); +#ifdef RBT_TEST_RANK + if (i % RANK_TEST_ITERATIONS == 0) { + rank = RBT_RANK(tree, RBT_ROOT(tree, &root)); + if (rank == -2) + errx(1, "rank error"); + } +#endif + } + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done root removals in: %llu.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + } + + // iterate over the tree using RBT_FOREACH* macros + // the *_SAFE macros are tested by using them to clear the tree + // insertions and removals have separate tests + if (test_target == NULL || + strcmp(test_target, "iteration-macros") == 0 + ) { + TDEBUGF("starting sequential insertions"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + mix_operations(nums, ITER, nodes, ITER, ITER, 0, 0); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done sequential insertions in: %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + +#ifdef RBT_FOREACH + TDEBUGF("iterating over tree with RBT_FOREACH"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + i = 0; + RBT_FOREACH(ins, tree, &root) { + if (i < ITER) + assert(ins->key == i); + else + assert(ins->key == ITER + 5); + i++; + } + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done iterations in %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); +#endif + +#ifdef RBT_FOREACH_REVERSE + TDEBUGF("iterating over tree with RBT_FOREACH_REVERSE"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + i = ITER + 5; + RBT_FOREACH_REVERSE(ins, tree, &root) { + assert(ins->key == i); + if (i > ITER) + i = ITER - 1; + else + i--; + } + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done iterations in %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); +#endif + + TDEBUGF("doing root removals"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + for (i = 0; i < ITER + 1; i++) { + tmp = RBT_ROOT(tree, &root); + assert(NULL != tmp); + assert(RBT_REMOVE(tree, &root, tmp) == tmp); +#ifdef RBT_TEST_RANK + if (i % RANK_TEST_ITERATIONS == 0) { + rank = RBT_RANK(tree, RBT_ROOT(tree, &root)); + if (rank == -2) + errx(1, "rank error"); + } +#endif + } + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done root removals in: %llu.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + +#ifdef RBT_FOREACH_SAFE + TDEBUGF("starting sequential insertions"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + mix_operations(nums, ITER, nodes, ITER, ITER, 0, 0); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done sequential insertions in: %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + TDEBUGF("iterating over tree and clearing with RBT_FOREACH_SAFE"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + i = 0; + RBT_FOREACH_SAFE(ins, tree, &root, tmp) { + if (i < ITER) + assert(ins->key == i); + else + assert(ins->key == ITER + 5); + i++; + assert(RBT_REMOVE(tree, &root, ins) == ins); + } + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done iterations in %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); +#endif + +#ifdef RBT_FOREACH_REVERSE_SAFE + TDEBUGF("starting sequential insertions"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + mix_operations(nums, ITER, nodes, ITER, ITER, 0, 0); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done sequential insertions in: %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + TDEBUGF("iterating over tree and clearing with RBT_FOREACH_REVERSE_SAFE"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + i = ITER + 5; + RBT_FOREACH_REVERSE_SAFE(ins, tree, &root, tmp) { + assert(ins->key == i); + if (i > ITER) + i = ITER - 1; + else + i--; + assert(RBT_REMOVE(tree, &root, ins) == ins); + } + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done iterations in %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); +#endif + } + +#ifdef RBT_INSERT_NEXT + // testing insertions at specific points in the tree + // the insertions are done at the next position in the tree at a give node + // this assumes that the location is correct for the given ordering + if (test_target == NULL || + strcmp(test_target, "insert-next") == 0 + ) { + TDEBUGF("starting sequential insertions using INSERT_NEXT"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + tmp = &(nodes[0]); + tmp->size = 1; + tmp->height = 1; + tmp->key = 0; + if (RBT_INSERT(tree, &root, tmp) != NULL) + errx(1, "RBT_INSERT failed"); + ins = tmp; + for(i = 1; i < ITER; i++) { + tmp = &(nodes[i]); + tmp->size = 1; + tmp->height = 1; + tmp->key = i; + if (RBT_INSERT_NEXT(tree, &root, ins, tmp) != NULL) + errx(1, "RBT_INSERT failed"); + ins = tmp; +#ifdef RBT_TEST_RANK + if (i % RANK_TEST_ITERATIONS == 0) { + rank = RBT_RANK(tree, RBT_ROOT(tree, &root)); + if (rank == -2) + errx(1, "rank error"); + } +#endif + } + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done insertions in %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + TDEBUGF("iterating over tree and clearing with RBT_FOREACH_REVERSE_SAFE"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + RBT_FOREACH_REVERSE_SAFE(ins, tree, &root, tmp) { + assert(RBT_REMOVE(tree, &root, ins) == ins); + } + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done iterations in %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + } +#endif + +#ifdef RBT_INSERT_PREV + // testing insertions at specific points in the tree + // the insertions are done at the next position in the tree at a give node + // this assumes that the location is correct for the given ordering + if (test_target == NULL || + strcmp(test_target, "insert-prev") == 0 + ) { + TDEBUGF("starting sequential insertions using INSERT_PREV"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + tmp = &(nodes[ITER]); + tmp->size = 1; + tmp->height = 1; + tmp->key = ITER; + if (RBT_INSERT(tree, &root, tmp) != NULL) + errx(1, "RBT_INSERT failed"); + ins = tmp; + for(i = ITER - 1; i >= 0; i--) { + tmp = &(nodes[i]); + tmp->size = 1; + tmp->height = 1; + tmp->key = i; + if (RBT_INSERT_PREV(tree, &root, ins, tmp) != NULL) + errx(1, "RBT_INSERT failed"); + ins = tmp; +#ifdef RBT_TEST_RANK + if (i % RANK_TEST_ITERATIONS == 0) { + rank = RBT_RANK(tree, RBT_ROOT(tree, &root)); + if (rank == -2) + errx(1, "rank error"); + } +#endif + } + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done insertions in %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + TDEBUGF("iterating over tree and clearing with RBT_FOREACH_REVERSE_SAFE"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + RBT_FOREACH_REVERSE_SAFE(ins, tree, &root, tmp) { + assert(RBT_REMOVE(tree, &root, ins) == ins); + } + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done iterations in %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + } +#endif + + if (test_target == NULL || + strcmp(test_target, "benchmarks") == 0 + ) { + TDEBUGF("doing 50%% insertions, 50%% lookups"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + mix_operations(perm, ITER, nodes, ITER, ITER / 2, ITER / 2, 1); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done operations in: %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + TDEBUGF("doing root removals"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + for (i = 0; i < ITER / 2 + 1; i++) { + tmp = RBT_ROOT(tree, &root); + if (tmp == NULL) + errx(1, "RBT_ROOT error"); + if (RBT_REMOVE(tree, &root, tmp) != tmp) + errx(1, "RBT_REMOVE error"); + } + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done root removals in: %llu.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + TDEBUGF("doing 20%% insertions, 80%% lookups"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + mix_operations(perm, ITER, nodes, ITER, ITER / 5, 4 * (ITER / 5), 1); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done operations in: %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + TDEBUGF("doing root removals"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + for (i = 0; i < ITER / 5 + 1; i++) { + tmp = RBT_ROOT(tree, &root); + if (tmp == NULL) + errx(1, "RBT_ROOT error"); + if (RBT_REMOVE(tree, &root, tmp) != tmp) + errx(1, "RBT_REMOVE error"); + } + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done root removals in: %llu.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + TDEBUGF("doing 10%% insertions, 90%% lookups"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + mix_operations(perm, ITER, nodes, ITER, ITER / 10, 9 * (ITER / 10), 1); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done operations in: %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + TDEBUGF("doing root removals"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + for (i = 0; i < ITER / 10 + 1; i++) { + tmp = RBT_ROOT(tree, &root); + if (tmp == NULL) + errx(1, "RBT_ROOT error"); + if (RBT_REMOVE(tree, &root, tmp) != tmp) + errx(1, "RBT_REMOVE error"); + } + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done root removals in: %llu.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + TDEBUGF("doing 5%% insertions, 95%% lookups"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + mix_operations(perm, ITER, nodes, + ITER, 5 * (ITER / 100), + 95 * (ITER / 100), 1); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done operations in: %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + TDEBUGF("doing root removals"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + for (i = 0; i < 5 * (ITER / 100) + 1; i++) { + tmp = RBT_ROOT(tree, &root); + if (tmp == NULL) + errx(1, "RBT_ROOT error"); + if (RBT_REMOVE(tree, &root, tmp) != tmp) + errx(1, "RBT_REMOVE error"); + } + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done root removals in: %llu.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + TDEBUGF("doing 2%% insertions, 98%% lookups"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + mix_operations(perm, ITER, nodes, ITER, + 2 * (ITER / 100), + 98 * (ITER / 100), 1); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done operations in: %lld.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + + TDEBUGF("doing root removals"); + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start); + for (i = 0; i < 2 * (ITER / 100) + 1; i++) { + tmp = RBT_ROOT(tree, &root); + if (tmp == NULL) + errx(1, "RBT_ROOT error"); + if (RBT_REMOVE(tree, &root, tmp) != tmp) + errx(1, "RBT_REMOVE error"); + } + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end); + timespecsub(&end, &start, &diff); + TDEBUGF("done root removals in: %llu.%09llu s", + (unsigned long long)diff.tv_sec, (unsigned long long)diff.tv_nsec); + } + + free(nodes); + free(perm); + free(nums); + + return 0; +} + + +static int +compare(const struct node *a, const struct node *b) +{ + return a->key - b->key; +} + +#ifdef RBT_TEST_DIAGNOSTIC +static void +print_helper(const struct node *n, int indent) +{ + if (RBT_RIGHT(n, node_link)) + print_helper(RBT_RIGHT(n, node_link), indent + 4); + TDEBUGF("%*s key=%d :: size=%zu :: rank=%d :: rdiff %lu:%lu", + indent, "", n->key, n->size, RBT_RANK(tree, n), + _RBT_GET_RDIFF(n, _RBT_LDIR, node_link), + _RBT_GET_RDIFF(n, _RBT_RDIR, node_link)); + if (RBT_LEFT(n, node_link)) + print_helper(RBT_LEFT(n, node_link), indent + 4); +} + +static void +print_tree(const struct tree *t) +{ + if (RBT_ROOT(tree, t)) print_helper(RBT_ROOT(tree, t), 0); +} +#endif + +#ifdef DOAUGMENT +static int +tree_augment(struct node *elm) +{ + size_t newsize = 1, newheight = 0; + if ((RBT_LEFT(elm, node_link))) { + newsize += (RBT_LEFT(elm, node_link))->size; + newheight = MAX((RBT_LEFT(elm, node_link))->height, newheight); + } + if ((RBT_RIGHT(elm, node_link))) { + newsize += (RBT_RIGHT(elm, node_link))->size; + newheight = MAX((RBT_RIGHT(elm, node_link))->height, newheight); + } + newheight += 1; + if (elm->size != newsize || elm->height != newheight) { + elm->size = newsize; + elm->height = newheight; + return 1; + } + return 0; +} +#endif + + +void +mix_operations(int *perm, int psize, struct node *nodes, int nsize, + int insertions, int reads, int do_reads) +{ + int i, rank; + struct node *tmp, *ins; + struct node it; + assert(psize == nsize); + assert(insertions + reads <= psize); + + for(i = 0; i < insertions; i++) { + //TDEBUGF("iteration %d", i); + tmp = &(nodes[i]); + if (tmp == NULL) err(1, "malloc"); + tmp->size = 1; + tmp->height = 1; + tmp->key = perm[i]; + //TDEBUGF("inserting %d", tmp->key); + if (RBT_INSERT(tree, &root, tmp) != NULL) + errx(1, "RBT_INSERT failed"); + print_tree(&root); +#ifdef DOAUGMENT + //TDEBUGF("size = %zu", RBT_ROOT(tree, &root)->size); + assert(RBT_ROOT(tree, &root)->size == i + 1); +#endif + +#ifdef RBT_TEST_RANK + if (i % RANK_TEST_ITERATIONS == 0) { + rank = RBT_RANK(tree, RBT_ROOT(tree, &root)); + if (rank == -2) + errx(1, "rank error"); + } +#endif + } + tmp = &(nodes[insertions]); + tmp->key = ITER + 5; + tmp->size = 1; + tmp->height = 1; + RBT_INSERT(tree, &root, tmp); + if (do_reads) { + for (i = 0; i < insertions; i++) { + it.key = perm[i]; + ins = RBT_FIND(tree, &root, &it); + if ((ins == NULL) || ins->key != it.key) + errx(1, "RBT_FIND failed"); + } + for (i = insertions; i < insertions + reads; i++) { + it.key = perm[i]; + ins = RBT_NFIND(tree, &root, &it); + if (ins->key < it.key) + errx(1, "RBT_NFIND failed"); + } + } +} diff --git a/share/man/man5/login.conf.5 b/share/man/man5/login.conf.5 index 85805ec6b..e2fad4fa3 100644 --- a/share/man/man5/login.conf.5 +++ b/share/man/man5/login.conf.5 @@ -30,10 +30,10 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $OpenBSD: login.conf.5,v 1.70 2022/03/31 17:27:23 naddy Exp $ +.\" $OpenBSD: login.conf.5,v 1.71 2023/12/29 11:57:38 claudio Exp $ .\" BSDI $From: login.conf.5,v 2.20 2000/06/26 14:50:38 prb Exp $ .\" -.Dd $Mdocdate: March 31 2022 $ +.Dd $Mdocdate: December 29 2023 $ .Dt LOGIN.CONF 5 .Os .Sh NAME @@ -284,7 +284,7 @@ Initial priority (nice) level. Require home directory to login. .\" .Pp -.It rtable Ta number Ta Dv 0 Ta +.It rtable Ta number Ta "" Ta Rtable to be set for the class. .\" .Pp diff --git a/sys/arch/amd64/amd64/pmap.c b/sys/arch/amd64/amd64/pmap.c index a5d2e901a..1886ef873 100644 --- a/sys/arch/amd64/amd64/pmap.c +++ b/sys/arch/amd64/amd64/pmap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap.c,v 1.164 2023/04/13 15:23:21 miod Exp $ */ +/* $OpenBSD: pmap.c,v 1.165 2023/12/29 13:23:27 jca Exp $ */ /* $NetBSD: pmap.c,v 1.3 2003/05/08 18:13:13 thorpej Exp $ */ /* @@ -913,6 +913,12 @@ pmap_bootstrap(paddr_t first_avail, paddr_t max_pa) return first_avail; } +void +pmap_init_percpu(void) +{ + pool_cache_init(&pmap_pv_pool); +} + /* * pmap_randomize * diff --git a/sys/arch/amd64/include/pmap.h b/sys/arch/amd64/include/pmap.h index 211fba595..e59037aa3 100644 --- a/sys/arch/amd64/include/pmap.h +++ b/sys/arch/amd64/include/pmap.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap.h,v 1.87 2023/12/11 22:12:52 kettenis Exp $ */ +/* $OpenBSD: pmap.h,v 1.88 2023/12/29 13:23:28 jca Exp $ */ /* $NetBSD: pmap.h,v 1.1 2003/04/26 18:39:46 fvdl Exp $ */ /* @@ -375,7 +375,6 @@ extern const long nbpd[], nkptpmax[]; #define pmap_valid_entry(E) ((E) & PG_V) /* is PDE or PTE valid? */ #define pmap_proc_iflush(p,va,len) /* nothing */ -#define pmap_init_percpu() do { /* nothing */ } while (0) #define pmap_unuse_final(p) /* nothing */ #define pmap_remove_holes(vm) do { /* nothing */ } while (0) @@ -386,6 +385,7 @@ extern const long nbpd[], nkptpmax[]; void map_tramps(void); /* machdep.c */ paddr_t pmap_bootstrap(paddr_t, paddr_t); +void pmap_init_percpu(void); void pmap_randomize(void); void pmap_randomize_level(pd_entry_t *, int); int pmap_clear_attrs(struct vm_page *, unsigned long); diff --git a/sys/dev/pci/drm/drm_drv.c b/sys/dev/pci/drm/drm_drv.c index 90500b5f0..ec2c1af86 100644 --- a/sys/dev/pci/drm/drm_drv.c +++ b/sys/dev/pci/drm/drm_drv.c @@ -1556,9 +1556,6 @@ struct drm_device * drm_get_device_from_kdev(dev_t kdev) { int unit = minor(kdev) & ((1 << CLONE_SHIFT) - 1); - /* control */ - if (unit >= 64 && unit < 128) - unit -= 64; /* render */ if (unit >= 128) unit -= 128; @@ -1701,12 +1698,18 @@ drmopen(dev_t kdev, int flags, int fmt, struct proc *p) realminor = dminor & ((1 << CLONE_SHIFT) - 1); if (realminor < 64) minor_type = DRM_MINOR_PRIMARY; - else if (realminor >= 64 && realminor < 128) - minor_type = DRM_MINOR_CONTROL; - else + else if (realminor >= 128 && realminor < 192) minor_type = DRM_MINOR_RENDER; + else { + ret = ENXIO; + goto err; + } dm = *drm_minor_get_slot(dev, minor_type); + if (dm == NULL) { + ret = ENXIO; + goto err; + } dm->index = minor(kdev); file_priv = drm_file_alloc(dm); diff --git a/sys/net/if.c b/sys/net/if.c index ff8042acb..bc1f417f6 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if.c,v 1.713 2023/12/23 10:52:54 bluhm Exp $ */ +/* $OpenBSD: if.c,v 1.714 2023/12/29 11:43:04 bluhm Exp $ */ /* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */ /* @@ -839,11 +839,14 @@ if_input_local(struct ifnet *ifp, struct mbuf *m, sa_family_t af) if (ISSET(keepcksum, M_ICMP_CSUM_OUT)) m->m_pkthdr.csum_flags |= M_ICMP_CSUM_IN_OK; - ifp->if_opackets++; - ifp->if_obytes += m->m_pkthdr.len; - - ifp->if_ipackets++; - ifp->if_ibytes += m->m_pkthdr.len; + if (ifp->if_counters == NULL) { + /* XXXSMP multicast loopback and simplex interfaces */ + ifp->if_opackets++; + ifp->if_obytes += m->m_pkthdr.len; + } else { + counters_pkt(ifp->if_counters, ifc_opackets, ifc_obytes, + m->m_pkthdr.len); + } switch (af) { case AF_INET: diff --git a/sys/net/if_loop.c b/sys/net/if_loop.c index 1c771d1bf..6a22baf4b 100644 --- a/sys/net/if_loop.c +++ b/sys/net/if_loop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_loop.c,v 1.97 2023/07/21 22:24:41 bluhm Exp $ */ +/* $OpenBSD: if_loop.c,v 1.98 2023/12/29 11:43:04 bluhm Exp $ */ /* $NetBSD: if_loop.c,v 1.15 1996/05/07 02:40:33 thorpej Exp $ */ /* @@ -185,6 +185,7 @@ loop_clone_create(struct if_clone *ifc, int unit) ifp->if_output = looutput; ifp->if_type = IFT_LOOP; ifp->if_hdrlen = sizeof(u_int32_t); + if_counters_alloc(ifp); if (unit == 0) { if_attachhead(ifp); if_addgroup(ifp, ifc->ifc_name); @@ -250,7 +251,7 @@ loinput(struct ifnet *ifp, struct mbuf *m) error = if_input_local(ifp, m, m->m_pkthdr.ph_family); if (error) - ifp->if_ierrors++; + counters_inc(ifp->if_counters, ifc_ierrors); } int diff --git a/usr.bin/openssl/openssl.1 b/usr.bin/openssl/openssl.1 index be060a3e5..3c376f4b4 100644 --- a/usr.bin/openssl/openssl.1 +++ b/usr.bin/openssl/openssl.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: openssl.1,v 1.152 2023/07/27 07:01:50 tb Exp $ +.\" $OpenBSD: openssl.1,v 1.153 2023/12/29 12:06:48 tb Exp $ .\" ==================================================================== .\" Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. .\" @@ -110,7 +110,7 @@ .\" copied and put under another distribution licence .\" [including the GNU Public Licence.] .\" -.Dd $Mdocdate: July 27 2023 $ +.Dd $Mdocdate: December 29 2023 $ .Dt OPENSSL 1 .Os .Sh NAME @@ -4279,7 +4279,6 @@ Verify the input data and output the recovered data. .Op Fl no_tls1_2 .Op Fl no_tls1_3 .Op Fl pass Ar arg -.Op Fl pause .Op Fl policy_check .Op Fl port Ar port .Op Fl prexit @@ -4445,8 +4444,6 @@ Disable the use of TLS1.2 and 1.3, respectively. Disable RFC 4507 session ticket support. .It Fl pass Ar arg The private key password source. -.It Fl pause -Pause 1 second between each read and write call. .It Fl port Ar port The .Ar port diff --git a/usr.bin/openssl/s_client.c b/usr.bin/openssl/s_client.c index e5a6b006b..299042c59 100644 --- a/usr.bin/openssl/s_client.c +++ b/usr.bin/openssl/s_client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: s_client.c,v 1.62 2023/07/03 08:03:56 beck Exp $ */ +/* $OpenBSD: s_client.c,v 1.64 2023/12/29 12:15:49 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -223,7 +223,6 @@ static struct { char *npn_in; unsigned int off; char *passarg; - int pause; int peekaboo; char *port; int prexit; @@ -659,9 +658,7 @@ static const struct option s_client_options[] = { }, { .name = "pause", - .desc = "Pause 1 second between each read and write call", - .type = OPTION_FLAG, - .opt.flag = &cfg.pause, + .type = OPTION_DISCARD, }, { .name = "peekaboo", @@ -832,7 +829,7 @@ sc_usage(void) " [-keymatexport label] [-keymatexportlen len] [-legacy_server_connect]\n" " [-msg] [-mtu mtu] [-nbio] [-nbio_test] [-no_comp] [-no_ign_eof]\n" " [-no_legacy_server_connect] [-no_ticket] \n" - " [-no_tls1_2] [-no_tls1_3] [-pass arg] [-pause] [-policy_check]\n" + " [-no_tls1_2] [-no_tls1_3] [-pass arg] [-policy_check]\n" " [-port port] [-prexit] [-proxy host:port] [-quiet] [-reconnect]\n" " [-servername name] [-serverpref] [-sess_in file] [-sess_out file]\n" " [-showcerts] [-starttls protocol] [-state] [-status] [-timeout]\n" @@ -1088,8 +1085,6 @@ s_client_main(int argc, char **argv) goto end; } } - if (cfg.pause & 0x01) - SSL_set_debug(con, 1); if (SSL_is_dtls(con)) { sbio = BIO_new_dgram(s, BIO_NOCLOSE); @@ -1130,7 +1125,6 @@ s_client_main(int argc, char **argv) sbio = BIO_push(test, sbio); } if (cfg.debug) { - SSL_set_debug(con, 1); BIO_set_callback(sbio, bio_dump_callback); BIO_set_callback_arg(sbio, (char *) bio_c_out); } diff --git a/usr.bin/openssl/s_server.c b/usr.bin/openssl/s_server.c index 95fe633ef..328ac28ab 100644 --- a/usr.bin/openssl/s_server.c +++ b/usr.bin/openssl/s_server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: s_server.c,v 1.58 2023/07/03 08:03:56 beck Exp $ */ +/* $OpenBSD: s_server.c,v 1.59 2023/12/29 12:15:49 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -1548,7 +1548,6 @@ sv_body(int s, unsigned char *context) /* SSL_set_fd(con,s); */ if (cfg.debug) { - SSL_set_debug(con, 1); BIO_set_callback(SSL_get_rbio(con), bio_dump_callback); BIO_set_callback_arg(SSL_get_rbio(con), (char *) bio_s_out); } @@ -1949,7 +1948,6 @@ www_body(int s, unsigned char *context) BIO_push(io, ssl_bio); if (cfg.debug) { - SSL_set_debug(con, 1); BIO_set_callback(SSL_get_rbio(con), bio_dump_callback); BIO_set_callback_arg(SSL_get_rbio(con), (char *) bio_s_out); } diff --git a/usr.sbin/rpki-client/parser.c b/usr.sbin/rpki-client/parser.c index 575e2a9a4..f02146d45 100644 --- a/usr.sbin/rpki-client/parser.c +++ b/usr.sbin/rpki-client/parser.c @@ -1,4 +1,4 @@ -/* $OpenBSD: parser.c,v 1.104 2023/12/18 23:42:20 job Exp $ */ +/* $OpenBSD: parser.c,v 1.106 2023/12/29 17:15:10 tb Exp $ */ /* * Copyright (c) 2019 Claudio Jeker * Copyright (c) 2019 Kristaps Dzonsons @@ -394,11 +394,10 @@ proc_parser_mft(struct entity *entp, struct mft **mp, char **crlfile, *mp = proc_parser_mft_post(file1, mft1, entp->path, err1, &warned); if (*mp == NULL) { - if (mft2 != NULL) - warnx("%s#%s: failed fetch, continuing with #%s" - " from cache", file1, mft1->seqnum, - mft2->seqnum); mft1 = NULL; + if (mft2 != NULL) + warnx("%s: failed fetch, continuing with #%s" + " from cache", file2, mft2->seqnum); } } diff --git a/usr.sbin/rpki-client/version.h b/usr.sbin/rpki-client/version.h index 6491446cd..5a707aac1 100644 --- a/usr.sbin/rpki-client/version.h +++ b/usr.sbin/rpki-client/version.h @@ -1,3 +1,3 @@ -/* $OpenBSD: version.h,v 1.19 2023/12/18 09:51:06 benno Exp $ */ +/* $OpenBSD: version.h,v 1.20 2023/12/29 18:52:11 tb Exp $ */ -#define RPKI_VERSION "8.7" +#define RPKI_VERSION "8.8"