sync with OpenBSD -current

This commit is contained in:
purplerain 2025-01-22 18:06:03 +00:00
parent 6f15bbf720
commit c170139b8d
Signed by: purplerain
GPG key ID: F42C07F07E2E35B7
42 changed files with 899 additions and 815 deletions

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bn_exp.c,v 1.53 2024/04/10 14:58:06 beck Exp $ */ /* $OpenBSD: bn_exp.c,v 1.56 2025/01/22 12:53:16 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved. * All rights reserved.
* *
@ -972,7 +972,7 @@ BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
BIGNUM *aa, *q; BIGNUM *aa, *q;
/* Table of variables obtained from 'ctx' */ /* Table of variables obtained from 'ctx' */
BIGNUM *val[TABLE_SIZE]; BIGNUM *val[TABLE_SIZE];
BN_RECP_CTX recp; BN_RECP_CTX *recp = NULL;
int ret = 0; int ret = 0;
if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) { if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
@ -992,8 +992,6 @@ BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
return ret; return ret;
} }
BN_RECP_CTX_init(&recp);
BN_CTX_start(ctx); BN_CTX_start(ctx);
if ((aa = BN_CTX_get(ctx)) == NULL) if ((aa = BN_CTX_get(ctx)) == NULL)
goto err; goto err;
@ -1002,17 +1000,8 @@ BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
if ((val[0] = BN_CTX_get(ctx)) == NULL) if ((val[0] = BN_CTX_get(ctx)) == NULL)
goto err; goto err;
if (m->neg) { if ((recp = BN_RECP_CTX_create(m)) == NULL)
/* ignore sign of 'm' */
if (!bn_copy(aa, m))
goto err; goto err;
aa->neg = 0;
if (BN_RECP_CTX_set(&recp, aa, ctx) <= 0)
goto err;
} else {
if (BN_RECP_CTX_set(&recp, m, ctx) <= 0)
goto err;
}
if (!BN_nnmod(val[0], a, m, ctx)) if (!BN_nnmod(val[0], a, m, ctx))
goto err; goto err;
@ -1025,13 +1014,13 @@ BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
window = BN_window_bits_for_exponent_size(bits); window = BN_window_bits_for_exponent_size(bits);
if (window > 1) { if (window > 1) {
if (!BN_mod_mul_reciprocal(aa, val[0], val[0], &recp, ctx)) if (!BN_mod_sqr_reciprocal(aa, val[0], recp, ctx))
goto err; goto err;
j = 1 << (window - 1); j = 1 << (window - 1);
for (i = 1; i < j; i++) { for (i = 1; i < j; i++) {
if (((val[i] = BN_CTX_get(ctx)) == NULL) || if (((val[i] = BN_CTX_get(ctx)) == NULL) ||
!BN_mod_mul_reciprocal(val[i], val[i - 1], !BN_mod_mul_reciprocal(val[i], val[i - 1],
aa, &recp, ctx)) aa, recp, ctx))
goto err; goto err;
} }
} }
@ -1049,7 +1038,7 @@ BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
for (;;) { for (;;) {
if (BN_is_bit_set(q, wstart) == 0) { if (BN_is_bit_set(q, wstart) == 0) {
if (!start) if (!start)
if (!BN_mod_mul_reciprocal(r, r, r, &recp, ctx)) if (!BN_mod_sqr_reciprocal(r, r, recp, ctx))
goto err; goto err;
if (wstart == 0) if (wstart == 0)
break; break;
@ -1078,12 +1067,12 @@ BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
/* add the 'bytes above' */ /* add the 'bytes above' */
if (!start) if (!start)
for (i = 0; i < j; i++) { for (i = 0; i < j; i++) {
if (!BN_mod_mul_reciprocal(r, r, r, &recp, ctx)) if (!BN_mod_sqr_reciprocal(r, r, recp, ctx))
goto err; goto err;
} }
/* wvalue will be an odd number < 2^window */ /* wvalue will be an odd number < 2^window */
if (!BN_mod_mul_reciprocal(r, r, val[wvalue >> 1], &recp, ctx)) if (!BN_mod_mul_reciprocal(r, r, val[wvalue >> 1], recp, ctx))
goto err; goto err;
/* move the 'window' down further */ /* move the 'window' down further */
@ -1099,7 +1088,7 @@ BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
err: err:
BN_CTX_end(ctx); BN_CTX_end(ctx);
BN_RECP_CTX_free(&recp); BN_RECP_CTX_free(recp);
return ret; return ret;
} }

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bn_local.h,v 1.45 2025/01/06 13:47:37 tb Exp $ */ /* $OpenBSD: bn_local.h,v 1.48 2025/01/22 10:12:01 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved. * All rights reserved.
* *
@ -138,16 +138,7 @@ struct bn_mont_ctx_st {
int flags; int flags;
}; };
/* Used for reciprocal division/mod functions typedef struct bn_recp_ctx_st BN_RECP_CTX;
* It cannot be shared between threads
*/
typedef struct bn_recp_ctx_st {
BIGNUM N; /* the divisor */
BIGNUM Nr; /* the reciprocal */
int num_bits;
int shift;
int flags;
} BN_RECP_CTX;
/* Used for slow "generation" functions. */ /* Used for slow "generation" functions. */
struct bn_gencb_st { struct bn_gencb_st {
@ -280,14 +271,14 @@ int bn_rand_interval(BIGNUM *rnd, BN_ULONG lower_word, const BIGNUM *upper_exc);
void BN_init(BIGNUM *); void BN_init(BIGNUM *);
void BN_RECP_CTX_init(BN_RECP_CTX *recp); BN_RECP_CTX *BN_RECP_CTX_create(const BIGNUM *N);
BN_RECP_CTX *BN_RECP_CTX_new(void);
void BN_RECP_CTX_free(BN_RECP_CTX *recp); void BN_RECP_CTX_free(BN_RECP_CTX *recp);
int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *rdiv, BN_CTX *ctx); int BN_div_reciprocal(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, BN_RECP_CTX *recp, BN_RECP_CTX *recp, BN_CTX *ctx);
BN_CTX *ctx);
int BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y, int BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y,
BN_RECP_CTX *recp, BN_CTX *ctx); BN_RECP_CTX *recp, BN_CTX *ctx);
int BN_mod_sqr_reciprocal(BIGNUM *r, const BIGNUM *x, BN_RECP_CTX *recp,
BN_CTX *ctx);
int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
const BIGNUM *m, BN_CTX *ctx); const BIGNUM *m, BN_CTX *ctx);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bn_recp.c,v 1.25 2025/01/08 20:21:28 tb Exp $ */ /* $OpenBSD: bn_recp.c,v 1.30 2025/01/22 12:53:16 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved. * All rights reserved.
* *
@ -62,26 +62,35 @@
#include "bn_local.h" #include "bn_local.h"
void struct bn_recp_ctx_st {
BN_RECP_CTX_init(BN_RECP_CTX *recp) BIGNUM *N; /* the divisor */
{ BIGNUM *Nr; /* the reciprocal 2^shift / N */
BN_init(&recp->N); int num_bits; /* number of bits in N */
BN_init(&recp->Nr); int shift;
recp->num_bits = 0; } /* BN_RECP_CTX */;
recp->flags = 0;
}
BN_RECP_CTX * BN_RECP_CTX *
BN_RECP_CTX_new(void) BN_RECP_CTX_create(const BIGNUM *N)
{ {
BN_RECP_CTX *ret; BN_RECP_CTX *recp;
if ((recp = calloc(1, sizeof(*recp))) == NULL)
goto err;
if ((recp->N = BN_dup(N)) == NULL)
goto err;
BN_set_negative(recp->N, 0);
recp->num_bits = BN_num_bits(recp->N);
if ((recp->Nr = BN_new()) == NULL)
goto err;
return recp;
err:
BN_RECP_CTX_free(recp);
if ((ret = malloc(sizeof(BN_RECP_CTX))) == NULL)
return NULL; return NULL;
BN_RECP_CTX_init(ret);
ret->flags = BN_FLG_MALLOCED;
return ret;
} }
void void
@ -90,23 +99,9 @@ BN_RECP_CTX_free(BN_RECP_CTX *recp)
if (recp == NULL) if (recp == NULL)
return; return;
BN_free(&recp->N); BN_free(recp->N);
BN_free(&recp->Nr); BN_free(recp->Nr);
if (recp->flags & BN_FLG_MALLOCED) freezero(recp, sizeof(*recp));
free(recp);
}
int
BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *d, BN_CTX *ctx)
{
if (!bn_copy(&recp->N, d))
return 0;
recp->num_bits = BN_num_bits(&recp->N);
BN_zero(&recp->Nr);
recp->shift = 0;
return 1;
} }
/* len is the expected size of the result /* len is the expected size of the result
@ -138,7 +133,7 @@ err:
} }
int int
BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, BN_RECP_CTX *recp, BN_div_reciprocal(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, BN_RECP_CTX *recp,
BN_CTX *ctx) BN_CTX *ctx)
{ {
int i, j, ret = 0; int i, j, ret = 0;
@ -158,7 +153,7 @@ BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, BN_RECP_CTX *recp,
if (a == NULL || b == NULL || d == NULL || r == NULL) if (a == NULL || b == NULL || d == NULL || r == NULL)
goto err; goto err;
if (BN_ucmp(m, &recp->N) < 0) { if (BN_ucmp(m, recp->N) < 0) {
BN_zero(d); BN_zero(d);
if (!bn_copy(r, m)) { if (!bn_copy(r, m)) {
BN_CTX_end(ctx); BN_CTX_end(ctx);
@ -182,7 +177,7 @@ BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, BN_RECP_CTX *recp,
/* Nr := round(2^i / N) */ /* Nr := round(2^i / N) */
if (i != recp->shift) if (i != recp->shift)
recp->shift = BN_reciprocal(&recp->Nr, &recp->N, i, ctx); recp->shift = BN_reciprocal(recp->Nr, recp->N, i, ctx);
/* BN_reciprocal returns i, or -1 for an error */ /* BN_reciprocal returns i, or -1 for an error */
if (recp->shift == -1) if (recp->shift == -1)
@ -195,13 +190,13 @@ BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, BN_RECP_CTX *recp,
*/ */
if (!BN_rshift(a, m, recp->num_bits)) if (!BN_rshift(a, m, recp->num_bits))
goto err; goto err;
if (!BN_mul(b, a, &recp->Nr, ctx)) if (!BN_mul(b, a, recp->Nr, ctx))
goto err; goto err;
if (!BN_rshift(d, b, i - recp->num_bits)) if (!BN_rshift(d, b, i - recp->num_bits))
goto err; goto err;
d->neg = 0; d->neg = 0;
if (!BN_mul(b, &recp->N, d, ctx)) if (!BN_mul(b, recp->N, d, ctx))
goto err; goto err;
if (!BN_usub(r, m, b)) if (!BN_usub(r, m, b))
goto err; goto err;
@ -209,12 +204,12 @@ BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, BN_RECP_CTX *recp,
#if 1 #if 1
j = 0; j = 0;
while (BN_ucmp(r, &recp->N) >= 0) { while (BN_ucmp(r, recp->N) >= 0) {
if (j++ > 2) { if (j++ > 2) {
BNerror(BN_R_BAD_RECIPROCAL); BNerror(BN_R_BAD_RECIPROCAL);
goto err; goto err;
} }
if (!BN_usub(r, r, &recp->N)) if (!BN_usub(r, r, recp->N))
goto err; goto err;
if (!BN_add_word(d, 1)) if (!BN_add_word(d, 1))
goto err; goto err;
@ -222,7 +217,7 @@ BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, BN_RECP_CTX *recp,
#endif #endif
BN_set_negative(r, m->neg); BN_set_negative(r, m->neg);
BN_set_negative(d, m->neg ^ recp->N.neg); BN_set_negative(d, m->neg ^ recp->N->neg);
ret = 1; ret = 1;
@ -231,32 +226,23 @@ err:
return ret; return ret;
} }
/* Compute r = (x * y) % m. */
int int
BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y, BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y,
BN_RECP_CTX *recp, BN_CTX *ctx) BN_RECP_CTX *recp, BN_CTX *ctx)
{ {
int ret = 0; if (!BN_mul(r, x, y, ctx))
BIGNUM *a; return 0;
const BIGNUM *ca;
BN_CTX_start(ctx); return BN_div_reciprocal(NULL, r, r, recp, ctx);
if ((a = BN_CTX_get(ctx)) == NULL)
goto err;
if (y != NULL) {
if (x == y) {
if (!BN_sqr(a, x, ctx))
goto err;
} else {
if (!BN_mul(a, x, y, ctx))
goto err;
} }
ca = a;
} else
ca = x; /* Just do the mod */
ret = BN_div_recp(NULL, r, ca, recp, ctx); /* Compute r = x^2 % m. */
int
BN_mod_sqr_reciprocal(BIGNUM *r, const BIGNUM *x, BN_RECP_CTX *recp, BN_CTX *ctx)
{
if (!BN_sqr(r, x, ctx))
return 0;
err: return BN_div_reciprocal(NULL, r, r, recp, ctx);
BN_CTX_end(ctx);
return ret;
} }

View file

@ -1,4 +1,4 @@
/* $OpenBSD: crypto.h,v 1.76 2024/10/03 03:47:40 tb Exp $ */ /* $OpenBSD: crypto.h,v 1.77 2025/01/20 17:50:12 tb Exp $ */
/* ==================================================================== /* ====================================================================
* Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
* *

View file

@ -1,4 +1,4 @@
/* $OpenBSD: ec_lib.c,v 1.111 2025/01/11 15:26:07 tb Exp $ */ /* $OpenBSD: ec_lib.c,v 1.113 2025/01/22 09:56:58 jsing Exp $ */
/* /*
* Originally written by Bodo Moeller for the OpenSSL project. * Originally written by Bodo Moeller for the OpenSSL project.
*/ */
@ -667,6 +667,7 @@ EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx_in)
{ {
BN_CTX *ctx; BN_CTX *ctx;
EC_POINT *point = NULL; EC_POINT *point = NULL;
const EC_POINT *generator;
const BIGNUM *order; const BIGNUM *order;
int ret = 0; int ret = 0;
@ -680,11 +681,11 @@ EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx_in)
goto err; goto err;
} }
if (group->generator == NULL) { if ((generator = EC_GROUP_get0_generator(group)) == NULL) {
ECerror(EC_R_UNDEFINED_GENERATOR); ECerror(EC_R_UNDEFINED_GENERATOR);
goto err; goto err;
} }
if (EC_POINT_is_on_curve(group, group->generator, ctx) <= 0) { if (EC_POINT_is_on_curve(group, generator, ctx) <= 0) {
ECerror(EC_R_POINT_IS_NOT_ON_CURVE); ECerror(EC_R_POINT_IS_NOT_ON_CURVE);
goto err; goto err;
} }
@ -1346,8 +1347,7 @@ EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
if (ctx == NULL) if (ctx == NULL)
goto err; goto err;
if (group->meth->mul_generator_ct == NULL || if (group->meth->mul_single_ct == NULL ||
group->meth->mul_single_ct == NULL ||
group->meth->mul_double_nonct == NULL) { group->meth->mul_double_nonct == NULL) {
ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
goto err; goto err;
@ -1362,7 +1362,8 @@ EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
* secret. This is why we ignore if BN_FLG_CONSTTIME is actually * secret. This is why we ignore if BN_FLG_CONSTTIME is actually
* set and we always call the constant time version. * set and we always call the constant time version.
*/ */
ret = group->meth->mul_generator_ct(group, r, g_scalar, ctx); ret = group->meth->mul_single_ct(group, r, g_scalar,
group->generator, ctx);
} else if (g_scalar == NULL && point != NULL && p_scalar != NULL) { } else if (g_scalar == NULL && point != NULL && p_scalar != NULL) {
/* /*
* In this case we want to compute p_scalar * GenericPoint: * In this case we want to compute p_scalar * GenericPoint:

View file

@ -1,4 +1,4 @@
/* $OpenBSD: ec_local.h,v 1.62 2025/01/11 20:57:03 tb Exp $ */ /* $OpenBSD: ec_local.h,v 1.63 2025/01/22 09:56:58 jsing Exp $ */
/* /*
* Originally written by Bodo Moeller for the OpenSSL project. * Originally written by Bodo Moeller for the OpenSSL project.
*/ */
@ -105,8 +105,6 @@ struct ec_method_st {
int (*dbl)(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *); int (*dbl)(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
int (*invert)(const EC_GROUP *, EC_POINT *, BN_CTX *); int (*invert)(const EC_GROUP *, EC_POINT *, BN_CTX *);
int (*mul_generator_ct)(const EC_GROUP *, EC_POINT *r,
const BIGNUM *scalar, BN_CTX *);
int (*mul_single_ct)(const EC_GROUP *group, EC_POINT *r, int (*mul_single_ct)(const EC_GROUP *group, EC_POINT *r,
const BIGNUM *scalar, const EC_POINT *point, BN_CTX *); const BIGNUM *scalar, const EC_POINT *point, BN_CTX *);
int (*mul_double_nonct)(const EC_GROUP *group, EC_POINT *r, int (*mul_double_nonct)(const EC_GROUP *group, EC_POINT *r,

View file

@ -1,4 +1,4 @@
/* $OpenBSD: ecp_methods.c,v 1.39 2025/01/17 11:11:27 tb Exp $ */ /* $OpenBSD: ecp_methods.c,v 1.41 2025/01/22 12:54:40 tb Exp $ */
/* Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de> /* Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
* for the OpenSSL project. * for the OpenSSL project.
* Includes code written by Bodo Moeller for the OpenSSL project. * Includes code written by Bodo Moeller for the OpenSSL project.
@ -1020,17 +1020,9 @@ ec_mul_ct(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
BN_CTX_start(ctx); BN_CTX_start(ctx);
if ((s = EC_POINT_new(group)) == NULL) if ((s = EC_POINT_dup(point, group)) == NULL)
goto err; goto err;
if (point == NULL) {
if (!EC_POINT_copy(s, group->generator))
goto err;
} else {
if (!EC_POINT_copy(s, point))
goto err;
}
EC_POINT_BN_set_flags(s, BN_FLG_CONSTTIME); EC_POINT_BN_set_flags(s, BN_FLG_CONSTTIME);
if ((cardinality = BN_CTX_get(ctx)) == NULL) if ((cardinality = BN_CTX_get(ctx)) == NULL)
@ -1194,13 +1186,6 @@ ec_mul_ct(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
#undef EC_POINT_BN_set_flags #undef EC_POINT_BN_set_flags
#undef EC_POINT_CSWAP #undef EC_POINT_CSWAP
static int
ec_mul_generator_ct(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
BN_CTX *ctx)
{
return ec_mul_ct(group, r, scalar, NULL, ctx);
}
static int static int
ec_mul_single_ct(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, ec_mul_single_ct(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
const EC_POINT *point, BN_CTX *ctx) const EC_POINT *point, BN_CTX *ctx)
@ -1317,7 +1302,6 @@ static const EC_METHOD ec_GFp_simple_method = {
.add = ec_add, .add = ec_add,
.dbl = ec_dbl, .dbl = ec_dbl,
.invert = ec_invert, .invert = ec_invert,
.mul_generator_ct = ec_mul_generator_ct,
.mul_single_ct = ec_mul_single_ct, .mul_single_ct = ec_mul_single_ct,
.mul_double_nonct = ec_mul_double_nonct, .mul_double_nonct = ec_mul_double_nonct,
.field_mul = ec_simple_field_mul, .field_mul = ec_simple_field_mul,
@ -1343,7 +1327,6 @@ static const EC_METHOD ec_GFp_mont_method = {
.add = ec_add, .add = ec_add,
.dbl = ec_dbl, .dbl = ec_dbl,
.invert = ec_invert, .invert = ec_invert,
.mul_generator_ct = ec_mul_generator_ct,
.mul_single_ct = ec_mul_single_ct, .mul_single_ct = ec_mul_single_ct,
.mul_double_nonct = ec_mul_double_nonct, .mul_double_nonct = ec_mul_double_nonct,
.field_mul = ec_mont_field_mul, .field_mul = ec_mont_field_mul,

View file

@ -1,4 +1,4 @@
/* $OpenBSD: sm4.c,v 1.2 2023/07/07 12:01:32 beck Exp $ */ /* $OpenBSD: sm4.c,v 1.6 2025/01/22 09:53:16 jsing Exp $ */
/* /*
* Copyright (c) 2017, 2019 Ribose Inc * Copyright (c) 2017, 2019 Ribose Inc
* *
@ -20,6 +20,8 @@
#ifndef OPENSSL_NO_SM4 #ifndef OPENSSL_NO_SM4
#include <openssl/sm4.h> #include <openssl/sm4.h>
#include "crypto_internal.h"
struct sm4_key { struct sm4_key {
uint32_t rk[SM4_KEY_SCHEDULE]; uint32_t rk[SM4_KEY_SCHEDULE];
}; };
@ -98,30 +100,6 @@ static const uint32_t SM4_SBOX_T[256] = {
0x8BD45F5F, 0xE7C82F2F, 0xDD39E4E4, 0x68492121, 0x8BD45F5F, 0xE7C82F2F, 0xDD39E4E4, 0x68492121,
}; };
static inline uint32_t
rotl(uint32_t a, uint8_t n)
{
return (a << n) | (a >> (32 - n));
}
static inline uint32_t
load_u32_be(const uint8_t *b, uint32_t n)
{
return ((uint32_t)b[4 * n] << 24) |
((uint32_t)b[4 * n + 1] << 16) |
((uint32_t)b[4 * n + 2] << 8) |
((uint32_t)b[4 * n + 3]);
}
static inline void
store_u32_be(uint32_t v, uint8_t *b)
{
b[0] = (uint8_t)(v >> 24);
b[1] = (uint8_t)(v >> 16);
b[2] = (uint8_t)(v >> 8);
b[3] = (uint8_t)(v);
}
static inline uint32_t static inline uint32_t
SM4_T_slow(uint32_t X) SM4_T_slow(uint32_t X)
{ {
@ -132,37 +110,31 @@ SM4_T_slow(uint32_t X)
t |= ((uint32_t)SM4_S[(uint8_t)(X >> 8)]) << 8; t |= ((uint32_t)SM4_S[(uint8_t)(X >> 8)]) << 8;
t |= SM4_S[(uint8_t)X]; t |= SM4_S[(uint8_t)X];
/* /* L linear transform. */
* L linear transform return t ^ crypto_rol_u32(t, 2) ^ crypto_rol_u32(t, 10) ^
*/ crypto_rol_u32(t, 18) ^ crypto_rol_u32(t, 24);
return t ^ rotl(t, 2) ^ rotl(t, 10) ^ rotl(t, 18) ^ rotl(t, 24);
} }
static inline uint32_t static inline uint32_t
SM4_T(uint32_t X) SM4_T(uint32_t X)
{ {
return SM4_SBOX_T[(uint8_t)(X >> 24)] ^ return SM4_SBOX_T[(uint8_t)(X >> 24)] ^
rotl(SM4_SBOX_T[(uint8_t)(X >> 16)], 24) ^ crypto_rol_u32(SM4_SBOX_T[(uint8_t)(X >> 16)], 24) ^
rotl(SM4_SBOX_T[(uint8_t)(X >> 8)], 16) ^ crypto_rol_u32(SM4_SBOX_T[(uint8_t)(X >> 8)], 16) ^
rotl(SM4_SBOX_T[(uint8_t)X], 8); crypto_rol_u32(SM4_SBOX_T[(uint8_t)X], 8);
} }
int
SM4_set_key(const uint8_t *key, SM4_KEY *k)
{
struct sm4_key *ks = (struct sm4_key *)k;
/* /*
* Family Key * SM4 Family Key
*/ */
static const uint32_t FK[4] = { static const uint32_t SM4_FK[4] = {
0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc, 0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc,
}; };
/* /*
* Constant Key * SM4 Constant Key
*/ */
static const uint32_t CK[32] = { static const uint32_t SM4_CK[32] = {
0x00070E15, 0x1C232A31, 0x383F464D, 0x545B6269, 0x00070E15, 0x1C232A31, 0x383F464D, 0x545B6269,
0x70777E85, 0x8C939AA1, 0xA8AFB6BD, 0xC4CBD2D9, 0x70777E85, 0x8C939AA1, 0xA8AFB6BD, 0xC4CBD2D9,
0xE0E7EEF5, 0xFC030A11, 0x181F262D, 0x343B4249, 0xE0E7EEF5, 0xFC030A11, 0x181F262D, 0x343B4249,
@ -173,26 +145,30 @@ SM4_set_key(const uint8_t *key, SM4_KEY *k)
0x10171E25, 0x2C333A41, 0x484F565D, 0x646B7279, 0x10171E25, 0x2C333A41, 0x484F565D, 0x646B7279,
}; };
int
SM4_set_key(const uint8_t *key, SM4_KEY *k)
{
struct sm4_key *ks = (struct sm4_key *)k;
uint32_t K[4]; uint32_t K[4];
int i; int i;
K[0] = load_u32_be(key, 0) ^ FK[0]; K[0] = crypto_load_be32toh(&key[0 * 4]) ^ SM4_FK[0];
K[1] = load_u32_be(key, 1) ^ FK[1]; K[1] = crypto_load_be32toh(&key[1 * 4]) ^ SM4_FK[1];
K[2] = load_u32_be(key, 2) ^ FK[2]; K[2] = crypto_load_be32toh(&key[2 * 4]) ^ SM4_FK[2];
K[3] = load_u32_be(key, 3) ^ FK[3]; K[3] = crypto_load_be32toh(&key[3 * 4]) ^ SM4_FK[3];
for (i = 0; i < SM4_KEY_SCHEDULE; i++) { for (i = 0; i < SM4_KEY_SCHEDULE; i++) {
uint32_t X; uint32_t X;
uint32_t t = 0; uint32_t t = 0;
X = K[(i + 1) % 4] ^ K[(i + 2) % 4] ^ K[(i + 3) % 4] ^ CK[i]; X = K[(i + 1) % 4] ^ K[(i + 2) % 4] ^ K[(i + 3) % 4] ^ SM4_CK[i];
t |= ((uint32_t)SM4_S[(uint8_t)(X >> 24)]) << 24; t |= ((uint32_t)SM4_S[(uint8_t)(X >> 24)]) << 24;
t |= ((uint32_t)SM4_S[(uint8_t)(X >> 16)]) << 16; t |= ((uint32_t)SM4_S[(uint8_t)(X >> 16)]) << 16;
t |= ((uint32_t)SM4_S[(uint8_t)(X >> 8)]) << 8; t |= ((uint32_t)SM4_S[(uint8_t)(X >> 8)]) << 8;
t |= SM4_S[(uint8_t)X]; t |= SM4_S[(uint8_t)X];
t = t ^ rotl(t, 13) ^ rotl(t, 23); t = t ^ crypto_rol_u32(t, 13) ^ crypto_rol_u32(t, 23);
K[i % 4] ^= t; K[i % 4] ^= t;
ks->rk[i] = K[i % 4]; ks->rk[i] = K[i % 4];
} }
@ -201,40 +177,65 @@ SM4_set_key(const uint8_t *key, SM4_KEY *k)
} }
LCRYPTO_ALIAS(SM4_set_key); LCRYPTO_ALIAS(SM4_set_key);
#define SM4_ROUNDS(k0, k1, k2, k3, F) \
do { \
B0 ^= F(B1 ^ B2 ^ B3 ^ ks->rk[k0]); \
B1 ^= F(B0 ^ B2 ^ B3 ^ ks->rk[k1]); \
B2 ^= F(B0 ^ B1 ^ B3 ^ ks->rk[k2]); \
B3 ^= F(B0 ^ B1 ^ B2 ^ ks->rk[k3]); \
} while(0)
void void
SM4_encrypt(const uint8_t *in, uint8_t *out, const SM4_KEY *k) SM4_encrypt(const uint8_t *in, uint8_t *out, const SM4_KEY *k)
{ {
struct sm4_key *ks = (struct sm4_key *)k; struct sm4_key *ks = (struct sm4_key *)k;
uint32_t B0 = load_u32_be(in, 0); uint32_t B0, B1, B2, B3;
uint32_t B1 = load_u32_be(in, 1);
uint32_t B2 = load_u32_be(in, 2); B0 = crypto_load_be32toh(&in[0 * 4]);
uint32_t B3 = load_u32_be(in, 3); B1 = crypto_load_be32toh(&in[1 * 4]);
B2 = crypto_load_be32toh(&in[2 * 4]);
B3 = crypto_load_be32toh(&in[3 * 4]);
/* /*
* Uses byte-wise sbox in the first and last rounds to provide some * Uses byte-wise sbox in the first and last rounds to provide some
* protection from cache based side channels. * protection from cache based side channels.
*/ */
SM4_ROUNDS( 0, 1, 2, 3, SM4_T_slow); B0 ^= SM4_T_slow(B1 ^ B2 ^ B3 ^ ks->rk[0]);
SM4_ROUNDS( 4, 5, 6, 7, SM4_T); B1 ^= SM4_T_slow(B0 ^ B2 ^ B3 ^ ks->rk[1]);
SM4_ROUNDS( 8, 9, 10, 11, SM4_T); B2 ^= SM4_T_slow(B0 ^ B1 ^ B3 ^ ks->rk[2]);
SM4_ROUNDS(12, 13, 14, 15, SM4_T); B3 ^= SM4_T_slow(B0 ^ B1 ^ B2 ^ ks->rk[3]);
SM4_ROUNDS(16, 17, 18, 19, SM4_T);
SM4_ROUNDS(20, 21, 22, 23, SM4_T);
SM4_ROUNDS(24, 25, 26, 27, SM4_T);
SM4_ROUNDS(28, 29, 30, 31, SM4_T_slow);
store_u32_be(B3, out); B0 ^= SM4_T(B1 ^ B2 ^ B3 ^ ks->rk[4]);
store_u32_be(B2, out + 4); B1 ^= SM4_T(B0 ^ B2 ^ B3 ^ ks->rk[5]);
store_u32_be(B1, out + 8); B2 ^= SM4_T(B0 ^ B1 ^ B3 ^ ks->rk[6]);
store_u32_be(B0, out + 12); B3 ^= SM4_T(B0 ^ B1 ^ B2 ^ ks->rk[7]);
B0 ^= SM4_T(B1 ^ B2 ^ B3 ^ ks->rk[8]);
B1 ^= SM4_T(B0 ^ B2 ^ B3 ^ ks->rk[9]);
B2 ^= SM4_T(B0 ^ B1 ^ B3 ^ ks->rk[10]);
B3 ^= SM4_T(B0 ^ B1 ^ B2 ^ ks->rk[11]);
B0 ^= SM4_T(B1 ^ B2 ^ B3 ^ ks->rk[12]);
B1 ^= SM4_T(B0 ^ B2 ^ B3 ^ ks->rk[13]);
B2 ^= SM4_T(B0 ^ B1 ^ B3 ^ ks->rk[14]);
B3 ^= SM4_T(B0 ^ B1 ^ B2 ^ ks->rk[15]);
B0 ^= SM4_T(B1 ^ B2 ^ B3 ^ ks->rk[16]);
B1 ^= SM4_T(B0 ^ B2 ^ B3 ^ ks->rk[17]);
B2 ^= SM4_T(B0 ^ B1 ^ B3 ^ ks->rk[18]);
B3 ^= SM4_T(B0 ^ B1 ^ B2 ^ ks->rk[19]);
B0 ^= SM4_T(B1 ^ B2 ^ B3 ^ ks->rk[20]);
B1 ^= SM4_T(B0 ^ B2 ^ B3 ^ ks->rk[21]);
B2 ^= SM4_T(B0 ^ B1 ^ B3 ^ ks->rk[22]);
B3 ^= SM4_T(B0 ^ B1 ^ B2 ^ ks->rk[23]);
B0 ^= SM4_T(B1 ^ B2 ^ B3 ^ ks->rk[24]);
B1 ^= SM4_T(B0 ^ B2 ^ B3 ^ ks->rk[25]);
B2 ^= SM4_T(B0 ^ B1 ^ B3 ^ ks->rk[26]);
B3 ^= SM4_T(B0 ^ B1 ^ B2 ^ ks->rk[27]);
B0 ^= SM4_T_slow(B1 ^ B2 ^ B3 ^ ks->rk[28]);
B1 ^= SM4_T_slow(B0 ^ B2 ^ B3 ^ ks->rk[29]);
B2 ^= SM4_T_slow(B0 ^ B1 ^ B3 ^ ks->rk[30]);
B3 ^= SM4_T_slow(B0 ^ B1 ^ B2 ^ ks->rk[31]);
crypto_store_htobe32(&out[0 * 4], B3);
crypto_store_htobe32(&out[1 * 4], B2);
crypto_store_htobe32(&out[2 * 4], B1);
crypto_store_htobe32(&out[3 * 4], B0);
} }
LCRYPTO_ALIAS(SM4_encrypt); LCRYPTO_ALIAS(SM4_encrypt);
@ -242,24 +243,61 @@ void
SM4_decrypt(const uint8_t *in, uint8_t *out, const SM4_KEY *k) SM4_decrypt(const uint8_t *in, uint8_t *out, const SM4_KEY *k)
{ {
struct sm4_key *ks = (struct sm4_key *)k; struct sm4_key *ks = (struct sm4_key *)k;
uint32_t B0 = load_u32_be(in, 0); uint32_t B0, B1, B2, B3;
uint32_t B1 = load_u32_be(in, 1);
uint32_t B2 = load_u32_be(in, 2);
uint32_t B3 = load_u32_be(in, 3);
SM4_ROUNDS(31, 30, 29, 28, SM4_T_slow); B0 = crypto_load_be32toh(&in[0 * 4]);
SM4_ROUNDS(27, 26, 25, 24, SM4_T); B1 = crypto_load_be32toh(&in[1 * 4]);
SM4_ROUNDS(23, 22, 21, 20, SM4_T); B2 = crypto_load_be32toh(&in[2 * 4]);
SM4_ROUNDS(19, 18, 17, 16, SM4_T); B3 = crypto_load_be32toh(&in[3 * 4]);
SM4_ROUNDS(15, 14, 13, 12, SM4_T);
SM4_ROUNDS(11, 10, 9, 8, SM4_T);
SM4_ROUNDS( 7, 6, 5, 4, SM4_T);
SM4_ROUNDS( 3, 2, 1, 0, SM4_T_slow);
store_u32_be(B3, out); /*
store_u32_be(B2, out + 4); * Uses byte-wise sbox in the first and last rounds to provide some
store_u32_be(B1, out + 8); * protection from cache based side channels.
store_u32_be(B0, out + 12); */
B0 ^= SM4_T_slow(B1 ^ B2 ^ B3 ^ ks->rk[31]);
B1 ^= SM4_T_slow(B0 ^ B2 ^ B3 ^ ks->rk[30]);
B2 ^= SM4_T_slow(B0 ^ B1 ^ B3 ^ ks->rk[29]);
B3 ^= SM4_T_slow(B0 ^ B1 ^ B2 ^ ks->rk[28]);
B0 ^= SM4_T(B1 ^ B2 ^ B3 ^ ks->rk[27]);
B1 ^= SM4_T(B0 ^ B2 ^ B3 ^ ks->rk[26]);
B2 ^= SM4_T(B0 ^ B1 ^ B3 ^ ks->rk[25]);
B3 ^= SM4_T(B0 ^ B1 ^ B2 ^ ks->rk[24]);
B0 ^= SM4_T(B1 ^ B2 ^ B3 ^ ks->rk[23]);
B1 ^= SM4_T(B0 ^ B2 ^ B3 ^ ks->rk[22]);
B2 ^= SM4_T(B0 ^ B1 ^ B3 ^ ks->rk[21]);
B3 ^= SM4_T(B0 ^ B1 ^ B2 ^ ks->rk[20]);
B0 ^= SM4_T(B1 ^ B2 ^ B3 ^ ks->rk[19]);
B1 ^= SM4_T(B0 ^ B2 ^ B3 ^ ks->rk[18]);
B2 ^= SM4_T(B0 ^ B1 ^ B3 ^ ks->rk[17]);
B3 ^= SM4_T(B0 ^ B1 ^ B2 ^ ks->rk[16]);
B0 ^= SM4_T(B1 ^ B2 ^ B3 ^ ks->rk[15]);
B1 ^= SM4_T(B0 ^ B2 ^ B3 ^ ks->rk[14]);
B2 ^= SM4_T(B0 ^ B1 ^ B3 ^ ks->rk[13]);
B3 ^= SM4_T(B0 ^ B1 ^ B2 ^ ks->rk[12]);
B0 ^= SM4_T(B1 ^ B2 ^ B3 ^ ks->rk[11]);
B1 ^= SM4_T(B0 ^ B2 ^ B3 ^ ks->rk[10]);
B2 ^= SM4_T(B0 ^ B1 ^ B3 ^ ks->rk[9]);
B3 ^= SM4_T(B0 ^ B1 ^ B2 ^ ks->rk[8]);
B0 ^= SM4_T(B1 ^ B2 ^ B3 ^ ks->rk[7]);
B1 ^= SM4_T(B0 ^ B2 ^ B3 ^ ks->rk[6]);
B2 ^= SM4_T(B0 ^ B1 ^ B3 ^ ks->rk[5]);
B3 ^= SM4_T(B0 ^ B1 ^ B2 ^ ks->rk[4]);
B0 ^= SM4_T_slow(B1 ^ B2 ^ B3 ^ ks->rk[3]);
B1 ^= SM4_T_slow(B0 ^ B2 ^ B3 ^ ks->rk[2]);
B2 ^= SM4_T_slow(B0 ^ B1 ^ B3 ^ ks->rk[1]);
B3 ^= SM4_T_slow(B0 ^ B1 ^ B2 ^ ks->rk[0]);
crypto_store_htobe32(&out[0 * 4], B3);
crypto_store_htobe32(&out[1 * 4], B2);
crypto_store_htobe32(&out[2 * 4], B1);
crypto_store_htobe32(&out[3 * 4], B0);
} }
LCRYPTO_ALIAS(SM4_decrypt); LCRYPTO_ALIAS(SM4_decrypt);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bn_test.c,v 1.19 2023/04/25 17:17:21 tb Exp $ */ /* $OpenBSD: bn_test.c,v 1.22 2025/01/22 13:02:14 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved. * All rights reserved.
* *
@ -224,7 +224,7 @@ main(int argc, char *argv[])
goto err; goto err;
(void)BIO_flush(out); (void)BIO_flush(out);
message(out, "BN_div_recp"); message(out, "BN_div_reciprocal");
if (!test_div_recp(out, ctx)) if (!test_div_recp(out, ctx))
goto err; goto err;
(void)BIO_flush(out); (void)BIO_flush(out);
@ -581,9 +581,6 @@ test_div_recp(BIO *bp, BN_CTX *ctx)
if ((e = BN_CTX_get(ctx)) == NULL) if ((e = BN_CTX_get(ctx)) == NULL)
goto err; goto err;
if ((recp = BN_RECP_CTX_new()) == NULL)
goto err;
for (i = 0; i < num0 + num1; i++) { for (i = 0; i < num0 + num1; i++) {
if (i < num1) { if (i < num1) {
CHECK_GOTO(BN_bntest_rand(a, 400, 0, 0)); CHECK_GOTO(BN_bntest_rand(a, 400, 0, 0));
@ -592,10 +589,9 @@ test_div_recp(BIO *bp, BN_CTX *ctx)
CHECK_GOTO(BN_add_word(a, i)); CHECK_GOTO(BN_add_word(a, i));
} else } else
CHECK_GOTO(BN_bntest_rand(b, 50 + 3 * (i - num1), 0, 0)); CHECK_GOTO(BN_bntest_rand(b, 50 + 3 * (i - num1), 0, 0));
BN_set_negative(a, rand_neg()); BN_RECP_CTX_free(recp);
BN_set_negative(b, rand_neg()); CHECK_GOTO(recp = BN_RECP_CTX_create(b));
CHECK_GOTO(BN_RECP_CTX_set(recp, b, ctx)); CHECK_GOTO(BN_div_reciprocal(d, c, a, recp, ctx));
CHECK_GOTO(BN_div_recp(d, c, a, recp, ctx));
if (bp != NULL) { if (bp != NULL) {
if (!results) { if (!results) {
CHECK_GOTO(BN_print(bp, a)); CHECK_GOTO(BN_print(bp, a));

View file

@ -1,4 +1,4 @@
# $OpenBSD: Makefile,v 1.9 2024/11/04 09:51:51 tb Exp $ # $OpenBSD: Makefile,v 1.10 2025/01/21 16:47:52 tb Exp $
.ifdef EOPENSSL33 .ifdef EOPENSSL33
LDADD += -Wl,-rpath,/usr/local/lib/eopenssl33 -L/usr/local/lib/eopenssl33 LDADD += -Wl,-rpath,/usr/local/lib/eopenssl33 -L/usr/local/lib/eopenssl33

View file

@ -1,4 +1,4 @@
/* $OpenBSD: ectest.c,v 1.26 2025/01/06 10:43:26 tb Exp $ */ /* $OpenBSD: ectest.c,v 1.34 2025/01/22 15:38:25 tb Exp $ */
/* /*
* Originally written by Bodo Moeller for the OpenSSL project. * Originally written by Bodo Moeller for the OpenSSL project.
*/ */
@ -88,27 +88,24 @@
exit(1); \ exit(1); \
} while (0) } while (0)
#define TIMING_BASE_PT 0
#define TIMING_RAND_PT 1
#define TIMING_SIMUL 2
/* test multiplication with group order, long and negative scalars */ /* test multiplication with group order, long and negative scalars */
static void static void
group_order_tests(EC_GROUP *group) group_order_tests(EC_GROUP *group, BN_CTX *ctx)
{ {
BIGNUM *n1, *n2, *order; BIGNUM *n1, *n2, *order;
EC_POINT *P = EC_POINT_new(group); EC_POINT *P = EC_POINT_new(group);
EC_POINT *Q = EC_POINT_new(group); EC_POINT *Q = EC_POINT_new(group);
BN_CTX *ctx;
if ((ctx = BN_CTX_new()) == NULL) if (P == NULL || Q == NULL)
ABORT; ABORT;
if ((n1 = BN_new()) == NULL) BN_CTX_start(ctx);
if ((n1 = BN_CTX_get(ctx)) == NULL)
ABORT; ABORT;
if ((n2 = BN_new()) == NULL) if ((n2 = BN_CTX_get(ctx)) == NULL)
ABORT; ABORT;
if ((order = BN_new()) == NULL) if ((order = BN_CTX_get(ctx)) == NULL)
ABORT; ABORT;
fprintf(stdout, "verify group order ..."); fprintf(stdout, "verify group order ...");
fflush(stdout); fflush(stdout);
@ -128,8 +125,7 @@ group_order_tests(EC_GROUP *group)
ABORT; ABORT;
fprintf(stdout, " ok\n"); fprintf(stdout, " ok\n");
fprintf(stdout, "long/negative scalar tests ... "); fprintf(stdout, "long/negative scalar tests ... ");
/* XXX - switch back to BN_one() after next bump. */ if (!BN_one(n1))
if (!BN_set_word(n1, 1))
ABORT; ABORT;
/* n1 = 1 - order */ /* n1 = 1 - order */
if (!BN_sub(n1, n1, order)) if (!BN_sub(n1, n1, order))
@ -155,10 +151,7 @@ group_order_tests(EC_GROUP *group)
fprintf(stdout, "ok\n"); fprintf(stdout, "ok\n");
EC_POINT_free(P); EC_POINT_free(P);
EC_POINT_free(Q); EC_POINT_free(Q);
BN_free(n1); BN_CTX_end(ctx);
BN_free(n2);
BN_free(order);
BN_CTX_free(ctx);
} }
static void static void
@ -191,20 +184,13 @@ prime_field_tests(void)
if (!BN_hex2bn(&b, "1")) if (!BN_hex2bn(&b, "1"))
ABORT; ABORT;
group = EC_GROUP_new(EC_GFp_mont_method()); /* applications should use EC_GROUP_new_curve_GFp if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL)
* so that the library gets to choose the EC_METHOD */
if (!group)
ABORT;
if (!EC_GROUP_set_curve(group, p, a, b, ctx))
ABORT; ABORT;
{ {
EC_GROUP *tmp; EC_GROUP *tmp;
tmp = EC_GROUP_new(EC_GROUP_method_of(group));
if (!tmp) if ((tmp = EC_GROUP_dup(group)) == NULL)
ABORT;
if (!EC_GROUP_copy(tmp, group))
ABORT; ABORT;
EC_GROUP_free(group); EC_GROUP_free(group);
group = tmp; group = tmp;
@ -263,11 +249,9 @@ prime_field_tests(void)
} }
fprintf(stdout, "A cyclic subgroup:\n"); fprintf(stdout, "A cyclic subgroup:\n");
k = 100; k = 0;
do { do {
if (k-- == 0) fprintf(stderr, " %d - ", k);
ABORT;
if (EC_POINT_is_at_infinity(group, P)) if (EC_POINT_is_at_infinity(group, P))
fprintf(stdout, "point at infinity\n"); fprintf(stdout, "point at infinity\n");
else { else {
@ -285,8 +269,15 @@ prime_field_tests(void)
ABORT; ABORT;
if (!EC_POINT_add(group, P, P, Q, ctx)) if (!EC_POINT_add(group, P, P, Q, ctx))
ABORT; ABORT;
if (k++ > 99)
ABORT;
} while (!EC_POINT_is_at_infinity(group, P)); } while (!EC_POINT_is_at_infinity(group, P));
if (k != 7) {
fprintf(stderr, "cycled in %d iterations, want 7\n", k);
ABORT;
}
if (!EC_POINT_add(group, P, Q, R, ctx)) if (!EC_POINT_add(group, P, Q, R, ctx))
ABORT; ABORT;
if (!EC_POINT_is_at_infinity(group, P)) if (!EC_POINT_is_at_infinity(group, P))
@ -300,7 +291,8 @@ prime_field_tests(void)
if (0 != EC_POINT_cmp(group, P, Q, ctx)) if (0 != EC_POINT_cmp(group, P, Q, ctx))
ABORT; ABORT;
fprintf(stdout, "Generator as octet string, compressed form:\n "); fprintf(stdout, "Generator as octet string, compressed form:\n ");
for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]); for (i = 0; i < len; i++)
fprintf(stdout, "%02X", buf[i]);
len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED, buf, sizeof buf, ctx); len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED, buf, sizeof buf, ctx);
if (len == 0) if (len == 0)
@ -310,7 +302,8 @@ prime_field_tests(void)
if (0 != EC_POINT_cmp(group, P, Q, ctx)) if (0 != EC_POINT_cmp(group, P, Q, ctx))
ABORT; ABORT;
fprintf(stdout, "\nGenerator as octet string, uncompressed form:\n "); fprintf(stdout, "\nGenerator as octet string, uncompressed form:\n ");
for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]); for (i = 0; i < len; i++)
fprintf(stdout, "%02X", buf[i]);
len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof buf, ctx); len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof buf, ctx);
if (len == 0) if (len == 0)
@ -381,13 +374,10 @@ prime_field_tests(void)
ABORT; ABORT;
fprintf(stdout, " ok\n"); fprintf(stdout, " ok\n");
group_order_tests(group); group_order_tests(group, ctx);
if (!(P_160 = EC_GROUP_new(EC_GROUP_method_of(group)))) if ((P_160 = EC_GROUP_dup(group)) == NULL)
ABORT; ABORT;
if (!EC_GROUP_copy(P_160, group))
ABORT;
/* Curve P-192 (FIPS PUB 186-2, App. 6) */ /* Curve P-192 (FIPS PUB 186-2, App. 6) */
@ -431,13 +421,10 @@ prime_field_tests(void)
ABORT; ABORT;
fprintf(stdout, " ok\n"); fprintf(stdout, " ok\n");
group_order_tests(group); group_order_tests(group, ctx);
if (!(P_192 = EC_GROUP_new(EC_GROUP_method_of(group)))) if ((P_192 = EC_GROUP_dup(group)) == NULL)
ABORT; ABORT;
if (!EC_GROUP_copy(P_192, group))
ABORT;
/* Curve P-224 (FIPS PUB 186-2, App. 6) */ /* Curve P-224 (FIPS PUB 186-2, App. 6) */
@ -481,13 +468,10 @@ prime_field_tests(void)
ABORT; ABORT;
fprintf(stdout, " ok\n"); fprintf(stdout, " ok\n");
group_order_tests(group); group_order_tests(group, ctx);
if (!(P_224 = EC_GROUP_new(EC_GROUP_method_of(group)))) if ((P_224 = EC_GROUP_dup(group)) == NULL)
ABORT; ABORT;
if (!EC_GROUP_copy(P_224, group))
ABORT;
/* Curve P-256 (FIPS PUB 186-2, App. 6) */ /* Curve P-256 (FIPS PUB 186-2, App. 6) */
@ -531,13 +515,10 @@ prime_field_tests(void)
ABORT; ABORT;
fprintf(stdout, " ok\n"); fprintf(stdout, " ok\n");
group_order_tests(group); group_order_tests(group, ctx);
if (!(P_256 = EC_GROUP_new(EC_GROUP_method_of(group)))) if ((P_256 = EC_GROUP_dup(group)) == NULL)
ABORT; ABORT;
if (!EC_GROUP_copy(P_256, group))
ABORT;
/* Curve P-384 (FIPS PUB 186-2, App. 6) */ /* Curve P-384 (FIPS PUB 186-2, App. 6) */
@ -581,13 +562,10 @@ prime_field_tests(void)
ABORT; ABORT;
fprintf(stdout, " ok\n"); fprintf(stdout, " ok\n");
group_order_tests(group); group_order_tests(group, ctx);
if (!(P_384 = EC_GROUP_new(EC_GROUP_method_of(group)))) if ((P_384 = EC_GROUP_dup(group)) == NULL)
ABORT; ABORT;
if (!EC_GROUP_copy(P_384, group))
ABORT;
/* Curve P-521 (FIPS PUB 186-2, App. 6) */ /* Curve P-521 (FIPS PUB 186-2, App. 6) */
@ -637,13 +615,10 @@ prime_field_tests(void)
ABORT; ABORT;
fprintf(stdout, " ok\n"); fprintf(stdout, " ok\n");
group_order_tests(group); group_order_tests(group, ctx);
if (!(P_521 = EC_GROUP_new(EC_GROUP_method_of(group)))) if ((P_521 = EC_GROUP_dup(group)) == NULL)
ABORT; ABORT;
if (!EC_GROUP_copy(P_521, group))
ABORT;
/* more tests using the last curve */ /* more tests using the last curve */
fprintf(stdout, "infinity tests ..."); fprintf(stdout, "infinity tests ...");
@ -683,19 +658,12 @@ prime_field_tests(void)
BN_free(y); BN_free(y);
BN_free(z); BN_free(z);
if (P_160)
EC_GROUP_free(P_160); EC_GROUP_free(P_160);
if (P_192)
EC_GROUP_free(P_192); EC_GROUP_free(P_192);
if (P_224)
EC_GROUP_free(P_224); EC_GROUP_free(P_224);
if (P_256)
EC_GROUP_free(P_256); EC_GROUP_free(P_256);
if (P_384)
EC_GROUP_free(P_384); EC_GROUP_free(P_384);
if (P_521)
EC_GROUP_free(P_521); EC_GROUP_free(P_521);
} }
int int

View file

@ -1,4 +1,4 @@
# $OpenBSD: Makefile,v 1.2 2016/09/27 06:52:50 kettenis Exp $ # $OpenBSD: Makefile,v 1.3 2025/01/21 19:14:27 anton Exp $
.include <bsd.obj.mk> .include <bsd.obj.mk>
@ -29,6 +29,6 @@ LDADD+=-laa
LDFLAGS=-L$(AA_OBJDIR) -L$(AB_OBJDIR) LDFLAGS=-L$(AA_OBJDIR) -L$(AB_OBJDIR)
LDFLAGS+= -Wl,-rpath,$(AA_OBJDIR) -Wl,-rpath,$(AB_OBJDIR) LDFLAGS+= -Wl,-rpath,$(AA_OBJDIR) -Wl,-rpath,$(AB_OBJDIR)
NOMAN= NOMAN=
CC=c++ CC=${CXX}
.include <bsd.regress.mk> .include <bsd.regress.mk>

View file

@ -1,4 +1,4 @@
# $OpenBSD: Makefile,v 1.2 2016/09/27 06:52:50 kettenis Exp $ # $OpenBSD: Makefile,v 1.3 2025/01/21 19:14:28 anton Exp $
.include <bsd.obj.mk> .include <bsd.obj.mk>
@ -29,6 +29,6 @@ LDADD+=-lab
LDFLAGS=-L$(AA_OBJDIR) -L$(AB_OBJDIR) LDFLAGS=-L$(AA_OBJDIR) -L$(AB_OBJDIR)
LDFLAGS+= -Wl,-rpath,$(AA_OBJDIR) -Wl,-rpath,$(AB_OBJDIR) LDFLAGS+= -Wl,-rpath,$(AA_OBJDIR) -Wl,-rpath,$(AB_OBJDIR)
NOMAN= NOMAN=
CC=c++ CC=${CXX}
.include <bsd.regress.mk> .include <bsd.regress.mk>

View file

@ -1,4 +1,4 @@
# $OpenBSD: Makefile,v 1.4 2015/06/15 01:10:19 deraadt Exp $ # $OpenBSD: Makefile,v 1.5 2025/01/21 19:14:28 anton Exp $
.include <bsd.obj.mk> .include <bsd.obj.mk>
@ -29,7 +29,7 @@ LDADD=
#LDFLAGS=-L$(AA_OBJDIR) -L$(AB_OBJDIR) #LDFLAGS=-L$(AA_OBJDIR) -L$(AB_OBJDIR)
LDFLAGS+= -Wl,-rpath,$(AA_OBJDIR) -Wl,-rpath,$(AB_OBJDIR) LDFLAGS+= -Wl,-rpath,$(AA_OBJDIR) -Wl,-rpath,$(AB_OBJDIR)
NOMAN= NOMAN=
CC=c++ CC=${CXX}
LD_LIBRARY_PATH=$(AA_OBJDIR):$(AB_OBJDIR) LD_LIBRARY_PATH=$(AA_OBJDIR):$(AB_OBJDIR)
.include <bsd.regress.mk> .include <bsd.regress.mk>

View file

@ -1,4 +1,4 @@
# $OpenBSD: Makefile,v 1.2 2015/06/15 01:10:19 deraadt Exp $ # $OpenBSD: Makefile,v 1.3 2025/01/21 19:14:28 anton Exp $
.include <bsd.obj.mk> .include <bsd.obj.mk>
@ -29,6 +29,6 @@ LDADD+=-lab
LDFLAGS=-L$(AA_OBJDIR) -L$(AB_OBJDIR) LDFLAGS=-L$(AA_OBJDIR) -L$(AB_OBJDIR)
LDFLAGS+= -Wl,-rpath,$(AA_OBJDIR) -Wl,-rpath,$(AB_OBJDIR) LDFLAGS+= -Wl,-rpath,$(AA_OBJDIR) -Wl,-rpath,$(AB_OBJDIR)
NOMAN= NOMAN=
CC=c++ CC=${CXX}
.include <bsd.regress.mk> .include <bsd.regress.mk>

View file

@ -1,4 +1,4 @@
# $OpenBSD: Makefile,v 1.4 2017/03/18 16:45:32 kettenis Exp $ # $OpenBSD: Makefile,v 1.5 2025/01/21 19:14:28 anton Exp $
.include <bsd.obj.mk> .include <bsd.obj.mk>
@ -29,6 +29,6 @@ LDFLAGS=-L$(AA_OBJDIR) -L$(AC_OBJDIR)
LDFLAGS+= -Wl,-disable-new-dtags LDFLAGS+= -Wl,-disable-new-dtags
LDFLAGS+= -Wl,-rpath,$(AA_OBJDIR) -Wl,-rpath,$(AC_OBJDIR) LDFLAGS+= -Wl,-rpath,$(AA_OBJDIR) -Wl,-rpath,$(AC_OBJDIR)
NOMAN= NOMAN=
CC=c++ CC=${CXX}
.include <bsd.regress.mk> .include <bsd.regress.mk>

View file

@ -1,4 +1,4 @@
# $OpenBSD: Makefile,v 1.3 2015/06/15 01:10:19 deraadt Exp $ # $OpenBSD: Makefile,v 1.4 2025/01/21 19:14:28 anton Exp $
.include <bsd.obj.mk> .include <bsd.obj.mk>
@ -30,6 +30,6 @@ LDFLAGS=-L$(AA_OBJDIR) -L$(AC_OBJDIR)
# This intentionally leaves out AA_OBJDIR from -rpath # This intentionally leaves out AA_OBJDIR from -rpath
LDFLAGS+= -Wl,-rpath,$(AC_OBJDIR) LDFLAGS+= -Wl,-rpath,$(AC_OBJDIR)
NOMAN= NOMAN=
CC=c++ CC=${CXX}
.include <bsd.regress.mk> .include <bsd.regress.mk>

View file

@ -1,4 +1,4 @@
# $OpenBSD: Makefile,v 1.1 2016/03/20 05:13:22 guenther Exp $ # $OpenBSD: Makefile,v 1.2 2025/01/21 19:14:28 anton Exp $
.include <bsd.obj.mk> .include <bsd.obj.mk>
@ -18,6 +18,6 @@ LDADD+=-laa
LDFLAGS=-L$(AA_OBJDIR) LDFLAGS=-L$(AA_OBJDIR)
LDFLAGS+= -Wl,-rpath,$(AA_OBJDIR) LDFLAGS+= -Wl,-rpath,$(AA_OBJDIR)
NOMAN= NOMAN=
CC=c++ CC=${CXX}
.include <bsd.regress.mk> .include <bsd.regress.mk>

View file

@ -1,4 +1,4 @@
# $OpenBSD: Makefile,v 1.2 2017/03/18 16:58:22 kettenis Exp $ # $OpenBSD: Makefile,v 1.3 2025/01/21 19:14:28 anton Exp $
.include <bsd.obj.mk> .include <bsd.obj.mk>
@ -50,7 +50,7 @@ LDFLAGS+= -Wl,-rpath,$(AC_OBJDIR)
LDFLAGS+= -Wl,-rpath,$(AD_OBJDIR) LDFLAGS+= -Wl,-rpath,$(AD_OBJDIR)
LDFLAGS+= -Wl,-rpath,$(AE_OBJDIR) LDFLAGS+= -Wl,-rpath,$(AE_OBJDIR)
NOMAN= NOMAN=
CC=c++ CC=${CXX}
run-regress-${PROG}: ${PROG} run-regress-${PROG}: ${PROG}
[ "`./${PROG}`" = "DBECAPpacebd" ] [ "`./${PROG}`" = "DBECAPpacebd" ]

View file

@ -1,4 +1,4 @@
# $OpenBSD: Makefile,v 1.2 2017/03/18 16:58:22 kettenis Exp $ # $OpenBSD: Makefile,v 1.3 2025/01/21 19:14:28 anton Exp $
.include <bsd.obj.mk> .include <bsd.obj.mk>
@ -50,7 +50,7 @@ LDFLAGS+= -Wl,-rpath,$(AC_OBJDIR)
LDFLAGS+= -Wl,-rpath,$(AD_OBJDIR) LDFLAGS+= -Wl,-rpath,$(AD_OBJDIR)
LDFLAGS+= -Wl,-rpath,$(AE_OBJDIR) LDFLAGS+= -Wl,-rpath,$(AE_OBJDIR)
NOMAN= NOMAN=
CC=c++ CC=${CXX}
run-regress-${PROG}: ${PROG} run-regress-${PROG}: ${PROG}
[ "`./${PROG}`" = "DBECAacebd" ] [ "`./${PROG}`" = "DBECAacebd" ]

View file

@ -1,4 +1,4 @@
/* $OpenBSD: cpufunc.c,v 1.57 2021/05/16 03:39:27 jsg Exp $ */ /* $OpenBSD: cpufunc.c,v 1.58 2025/01/20 20:13:29 kettenis Exp $ */
/* $NetBSD: cpufunc.c,v 1.65 2003/11/05 12:53:15 scw Exp $ */ /* $NetBSD: cpufunc.c,v 1.65 2003/11/05 12:53:15 scw Exp $ */
/* /*
@ -392,7 +392,6 @@ armv7_setup(void)
| CPU_CONTROL_AFE; | CPU_CONTROL_AFE;
cpuctrl = CPU_CONTROL_MMU_ENABLE cpuctrl = CPU_CONTROL_MMU_ENABLE
| CPU_CONTROL_AFLT_ENABLE
| CPU_CONTROL_DC_ENABLE | CPU_CONTROL_DC_ENABLE
| CPU_CONTROL_BPRD_ENABLE | CPU_CONTROL_BPRD_ENABLE
| CPU_CONTROL_IC_ENABLE | CPU_CONTROL_IC_ENABLE

View file

@ -1,4 +1,4 @@
/* $OpenBSD: wsevent.c,v 1.28 2024/03/25 13:01:49 mvs Exp $ */ /* $OpenBSD: wsevent.c,v 1.29 2025/01/21 20:13:19 mvs Exp $ */
/* $NetBSD: wsevent.c,v 1.16 2003/08/07 16:31:29 agc Exp $ */ /* $NetBSD: wsevent.c,v 1.16 2003/08/07 16:31:29 agc Exp $ */
/* /*
@ -85,19 +85,61 @@
void filt_wseventdetach(struct knote *); void filt_wseventdetach(struct knote *);
int filt_wseventread(struct knote *, long); int filt_wseventread(struct knote *, long);
int filt_wseventmodify(struct kevent *, struct knote *);
int filt_wseventprocess(struct knote *, struct kevent *);
static void
wsevent_klist_assertlk(void *arg)
{
struct wseventvar *ev = arg;
if((ev->ws_flags & WSEVENT_MPSAFE) == 0)
KERNEL_ASSERT_LOCKED();
MUTEX_ASSERT_LOCKED(&ev->ws_mtx);
}
static int
wsevent_klist_lock(void *arg)
{
struct wseventvar *ev = arg;
if((ev->ws_flags & WSEVENT_MPSAFE) == 0)
KERNEL_LOCK();
mtx_enter(&ev->ws_mtx);
return (0);
}
static void
wsevent_klist_unlock(void *arg, int s)
{
struct wseventvar *ev = arg;
mtx_leave(&ev->ws_mtx);
if ((ev->ws_flags & WSEVENT_MPSAFE) == 0)
KERNEL_UNLOCK();
}
static const struct klistops wsevent_klistops = {
.klo_assertlk = wsevent_klist_assertlk,
.klo_lock = wsevent_klist_lock,
.klo_unlock = wsevent_klist_unlock,
};
const struct filterops wsevent_filtops = { const struct filterops wsevent_filtops = {
.f_flags = FILTEROP_ISFD, .f_flags = FILTEROP_ISFD | FILTEROP_MPSAFE,
.f_attach = NULL, .f_attach = NULL,
.f_detach = filt_wseventdetach, .f_detach = filt_wseventdetach,
.f_event = filt_wseventread, .f_event = filt_wseventread,
.f_modify = filt_wseventmodify,
.f_process = filt_wseventprocess,
}; };
/* /*
* Initialize a wscons_event queue. * Initialize a wscons_event queue.
*/ */
int int
wsevent_init(struct wseventvar *ev) wsevent_init_flags(struct wseventvar *ev, int flags)
{ {
struct wscons_event *queue; struct wscons_event *queue;
@ -112,6 +154,10 @@ wsevent_init(struct wseventvar *ev)
return (1); return (1);
} }
mtx_init_flags(&ev->ws_mtx, IPL_TTY, "wsmtx", 0);
klist_init(&ev->ws_klist, &wsevent_klistops, ev);
ev->ws_flags = flags;
ev->ws_q = queue; ev->ws_q = queue;
ev->ws_get = ev->ws_put = 0; ev->ws_get = ev->ws_put = 0;
@ -135,7 +181,7 @@ wsevent_fini(struct wseventvar *ev)
free(ev->ws_q, M_DEVBUF, WSEVENT_QSIZE * sizeof(struct wscons_event)); free(ev->ws_q, M_DEVBUF, WSEVENT_QSIZE * sizeof(struct wscons_event));
ev->ws_q = NULL; ev->ws_q = NULL;
klist_invalidate(&ev->ws_sel.si_note); klist_invalidate(&ev->ws_klist);
sigio_free(&ev->ws_sigio); sigio_free(&ev->ws_sigio);
} }
@ -147,8 +193,8 @@ wsevent_fini(struct wseventvar *ev)
int int
wsevent_read(struct wseventvar *ev, struct uio *uio, int flags) wsevent_read(struct wseventvar *ev, struct uio *uio, int flags)
{ {
int s, error; int error, wrap = 0;
u_int cnt; u_int cnt, tcnt, get;
size_t n; size_t n;
/* /*
@ -156,17 +202,20 @@ wsevent_read(struct wseventvar *ev, struct uio *uio, int flags)
*/ */
if (uio->uio_resid < sizeof(struct wscons_event)) if (uio->uio_resid < sizeof(struct wscons_event))
return (EMSGSIZE); /* ??? */ return (EMSGSIZE); /* ??? */
s = splwsevent(); n = howmany(uio->uio_resid, sizeof(struct wscons_event));
mtx_enter(&ev->ws_mtx);
while (ev->ws_get == ev->ws_put) { while (ev->ws_get == ev->ws_put) {
if (flags & IO_NDELAY) { if (flags & IO_NDELAY) {
splx(s); mtx_leave(&ev->ws_mtx);
return (EWOULDBLOCK); return (EWOULDBLOCK);
} }
ev->ws_wanted = 1; ev->ws_wanted = 1;
error = tsleep_nsec(ev, PWSEVENT | PCATCH, error = msleep_nsec(ev, &ev->ws_mtx, PWSEVENT | PCATCH,
"wsevent_read", INFSLP); "wsevent_read", INFSLP);
if (error) { if (error) {
splx(s); mtx_leave(&ev->ws_mtx);
return (error); return (error);
} }
} }
@ -178,37 +227,43 @@ wsevent_read(struct wseventvar *ev, struct uio *uio, int flags)
cnt = WSEVENT_QSIZE - ev->ws_get; /* events in [get..QSIZE) */ cnt = WSEVENT_QSIZE - ev->ws_get; /* events in [get..QSIZE) */
else else
cnt = ev->ws_put - ev->ws_get; /* events in [get..put) */ cnt = ev->ws_put - ev->ws_get; /* events in [get..put) */
splx(s);
n = howmany(uio->uio_resid, sizeof(struct wscons_event));
if (cnt > n) if (cnt > n)
cnt = n; cnt = n;
error = uiomove((caddr_t)&ev->ws_q[ev->ws_get],
cnt * sizeof(struct wscons_event), uio); get = ev->ws_get;
tcnt = ev->ws_put;
n -= cnt; n -= cnt;
/*
* If we do not wrap to 0, used up all our space, or had an error, ev->ws_get = (get + cnt) % WSEVENT_QSIZE;
* stop. Otherwise move from front of queue to put index, if there if (!(ev->ws_get != 0 || n == 0 || tcnt == 0)) {
* is anything there to move. wrap = 1;
*/
if ((ev->ws_get = (ev->ws_get + cnt) % WSEVENT_QSIZE) != 0 || if (tcnt > n)
n == 0 || error || (cnt = ev->ws_put) == 0) tcnt = n;
return (error); ev->ws_get = tcnt;
if (cnt > n) }
cnt = n;
error = uiomove((caddr_t)&ev->ws_q[0], mtx_leave(&ev->ws_mtx);
error = uiomove((caddr_t)&ev->ws_q[get],
cnt * sizeof(struct wscons_event), uio); cnt * sizeof(struct wscons_event), uio);
ev->ws_get = cnt;
/*
* If we do wrap to 0, move from front of queue to put index, if
* there is anything there to move.
*/
if (wrap && error == 0) {
error = uiomove((caddr_t)&ev->ws_q[0],
tcnt * sizeof(struct wscons_event), uio);
}
return (error); return (error);
} }
int int
wsevent_kqfilter(struct wseventvar *ev, struct knote *kn) wsevent_kqfilter(struct wseventvar *ev, struct knote *kn)
{ {
struct klist *klist;
int s;
klist = &ev->ws_sel.si_note;
switch (kn->kn_filter) { switch (kn->kn_filter) {
case EVFILT_READ: case EVFILT_READ:
kn->kn_fop = &wsevent_filtops; kn->kn_fop = &wsevent_filtops;
@ -218,10 +273,7 @@ wsevent_kqfilter(struct wseventvar *ev, struct knote *kn)
} }
kn->kn_hook = ev; kn->kn_hook = ev;
klist_insert(&ev->ws_klist, kn);
s = splwsevent();
klist_insert_locked(klist, kn);
splx(s);
return (0); return (0);
} }
@ -230,12 +282,8 @@ void
filt_wseventdetach(struct knote *kn) filt_wseventdetach(struct knote *kn)
{ {
struct wseventvar *ev = kn->kn_hook; struct wseventvar *ev = kn->kn_hook;
struct klist *klist = &ev->ws_sel.si_note;
int s;
s = splwsevent(); klist_remove(&ev->ws_klist, kn);
klist_remove_locked(klist, kn);
splx(s);
} }
int int
@ -243,6 +291,10 @@ filt_wseventread(struct knote *kn, long hint)
{ {
struct wseventvar *ev = kn->kn_hook; struct wseventvar *ev = kn->kn_hook;
if((ev->ws_flags & WSEVENT_MPSAFE) == 0)
KERNEL_ASSERT_LOCKED();
MUTEX_ASSERT_LOCKED(&ev->ws_mtx);
if (ev->ws_get == ev->ws_put) if (ev->ws_get == ev->ws_put)
return (0); return (0);
@ -253,3 +305,38 @@ filt_wseventread(struct knote *kn, long hint)
return (1); return (1);
} }
int
filt_wseventmodify(struct kevent *kev, struct knote *kn)
{
struct wseventvar *ev = kn->kn_hook;
int active, dolock = ((ev->ws_flags & WSEVENT_MPSAFE) == 0);
if (dolock)
KERNEL_LOCK();
mtx_enter(&ev->ws_mtx);
active = knote_modify(kev, kn);
mtx_leave(&ev->ws_mtx);
if (dolock)
KERNEL_UNLOCK();
return (active);
}
int
filt_wseventprocess(struct knote *kn, struct kevent *kev)
{
struct wseventvar *ev = kn->kn_hook;
int active, dolock = ((ev->ws_flags & WSEVENT_MPSAFE) == 0);
if (dolock)
KERNEL_LOCK();
mtx_enter(&ev->ws_mtx);
active = knote_process(kn, kev);
mtx_leave(&ev->ws_mtx);
if (dolock)
KERNEL_UNLOCK();
return (active);
}

View file

@ -1,4 +1,4 @@
/* $OpenBSD: wseventvar.h,v 1.13 2024/03/25 13:01:49 mvs Exp $ */ /* $OpenBSD: wseventvar.h,v 1.14 2025/01/21 20:13:19 mvs Exp $ */
/* $NetBSD: wseventvar.h,v 1.1 1998/03/22 14:24:03 drochner Exp $ */ /* $NetBSD: wseventvar.h,v 1.1 1998/03/22 14:24:03 drochner Exp $ */
/* /*
@ -71,8 +71,9 @@
* @(#)event_var.h 8.1 (Berkeley) 6/11/93 * @(#)event_var.h 8.1 (Berkeley) 6/11/93
*/ */
#include <sys/selinfo.h> #include <sys/event.h>
#include <sys/sigio.h> #include <sys/sigio.h>
#include <sys/signalvar.h>
/* /*
* Internal "wscons_event" queue interface for the keyboard and mouse drivers. * Internal "wscons_event" queue interface for the keyboard and mouse drivers.
@ -80,38 +81,69 @@
* i.e., are expected to run off serial ports or similar devices. * i.e., are expected to run off serial ports or similar devices.
*/ */
/*
* Locks used to protect data
* I immutable
* m ws_mtx
*/
/*
* XXXSMP: Non WSEVENT_MPSAFE wseventvar structures rely on kernel lock
*/
/* WSEVENT_QSIZE should be a power of two so that `%' is fast */ /* WSEVENT_QSIZE should be a power of two so that `%' is fast */
#define WSEVENT_QSIZE 256 /* may need tuning; this uses 2k */ #define WSEVENT_QSIZE 256 /* may need tuning; this uses 2k */
struct wseventvar { struct wseventvar {
u_int ws_get; /* get (read) index (modified u_int ws_get; /* [m] get (read) index (modified
synchronously) */ synchronously) */
volatile u_int ws_put; /* put (write) index (modified by volatile u_int ws_put; /* [m] put (write) index (modified by
interrupt) */ interrupt) */
struct selinfo ws_sel; /* process selecting */ int ws_flags; /* [I] flags, see below*/
struct mutex ws_mtx;
struct klist ws_klist; /* [m] list of knotes */
struct sigio_ref ws_sigio; /* async I/O registration */ struct sigio_ref ws_sigio; /* async I/O registration */
int ws_wanted; /* wake up on input ready */ int ws_wanted; /* [m] wake up on input ready */
int ws_async; /* send SIGIO on input ready */ int ws_async; /* [m] send SIGIO on input ready */
struct wscons_event *ws_q; /* circular buffer (queue) of events */ struct wscons_event *ws_q; /* [m] circular buffer (queue) of
events */
}; };
#define splwsevent() spltty() #define WSEVENT_MPSAFE 0x0001
#define WSEVENT_WAKEUP(ev) { \ static inline void
selwakeup(&(ev)->ws_sel); \ wsevent_wakeup(struct wseventvar *ev)
if ((ev)->ws_wanted) { \ {
(ev)->ws_wanted = 0; \ int dosigio = 0;
wakeup((caddr_t)(ev)); \
} \ knote(&ev->ws_klist, 0);
if ((ev)->ws_async) \
pgsigio(&(ev)->ws_sigio, SIGIO, 0); \ mtx_enter(&ev->ws_mtx);
if (ev->ws_wanted) {
ev->ws_wanted = 0;
wakeup(ev);
}
if (ev->ws_async)
dosigio = 1;
mtx_leave(&ev->ws_mtx);
if (dosigio)
pgsigio(&ev->ws_sigio, SIGIO, 0);
} }
int wsevent_init(struct wseventvar *); #define WSEVENT_WAKEUP(ev) do { wsevent_wakeup(ev); } while (0)
int wsevent_init_flags(struct wseventvar *, int);
void wsevent_fini(struct wseventvar *); void wsevent_fini(struct wseventvar *);
int wsevent_read(struct wseventvar *, struct uio *, int); int wsevent_read(struct wseventvar *, struct uio *, int);
int wsevent_kqfilter(struct wseventvar *, struct knote *); int wsevent_kqfilter(struct wseventvar *, struct knote *);
static inline int
wsevent_init(struct wseventvar *ev)
{
return wsevent_init_flags(ev, 0);
}
/* /*
* PWSEVENT is set just above PSOCK, which is just above TTIPRI, on the * PWSEVENT is set just above PSOCK, which is just above TTIPRI, on the
* theory that mouse and keyboard `user' input should be quick. * theory that mouse and keyboard `user' input should be quick.

View file

@ -1,4 +1,4 @@
/* $OpenBSD: wskbd.c,v 1.120 2024/12/30 02:46:00 guenther Exp $ */ /* $OpenBSD: wskbd.c,v 1.121 2025/01/21 20:13:19 mvs Exp $ */
/* $NetBSD: wskbd.c,v 1.80 2005/05/04 01:52:16 augustss Exp $ */ /* $NetBSD: wskbd.c,v 1.80 2005/05/04 01:52:16 augustss Exp $ */
/* /*
@ -625,7 +625,6 @@ wskbd_detach(struct device *self, int flags)
struct wskbd_softc *sc = (struct wskbd_softc *)self; struct wskbd_softc *sc = (struct wskbd_softc *)self;
struct wseventvar *evar; struct wseventvar *evar;
int maj, mn; int maj, mn;
int s;
#if NWSMUX > 0 #if NWSMUX > 0
/* Tell parent mux we're leaving. */ /* Tell parent mux we're leaving. */
@ -647,18 +646,19 @@ wskbd_detach(struct device *self, int flags)
evar = sc->sc_base.me_evp; evar = sc->sc_base.me_evp;
if (evar != NULL) { if (evar != NULL) {
s = spltty();
if (--sc->sc_refcnt >= 0) { if (--sc->sc_refcnt >= 0) {
/* Wake everyone by generating a dummy event. */ /* Wake everyone by generating a dummy event. */
mtx_enter(&evar->ws_mtx);
if (++evar->ws_put >= WSEVENT_QSIZE) if (++evar->ws_put >= WSEVENT_QSIZE)
evar->ws_put = 0; evar->ws_put = 0;
WSEVENT_WAKEUP(evar); mtx_leave(&evar->ws_mtx);
wsevent_wakeup(evar);
/* Wait for processes to go away. */ /* Wait for processes to go away. */
if (tsleep_nsec(sc, PZERO, "wskdet", SEC_TO_NSEC(60))) if (tsleep_nsec(sc, PZERO, "wskdet", SEC_TO_NSEC(60)))
printf("wskbd_detach: %s didn't detach\n", printf("wskbd_detach: %s didn't detach\n",
sc->sc_base.me_dv.dv_xname); sc->sc_base.me_dv.dv_xname);
} }
splx(s);
} }
free(sc->sc_map, M_DEVBUF, free(sc->sc_map, M_DEVBUF,
@ -763,6 +763,7 @@ wskbd_deliver_event(struct wskbd_softc *sc, u_int type, int value)
} }
#endif #endif
mtx_enter(&evar->ws_mtx);
put = evar->ws_put; put = evar->ws_put;
ev = &evar->ws_q[put]; ev = &evar->ws_q[put];
put = (put + 1) % WSEVENT_QSIZE; put = (put + 1) % WSEVENT_QSIZE;
@ -775,7 +776,8 @@ wskbd_deliver_event(struct wskbd_softc *sc, u_int type, int value)
ev->value = value; ev->value = value;
nanotime(&ev->time); nanotime(&ev->time);
evar->ws_put = put; evar->ws_put = put;
WSEVENT_WAKEUP(evar); mtx_leave(&evar->ws_mtx);
wsevent_wakeup(evar);
} }
#ifdef WSDISPLAY_COMPAT_RAWKBD #ifdef WSDISPLAY_COMPAT_RAWKBD
@ -862,7 +864,7 @@ wskbdopen(dev_t dev, int flags, int mode, struct proc *p)
return (EBUSY); return (EBUSY);
evar = &sc->sc_base.me_evar; evar = &sc->sc_base.me_evar;
if (wsevent_init(evar)) if (wsevent_init_flags(evar, WSEVENT_MPSAFE))
return (EBUSY); return (EBUSY);
error = wskbd_do_open(sc, evar); error = wskbd_do_open(sc, evar);
@ -1005,7 +1007,9 @@ wskbd_do_ioctl_sc(struct wskbd_softc *sc, u_long cmd, caddr_t data, int flag,
case FIOASYNC: case FIOASYNC:
if (sc->sc_base.me_evp == NULL) if (sc->sc_base.me_evp == NULL)
return (EINVAL); return (EINVAL);
mtx_enter(&sc->sc_base.me_evp->ws_mtx);
sc->sc_base.me_evp->ws_async = *(int *)data != 0; sc->sc_base.me_evp->ws_async = *(int *)data != 0;
mtx_leave(&sc->sc_base.me_evp->ws_mtx);
return (0); return (0);
case FIOGETOWN: case FIOGETOWN:

View file

@ -1,4 +1,4 @@
/* $OpenBSD: wsmux.c,v 1.60 2024/12/30 02:46:00 guenther Exp $ */ /* $OpenBSD: wsmux.c,v 1.61 2025/01/22 15:06:56 mvs Exp $ */
/* $NetBSD: wsmux.c,v 1.37 2005/04/30 03:47:12 augustss Exp $ */ /* $NetBSD: wsmux.c,v 1.37 2005/04/30 03:47:12 augustss Exp $ */
/* /*
@ -208,7 +208,7 @@ wsmuxopen(dev_t dev, int flags, int mode, struct proc *p)
return (EBUSY); return (EBUSY);
evar = &sc->sc_base.me_evar; evar = &sc->sc_base.me_evar;
if (wsevent_init(evar)) if (wsevent_init_flags(evar, WSEVENT_MPSAFE))
return (EBUSY); return (EBUSY);
#ifdef WSDISPLAY_COMPAT_RAWKBD #ifdef WSDISPLAY_COMPAT_RAWKBD
sc->sc_rawkbd = 0; sc->sc_rawkbd = 0;
@ -385,7 +385,7 @@ wsmux_do_ioctl(struct device *dv, u_long cmd, caddr_t data, int flag,
struct wsmux_softc *sc = (struct wsmux_softc *)dv; struct wsmux_softc *sc = (struct wsmux_softc *)dv;
struct wsevsrc *me; struct wsevsrc *me;
int error, ok; int error, ok;
int s, put, get, n; int put, get, n;
struct wseventvar *evar; struct wseventvar *evar;
struct wscons_event *ev; struct wscons_event *ev;
struct wsmux_device_list *l; struct wsmux_device_list *l;
@ -415,13 +415,12 @@ wsmux_do_ioctl(struct device *dv, u_long cmd, caddr_t data, int flag,
return (0); return (0);
} }
s = spltty(); mtx_enter(&evar->ws_mtx);
get = evar->ws_get; get = evar->ws_get;
put = evar->ws_put; put = evar->ws_put;
ev = &evar->ws_q[put]; ev = &evar->ws_q[put];
if (++put % WSEVENT_QSIZE == get) { if (++put % WSEVENT_QSIZE == get) {
put--; mtx_leave(&evar->ws_mtx);
splx(s);
return (ENOSPC); return (ENOSPC);
} }
if (put >= WSEVENT_QSIZE) if (put >= WSEVENT_QSIZE)
@ -429,8 +428,8 @@ wsmux_do_ioctl(struct device *dv, u_long cmd, caddr_t data, int flag,
*ev = *(struct wscons_event *)data; *ev = *(struct wscons_event *)data;
nanotime(&ev->time); nanotime(&ev->time);
evar->ws_put = put; evar->ws_put = put;
WSEVENT_WAKEUP(evar); mtx_leave(&evar->ws_mtx);
splx(s); wsevent_wakeup(evar);
return (0); return (0);
case WSMUXIO_ADD_DEVICE: case WSMUXIO_ADD_DEVICE:
#define d ((struct wsmux_device *)data) #define d ((struct wsmux_device *)data)
@ -496,7 +495,9 @@ wsmux_do_ioctl(struct device *dv, u_long cmd, caddr_t data, int flag,
evar = sc->sc_base.me_evp; evar = sc->sc_base.me_evp;
if (evar == NULL) if (evar == NULL)
return (EINVAL); return (EINVAL);
mtx_enter(&evar->ws_mtx);
evar->ws_async = *(int *)data != 0; evar->ws_async = *(int *)data != 0;
mtx_leave(&evar->ws_mtx);
return (0); return (0);
case FIOGETOWN: case FIOGETOWN:
case TIOCGPGRP: case TIOCGPGRP:

View file

@ -1,4 +1,4 @@
/* $OpenBSD: kern_sig.c,v 1.355 2025/01/06 13:17:56 claudio Exp $ */ /* $OpenBSD: kern_sig.c,v 1.357 2025/01/22 16:13:09 claudio Exp $ */
/* $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $ */ /* $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $ */
/* /*
@ -1549,10 +1549,8 @@ process_continue(struct proc *p, int flag)
SCHED_ASSERT_LOCKED(); SCHED_ASSERT_LOCKED();
if (q->p_wchan == NULL) if (q->p_wchan == NULL)
setrunnable(q); setrunnable(q);
else { else
atomic_clearbits_int(&q->p_flag, P_WSLEEP);
q->p_stat = SSLEEP; q->p_stat = SSLEEP;
}
/* XXX SCHED_UNLOCK(); */ /* XXX SCHED_UNLOCK(); */
} }
} }
@ -2123,15 +2121,21 @@ single_thread_check_locked(struct proc *p, int deep)
if (pr->ps_single == NULL || pr->ps_single == p) if (pr->ps_single == NULL || pr->ps_single == p)
return (0); return (0);
do {
/* if we're in deep, we need to unwind to the edge */ /* if we're in deep, we need to unwind to the edge */
if (deep) { if (deep) {
if (pr->ps_flags & PS_SINGLEUNWIND) int err = 0;
if (pr->ps_flags & PS_SINGLEUNWIND ||
pr->ps_flags & PS_SINGLEEXIT)
return (ERESTART); return (ERESTART);
if (pr->ps_flags & PS_SINGLEEXIT) SCHED_LOCK();
return (EINTR); if (p->p_stat != SSTOP)
err = EWOULDBLOCK;
SCHED_UNLOCK();
return (err);
} }
do {
if (pr->ps_flags & PS_SINGLEEXIT) { if (pr->ps_flags & PS_SINGLEEXIT) {
mtx_leave(&pr->ps_mtx); mtx_leave(&pr->ps_mtx);
KERNEL_LOCK(); KERNEL_LOCK();

View file

@ -1,4 +1,4 @@
/* $OpenBSD: kern_synch.c,v 1.215 2024/12/05 14:53:55 claudio Exp $ */ /* $OpenBSD: kern_synch.c,v 1.218 2025/01/22 16:14:22 claudio Exp $ */
/* $NetBSD: kern_synch.c,v 1.37 1996/04/22 01:38:37 christos Exp $ */ /* $NetBSD: kern_synch.c,v 1.37 1996/04/22 01:38:37 christos Exp $ */
/* /*
@ -376,15 +376,6 @@ sleep_finish(int timo, int do_sleep)
} }
if (catch != 0) { if (catch != 0) {
/*
* We put ourselves on the sleep queue and start our
* timeout before calling sleep_signal_check(), as we could
* stop there, and a wakeup or a SIGCONT (or both) could
* occur while we were stopped. A SIGCONT would cause
* us to be marked as SSLEEP without resuming us, thus
* we must be ready for sleep when sleep_signal_check() is
* called.
*/
if ((error = sleep_signal_check(p, 0)) != 0) { if ((error = sleep_signal_check(p, 0)) != 0) {
catch = 0; catch = 0;
do_sleep = 0; do_sleep = 0;
@ -459,31 +450,48 @@ sleep_finish(int timo, int do_sleep)
/* /*
* Check and handle signals and suspensions around a sleep cycle. * Check and handle signals and suspensions around a sleep cycle.
* The 2nd call in sleep_finish() sets nostop = 1 and then stop * The 2nd call in sleep_finish() sets after_sleep = 1. In this case
* signals can be ignored since the sleep is over and the process * any pending suspend event came in after the wakeup / unsleep and
* will stop in userret. * can therefor be ignored. Once the process hits userret the event
* will be picked up again.
*/ */
int int
sleep_signal_check(struct proc *p, int nostop) sleep_signal_check(struct proc *p, int after_sleep)
{ {
struct sigctx ctx; struct sigctx ctx;
int err, sig; int err, sig;
if ((err = single_thread_check(p, 1)) != 0) if ((err = single_thread_check(p, 1)) != 0) {
if (err != EWOULDBLOCK)
return err; return err;
/* requested to stop */
if (!after_sleep) {
mtx_enter(&p->p_p->ps_mtx);
if (--p->p_p->ps_singlecnt == 0)
wakeup(&p->p_p->ps_singlecnt);
mtx_leave(&p->p_p->ps_mtx);
SCHED_LOCK();
p->p_stat = SSTOP;
SCHED_UNLOCK();
}
}
if ((sig = cursig(p, &ctx, 1)) != 0) { if ((sig = cursig(p, &ctx, 1)) != 0) {
if (ctx.sig_stop) { if (ctx.sig_stop) {
if (nostop) if (!after_sleep) {
return 0;
p->p_p->ps_xsig = sig; p->p_p->ps_xsig = sig;
SCHED_LOCK(); SCHED_LOCK();
proc_stop(p, 0); proc_stop(p, 0);
SCHED_UNLOCK(); SCHED_UNLOCK();
}
} else if (ctx.sig_intr && !ctx.sig_ignore) } else if (ctx.sig_intr && !ctx.sig_ignore)
return EINTR; return EINTR;
else else
return ERESTART; return ERESTART;
} }
return 0; return 0;
} }

View file

@ -1,4 +1,4 @@
/* $OpenBSD: uipc_socket.c,v 1.361 2025/01/20 16:34:48 bluhm Exp $ */ /* $OpenBSD: uipc_socket.c,v 1.363 2025/01/22 15:05:49 mvs Exp $ */
/* $NetBSD: uipc_socket.c,v 1.21 1996/02/04 02:17:52 christos Exp $ */ /* $NetBSD: uipc_socket.c,v 1.21 1996/02/04 02:17:52 christos Exp $ */
/* /*
@ -166,9 +166,6 @@ soalloc(const struct protosw *prp, int wait)
TAILQ_INIT(&so->so_q0); TAILQ_INIT(&so->so_q0);
TAILQ_INIT(&so->so_q); TAILQ_INIT(&so->so_q);
so->so_snd.sb_flags |= SB_MTXLOCK;
so->so_rcv.sb_flags |= SB_MTXLOCK;
return (so); return (so);
} }
@ -598,7 +595,6 @@ sosend(struct socket *so, struct mbuf *addr, struct uio *uio, struct mbuf *top,
size_t resid; size_t resid;
int error; int error;
int atomic = sosendallatonce(so) || top; int atomic = sosendallatonce(so) || top;
int dosolock = ((so->so_snd.sb_flags & SB_MTXLOCK) == 0);
if (uio) if (uio)
resid = uio->uio_resid; resid = uio->uio_resid;
@ -634,9 +630,7 @@ sosend(struct socket *so, struct mbuf *addr, struct uio *uio, struct mbuf *top,
restart: restart:
if ((error = sblock(&so->so_snd, SBLOCKWAIT(flags))) != 0) if ((error = sblock(&so->so_snd, SBLOCKWAIT(flags))) != 0)
goto out; goto out;
if (dosolock) mtx_enter(&so->so_snd.sb_mtx);
solock_shared(so);
sb_mtx_lock(&so->so_snd);
so->so_snd.sb_state |= SS_ISSENDING; so->so_snd.sb_state |= SS_ISSENDING;
do { do {
if (so->so_snd.sb_state & SS_CANTSENDMORE) if (so->so_snd.sb_state & SS_CANTSENDMORE)
@ -669,11 +663,9 @@ restart:
if (flags & MSG_DONTWAIT) if (flags & MSG_DONTWAIT)
snderr(EWOULDBLOCK); snderr(EWOULDBLOCK);
sbunlock(&so->so_snd); sbunlock(&so->so_snd);
error = sbwait(so, &so->so_snd); error = sbwait(&so->so_snd);
so->so_snd.sb_state &= ~SS_ISSENDING; so->so_snd.sb_state &= ~SS_ISSENDING;
sb_mtx_unlock(&so->so_snd); mtx_leave(&so->so_snd.sb_mtx);
if (dosolock)
sounlock_shared(so);
if (error) if (error)
goto out; goto out;
goto restart; goto restart;
@ -688,13 +680,9 @@ restart:
if (flags & MSG_EOR) if (flags & MSG_EOR)
top->m_flags |= M_EOR; top->m_flags |= M_EOR;
} else { } else {
sb_mtx_unlock(&so->so_snd); mtx_leave(&so->so_snd.sb_mtx);
if (dosolock)
sounlock_shared(so);
error = m_getuio(&top, atomic, space, uio); error = m_getuio(&top, atomic, space, uio);
if (dosolock) mtx_enter(&so->so_snd.sb_mtx);
solock_shared(so);
sb_mtx_lock(&so->so_snd);
if (error) if (error)
goto release; goto release;
space -= top->m_pkthdr.len; space -= top->m_pkthdr.len;
@ -706,16 +694,14 @@ restart:
so->so_snd.sb_state &= ~SS_ISSENDING; so->so_snd.sb_state &= ~SS_ISSENDING;
if (top && so->so_options & SO_ZEROIZE) if (top && so->so_options & SO_ZEROIZE)
top->m_flags |= M_ZEROIZE; top->m_flags |= M_ZEROIZE;
sb_mtx_unlock(&so->so_snd); mtx_leave(&so->so_snd.sb_mtx);
if (!dosolock)
solock_shared(so); solock_shared(so);
if (flags & MSG_OOB) if (flags & MSG_OOB)
error = pru_sendoob(so, top, addr, control); error = pru_sendoob(so, top, addr, control);
else else
error = pru_send(so, top, addr, control); error = pru_send(so, top, addr, control);
if (!dosolock)
sounlock_shared(so); sounlock_shared(so);
sb_mtx_lock(&so->so_snd); mtx_enter(&so->so_snd.sb_mtx);
clen = 0; clen = 0;
control = NULL; control = NULL;
top = NULL; top = NULL;
@ -726,9 +712,7 @@ restart:
release: release:
so->so_snd.sb_state &= ~SS_ISSENDING; so->so_snd.sb_state &= ~SS_ISSENDING;
sb_mtx_unlock(&so->so_snd); mtx_leave(&so->so_snd.sb_mtx);
if (dosolock)
sounlock_shared(so);
sbunlock(&so->so_snd); sbunlock(&so->so_snd);
out: out:
m_freem(top); m_freem(top);
@ -865,7 +849,6 @@ soreceive(struct socket *so, struct mbuf **paddr, struct uio *uio,
const struct protosw *pr = so->so_proto; const struct protosw *pr = so->so_proto;
struct mbuf *nextrecord; struct mbuf *nextrecord;
size_t resid, orig_resid = uio->uio_resid; size_t resid, orig_resid = uio->uio_resid;
int dosolock = ((so->so_rcv.sb_flags & SB_MTXLOCK) == 0);
mp = mp0; mp = mp0;
if (paddr) if (paddr)
@ -898,9 +881,7 @@ bad:
restart: restart:
if ((error = sblock(&so->so_rcv, SBLOCKWAIT(flags))) != 0) if ((error = sblock(&so->so_rcv, SBLOCKWAIT(flags))) != 0)
return (error); return (error);
if (dosolock) mtx_enter(&so->so_rcv.sb_mtx);
solock_shared(so);
sb_mtx_lock(&so->so_rcv);
m = so->so_rcv.sb_mb; m = so->so_rcv.sb_mb;
#ifdef SOCKET_SPLICE #ifdef SOCKET_SPLICE
@ -965,10 +946,8 @@ restart:
SBLASTMBUFCHK(&so->so_rcv, "soreceive sbwait 1"); SBLASTMBUFCHK(&so->so_rcv, "soreceive sbwait 1");
sbunlock(&so->so_rcv); sbunlock(&so->so_rcv);
error = sbwait(so, &so->so_rcv); error = sbwait(&so->so_rcv);
sb_mtx_unlock(&so->so_rcv); mtx_leave(&so->so_rcv.sb_mtx);
if (dosolock)
sounlock_shared(so);
if (error) if (error)
return (error); return (error);
goto restart; goto restart;
@ -1037,15 +1016,11 @@ dontblock:
sbsync(&so->so_rcv, nextrecord); sbsync(&so->so_rcv, nextrecord);
if (controlp) { if (controlp) {
if (pr->pr_domain->dom_externalize) { if (pr->pr_domain->dom_externalize) {
sb_mtx_unlock(&so->so_rcv); mtx_leave(&so->so_rcv.sb_mtx);
if (dosolock)
sounlock_shared(so);
error = error =
(*pr->pr_domain->dom_externalize) (*pr->pr_domain->dom_externalize)
(cm, controllen, flags); (cm, controllen, flags);
if (dosolock) mtx_enter(&so->so_rcv.sb_mtx);
solock_shared(so);
sb_mtx_lock(&so->so_rcv);
} }
*controlp = cm; *controlp = cm;
} else { } else {
@ -1054,9 +1029,9 @@ dontblock:
* through the read path rather than recv. * through the read path rather than recv.
*/ */
if (pr->pr_domain->dom_dispose) { if (pr->pr_domain->dom_dispose) {
sb_mtx_unlock(&so->so_rcv); mtx_leave(&so->so_rcv.sb_mtx);
pr->pr_domain->dom_dispose(cm); pr->pr_domain->dom_dispose(cm);
sb_mtx_lock(&so->so_rcv); mtx_enter(&so->so_rcv.sb_mtx);
} }
m_free(cm); m_free(cm);
} }
@ -1122,13 +1097,9 @@ dontblock:
SBLASTRECORDCHK(&so->so_rcv, "soreceive uiomove"); SBLASTRECORDCHK(&so->so_rcv, "soreceive uiomove");
SBLASTMBUFCHK(&so->so_rcv, "soreceive uiomove"); SBLASTMBUFCHK(&so->so_rcv, "soreceive uiomove");
resid = uio->uio_resid; resid = uio->uio_resid;
sb_mtx_unlock(&so->so_rcv); mtx_leave(&so->so_rcv.sb_mtx);
if (dosolock)
sounlock_shared(so);
uio_error = uiomove(mtod(m, caddr_t) + moff, len, uio); uio_error = uiomove(mtod(m, caddr_t) + moff, len, uio);
if (dosolock) mtx_enter(&so->so_rcv.sb_mtx);
solock_shared(so);
sb_mtx_lock(&so->so_rcv);
if (uio_error) if (uio_error)
uio->uio_resid = resid - len; uio->uio_resid = resid - len;
} else } else
@ -1210,10 +1181,8 @@ dontblock:
break; break;
SBLASTRECORDCHK(&so->so_rcv, "soreceive sbwait 2"); SBLASTRECORDCHK(&so->so_rcv, "soreceive sbwait 2");
SBLASTMBUFCHK(&so->so_rcv, "soreceive sbwait 2"); SBLASTMBUFCHK(&so->so_rcv, "soreceive sbwait 2");
if (sbwait(so, &so->so_rcv)) { if (sbwait(&so->so_rcv)) {
sb_mtx_unlock(&so->so_rcv); mtx_leave(&so->so_rcv.sb_mtx);
if (dosolock)
sounlock_shared(so);
sbunlock(&so->so_rcv); sbunlock(&so->so_rcv);
return (0); return (0);
} }
@ -1244,19 +1213,17 @@ dontblock:
SBLASTRECORDCHK(&so->so_rcv, "soreceive 4"); SBLASTRECORDCHK(&so->so_rcv, "soreceive 4");
SBLASTMBUFCHK(&so->so_rcv, "soreceive 4"); SBLASTMBUFCHK(&so->so_rcv, "soreceive 4");
if (pr->pr_flags & PR_WANTRCVD) { if (pr->pr_flags & PR_WANTRCVD) {
sb_mtx_unlock(&so->so_rcv); mtx_leave(&so->so_rcv.sb_mtx);
if (!dosolock)
solock_shared(so); solock_shared(so);
pru_rcvd(so); pru_rcvd(so);
if (!dosolock)
sounlock_shared(so); sounlock_shared(so);
sb_mtx_lock(&so->so_rcv); mtx_enter(&so->so_rcv.sb_mtx);
} }
} }
if (orig_resid == uio->uio_resid && orig_resid && if (orig_resid == uio->uio_resid && orig_resid &&
(flags & MSG_EOR) == 0 && (flags & MSG_EOR) == 0 &&
(so->so_rcv.sb_state & SS_CANTRCVMORE) == 0) { (so->so_rcv.sb_state & SS_CANTRCVMORE) == 0) {
sb_mtx_unlock(&so->so_rcv); mtx_leave(&so->so_rcv.sb_mtx);
sbunlock(&so->so_rcv); sbunlock(&so->so_rcv);
goto restart; goto restart;
} }
@ -1267,9 +1234,7 @@ dontblock:
if (flagsp) if (flagsp)
*flagsp |= flags; *flagsp |= flags;
release: release:
sb_mtx_unlock(&so->so_rcv); mtx_leave(&so->so_rcv.sb_mtx);
if (dosolock)
sounlock_shared(so);
sbunlock(&so->so_rcv); sbunlock(&so->so_rcv);
return (error); return (error);
} }
@ -1937,19 +1902,16 @@ somove(struct socket *so, int wait)
void void
sorwakeup(struct socket *so) sorwakeup(struct socket *so)
{ {
if ((so->so_rcv.sb_flags & SB_MTXLOCK) == 0)
soassertlocked_readonly(so);
#ifdef SOCKET_SPLICE #ifdef SOCKET_SPLICE
if (so->so_proto->pr_flags & PR_SPLICE) { if (so->so_proto->pr_flags & PR_SPLICE) {
sb_mtx_lock(&so->so_rcv); mtx_enter(&so->so_rcv.sb_mtx);
if (so->so_rcv.sb_flags & SB_SPLICE) if (so->so_rcv.sb_flags & SB_SPLICE)
task_add(sosplice_taskq, &so->so_splicetask); task_add(sosplice_taskq, &so->so_splicetask);
if (isspliced(so)) { if (isspliced(so)) {
sb_mtx_unlock(&so->so_rcv); mtx_leave(&so->so_rcv.sb_mtx);
return; return;
} }
sb_mtx_unlock(&so->so_rcv); mtx_leave(&so->so_rcv.sb_mtx);
} }
#endif #endif
sowakeup(so, &so->so_rcv); sowakeup(so, &so->so_rcv);
@ -1960,20 +1922,17 @@ sorwakeup(struct socket *so)
void void
sowwakeup(struct socket *so) sowwakeup(struct socket *so)
{ {
if ((so->so_snd.sb_flags & SB_MTXLOCK) == 0)
soassertlocked_readonly(so);
#ifdef SOCKET_SPLICE #ifdef SOCKET_SPLICE
if (so->so_proto->pr_flags & PR_SPLICE) { if (so->so_proto->pr_flags & PR_SPLICE) {
sb_mtx_lock(&so->so_snd); mtx_enter(&so->so_snd.sb_mtx);
if (so->so_snd.sb_flags & SB_SPLICE) if (so->so_snd.sb_flags & SB_SPLICE)
task_add(sosplice_taskq, task_add(sosplice_taskq,
&so->so_sp->ssp_soback->so_splicetask); &so->so_sp->ssp_soback->so_splicetask);
if (issplicedback(so)) { if (issplicedback(so)) {
sb_mtx_unlock(&so->so_snd); mtx_leave(&so->so_snd.sb_mtx);
return; return;
} }
sb_mtx_unlock(&so->so_snd); mtx_leave(&so->so_snd.sb_mtx);
} }
#endif #endif
sowakeup(so, &so->so_snd); sowakeup(so, &so->so_snd);
@ -2059,10 +2018,7 @@ sosetopt(struct socket *so, int level, int optname, struct mbuf *m)
if ((long)cnt <= 0) if ((long)cnt <= 0)
cnt = 1; cnt = 1;
if (((sb->sb_flags & SB_MTXLOCK) == 0))
solock(so);
mtx_enter(&sb->sb_mtx); mtx_enter(&sb->sb_mtx);
switch (optname) { switch (optname) {
case SO_SNDBUF: case SO_SNDBUF:
case SO_RCVBUF: case SO_RCVBUF:
@ -2084,10 +2040,7 @@ sosetopt(struct socket *so, int level, int optname, struct mbuf *m)
sb->sb_hiwat : cnt; sb->sb_hiwat : cnt;
break; break;
} }
mtx_leave(&sb->sb_mtx); mtx_leave(&sb->sb_mtx);
if (((sb->sb_flags & SB_MTXLOCK) == 0))
sounlock(so);
break; break;
} }
@ -2403,13 +2356,10 @@ filt_soread(struct knote *kn, long hint)
int rv = 0; int rv = 0;
MUTEX_ASSERT_LOCKED(&so->so_rcv.sb_mtx); MUTEX_ASSERT_LOCKED(&so->so_rcv.sb_mtx);
if ((so->so_rcv.sb_flags & SB_MTXLOCK) == 0)
soassertlocked_readonly(so);
if (so->so_options & SO_ACCEPTCONN) { if (so->so_options & SO_ACCEPTCONN) {
short qlen = READ_ONCE(so->so_qlen); short qlen = READ_ONCE(so->so_qlen);
if (so->so_rcv.sb_flags & SB_MTXLOCK)
soassertlocked_readonly(so); soassertlocked_readonly(so);
kn->kn_data = qlen; kn->kn_data = qlen;
@ -2469,8 +2419,6 @@ filt_sowrite(struct knote *kn, long hint)
int rv; int rv;
MUTEX_ASSERT_LOCKED(&so->so_snd.sb_mtx); MUTEX_ASSERT_LOCKED(&so->so_snd.sb_mtx);
if ((so->so_snd.sb_flags & SB_MTXLOCK) == 0)
soassertlocked_readonly(so);
kn->kn_data = sbspace_locked(so, &so->so_snd); kn->kn_data = sbspace_locked(so, &so->so_snd);
if (so->so_snd.sb_state & SS_CANTSENDMORE) { if (so->so_snd.sb_state & SS_CANTSENDMORE) {
@ -2502,8 +2450,6 @@ filt_soexcept(struct knote *kn, long hint)
int rv = 0; int rv = 0;
MUTEX_ASSERT_LOCKED(&so->so_rcv.sb_mtx); MUTEX_ASSERT_LOCKED(&so->so_rcv.sb_mtx);
if ((so->so_rcv.sb_flags & SB_MTXLOCK) == 0)
soassertlocked_readonly(so);
#ifdef SOCKET_SPLICE #ifdef SOCKET_SPLICE
if (isspliced(so)) { if (isspliced(so)) {

View file

@ -1,4 +1,4 @@
/* $OpenBSD: uipc_socket2.c,v 1.167 2025/01/20 16:34:48 bluhm Exp $ */ /* $OpenBSD: uipc_socket2.c,v 1.168 2025/01/22 15:05:49 mvs Exp $ */
/* $NetBSD: uipc_socket2.c,v 1.11 1996/02/04 02:17:55 christos Exp $ */ /* $NetBSD: uipc_socket2.c,v 1.11 1996/02/04 02:17:55 christos Exp $ */
/* /*
@ -316,9 +316,6 @@ socantsendmore(struct socket *so)
void void
socantrcvmore(struct socket *so) socantrcvmore(struct socket *so)
{ {
if ((so->so_rcv.sb_flags & SB_MTXLOCK) == 0)
soassertlocked(so);
mtx_enter(&so->so_rcv.sb_mtx); mtx_enter(&so->so_rcv.sb_mtx);
so->so_rcv.sb_state |= SS_CANTRCVMORE; so->so_rcv.sb_state |= SS_CANTRCVMORE;
mtx_leave(&so->so_rcv.sb_mtx); mtx_leave(&so->so_rcv.sb_mtx);
@ -482,25 +479,20 @@ sosleep_nsec(struct socket *so, void *ident, int prio, const char *wmesg,
} }
void void
sbmtxassertlocked(struct socket *so, struct sockbuf *sb) sbmtxassertlocked(struct sockbuf *sb)
{ {
if (sb->sb_flags & SB_MTXLOCK) {
if (splassert_ctl > 0 && mtx_owned(&sb->sb_mtx) == 0) if (splassert_ctl > 0 && mtx_owned(&sb->sb_mtx) == 0)
splassert_fail(0, RW_WRITE, __func__); splassert_fail(0, RW_WRITE, __func__);
} else
soassertlocked(so);
} }
/* /*
* Wait for data to arrive at/drain from a socket buffer. * Wait for data to arrive at/drain from a socket buffer.
*/ */
int int
sbwait(struct socket *so, struct sockbuf *sb) sbwait(struct sockbuf *sb)
{ {
uint64_t timeo_nsecs;
int prio = (sb->sb_flags & SB_NOINTR) ? PSOCK : PSOCK | PCATCH; int prio = (sb->sb_flags & SB_NOINTR) ? PSOCK : PSOCK | PCATCH;
if (sb->sb_flags & SB_MTXLOCK) {
MUTEX_ASSERT_LOCKED(&sb->sb_mtx); MUTEX_ASSERT_LOCKED(&sb->sb_mtx);
sb->sb_flags |= SB_WAIT; sb->sb_flags |= SB_WAIT;
@ -508,16 +500,6 @@ sbwait(struct socket *so, struct sockbuf *sb)
sb->sb_timeo_nsecs); sb->sb_timeo_nsecs);
} }
soassertlocked(so);
mtx_enter(&sb->sb_mtx);
timeo_nsecs = sb->sb_timeo_nsecs;
sb->sb_flags |= SB_WAIT;
mtx_leave(&sb->sb_mtx);
return sosleep_nsec(so, &sb->sb_cc, prio, "netio", timeo_nsecs);
}
int int
sblock(struct sockbuf *sb, int flags) sblock(struct sockbuf *sb, int flags)
{ {
@ -640,7 +622,7 @@ bad:
int int
sbreserve(struct socket *so, struct sockbuf *sb, u_long cc) sbreserve(struct socket *so, struct sockbuf *sb, u_long cc)
{ {
sbmtxassertlocked(so, sb); sbmtxassertlocked(sb);
if (cc == 0 || cc > sb_max) if (cc == 0 || cc > sb_max)
return (1); return (1);
@ -787,7 +769,7 @@ sbappend(struct socket *so, struct sockbuf *sb, struct mbuf *m)
if (m == NULL) if (m == NULL)
return; return;
sbmtxassertlocked(so, sb); sbmtxassertlocked(sb);
SBLASTRECORDCHK(sb, "sbappend 1"); SBLASTRECORDCHK(sb, "sbappend 1");
if ((n = sb->sb_lastrecord) != NULL) { if ((n = sb->sb_lastrecord) != NULL) {
@ -821,7 +803,7 @@ sbappend(struct socket *so, struct sockbuf *sb, struct mbuf *m)
void void
sbappendstream(struct socket *so, struct sockbuf *sb, struct mbuf *m) sbappendstream(struct socket *so, struct sockbuf *sb, struct mbuf *m)
{ {
sbmtxassertlocked(so, sb); sbmtxassertlocked(sb);
KDASSERT(m->m_nextpkt == NULL); KDASSERT(m->m_nextpkt == NULL);
KASSERT(sb->sb_mb == sb->sb_lastrecord); KASSERT(sb->sb_mb == sb->sb_lastrecord);
@ -867,7 +849,7 @@ sbappendrecord(struct socket *so, struct sockbuf *sb, struct mbuf *m0)
{ {
struct mbuf *m; struct mbuf *m;
sbmtxassertlocked(so, sb); sbmtxassertlocked(sb);
if (m0 == NULL) if (m0 == NULL)
return; return;
@ -902,7 +884,7 @@ sbappendaddr(struct socket *so, struct sockbuf *sb, const struct sockaddr *asa,
struct mbuf *m, *n, *nlast; struct mbuf *m, *n, *nlast;
int space = asa->sa_len; int space = asa->sa_len;
sbmtxassertlocked(so, sb); sbmtxassertlocked(sb);
if (m0 && (m0->m_flags & M_PKTHDR) == 0) if (m0 && (m0->m_flags & M_PKTHDR) == 0)
panic("sbappendaddr"); panic("sbappendaddr");
@ -951,7 +933,7 @@ sbappendcontrol(struct socket *so, struct sockbuf *sb, struct mbuf *m0,
struct mbuf *m, *mlast, *n; struct mbuf *m, *mlast, *n;
int eor = 0, space = 0; int eor = 0, space = 0;
sbmtxassertlocked(so, sb); sbmtxassertlocked(sb);
if (control == NULL) if (control == NULL)
panic("sbappendcontrol"); panic("sbappendcontrol");
@ -1078,7 +1060,7 @@ sbdrop(struct socket *so, struct sockbuf *sb, int len)
struct mbuf *m, *mn; struct mbuf *m, *mn;
struct mbuf *next; struct mbuf *next;
sbmtxassertlocked(so, sb); sbmtxassertlocked(sb);
next = (m = sb->sb_mb) ? m->m_nextpkt : NULL; next = (m = sb->sb_mb) ? m->m_nextpkt : NULL;
while (len > 0) { while (len > 0) {

View file

@ -1,4 +1,4 @@
/* $OpenBSD: if.c,v 1.722 2025/01/16 17:20:23 mvs Exp $ */ /* $OpenBSD: if.c,v 1.723 2025/01/21 17:40:57 mvs Exp $ */
/* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */ /* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */
/* /*
@ -2798,7 +2798,29 @@ if_getdata(struct ifnet *ifp, struct if_data *data)
{ {
unsigned int i; unsigned int i;
*data = ifp->if_data; data->ifi_type = ifp->if_type;
data->ifi_addrlen = ifp->if_addrlen;
data->ifi_hdrlen = ifp->if_hdrlen;
data->ifi_link_state = ifp->if_link_state;
data->ifi_mtu = ifp->if_mtu;
data->ifi_metric = ifp->if_metric;
data->ifi_baudrate = ifp->if_baudrate;
data->ifi_capabilities = ifp->if_capabilities;
data->ifi_rdomain = ifp->if_rdomain;
data->ifi_lastchange = ifp->if_lastchange;
data->ifi_ipackets = ifp->if_data_counters[ifc_ipackets];
data->ifi_ierrors = ifp->if_data_counters[ifc_ierrors];
data->ifi_opackets = ifp->if_data_counters[ifc_opackets];
data->ifi_oerrors = ifp->if_data_counters[ifc_oerrors];
data->ifi_collisions = ifp->if_data_counters[ifc_collisions];
data->ifi_ibytes = ifp->if_data_counters[ifc_ibytes];
data->ifi_obytes = ifp->if_data_counters[ifc_obytes];
data->ifi_imcasts = ifp->if_data_counters[ifc_imcasts];
data->ifi_omcasts = ifp->if_data_counters[ifc_omcasts];
data->ifi_iqdrops = ifp->if_data_counters[ifc_iqdrops];
data->ifi_oqdrops = ifp->if_data_counters[ifc_oqdrops];
data->ifi_noproto = ifp->if_data_counters[ifc_noproto];
if (ifp->if_counters != NULL) { if (ifp->if_counters != NULL) {
uint64_t counters[ifc_ncounters]; uint64_t counters[ifc_ncounters];

View file

@ -1,4 +1,4 @@
/* $OpenBSD: if_var.h,v 1.133 2024/10/12 23:18:10 jsg Exp $ */ /* $OpenBSD: if_var.h,v 1.134 2025/01/21 17:40:57 mvs Exp $ */
/* $NetBSD: if.h,v 1.23 1996/05/07 02:40:27 thorpej Exp $ */ /* $NetBSD: if.h,v 1.23 1996/05/07 02:40:27 thorpej Exp $ */
/* /*
@ -110,6 +110,23 @@ struct if_clone {
.ifc_destroy = destroy, \ .ifc_destroy = destroy, \
} }
enum if_counters {
ifc_ipackets, /* packets received on interface */
ifc_ierrors, /* input errors on interface */
ifc_opackets, /* packets sent on interface */
ifc_oerrors, /* output errors on interface */
ifc_collisions, /* collisions on csma interfaces */
ifc_ibytes, /* total number of octets received */
ifc_obytes, /* total number of octets sent */
ifc_imcasts, /* packets received via multicast */
ifc_omcasts, /* packets sent via multicast */
ifc_iqdrops, /* dropped on input, this interface */
ifc_oqdrops, /* dropped on output, this interface */
ifc_noproto, /* destined for unsupported protocol */
ifc_ncounters
};
/* /*
* Structure defining a queue for a network interface. * Structure defining a queue for a network interface.
* *
@ -147,7 +164,20 @@ struct ifnet { /* and the entries */
short if_timer; /* time 'til if_watchdog called */ short if_timer; /* time 'til if_watchdog called */
unsigned short if_flags; /* [N] up/down, broadcast, etc. */ unsigned short if_flags; /* [N] up/down, broadcast, etc. */
int if_xflags; /* [N] extra softnet flags */ int if_xflags; /* [N] extra softnet flags */
struct if_data if_data; /* stats and other data about if */
/* Stats and other data about if. Should be in sync with if_data. */
u_char if_type;
u_char if_addrlen;
u_char if_hdrlen;
u_char if_link_state;
uint32_t if_mtu;
uint32_t if_metric;
uint64_t if_baudrate;
uint32_t if_capabilities;
uint32_t if_rdomain;
struct timeval if_lastchange; /* [c] last op. state change */
uint64_t if_data_counters[ifc_ncounters];
struct cpumem *if_counters; /* per cpu stats */ struct cpumem *if_counters; /* per cpu stats */
uint32_t if_hardmtu; /* [d] maximum MTU device supports */ uint32_t if_hardmtu; /* [d] maximum MTU device supports */
char if_description[IFDESCRSIZE]; /* [c] interface description */ char if_description[IFDESCRSIZE]; /* [c] interface description */
@ -187,45 +217,19 @@ struct ifnet { /* and the entries */
struct nd_ifinfo *if_nd; /* [I] IPv6 Neighbor Discovery info */ struct nd_ifinfo *if_nd; /* [I] IPv6 Neighbor Discovery info */
}; };
#define if_mtu if_data.ifi_mtu
#define if_type if_data.ifi_type
#define if_addrlen if_data.ifi_addrlen
#define if_hdrlen if_data.ifi_hdrlen
#define if_metric if_data.ifi_metric
#define if_link_state if_data.ifi_link_state
#define if_baudrate if_data.ifi_baudrate
#define if_ipackets if_data.ifi_ipackets
#define if_ierrors if_data.ifi_ierrors
#define if_opackets if_data.ifi_opackets
#define if_oerrors if_data.ifi_oerrors
#define if_collisions if_data.ifi_collisions
#define if_ibytes if_data.ifi_ibytes
#define if_obytes if_data.ifi_obytes
#define if_imcasts if_data.ifi_imcasts
#define if_omcasts if_data.ifi_omcasts
#define if_iqdrops if_data.ifi_iqdrops
#define if_oqdrops if_data.ifi_oqdrops
#define if_noproto if_data.ifi_noproto
#define if_lastchange if_data.ifi_lastchange /* [c] last op. state change */
#define if_capabilities if_data.ifi_capabilities
#define if_rdomain if_data.ifi_rdomain
enum if_counters { #define if_ipackets if_data_counters[ifc_ipackets]
ifc_ipackets, /* packets received on interface */ #define if_ierrors if_data_counters[ifc_ierrors]
ifc_ierrors, /* input errors on interface */ #define if_opackets if_data_counters[ifc_opackets]
ifc_opackets, /* packets sent on interface */ #define if_oerrors if_data_counters[ifc_oerrors]
ifc_oerrors, /* output errors on interface */ #define if_collisions if_data_counters[ifc_collisions]
ifc_collisions, /* collisions on csma interfaces */ #define if_ibytes if_data_counters[ifc_ibytes]
ifc_ibytes, /* total number of octets received */ #define if_obytes if_data_counters[ifc_obytes]
ifc_obytes, /* total number of octets sent */ #define if_imcasts if_data_counters[ifc_imcasts]
ifc_imcasts, /* packets received via multicast */ #define if_omcasts if_data_counters[ifc_omcasts]
ifc_omcasts, /* packets sent via multicast */ #define if_iqdrops if_data_counters[ifc_iqdrops]
ifc_iqdrops, /* dropped on input, this interface */ #define if_oqdrops if_data_counters[ifc_oqdrops]
ifc_oqdrops, /* dropped on output, this interface */ #define if_noproto if_data_counters[ifc_noproto]
ifc_noproto, /* destined for unsupported protocol */
ifc_ncounters
};
/* /*
* The ifaddr structure contains information about one address * The ifaddr structure contains information about one address

View file

@ -1,4 +1,4 @@
/* $OpenBSD: tcp_subr.c,v 1.205 2025/01/16 11:59:20 bluhm Exp $ */ /* $OpenBSD: tcp_subr.c,v 1.206 2025/01/22 09:37:06 bluhm Exp $ */
/* $NetBSD: tcp_subr.c,v 1.22 1996/02/13 23:44:00 christos Exp $ */ /* $NetBSD: tcp_subr.c,v 1.22 1996/02/13 23:44:00 christos Exp $ */
/* /*
@ -331,11 +331,11 @@ tcp_respond(struct tcpcb *tp, caddr_t template, struct tcphdr *th0,
th = (struct tcphdr *)(ip6 + 1); th = (struct tcphdr *)(ip6 + 1);
tlen = sizeof(*ip6) + sizeof(*th); tlen = sizeof(*ip6) + sizeof(*th);
if (th0) { if (th0) {
bcopy(template, ip6, sizeof(*ip6)); memcpy(ip6, template, sizeof(*ip6));
bcopy(th0, th, sizeof(*th)); memcpy(th, th0, sizeof(*th));
xchg(ip6->ip6_dst, ip6->ip6_src, struct in6_addr); xchg(ip6->ip6_dst, ip6->ip6_src, struct in6_addr);
} else { } else {
bcopy(template, ip6, tlen); memcpy(ip6, template, tlen);
} }
break; break;
#endif /* INET6 */ #endif /* INET6 */
@ -344,11 +344,11 @@ tcp_respond(struct tcpcb *tp, caddr_t template, struct tcphdr *th0,
th = (struct tcphdr *)(ip + 1); th = (struct tcphdr *)(ip + 1);
tlen = sizeof(*ip) + sizeof(*th); tlen = sizeof(*ip) + sizeof(*th);
if (th0) { if (th0) {
bcopy(template, ip, sizeof(*ip)); memcpy(ip, template, sizeof(*ip));
bcopy(th0, th, sizeof(*th)); memcpy(th, th0, sizeof(*th));
xchg(ip->ip_dst.s_addr, ip->ip_src.s_addr, u_int32_t); xchg(ip->ip_dst.s_addr, ip->ip_src.s_addr, u_int32_t);
} else { } else {
bcopy(template, ip, tlen); memcpy(ip, template, tlen);
} }
break; break;
} }

View file

@ -1,4 +1,4 @@
/* $OpenBSD: socketvar.h,v 1.139 2025/01/16 16:35:01 bluhm Exp $ */ /* $OpenBSD: socketvar.h,v 1.140 2025/01/22 15:05:49 mvs Exp $ */
/* $NetBSD: socketvar.h,v 1.18 1996/02/09 18:25:38 christos Exp $ */ /* $NetBSD: socketvar.h,v 1.18 1996/02/09 18:25:38 christos Exp $ */
/*- /*-
@ -112,7 +112,6 @@ struct sockbuf {
#define SB_ASYNC 0x0002 /* ASYNC I/O, need signals */ #define SB_ASYNC 0x0002 /* ASYNC I/O, need signals */
#define SB_SPLICE 0x0004 /* buffer is splice source or drain */ #define SB_SPLICE 0x0004 /* buffer is splice source or drain */
#define SB_NOINTR 0x0008 /* operations not interruptible */ #define SB_NOINTR 0x0008 /* operations not interruptible */
#define SB_MTXLOCK 0x0010 /* sblock() doesn't need solock() */
/* /*
* Kernel structure per socket. * Kernel structure per socket.
@ -225,21 +224,7 @@ soref(struct socket *so)
#define isspliced(so) ((so)->so_sp && (so)->so_sp->ssp_socket) #define isspliced(so) ((so)->so_sp && (so)->so_sp->ssp_socket)
#define issplicedback(so) ((so)->so_sp && (so)->so_sp->ssp_soback) #define issplicedback(so) ((so)->so_sp && (so)->so_sp->ssp_soback)
static inline void void sbmtxassertlocked(struct sockbuf *);
sb_mtx_lock(struct sockbuf *sb)
{
if (sb->sb_flags & SB_MTXLOCK)
mtx_enter(&sb->sb_mtx);
}
static inline void
sb_mtx_unlock(struct sockbuf *sb)
{
if (sb->sb_flags & SB_MTXLOCK)
mtx_leave(&sb->sb_mtx);
}
void sbmtxassertlocked(struct socket *so, struct sockbuf *);
/* /*
* Do we need to notify the other side when I/O is possible? * Do we need to notify the other side when I/O is possible?
@ -249,8 +234,6 @@ sb_notify(struct socket *so, struct sockbuf *sb)
{ {
int rv; int rv;
soassertlocked(so);
mtx_enter(&sb->sb_mtx); mtx_enter(&sb->sb_mtx);
rv = ((sb->sb_flags & (SB_WAIT|SB_ASYNC|SB_SPLICE)) != 0 || rv = ((sb->sb_flags & (SB_WAIT|SB_ASYNC|SB_SPLICE)) != 0 ||
!klist_empty(&sb->sb_klist)); !klist_empty(&sb->sb_klist));
@ -269,10 +252,7 @@ sb_notify(struct socket *so, struct sockbuf *sb)
static inline long static inline long
sbspace_locked(struct socket *so, struct sockbuf *sb) sbspace_locked(struct socket *so, struct sockbuf *sb)
{ {
if (sb->sb_flags & SB_MTXLOCK) sbmtxassertlocked(sb);
sbmtxassertlocked(so, sb);
else
soassertlocked_readonly(so);
return lmin(sb->sb_hiwat - sb->sb_cc, sb->sb_mbmax - sb->sb_mbcnt); return lmin(sb->sb_hiwat - sb->sb_cc, sb->sb_mbmax - sb->sb_mbcnt);
} }
@ -282,9 +262,9 @@ sbspace(struct socket *so, struct sockbuf *sb)
{ {
long ret; long ret;
sb_mtx_lock(sb); mtx_enter(&sb->sb_mtx);
ret = sbspace_locked(so, sb); ret = sbspace_locked(so, sb);
sb_mtx_unlock(sb); mtx_leave(&sb->sb_mtx);
return ret; return ret;
} }
@ -411,7 +391,7 @@ void sbrelease(struct socket *, struct sockbuf *);
int sbcheckreserve(u_long, u_long); int sbcheckreserve(u_long, u_long);
int sbchecklowmem(void); int sbchecklowmem(void);
int sbreserve(struct socket *, struct sockbuf *, u_long); int sbreserve(struct socket *, struct sockbuf *, u_long);
int sbwait(struct socket *, struct sockbuf *); int sbwait(struct sockbuf *);
void soinit(void); void soinit(void);
void soabort(struct socket *); void soabort(struct socket *);
int soaccept(struct socket *, struct mbuf *); int soaccept(struct socket *, struct mbuf *);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: uvm_fault.c,v 1.160 2025/01/18 16:35:30 kettenis Exp $ */ /* $OpenBSD: uvm_fault.c,v 1.162 2025/01/22 10:52:09 mpi Exp $ */
/* $NetBSD: uvm_fault.c,v 1.51 2000/08/06 00:22:53 thorpej Exp $ */ /* $NetBSD: uvm_fault.c,v 1.51 2000/08/06 00:22:53 thorpej Exp $ */
/* /*
@ -321,16 +321,9 @@ uvmfault_anonget(struct uvm_faultinfo *ufi, struct vm_amap *amap,
* The last unlock must be an atomic unlock and wait * The last unlock must be an atomic unlock and wait
* on the owner of page. * on the owner of page.
*/ */
if (pg->uobject) { KASSERT(pg->uobject == NULL);
/* Owner of page is UVM object. */
uvmfault_unlockall(ufi, amap, NULL);
uvm_pagewait(pg, pg->uobject->vmobjlock,
"anonget1");
} else {
/* Owner of page is anon. */
uvmfault_unlockall(ufi, NULL, NULL); uvmfault_unlockall(ufi, NULL, NULL);
uvm_pagewait(pg, anon->an_lock, "anonget2"); uvm_pagewait(pg, anon->an_lock, "anonget");
}
} else { } else {
/* /*
* No page, therefore allocate one. * No page, therefore allocate one.
@ -468,7 +461,6 @@ uvmfault_anonget(struct uvm_faultinfo *ufi, struct vm_amap *amap,
*/ */
if (ufi != NULL && amap_lookup(&ufi->entry->aref, if (ufi != NULL && amap_lookup(&ufi->entry->aref,
ufi->orig_rvaddr - ufi->entry->start) != anon) { ufi->orig_rvaddr - ufi->entry->start) != anon) {
uvmfault_unlockall(ufi, amap, NULL); uvmfault_unlockall(ufi, amap, NULL);
return ERESTART; return ERESTART;
} }
@ -1004,8 +996,6 @@ uvm_fault_upper(struct uvm_faultinfo *ufi, struct uvm_faultctx *flt,
* if it fails (!OK) it will unlock everything for us. * if it fails (!OK) it will unlock everything for us.
* if it succeeds, locks are still valid and locked. * if it succeeds, locks are still valid and locked.
* also, if it is OK, then the anon's page is on the queues. * also, if it is OK, then the anon's page is on the queues.
* if the page is on loan from a uvm_object, then anonget will
* lock that object for us if it does not fail.
*/ */
error = uvmfault_anonget(ufi, amap, anon); error = uvmfault_anonget(ufi, amap, anon);
switch (error) { switch (error) {

View file

@ -1,4 +1,4 @@
/* $OpenBSD: session.c,v 1.507 2025/01/13 13:50:34 claudio Exp $ */ /* $OpenBSD: session.c,v 1.508 2025/01/22 12:19:47 claudio Exp $ */
/* /*
* Copyright (c) 2003, 2004, 2005 Henning Brauer <henning@openbsd.org> * Copyright (c) 2003, 2004, 2005 Henning Brauer <henning@openbsd.org>
@ -2572,7 +2572,7 @@ int
parse_capabilities(struct peer *peer, struct ibuf *buf, uint32_t *as) parse_capabilities(struct peer *peer, struct ibuf *buf, uint32_t *as)
{ {
struct ibuf capabuf; struct ibuf capabuf;
uint16_t afi, nhafi, tmp16, gr_header; uint16_t afi, nhafi, gr_header;
uint8_t capa_code, capa_len; uint8_t capa_code, capa_len;
uint8_t safi, aid, role, flags; uint8_t safi, aid, role, flags;
@ -2616,6 +2616,7 @@ parse_capabilities(struct peer *peer, struct ibuf *buf, uint32_t *as)
break; break;
case CAPA_EXT_NEXTHOP: case CAPA_EXT_NEXTHOP:
while (ibuf_size(&capabuf) > 0) { while (ibuf_size(&capabuf) > 0) {
uint16_t tmp16;
if (ibuf_get_n16(&capabuf, &afi) == -1 || if (ibuf_get_n16(&capabuf, &afi) == -1 ||
ibuf_get_n16(&capabuf, &tmp16) == -1 || ibuf_get_n16(&capabuf, &tmp16) == -1 ||
ibuf_get_n16(&capabuf, &nhafi) == -1) { ibuf_get_n16(&capabuf, &nhafi) == -1) {
@ -2626,7 +2627,8 @@ parse_capabilities(struct peer *peer, struct ibuf *buf, uint32_t *as)
sizeof(peer->capa.peer.ext_nh)); sizeof(peer->capa.peer.ext_nh));
break; break;
} }
if (afi2aid(afi, tmp16, &aid) == -1 || safi = tmp16;
if (afi2aid(afi, safi, &aid) == -1 ||
!(aid == AID_INET || aid == AID_VPN_IPv4)) { !(aid == AID_INET || aid == AID_VPN_IPv4)) {
log_peer_warnx(&peer->conf, log_peer_warnx(&peer->conf,
"Received %s capability: " "Received %s capability: "

View file

@ -1,4 +1,4 @@
/* $OpenBSD: connection.c,v 1.22 2025/01/16 16:19:39 claudio Exp $ */ /* $OpenBSD: connection.c,v 1.24 2025/01/22 10:14:54 claudio Exp $ */
/* /*
* Copyright (c) 2009 Claudio Jeker <claudio@openbsd.org> * Copyright (c) 2009 Claudio Jeker <claudio@openbsd.org>
@ -66,10 +66,15 @@ conn_new(struct session *s, struct connection_config *cc)
c->cid = arc4random(); c->cid = arc4random();
c->config = *cc; c->config = *cc;
c->mine = initiator_conn_defaults; c->mine = initiator_conn_defaults;
if (s->config.HeaderDigest != 0)
c->mine.HeaderDigest = s->config.HeaderDigest; c->mine.HeaderDigest = s->config.HeaderDigest;
if (s->config.DataDigest != 0)
c->mine.DataDigest = s->config.DataDigest; c->mine.DataDigest = s->config.DataDigest;
c->his = iscsi_conn_defaults; c->his = iscsi_conn_defaults;
c->active = iscsi_conn_defaults;
c->sev.sess = s;
c->sev.conn = c;
evtimer_set(&c->sev.ev, session_fsm_callback, &c->sev);
TAILQ_INIT(&c->pdu_w); TAILQ_INIT(&c->pdu_w);
TAILQ_INIT(&c->tasks); TAILQ_INIT(&c->tasks);
@ -113,6 +118,7 @@ conn_free(struct connection *c)
pdu_readbuf_free(&c->prbuf); pdu_readbuf_free(&c->prbuf);
pdu_free_queue(&c->pdu_w); pdu_free_queue(&c->pdu_w);
event_del(&c->sev.ev);
event_del(&c->ev); event_del(&c->ev);
event_del(&c->wev); event_del(&c->wev);
if (c->fd != -1) if (c->fd != -1)
@ -262,7 +268,6 @@ do { \
(p)->key, (p)->value, err); \ (p)->key, (p)->value, err); \
errors++; \ errors++; \
} \ } \
log_debug("SET_NUM: %s = %llu", #v, (u_int64_t)(x)->his.v); \
} \ } \
} while (0) } while (0)
@ -275,7 +280,18 @@ do { \
(p)->key, (p)->value, err); \ (p)->key, (p)->value, err); \
errors++; \ errors++; \
} \ } \
log_debug("SET_BOOL: %s = %u", #v, (int)(x)->his.v); \ } \
} while (0)
#define SET_DIGEST(p, x, v) \
do { \
if (!strcmp((p)->key, #v)) { \
(x)->his.v = text_to_digest((p)->value, &err); \
if (err) { \
log_warnx("bad param %s=%s: %s", \
(p)->key, (p)->value, err); \
errors++; \
} \
} \ } \
} while (0) } while (0)
@ -304,6 +320,8 @@ log_debug("conn_parse_kvp: %s = %s", k->key, k->value);
SET_BOOL(k, s, DataSequenceInOrder); SET_BOOL(k, s, DataSequenceInOrder);
SET_NUM(k, s, ErrorRecoveryLevel, 0, 2); SET_NUM(k, s, ErrorRecoveryLevel, 0, 2);
SET_NUM(k, c, MaxRecvDataSegmentLength, 512, 16777215); SET_NUM(k, c, MaxRecvDataSegmentLength, 512, 16777215);
SET_DIGEST(k, c, HeaderDigest);
SET_DIGEST(k, c, DataDigest);
} }
if (errors) { if (errors) {
@ -315,6 +333,7 @@ log_debug("conn_parse_kvp: %s = %s", k->key, k->value);
#undef SET_NUM #undef SET_NUM
#undef SET_BOOL #undef SET_BOOL
#undef SET_DIGEST
int int
conn_gen_kvp(struct connection *c, struct kvp *kvp, size_t *nkvp) conn_gen_kvp(struct connection *c, struct kvp *kvp, size_t *nkvp)
@ -435,7 +454,7 @@ c_do_connect(struct connection *c, enum c_event ev)
if (c->fd == -1) { if (c->fd == -1) {
log_warnx("connect(%s), lost socket", log_warnx("connect(%s), lost socket",
log_sockaddr(&c->config.TargetAddr)); log_sockaddr(&c->config.TargetAddr));
session_fsm(c->session, SESS_EV_CONN_FAIL, c, 0); session_fsm(&c->sev, SESS_EV_CONN_FAIL, 0);
return CONN_FREE; return CONN_FREE;
} }
if (c->config.LocalAddr.ss_len != 0) { if (c->config.LocalAddr.ss_len != 0) {
@ -443,7 +462,7 @@ c_do_connect(struct connection *c, enum c_event ev)
c->config.LocalAddr.ss_len) == -1) { c->config.LocalAddr.ss_len) == -1) {
log_warn("bind(%s)", log_warn("bind(%s)",
log_sockaddr(&c->config.LocalAddr)); log_sockaddr(&c->config.LocalAddr));
session_fsm(c->session, SESS_EV_CONN_FAIL, c, 0); session_fsm(&c->sev, SESS_EV_CONN_FAIL, 0);
return CONN_FREE; return CONN_FREE;
} }
} }
@ -456,7 +475,7 @@ c_do_connect(struct connection *c, enum c_event ev)
} else { } else {
log_warn("connect(%s)", log_warn("connect(%s)",
log_sockaddr(&c->config.TargetAddr)); log_sockaddr(&c->config.TargetAddr));
session_fsm(c->session, SESS_EV_CONN_FAIL, c, 0); session_fsm(&c->sev, SESS_EV_CONN_FAIL, 0);
return CONN_FREE; return CONN_FREE;
} }
} }
@ -477,7 +496,7 @@ int
c_do_loggedin(struct connection *c, enum c_event ev) c_do_loggedin(struct connection *c, enum c_event ev)
{ {
iscsi_merge_conn_params(&c->active, &c->mine, &c->his); iscsi_merge_conn_params(&c->active, &c->mine, &c->his);
session_fsm(c->session, SESS_EV_CONN_LOGGED_IN, c, 0); session_fsm(&c->sev, SESS_EV_CONN_LOGGED_IN, 0);
return CONN_LOGGED_IN; return CONN_LOGGED_IN;
} }
@ -525,7 +544,7 @@ c_do_fail(struct connection *c, enum c_event ev)
taskq_cleanup(&c->tasks); taskq_cleanup(&c->tasks);
/* session will take care of cleaning up the mess */ /* session will take care of cleaning up the mess */
session_fsm(c->session, SESS_EV_CONN_FAIL, c, 0); session_fsm(&c->sev, SESS_EV_CONN_FAIL, 0);
if (ev == CONN_EV_FREE || c->state & CONN_NEVER_LOGGED_IN) if (ev == CONN_EV_FREE || c->state & CONN_NEVER_LOGGED_IN)
return CONN_FREE; return CONN_FREE;

View file

@ -1,4 +1,4 @@
/* $OpenBSD: initiator.c,v 1.16 2025/01/16 16:19:39 claudio Exp $ */ /* $OpenBSD: initiator.c,v 1.20 2025/01/22 16:06:36 claudio Exp $ */
/* /*
* Copyright (c) 2009 Claudio Jeker <claudio@openbsd.org> * Copyright (c) 2009 Claudio Jeker <claudio@openbsd.org>
@ -33,7 +33,7 @@
#include "iscsid.h" #include "iscsid.h"
#include "log.h" #include "log.h"
struct initiator *initiator; static struct initiator *initiator;
struct task_login { struct task_login {
struct task task; struct task task;
@ -58,11 +58,10 @@ void initiator_login_cb(struct connection *, void *, struct pdu *);
void initiator_discovery_cb(struct connection *, void *, struct pdu *); void initiator_discovery_cb(struct connection *, void *, struct pdu *);
void initiator_logout_cb(struct connection *, void *, struct pdu *); void initiator_logout_cb(struct connection *, void *, struct pdu *);
struct session_params initiator_sess_defaults; struct session_params initiator_sess_defaults;
struct connection_params initiator_conn_defaults; struct connection_params initiator_conn_defaults;
struct initiator * void
initiator_init(void) initiator_init(void)
{ {
if (!(initiator = calloc(1, sizeof(*initiator)))) if (!(initiator = calloc(1, sizeof(*initiator))))
@ -78,24 +77,34 @@ initiator_init(void)
initiator_conn_defaults = iscsi_conn_defaults; initiator_conn_defaults = iscsi_conn_defaults;
initiator_sess_defaults.MaxConnections = ISCSID_DEF_CONNS; initiator_sess_defaults.MaxConnections = ISCSID_DEF_CONNS;
initiator_conn_defaults.MaxRecvDataSegmentLength = 65536; initiator_conn_defaults.MaxRecvDataSegmentLength = 65536;
return initiator;
} }
void void
initiator_cleanup(struct initiator *i) initiator_cleanup(void)
{ {
struct session *s; struct session *s;
while ((s = TAILQ_FIRST(&i->sessions)) != NULL) { while ((s = TAILQ_FIRST(&initiator->sessions)) != NULL) {
TAILQ_REMOVE(&i->sessions, s, entry); TAILQ_REMOVE(&initiator->sessions, s, entry);
session_cleanup(s); session_cleanup(s);
} }
free(initiator); free(initiator);
} }
void void
initiator_shutdown(struct initiator *i) initiator_set_config(struct initiator_config *ic)
{
initiator->config = *ic;
}
struct initiator_config *
initiator_get_config(void)
{
return &initiator->config;
}
void
initiator_shutdown(void)
{ {
struct session *s; struct session *s;
@ -106,7 +115,7 @@ initiator_shutdown(struct initiator *i)
} }
int int
initiator_isdown(struct initiator *i) initiator_isdown(void)
{ {
struct session *s; struct session *s;
int inprogres = 0; int inprogres = 0;
@ -118,6 +127,49 @@ initiator_isdown(struct initiator *i)
return !inprogres; return !inprogres;
} }
struct session *
initiator_new_session(u_int8_t st)
{
struct session *s;
if (!(s = calloc(1, sizeof(*s))))
return NULL;
/* use the same qualifier unless there is a conflict */
s->isid_base = initiator->config.isid_base;
s->isid_qual = initiator->config.isid_qual;
s->cmdseqnum = arc4random();
s->itt = arc4random();
s->state = SESS_INIT;
s->sev.sess = s;
evtimer_set(&s->sev.ev, session_fsm_callback, &s->sev);
if (st == SESSION_TYPE_DISCOVERY)
s->target = 0;
else
s->target = initiator->target++;
TAILQ_INIT(&s->connections);
TAILQ_INIT(&s->tasks);
TAILQ_INSERT_HEAD(&initiator->sessions, s, entry);
return s;
}
struct session *
initiator_find_session(char *name)
{
struct session *s;
TAILQ_FOREACH(s, &initiator->sessions, entry) {
if (strcmp(s->config.SessionName, name) == 0)
return s;
}
return NULL;
}
struct session * struct session *
initiator_t2s(u_int target) initiator_t2s(u_int target)
{ {
@ -130,6 +182,12 @@ initiator_t2s(u_int target)
return NULL; return NULL;
} }
struct session_head *
initiator_get_sessions(void)
{
return &initiator->sessions;
}
void void
initiator_login(struct connection *c) initiator_login(struct connection *c)
{ {
@ -258,7 +316,7 @@ initiator_login_kvp(struct connection *c, u_int8_t stage)
switch (stage) { switch (stage) {
case ISCSI_LOGIN_STG_SECNEG: case ISCSI_LOGIN_STG_SECNEG:
if (!(kvp = calloc(4, sizeof(*kvp)))) if (!(kvp = calloc(5, sizeof(*kvp))))
return NULL; return NULL;
kvp[0].key = "AuthMethod"; kvp[0].key = "AuthMethod";
kvp[0].value = "None"; kvp[0].value = "None";
@ -269,8 +327,10 @@ initiator_login_kvp(struct connection *c, u_int8_t stage)
kvp[2].key = "SessionType"; kvp[2].key = "SessionType";
kvp[2].value = "Discovery"; kvp[2].value = "Discovery";
} else { } else {
kvp[2].key = "TargetName"; kvp[2].key = "SessionType";
kvp[2].value = c->session->config.TargetName; kvp[2].value = "Normal";
kvp[3].key = "TargetName";
kvp[3].value = c->session->config.TargetName;
} }
break; break;
case ISCSI_LOGIN_STG_OPNEG: case ISCSI_LOGIN_STG_OPNEG:
@ -512,10 +572,10 @@ initiator_logout_cb(struct connection *c, void *arg, struct pdu *p)
case ISCSI_LOGOUT_RESP_SUCCESS: case ISCSI_LOGOUT_RESP_SUCCESS:
if (tl->reason == ISCSI_LOGOUT_CLOSE_SESS) { if (tl->reason == ISCSI_LOGOUT_CLOSE_SESS) {
conn_fsm(c, CONN_EV_LOGGED_OUT); conn_fsm(c, CONN_EV_LOGGED_OUT);
session_fsm(c->session, SESS_EV_CLOSED, NULL, 0); session_fsm(&c->session->sev, SESS_EV_CLOSED, 0);
} else { } else {
conn_fsm(tl->c, CONN_EV_LOGGED_OUT); conn_fsm(tl->c, CONN_EV_LOGGED_OUT);
session_fsm(c->session, SESS_EV_CONN_CLOSED, tl->c, 0); session_fsm(&tl->c->sev, SESS_EV_CONN_CLOSED, 0);
} }
break; break;
case ISCSI_LOGOUT_RESP_UNKN_CID: case ISCSI_LOGOUT_RESP_UNKN_CID:

View file

@ -1,4 +1,4 @@
.\" $OpenBSD: iscsid.8,v 1.10 2015/07/27 17:28:39 sobrado Exp $ .\" $OpenBSD: iscsid.8,v 1.11 2025/01/21 12:26:47 claudio Exp $
.\" .\"
.\" Copyright (c) 2010 David Gwynne <dlg@openbsd.org> .\" Copyright (c) 2010 David Gwynne <dlg@openbsd.org>
.\" .\"
@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\" .\"
.Dd $Mdocdate: July 27 2015 $ .Dd $Mdocdate: January 21 2025 $
.Dt ISCSID 8 .Dt ISCSID 8
.Os .Os
.Sh NAME .Sh NAME
@ -74,26 +74,16 @@ socket used for communication with
.Xr iscsictl 8 .Xr iscsictl 8
.Sh STANDARDS .Sh STANDARDS
.Rs .Rs
.%A J. Satran
.%A K. Meth
.%A C. Sapuntzakis
.%A M. Chadalapaka
.%A E. Zeidner
.%D April 2004
.%R RFC 3720
.%T Internet Small Computer Systems Interface (iSCSI)
.Re
.Pp
.Rs
.%A M. Bakke
.%A J. Hafner
.%A J. Hufferd
.%A K. Voruganti
.%A M. Krueger
.%D April 2004 .%D April 2004
.%R RFC 3721 .%R RFC 3721
.%T Internet Small Computer Systems Interface (iSCSI) Naming and Discovery .%T Internet Small Computer Systems Interface (iSCSI) Naming and Discovery
.Re .Re
.Pp
.Rs
.%D April 2014
.%R RFC 7143
.%T Internet Small Computer System Interface (iSCSI) Protocol (Consolidated)
.Re
.Sh HISTORY .Sh HISTORY
The The
.Nm .Nm

View file

@ -1,4 +1,4 @@
/* $OpenBSD: iscsid.c,v 1.22 2021/04/16 14:37:06 claudio Exp $ */ /* $OpenBSD: iscsid.c,v 1.25 2025/01/22 16:06:36 claudio Exp $ */
/* /*
* Copyright (c) 2009 Claudio Jeker <claudio@openbsd.org> * Copyright (c) 2009 Claudio Jeker <claudio@openbsd.org>
@ -38,7 +38,6 @@ void main_sig_handler(int, short, void *);
__dead void usage(void); __dead void usage(void);
void shutdown_cb(int, short, void *); void shutdown_cb(int, short, void *);
extern struct initiator *initiator;
struct event exit_ev; struct event exit_ev;
int exit_rounds; int exit_rounds;
#define ISCSI_EXIT_WAIT 5 #define ISCSI_EXIT_WAIT 5
@ -54,11 +53,13 @@ const struct session_params iscsi_sess_defaults = {
.ImmediateData = 1, .ImmediateData = 1,
.DataPDUInOrder = 1, .DataPDUInOrder = 1,
.DataSequenceInOrder = 1, .DataSequenceInOrder = 1,
.ErrorRecoveryLevel = 0 .ErrorRecoveryLevel = 0,
}; };
const struct connection_params iscsi_conn_defaults = { const struct connection_params iscsi_conn_defaults = {
.MaxRecvDataSegmentLength = 8192 .MaxRecvDataSegmentLength = 8192,
.HeaderDigest = DIGEST_NONE,
.DataDigest = DIGEST_NONE,
}; };
int int
@ -146,13 +147,13 @@ main(int argc, char *argv[])
signal(SIGPIPE, SIG_IGN); signal(SIGPIPE, SIG_IGN);
control_event_init(); control_event_init();
initiator = initiator_init(); initiator_init();
event_dispatch(); event_dispatch();
/* do some cleanup on the way out */ /* do some cleanup on the way out */
control_cleanup(ctrlsock); control_cleanup(ctrlsock);
initiator_cleanup(initiator); initiator_cleanup();
log_info("exiting."); log_info("exiting.");
return 0; return 0;
} }
@ -162,7 +163,7 @@ shutdown_cb(int fd, short event, void *arg)
{ {
struct timeval tv; struct timeval tv;
if (exit_rounds++ >= ISCSI_EXIT_WAIT || initiator_isdown(initiator)) if (exit_rounds++ >= ISCSI_EXIT_WAIT || initiator_isdown())
event_loopexit(NULL); event_loopexit(NULL);
timerclear(&tv); timerclear(&tv);
@ -182,7 +183,7 @@ main_sig_handler(int sig, short event, void *arg)
case SIGTERM: case SIGTERM:
case SIGINT: case SIGINT:
case SIGHUP: case SIGHUP:
initiator_shutdown(initiator); initiator_shutdown();
evtimer_set(&exit_ev, shutdown_cb, NULL); evtimer_set(&exit_ev, shutdown_cb, NULL);
timerclear(&tv); timerclear(&tv);
if (evtimer_add(&exit_ev, &tv) == -1) if (evtimer_add(&exit_ev, &tv) == -1)
@ -209,6 +210,7 @@ iscsid_ctrl_dispatch(void *ch, struct pdu *pdu)
{ {
struct ctrlmsghdr *cmh; struct ctrlmsghdr *cmh;
struct initiator_config *ic; struct initiator_config *ic;
struct session_head *sh;
struct session_config *sc; struct session_config *sc;
struct session *s; struct session *s;
struct session_poll p = { 0 }; struct session_poll p = { 0 };
@ -226,7 +228,7 @@ iscsid_ctrl_dispatch(void *ch, struct pdu *pdu)
break; break;
} }
ic = pdu_getbuf(pdu, NULL, 1); ic = pdu_getbuf(pdu, NULL, 1);
memcpy(&initiator->config, ic, sizeof(initiator->config)); initiator_set_config(ic);
control_compose(ch, CTRL_SUCCESS, NULL, 0); control_compose(ch, CTRL_SUCCESS, NULL, 0);
break; break;
case CTRL_SESSION_CONFIG: case CTRL_SESSION_CONFIG:
@ -248,9 +250,9 @@ iscsid_ctrl_dispatch(void *ch, struct pdu *pdu)
else else
sc->InitiatorName = NULL; sc->InitiatorName = NULL;
s = session_find(initiator, sc->SessionName); s = initiator_find_session(sc->SessionName);
if (s == NULL) { if (s == NULL) {
s = session_new(initiator, sc->SessionType); s = initiator_new_session(sc->SessionType);
if (s == NULL) { if (s == NULL) {
control_compose(ch, CTRL_FAILURE, NULL, 0); control_compose(ch, CTRL_FAILURE, NULL, 0);
goto done; goto done;
@ -259,7 +261,7 @@ iscsid_ctrl_dispatch(void *ch, struct pdu *pdu)
session_config(s, sc); session_config(s, sc);
if (s->state == SESS_INIT) if (s->state == SESS_INIT)
session_fsm(s, SESS_EV_START, NULL, 0); session_fsm(&s->sev, SESS_EV_START, 0);
control_compose(ch, CTRL_SUCCESS, NULL, 0); control_compose(ch, CTRL_SUCCESS, NULL, 0);
break; break;
@ -278,10 +280,11 @@ iscsid_ctrl_dispatch(void *ch, struct pdu *pdu)
sizeof(struct vscsi_stats)); sizeof(struct vscsi_stats));
break; break;
case CTRL_SHOW_SUM: case CTRL_SHOW_SUM:
control_compose(ch, CTRL_INITIATOR_CONFIG, &initiator->config, ic = initiator_get_config();
sizeof(initiator->config)); control_compose(ch, CTRL_INITIATOR_CONFIG, ic, sizeof(*ic));
TAILQ_FOREACH(s, &initiator->sessions, entry) { sh = initiator_get_sessions();
TAILQ_FOREACH(s, sh, entry) {
struct ctrldata cdv[3]; struct ctrldata cdv[3];
bzero(cdv, sizeof(cdv)); bzero(cdv, sizeof(cdv));
@ -306,7 +309,8 @@ iscsid_ctrl_dispatch(void *ch, struct pdu *pdu)
control_compose(ch, CTRL_SUCCESS, NULL, 0); control_compose(ch, CTRL_SUCCESS, NULL, 0);
break; break;
case CTRL_SESS_POLL: case CTRL_SESS_POLL:
TAILQ_FOREACH(s, &initiator->sessions, entry) sh = initiator_get_sessions();
TAILQ_FOREACH(s, sh, entry)
poll_session(&p, s); poll_session(&p, s);
poll_finalize(&p); poll_finalize(&p);
control_compose(ch, CTRL_SESS_POLL, &p, sizeof(p)); control_compose(ch, CTRL_SESS_POLL, &p, sizeof(p));
@ -334,6 +338,8 @@ void
iscsi_merge_sess_params(struct session_params *res, iscsi_merge_sess_params(struct session_params *res,
struct session_params *mine, struct session_params *his) struct session_params *mine, struct session_params *his)
{ {
memset(res, 0, sizeof(*res));
MERGE_MIN(res, mine, his, MaxBurstLength); MERGE_MIN(res, mine, his, MaxBurstLength);
MERGE_MIN(res, mine, his, FirstBurstLength); MERGE_MIN(res, mine, his, FirstBurstLength);
MERGE_MAX(res, mine, his, DefaultTime2Wait); MERGE_MAX(res, mine, his, DefaultTime2Wait);
@ -353,8 +359,26 @@ void
iscsi_merge_conn_params(struct connection_params *res, iscsi_merge_conn_params(struct connection_params *res,
struct connection_params *mine, struct connection_params *his) struct connection_params *mine, struct connection_params *his)
{ {
int mask;
memset(res, 0, sizeof(*res));
res->MaxRecvDataSegmentLength = his->MaxRecvDataSegmentLength; res->MaxRecvDataSegmentLength = his->MaxRecvDataSegmentLength;
/* XXX HeaderDigest and DataDigest */
/* for digest select first bit that is set in both his and mine */
mask = mine->HeaderDigest & his->HeaderDigest;
mask = ffs(mask) - 1;
if (mask == -1)
res->HeaderDigest = 0;
else
res->HeaderDigest = 1 << mask;
mask = mine->DataDigest & his->DataDigest;
mask = ffs(mask) - 1;
if (mask == -1)
res->DataDigest = 0;
else
res->DataDigest = 1 << mask;
} }
#undef MERGE_MIN #undef MERGE_MIN

View file

@ -1,4 +1,4 @@
/* $OpenBSD: iscsid.h,v 1.20 2025/01/16 16:19:39 claudio Exp $ */ /* $OpenBSD: iscsid.h,v 1.23 2025/01/22 16:06:36 claudio Exp $ */
/* /*
* Copyright (c) 2009 Claudio Jeker <claudio@openbsd.org> * Copyright (c) 2009 Claudio Jeker <claudio@openbsd.org>
@ -181,6 +181,9 @@ struct session_config {
u_int8_t disabled; u_int8_t disabled;
}; };
#define DIGEST_NONE 0x1
#define DIGEST_CRC32C 0x2
#define SESSION_TYPE_NORMAL 0 #define SESSION_TYPE_NORMAL 0
#define SESSION_TYPE_DISCOVERY 1 #define SESSION_TYPE_DISCOVERY 1
@ -226,6 +229,7 @@ struct initiator {
}; };
struct sessev { struct sessev {
struct event ev;
struct session *sess; struct session *sess;
struct connection *conn; struct connection *conn;
enum s_event event; enum s_event event;
@ -233,13 +237,13 @@ struct sessev {
struct session { struct session {
TAILQ_ENTRY(session) entry; TAILQ_ENTRY(session) entry;
struct sessev sev;
struct connection_head connections; struct connection_head connections;
struct taskq tasks; struct taskq tasks;
struct session_config config; struct session_config config;
struct session_params mine; struct session_params mine;
struct session_params his; struct session_params his;
struct session_params active; struct session_params active;
struct initiator *initiator;
u_int32_t cmdseqnum; u_int32_t cmdseqnum;
u_int32_t itt; u_int32_t itt;
u_int32_t isid_base; /* only 24 bits */ u_int32_t isid_base; /* only 24 bits */
@ -264,6 +268,7 @@ struct session_poll {
struct connection { struct connection {
struct event ev; struct event ev;
struct event wev; struct event wev;
struct sessev sev;
TAILQ_ENTRY(connection) entry; TAILQ_ENTRY(connection) entry;
struct connection_params mine; struct connection_params mine;
struct connection_params his; struct connection_params his;
@ -323,11 +328,16 @@ void iscsi_merge_sess_params(struct session_params *,
void iscsi_merge_conn_params(struct connection_params *, void iscsi_merge_conn_params(struct connection_params *,
struct connection_params *, struct connection_params *); struct connection_params *, struct connection_params *);
struct initiator *initiator_init(void); void initiator_init(void);
void initiator_cleanup(struct initiator *); void initiator_cleanup(void);
void initiator_shutdown(struct initiator *); void initiator_set_config(struct initiator_config *);
int initiator_isdown(struct initiator *); struct initiator_config *initiator_get_config(void);
void initiator_shutdown(void);
int initiator_isdown(void);
struct session *initiator_new_session(u_int8_t);
struct session *initiator_find_session(char *);
struct session *initiator_t2s(u_int); struct session *initiator_t2s(u_int);
struct session_head *initiator_get_sessions(void);
void initiator_login(struct connection *); void initiator_login(struct connection *);
void initiator_discovery(struct session *); void initiator_discovery(struct session *);
void initiator_logout(struct session *, struct connection *, u_int8_t); void initiator_logout(struct session *, struct connection *, u_int8_t);
@ -341,16 +351,14 @@ void control_queue(void *, struct pdu *);
int control_compose(void *, u_int16_t, void *, size_t); int control_compose(void *, u_int16_t, void *, size_t);
int control_build(void *, u_int16_t, int, struct ctrldata *); int control_build(void *, u_int16_t, int, struct ctrldata *);
struct session *session_find(struct initiator *, char *);
struct session *session_new(struct initiator *, u_int8_t);
void session_cleanup(struct session *); void session_cleanup(struct session *);
int session_shutdown(struct session *); int session_shutdown(struct session *);
void session_config(struct session *, struct session_config *); void session_config(struct session *, struct session_config *);
void session_task_issue(struct session *, struct task *); void session_task_issue(struct session *, struct task *);
void session_logout_issue(struct session *, struct task *); void session_logout_issue(struct session *, struct task *);
void session_schedule(struct session *); void session_schedule(struct session *);
void session_fsm(struct session *, enum s_event, struct connection *, void session_fsm(struct sessev *, enum s_event, unsigned int);
unsigned int); void session_fsm_callback(int, short, void *);
void conn_new(struct session *, struct connection_config *); void conn_new(struct session *, struct connection_config *);
void conn_free(struct connection *); void conn_free(struct connection *);
@ -369,6 +377,7 @@ int text_to_pdu(struct kvp *, struct pdu *);
struct kvp *pdu_to_text(char *, size_t); struct kvp *pdu_to_text(char *, size_t);
u_int64_t text_to_num(const char *, u_int64_t, u_int64_t, const char **); u_int64_t text_to_num(const char *, u_int64_t, u_int64_t, const char **);
int text_to_bool(const char *, const char **); int text_to_bool(const char *, const char **);
int text_to_digest(const char *, const char **);
void pdu_free_queue(struct pduq *); void pdu_free_queue(struct pduq *);
ssize_t pdu_read(struct connection *); ssize_t pdu_read(struct connection *);
ssize_t pdu_write(struct connection *); ssize_t pdu_write(struct connection *);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: pdu.c,v 1.13 2021/04/12 10:03:33 claudio Exp $ */ /* $OpenBSD: pdu.c,v 1.14 2025/01/22 10:14:54 claudio Exp $ */
/* /*
* Copyright (c) 2009 Claudio Jeker <claudio@openbsd.org> * Copyright (c) 2009 Claudio Jeker <claudio@openbsd.org>
@ -193,23 +193,42 @@ text_to_bool(const char *buf, const char **errstrp)
{ {
int val = 0; int val = 0;
if (!strcmp(buf, "Yes")) { if (strcmp(buf, "Yes") == 0)
val = 1; val = 1;
errno = 0; else if (strcmp(buf, "No") != 0) {
} else if (!strcmp(buf, "No")) if (errstrp != NULL)
errno = 0;
else
errno = EINVAL;
if (errstrp != NULL) {
if (errno == 0)
*errstrp = NULL;
else
*errstrp = "invalid"; *errstrp = "invalid";
} }
return val; return val;
} }
int
text_to_digest(const char *buf, const char **errstrp)
{
int val = 0;
size_t len;
const char *p;
while (buf != NULL) {
p = strchr(buf, ',');
if (p == NULL)
len = strlen(buf);
else
len = p++ - buf;
if (strncmp(buf, "None", len) == 0)
val |= DIGEST_NONE;
else if (strncmp(buf, "CRC32C", len) == 0)
val |= DIGEST_CRC32C;
else {
if (errstrp != NULL)
*errstrp = "invalid";
return 0;
}
buf = p;
}
return val;
}
/* /*
* Internal functions to send/recv pdus. * Internal functions to send/recv pdus.

View file

@ -1,4 +1,4 @@
/* $OpenBSD: session.c,v 1.10 2025/01/16 16:17:32 claudio Exp $ */ /* $OpenBSD: session.c,v 1.13 2025/01/22 16:06:36 claudio Exp $ */
/* /*
* Copyright (c) 2011 Claudio Jeker <claudio@openbsd.org> * Copyright (c) 2011 Claudio Jeker <claudio@openbsd.org>
@ -35,7 +35,6 @@
#include "iscsid.h" #include "iscsid.h"
#include "log.h" #include "log.h"
void session_fsm_callback(int, short, void *);
int sess_do_start(struct session *, struct sessev *); int sess_do_start(struct session *, struct sessev *);
int sess_do_conn_loggedin(struct session *, struct sessev *); int sess_do_conn_loggedin(struct session *, struct sessev *);
int sess_do_conn_fail(struct session *, struct sessev *); int sess_do_conn_fail(struct session *, struct sessev *);
@ -47,46 +46,6 @@ int sess_do_reinstatement(struct session *, struct sessev *);
const char *sess_state(int); const char *sess_state(int);
const char *sess_event(enum s_event); const char *sess_event(enum s_event);
struct session *
session_find(struct initiator *i, char *name)
{
struct session *s;
TAILQ_FOREACH(s, &i->sessions, entry) {
if (strcmp(s->config.SessionName, name) == 0)
return s;
}
return NULL;
}
struct session *
session_new(struct initiator *i, u_int8_t st)
{
struct session *s;
if (!(s = calloc(1, sizeof(*s))))
return NULL;
/* use the same qualifier unless there is a conflict */
s->isid_base = i->config.isid_base;
s->isid_qual = i->config.isid_qual;
s->cmdseqnum = arc4random();
s->itt = arc4random();
s->initiator = i;
s->state = SESS_INIT;
if (st == SESSION_TYPE_DISCOVERY)
s->target = 0;
else
s->target = s->initiator->target++;
TAILQ_INSERT_HEAD(&i->sessions, s, entry);
TAILQ_INIT(&s->connections);
TAILQ_INIT(&s->tasks);
return s;
}
void void
session_cleanup(struct session *s) session_cleanup(struct session *s)
{ {
@ -204,25 +163,20 @@ session_schedule(struct session *s)
* The session FSM runs from a callback so that the connection FSM can finish. * The session FSM runs from a callback so that the connection FSM can finish.
*/ */
void void
session_fsm(struct session *s, enum s_event ev, struct connection *c, session_fsm(struct sessev *sev, enum s_event event, unsigned int timeout)
unsigned int timeout)
{ {
struct session *s = sev->sess;
struct timeval tv; struct timeval tv;
struct sessev *sev;
log_debug("session_fsm[%s]: %s ev %s timeout %d", log_debug("session_fsm[%s]: %s ev %s timeout %d",
s->config.SessionName, sess_state(s->state), s->config.SessionName, sess_state(s->state),
sess_event(ev), timeout); sess_event(event), timeout);
if ((sev = malloc(sizeof(*sev))) == NULL) sev->event = event;
fatal("session_fsm");
sev->conn = c;
sev->sess = s;
sev->event = ev;
timerclear(&tv); timerclear(&tv);
tv.tv_sec = timeout; tv.tv_sec = timeout;
if (event_once(-1, EV_TIMEOUT, session_fsm_callback, sev, &tv) == -1) if (evtimer_add(&sev->ev, &tv) == -1)
fatal("session_fsm"); fatal("session_fsm");
} }
@ -276,8 +230,6 @@ session_fsm_callback(int fd, short event, void *arg)
sess_state(s->state), sess_event(sev->event)); sess_state(s->state), sess_event(sev->event));
fatalx("bjork bjork bjork"); fatalx("bjork bjork bjork");
} }
free(sev);
log_debug("sess_fsm: done");
} }
int int
@ -286,7 +238,7 @@ sess_do_start(struct session *s, struct sessev *sev)
log_debug("new connection to %s", log_debug("new connection to %s",
log_sockaddr(&s->config.connection.TargetAddr)); log_sockaddr(&s->config.connection.TargetAddr));
/* initialize the session params */ /* initialize the session params, and reset the active state */
s->mine = initiator_sess_defaults; s->mine = initiator_sess_defaults;
s->his = iscsi_sess_defaults; s->his = iscsi_sess_defaults;
s->active = iscsi_sess_defaults; s->active = iscsi_sess_defaults;
@ -360,7 +312,7 @@ sess_do_conn_fail(struct session *s, struct sessev *sev)
state = SESS_LOGGED_IN; state = SESS_LOGGED_IN;
} }
session_fsm(s, SESS_EV_START, NULL, s->holdTimer); session_fsm(&s->sev, SESS_EV_START, s->holdTimer);
/* exponential back-off on constant failure */ /* exponential back-off on constant failure */
if (s->holdTimer < ISCSID_HOLD_TIME_MAX) if (s->holdTimer < ISCSID_HOLD_TIME_MAX)
s->holdTimer = s->holdTimer ? s->holdTimer * 2 : 1; s->holdTimer = s->holdTimer ? s->holdTimer * 2 : 1;