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)
* 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;
/* Table of variables obtained from 'ctx' */
BIGNUM *val[TABLE_SIZE];
BN_RECP_CTX recp;
BN_RECP_CTX *recp = NULL;
int ret = 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;
}
BN_RECP_CTX_init(&recp);
BN_CTX_start(ctx);
if ((aa = BN_CTX_get(ctx)) == NULL)
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)
goto err;
if (m->neg) {
/* ignore sign of 'm' */
if (!bn_copy(aa, m))
if ((recp = BN_RECP_CTX_create(m)) == NULL)
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))
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);
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;
j = 1 << (window - 1);
for (i = 1; i < j; i++) {
if (((val[i] = BN_CTX_get(ctx)) == NULL) ||
!BN_mod_mul_reciprocal(val[i], val[i - 1],
aa, &recp, ctx))
aa, recp, ctx))
goto err;
}
}
@ -1049,7 +1038,7 @@ BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
for (;;) {
if (BN_is_bit_set(q, wstart) == 0) {
if (!start)
if (!BN_mod_mul_reciprocal(r, r, r, &recp, ctx))
if (!BN_mod_sqr_reciprocal(r, r, recp, ctx))
goto err;
if (wstart == 0)
break;
@ -1078,12 +1067,12 @@ BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
/* add the 'bytes above' */
if (!start)
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;
}
/* 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;
/* 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:
BN_CTX_end(ctx);
BN_RECP_CTX_free(&recp);
BN_RECP_CTX_free(recp);
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)
* All rights reserved.
*
@ -138,16 +138,7 @@ struct bn_mont_ctx_st {
int flags;
};
/* Used for reciprocal division/mod functions
* 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;
typedef struct bn_recp_ctx_st BN_RECP_CTX;
/* Used for slow "generation" functions. */
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_RECP_CTX_init(BN_RECP_CTX *recp);
BN_RECP_CTX *BN_RECP_CTX_new(void);
BN_RECP_CTX *BN_RECP_CTX_create(const BIGNUM *N);
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_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, BN_RECP_CTX *recp,
BN_CTX *ctx);
int BN_div_reciprocal(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
BN_RECP_CTX *recp, BN_CTX *ctx);
int BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y,
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,
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)
* All rights reserved.
*
@ -62,26 +62,35 @@
#include "bn_local.h"
void
BN_RECP_CTX_init(BN_RECP_CTX *recp)
{
BN_init(&recp->N);
BN_init(&recp->Nr);
recp->num_bits = 0;
recp->flags = 0;
}
struct bn_recp_ctx_st {
BIGNUM *N; /* the divisor */
BIGNUM *Nr; /* the reciprocal 2^shift / N */
int num_bits; /* number of bits in N */
int shift;
} /* 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;
BN_RECP_CTX_init(ret);
ret->flags = BN_FLG_MALLOCED;
return ret;
}
void
@ -90,23 +99,9 @@ BN_RECP_CTX_free(BN_RECP_CTX *recp)
if (recp == NULL)
return;
BN_free(&recp->N);
BN_free(&recp->Nr);
if (recp->flags & BN_FLG_MALLOCED)
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;
BN_free(recp->N);
BN_free(recp->Nr);
freezero(recp, sizeof(*recp));
}
/* len is the expected size of the result
@ -138,7 +133,7 @@ err:
}
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)
{
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)
goto err;
if (BN_ucmp(m, &recp->N) < 0) {
if (BN_ucmp(m, recp->N) < 0) {
BN_zero(d);
if (!bn_copy(r, m)) {
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) */
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 */
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))
goto err;
if (!BN_mul(b, a, &recp->Nr, ctx))
if (!BN_mul(b, a, recp->Nr, ctx))
goto err;
if (!BN_rshift(d, b, i - recp->num_bits))
goto err;
d->neg = 0;
if (!BN_mul(b, &recp->N, d, ctx))
if (!BN_mul(b, recp->N, d, ctx))
goto err;
if (!BN_usub(r, m, b))
goto err;
@ -209,12 +204,12 @@ BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, BN_RECP_CTX *recp,
#if 1
j = 0;
while (BN_ucmp(r, &recp->N) >= 0) {
while (BN_ucmp(r, recp->N) >= 0) {
if (j++ > 2) {
BNerror(BN_R_BAD_RECIPROCAL);
goto err;
}
if (!BN_usub(r, r, &recp->N))
if (!BN_usub(r, r, recp->N))
goto err;
if (!BN_add_word(d, 1))
goto err;
@ -222,7 +217,7 @@ BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, BN_RECP_CTX *recp,
#endif
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;
@ -231,32 +226,23 @@ err:
return ret;
}
/* Compute r = (x * y) % m. */
int
BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y,
BN_RECP_CTX *recp, BN_CTX *ctx)
{
int ret = 0;
BIGNUM *a;
const BIGNUM *ca;
if (!BN_mul(r, x, y, ctx))
return 0;
BN_CTX_start(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;
return BN_div_reciprocal(NULL, r, r, recp, ctx);
}
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:
BN_CTX_end(ctx);
return ret;
return BN_div_reciprocal(NULL, r, r, recp, ctx);
}

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.
*

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.
*/
@ -667,6 +667,7 @@ EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx_in)
{
BN_CTX *ctx;
EC_POINT *point = NULL;
const EC_POINT *generator;
const BIGNUM *order;
int ret = 0;
@ -680,11 +681,11 @@ EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx_in)
goto err;
}
if (group->generator == NULL) {
if ((generator = EC_GROUP_get0_generator(group)) == NULL) {
ECerror(EC_R_UNDEFINED_GENERATOR);
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);
goto err;
}
@ -1346,8 +1347,7 @@ EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
if (ctx == NULL)
goto err;
if (group->meth->mul_generator_ct == NULL ||
group->meth->mul_single_ct == NULL ||
if (group->meth->mul_single_ct == NULL ||
group->meth->mul_double_nonct == NULL) {
ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
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
* 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) {
/*
* 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.
*/
@ -105,8 +105,6 @@ struct ec_method_st {
int (*dbl)(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, 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,
const BIGNUM *scalar, const EC_POINT *point, BN_CTX *);
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>
* 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);
if ((s = EC_POINT_new(group)) == NULL)
if ((s = EC_POINT_dup(point, group)) == NULL)
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);
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_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
ec_mul_single_ct(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
const EC_POINT *point, BN_CTX *ctx)
@ -1317,7 +1302,6 @@ static const EC_METHOD ec_GFp_simple_method = {
.add = ec_add,
.dbl = ec_dbl,
.invert = ec_invert,
.mul_generator_ct = ec_mul_generator_ct,
.mul_single_ct = ec_mul_single_ct,
.mul_double_nonct = ec_mul_double_nonct,
.field_mul = ec_simple_field_mul,
@ -1343,7 +1327,6 @@ static const EC_METHOD ec_GFp_mont_method = {
.add = ec_add,
.dbl = ec_dbl,
.invert = ec_invert,
.mul_generator_ct = ec_mul_generator_ct,
.mul_single_ct = ec_mul_single_ct,
.mul_double_nonct = ec_mul_double_nonct,
.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
*
@ -20,6 +20,8 @@
#ifndef OPENSSL_NO_SM4
#include <openssl/sm4.h>
#include "crypto_internal.h"
struct sm4_key {
uint32_t rk[SM4_KEY_SCHEDULE];
};
@ -98,30 +100,6 @@ static const uint32_t SM4_SBOX_T[256] = {
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
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 |= SM4_S[(uint8_t)X];
/*
* L linear transform
*/
return t ^ rotl(t, 2) ^ rotl(t, 10) ^ rotl(t, 18) ^ rotl(t, 24);
/* 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);
}
static inline uint32_t
SM4_T(uint32_t X)
{
return SM4_SBOX_T[(uint8_t)(X >> 24)] ^
rotl(SM4_SBOX_T[(uint8_t)(X >> 16)], 24) ^
rotl(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 >> 16)], 24) ^
crypto_rol_u32(SM4_SBOX_T[(uint8_t)(X >> 8)], 16) ^
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,
};
/*
* Constant Key
* SM4 Constant Key
*/
static const uint32_t CK[32] = {
static const uint32_t SM4_CK[32] = {
0x00070E15, 0x1C232A31, 0x383F464D, 0x545B6269,
0x70777E85, 0x8C939AA1, 0xA8AFB6BD, 0xC4CBD2D9,
0xE0E7EEF5, 0xFC030A11, 0x181F262D, 0x343B4249,
@ -173,26 +145,30 @@ SM4_set_key(const uint8_t *key, SM4_KEY *k)
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];
int i;
K[0] = load_u32_be(key, 0) ^ FK[0];
K[1] = load_u32_be(key, 1) ^ FK[1];
K[2] = load_u32_be(key, 2) ^ FK[2];
K[3] = load_u32_be(key, 3) ^ FK[3];
K[0] = crypto_load_be32toh(&key[0 * 4]) ^ SM4_FK[0];
K[1] = crypto_load_be32toh(&key[1 * 4]) ^ SM4_FK[1];
K[2] = crypto_load_be32toh(&key[2 * 4]) ^ SM4_FK[2];
K[3] = crypto_load_be32toh(&key[3 * 4]) ^ SM4_FK[3];
for (i = 0; i < SM4_KEY_SCHEDULE; i++) {
uint32_t X;
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 >> 16)]) << 16;
t |= ((uint32_t)SM4_S[(uint8_t)(X >> 8)]) << 8;
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;
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);
#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
SM4_encrypt(const uint8_t *in, uint8_t *out, const SM4_KEY *k)
{
struct sm4_key *ks = (struct sm4_key *)k;
uint32_t B0 = load_u32_be(in, 0);
uint32_t B1 = load_u32_be(in, 1);
uint32_t B2 = load_u32_be(in, 2);
uint32_t B3 = load_u32_be(in, 3);
uint32_t B0, B1, B2, B3;
B0 = crypto_load_be32toh(&in[0 * 4]);
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
* protection from cache based side channels.
*/
SM4_ROUNDS( 0, 1, 2, 3, SM4_T_slow);
SM4_ROUNDS( 4, 5, 6, 7, SM4_T);
SM4_ROUNDS( 8, 9, 10, 11, SM4_T);
SM4_ROUNDS(12, 13, 14, 15, SM4_T);
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);
B0 ^= SM4_T_slow(B1 ^ B2 ^ B3 ^ ks->rk[0]);
B1 ^= SM4_T_slow(B0 ^ B2 ^ B3 ^ ks->rk[1]);
B2 ^= SM4_T_slow(B0 ^ B1 ^ B3 ^ ks->rk[2]);
B3 ^= SM4_T_slow(B0 ^ B1 ^ B2 ^ ks->rk[3]);
store_u32_be(B3, out);
store_u32_be(B2, out + 4);
store_u32_be(B1, out + 8);
store_u32_be(B0, out + 12);
B0 ^= SM4_T(B1 ^ B2 ^ B3 ^ ks->rk[4]);
B1 ^= SM4_T(B0 ^ B2 ^ B3 ^ ks->rk[5]);
B2 ^= SM4_T(B0 ^ B1 ^ B3 ^ ks->rk[6]);
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);
@ -242,24 +243,61 @@ void
SM4_decrypt(const uint8_t *in, uint8_t *out, const SM4_KEY *k)
{
struct sm4_key *ks = (struct sm4_key *)k;
uint32_t B0 = load_u32_be(in, 0);
uint32_t B1 = load_u32_be(in, 1);
uint32_t B2 = load_u32_be(in, 2);
uint32_t B3 = load_u32_be(in, 3);
uint32_t B0, B1, B2, B3;
SM4_ROUNDS(31, 30, 29, 28, SM4_T_slow);
SM4_ROUNDS(27, 26, 25, 24, SM4_T);
SM4_ROUNDS(23, 22, 21, 20, SM4_T);
SM4_ROUNDS(19, 18, 17, 16, SM4_T);
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);
B0 = crypto_load_be32toh(&in[0 * 4]);
B1 = crypto_load_be32toh(&in[1 * 4]);
B2 = crypto_load_be32toh(&in[2 * 4]);
B3 = crypto_load_be32toh(&in[3 * 4]);
store_u32_be(B3, out);
store_u32_be(B2, out + 4);
store_u32_be(B1, out + 8);
store_u32_be(B0, out + 12);
/*
* Uses byte-wise sbox in the first and last rounds to provide some
* protection from cache based side channels.
*/
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);

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)
* All rights reserved.
*
@ -224,7 +224,7 @@ main(int argc, char *argv[])
goto err;
(void)BIO_flush(out);
message(out, "BN_div_recp");
message(out, "BN_div_reciprocal");
if (!test_div_recp(out, ctx))
goto err;
(void)BIO_flush(out);
@ -581,9 +581,6 @@ test_div_recp(BIO *bp, BN_CTX *ctx)
if ((e = BN_CTX_get(ctx)) == NULL)
goto err;
if ((recp = BN_RECP_CTX_new()) == NULL)
goto err;
for (i = 0; i < num0 + num1; i++) {
if (i < num1) {
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));
} else
CHECK_GOTO(BN_bntest_rand(b, 50 + 3 * (i - num1), 0, 0));
BN_set_negative(a, rand_neg());
BN_set_negative(b, rand_neg());
CHECK_GOTO(BN_RECP_CTX_set(recp, b, ctx));
CHECK_GOTO(BN_div_recp(d, c, a, recp, ctx));
BN_RECP_CTX_free(recp);
CHECK_GOTO(recp = BN_RECP_CTX_create(b));
CHECK_GOTO(BN_div_reciprocal(d, c, a, recp, ctx));
if (bp != NULL) {
if (!results) {
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
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.
*/
@ -88,27 +88,24 @@
exit(1); \
} 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 */
static void
group_order_tests(EC_GROUP *group)
group_order_tests(EC_GROUP *group, BN_CTX *ctx)
{
BIGNUM *n1, *n2, *order;
EC_POINT *P = 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;
if ((n1 = BN_new()) == NULL)
BN_CTX_start(ctx);
if ((n1 = BN_CTX_get(ctx)) == NULL)
ABORT;
if ((n2 = BN_new()) == NULL)
if ((n2 = BN_CTX_get(ctx)) == NULL)
ABORT;
if ((order = BN_new()) == NULL)
if ((order = BN_CTX_get(ctx)) == NULL)
ABORT;
fprintf(stdout, "verify group order ...");
fflush(stdout);
@ -128,8 +125,7 @@ group_order_tests(EC_GROUP *group)
ABORT;
fprintf(stdout, " ok\n");
fprintf(stdout, "long/negative scalar tests ... ");
/* XXX - switch back to BN_one() after next bump. */
if (!BN_set_word(n1, 1))
if (!BN_one(n1))
ABORT;
/* n1 = 1 - order */
if (!BN_sub(n1, n1, order))
@ -155,10 +151,7 @@ group_order_tests(EC_GROUP *group)
fprintf(stdout, "ok\n");
EC_POINT_free(P);
EC_POINT_free(Q);
BN_free(n1);
BN_free(n2);
BN_free(order);
BN_CTX_free(ctx);
BN_CTX_end(ctx);
}
static void
@ -191,20 +184,13 @@ prime_field_tests(void)
if (!BN_hex2bn(&b, "1"))
ABORT;
group = EC_GROUP_new(EC_GFp_mont_method()); /* applications should use EC_GROUP_new_curve_GFp
* so that the library gets to choose the EC_METHOD */
if (!group)
ABORT;
if (!EC_GROUP_set_curve(group, p, a, b, ctx))
if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL)
ABORT;
{
EC_GROUP *tmp;
tmp = EC_GROUP_new(EC_GROUP_method_of(group));
if (!tmp)
ABORT;
if (!EC_GROUP_copy(tmp, group))
if ((tmp = EC_GROUP_dup(group)) == NULL)
ABORT;
EC_GROUP_free(group);
group = tmp;
@ -263,11 +249,9 @@ prime_field_tests(void)
}
fprintf(stdout, "A cyclic subgroup:\n");
k = 100;
k = 0;
do {
if (k-- == 0)
ABORT;
fprintf(stderr, " %d - ", k);
if (EC_POINT_is_at_infinity(group, P))
fprintf(stdout, "point at infinity\n");
else {
@ -285,8 +269,15 @@ prime_field_tests(void)
ABORT;
if (!EC_POINT_add(group, P, P, Q, ctx))
ABORT;
if (k++ > 99)
ABORT;
} 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))
ABORT;
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))
ABORT;
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);
if (len == 0)
@ -310,7 +302,8 @@ prime_field_tests(void)
if (0 != EC_POINT_cmp(group, P, Q, ctx))
ABORT;
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);
if (len == 0)
@ -381,13 +374,10 @@ prime_field_tests(void)
ABORT;
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;
if (!EC_GROUP_copy(P_160, group))
ABORT;
/* Curve P-192 (FIPS PUB 186-2, App. 6) */
@ -431,13 +421,10 @@ prime_field_tests(void)
ABORT;
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;
if (!EC_GROUP_copy(P_192, group))
ABORT;
/* Curve P-224 (FIPS PUB 186-2, App. 6) */
@ -481,13 +468,10 @@ prime_field_tests(void)
ABORT;
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;
if (!EC_GROUP_copy(P_224, group))
ABORT;
/* Curve P-256 (FIPS PUB 186-2, App. 6) */
@ -531,13 +515,10 @@ prime_field_tests(void)
ABORT;
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;
if (!EC_GROUP_copy(P_256, group))
ABORT;
/* Curve P-384 (FIPS PUB 186-2, App. 6) */
@ -581,13 +562,10 @@ prime_field_tests(void)
ABORT;
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;
if (!EC_GROUP_copy(P_384, group))
ABORT;
/* Curve P-521 (FIPS PUB 186-2, App. 6) */
@ -637,13 +615,10 @@ prime_field_tests(void)
ABORT;
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;
if (!EC_GROUP_copy(P_521, group))
ABORT;
/* more tests using the last curve */
fprintf(stdout, "infinity tests ...");
@ -683,19 +658,12 @@ prime_field_tests(void)
BN_free(y);
BN_free(z);
if (P_160)
EC_GROUP_free(P_160);
if (P_192)
EC_GROUP_free(P_192);
if (P_224)
EC_GROUP_free(P_224);
if (P_256)
EC_GROUP_free(P_256);
if (P_384)
EC_GROUP_free(P_384);
if (P_521)
EC_GROUP_free(P_521);
}
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>
@ -29,6 +29,6 @@ LDADD+=-laa
LDFLAGS=-L$(AA_OBJDIR) -L$(AB_OBJDIR)
LDFLAGS+= -Wl,-rpath,$(AA_OBJDIR) -Wl,-rpath,$(AB_OBJDIR)
NOMAN=
CC=c++
CC=${CXX}
.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>
@ -29,6 +29,6 @@ LDADD+=-lab
LDFLAGS=-L$(AA_OBJDIR) -L$(AB_OBJDIR)
LDFLAGS+= -Wl,-rpath,$(AA_OBJDIR) -Wl,-rpath,$(AB_OBJDIR)
NOMAN=
CC=c++
CC=${CXX}
.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>
@ -29,7 +29,7 @@ LDADD=
#LDFLAGS=-L$(AA_OBJDIR) -L$(AB_OBJDIR)
LDFLAGS+= -Wl,-rpath,$(AA_OBJDIR) -Wl,-rpath,$(AB_OBJDIR)
NOMAN=
CC=c++
CC=${CXX}
LD_LIBRARY_PATH=$(AA_OBJDIR):$(AB_OBJDIR)
.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>
@ -29,6 +29,6 @@ LDADD+=-lab
LDFLAGS=-L$(AA_OBJDIR) -L$(AB_OBJDIR)
LDFLAGS+= -Wl,-rpath,$(AA_OBJDIR) -Wl,-rpath,$(AB_OBJDIR)
NOMAN=
CC=c++
CC=${CXX}
.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>
@ -29,6 +29,6 @@ LDFLAGS=-L$(AA_OBJDIR) -L$(AC_OBJDIR)
LDFLAGS+= -Wl,-disable-new-dtags
LDFLAGS+= -Wl,-rpath,$(AA_OBJDIR) -Wl,-rpath,$(AC_OBJDIR)
NOMAN=
CC=c++
CC=${CXX}
.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>
@ -30,6 +30,6 @@ LDFLAGS=-L$(AA_OBJDIR) -L$(AC_OBJDIR)
# This intentionally leaves out AA_OBJDIR from -rpath
LDFLAGS+= -Wl,-rpath,$(AC_OBJDIR)
NOMAN=
CC=c++
CC=${CXX}
.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>
@ -18,6 +18,6 @@ LDADD+=-laa
LDFLAGS=-L$(AA_OBJDIR)
LDFLAGS+= -Wl,-rpath,$(AA_OBJDIR)
NOMAN=
CC=c++
CC=${CXX}
.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>
@ -50,7 +50,7 @@ LDFLAGS+= -Wl,-rpath,$(AC_OBJDIR)
LDFLAGS+= -Wl,-rpath,$(AD_OBJDIR)
LDFLAGS+= -Wl,-rpath,$(AE_OBJDIR)
NOMAN=
CC=c++
CC=${CXX}
run-regress-${PROG}: ${PROG}
[ "`./${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>
@ -50,7 +50,7 @@ LDFLAGS+= -Wl,-rpath,$(AC_OBJDIR)
LDFLAGS+= -Wl,-rpath,$(AD_OBJDIR)
LDFLAGS+= -Wl,-rpath,$(AE_OBJDIR)
NOMAN=
CC=c++
CC=${CXX}
run-regress-${PROG}: ${PROG}
[ "`./${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 $ */
/*
@ -392,7 +392,6 @@ armv7_setup(void)
| CPU_CONTROL_AFE;
cpuctrl = CPU_CONTROL_MMU_ENABLE
| CPU_CONTROL_AFLT_ENABLE
| CPU_CONTROL_DC_ENABLE
| CPU_CONTROL_BPRD_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 $ */
/*
@ -85,19 +85,61 @@
void filt_wseventdetach(struct knote *);
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 = {
.f_flags = FILTEROP_ISFD,
.f_flags = FILTEROP_ISFD | FILTEROP_MPSAFE,
.f_attach = NULL,
.f_detach = filt_wseventdetach,
.f_event = filt_wseventread,
.f_modify = filt_wseventmodify,
.f_process = filt_wseventprocess,
};
/*
* Initialize a wscons_event queue.
*/
int
wsevent_init(struct wseventvar *ev)
wsevent_init_flags(struct wseventvar *ev, int flags)
{
struct wscons_event *queue;
@ -112,6 +154,10 @@ wsevent_init(struct wseventvar *ev)
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_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));
ev->ws_q = NULL;
klist_invalidate(&ev->ws_sel.si_note);
klist_invalidate(&ev->ws_klist);
sigio_free(&ev->ws_sigio);
}
@ -147,8 +193,8 @@ wsevent_fini(struct wseventvar *ev)
int
wsevent_read(struct wseventvar *ev, struct uio *uio, int flags)
{
int s, error;
u_int cnt;
int error, wrap = 0;
u_int cnt, tcnt, get;
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))
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) {
if (flags & IO_NDELAY) {
splx(s);
mtx_leave(&ev->ws_mtx);
return (EWOULDBLOCK);
}
ev->ws_wanted = 1;
error = tsleep_nsec(ev, PWSEVENT | PCATCH,
error = msleep_nsec(ev, &ev->ws_mtx, PWSEVENT | PCATCH,
"wsevent_read", INFSLP);
if (error) {
splx(s);
mtx_leave(&ev->ws_mtx);
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) */
else
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)
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;
/*
* If we do not wrap to 0, used up all our space, or had an error,
* stop. Otherwise move from front of queue to put index, if there
* is anything there to move.
*/
if ((ev->ws_get = (ev->ws_get + cnt) % WSEVENT_QSIZE) != 0 ||
n == 0 || error || (cnt = ev->ws_put) == 0)
return (error);
if (cnt > n)
cnt = n;
error = uiomove((caddr_t)&ev->ws_q[0],
ev->ws_get = (get + cnt) % WSEVENT_QSIZE;
if (!(ev->ws_get != 0 || n == 0 || tcnt == 0)) {
wrap = 1;
if (tcnt > n)
tcnt = n;
ev->ws_get = tcnt;
}
mtx_leave(&ev->ws_mtx);
error = uiomove((caddr_t)&ev->ws_q[get],
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);
}
int
wsevent_kqfilter(struct wseventvar *ev, struct knote *kn)
{
struct klist *klist;
int s;
klist = &ev->ws_sel.si_note;
switch (kn->kn_filter) {
case EVFILT_READ:
kn->kn_fop = &wsevent_filtops;
@ -218,10 +273,7 @@ wsevent_kqfilter(struct wseventvar *ev, struct knote *kn)
}
kn->kn_hook = ev;
s = splwsevent();
klist_insert_locked(klist, kn);
splx(s);
klist_insert(&ev->ws_klist, kn);
return (0);
}
@ -230,12 +282,8 @@ void
filt_wseventdetach(struct knote *kn)
{
struct wseventvar *ev = kn->kn_hook;
struct klist *klist = &ev->ws_sel.si_note;
int s;
s = splwsevent();
klist_remove_locked(klist, kn);
splx(s);
klist_remove(&ev->ws_klist, kn);
}
int
@ -243,6 +291,10 @@ filt_wseventread(struct knote *kn, long hint)
{
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)
return (0);
@ -253,3 +305,38 @@ filt_wseventread(struct knote *kn, long hint)
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 $ */
/*
@ -71,8 +71,9 @@
* @(#)event_var.h 8.1 (Berkeley) 6/11/93
*/
#include <sys/selinfo.h>
#include <sys/event.h>
#include <sys/sigio.h>
#include <sys/signalvar.h>
/*
* 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.
*/
/*
* 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 */
#define WSEVENT_QSIZE 256 /* may need tuning; this uses 2k */
struct wseventvar {
u_int ws_get; /* get (read) index (modified
u_int ws_get; /* [m] get (read) index (modified
synchronously) */
volatile u_int ws_put; /* put (write) index (modified by
volatile u_int ws_put; /* [m] put (write) index (modified by
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 */
int ws_wanted; /* wake up on input ready */
int ws_async; /* send SIGIO on input ready */
struct wscons_event *ws_q; /* circular buffer (queue) of events */
int ws_wanted; /* [m] wake up on input ready */
int ws_async; /* [m] send SIGIO on input ready */
struct wscons_event *ws_q; /* [m] circular buffer (queue) of
events */
};
#define splwsevent() spltty()
#define WSEVENT_MPSAFE 0x0001
#define WSEVENT_WAKEUP(ev) { \
selwakeup(&(ev)->ws_sel); \
if ((ev)->ws_wanted) { \
(ev)->ws_wanted = 0; \
wakeup((caddr_t)(ev)); \
} \
if ((ev)->ws_async) \
pgsigio(&(ev)->ws_sigio, SIGIO, 0); \
static inline void
wsevent_wakeup(struct wseventvar *ev)
{
int dosigio = 0;
knote(&ev->ws_klist, 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 *);
int wsevent_read(struct wseventvar *, struct uio *, int);
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
* 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 $ */
/*
@ -625,7 +625,6 @@ wskbd_detach(struct device *self, int flags)
struct wskbd_softc *sc = (struct wskbd_softc *)self;
struct wseventvar *evar;
int maj, mn;
int s;
#if NWSMUX > 0
/* Tell parent mux we're leaving. */
@ -647,18 +646,19 @@ wskbd_detach(struct device *self, int flags)
evar = sc->sc_base.me_evp;
if (evar != NULL) {
s = spltty();
if (--sc->sc_refcnt >= 0) {
/* Wake everyone by generating a dummy event. */
mtx_enter(&evar->ws_mtx);
if (++evar->ws_put >= WSEVENT_QSIZE)
evar->ws_put = 0;
WSEVENT_WAKEUP(evar);
mtx_leave(&evar->ws_mtx);
wsevent_wakeup(evar);
/* Wait for processes to go away. */
if (tsleep_nsec(sc, PZERO, "wskdet", SEC_TO_NSEC(60)))
printf("wskbd_detach: %s didn't detach\n",
sc->sc_base.me_dv.dv_xname);
}
splx(s);
}
free(sc->sc_map, M_DEVBUF,
@ -763,6 +763,7 @@ wskbd_deliver_event(struct wskbd_softc *sc, u_int type, int value)
}
#endif
mtx_enter(&evar->ws_mtx);
put = evar->ws_put;
ev = &evar->ws_q[put];
put = (put + 1) % WSEVENT_QSIZE;
@ -775,7 +776,8 @@ wskbd_deliver_event(struct wskbd_softc *sc, u_int type, int value)
ev->value = value;
nanotime(&ev->time);
evar->ws_put = put;
WSEVENT_WAKEUP(evar);
mtx_leave(&evar->ws_mtx);
wsevent_wakeup(evar);
}
#ifdef WSDISPLAY_COMPAT_RAWKBD
@ -862,7 +864,7 @@ wskbdopen(dev_t dev, int flags, int mode, struct proc *p)
return (EBUSY);
evar = &sc->sc_base.me_evar;
if (wsevent_init(evar))
if (wsevent_init_flags(evar, WSEVENT_MPSAFE))
return (EBUSY);
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:
if (sc->sc_base.me_evp == NULL)
return (EINVAL);
mtx_enter(&sc->sc_base.me_evp->ws_mtx);
sc->sc_base.me_evp->ws_async = *(int *)data != 0;
mtx_leave(&sc->sc_base.me_evp->ws_mtx);
return (0);
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 $ */
/*
@ -208,7 +208,7 @@ wsmuxopen(dev_t dev, int flags, int mode, struct proc *p)
return (EBUSY);
evar = &sc->sc_base.me_evar;
if (wsevent_init(evar))
if (wsevent_init_flags(evar, WSEVENT_MPSAFE))
return (EBUSY);
#ifdef WSDISPLAY_COMPAT_RAWKBD
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 wsevsrc *me;
int error, ok;
int s, put, get, n;
int put, get, n;
struct wseventvar *evar;
struct wscons_event *ev;
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);
}
s = spltty();
mtx_enter(&evar->ws_mtx);
get = evar->ws_get;
put = evar->ws_put;
ev = &evar->ws_q[put];
if (++put % WSEVENT_QSIZE == get) {
put--;
splx(s);
mtx_leave(&evar->ws_mtx);
return (ENOSPC);
}
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;
nanotime(&ev->time);
evar->ws_put = put;
WSEVENT_WAKEUP(evar);
splx(s);
mtx_leave(&evar->ws_mtx);
wsevent_wakeup(evar);
return (0);
case WSMUXIO_ADD_DEVICE:
#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;
if (evar == NULL)
return (EINVAL);
mtx_enter(&evar->ws_mtx);
evar->ws_async = *(int *)data != 0;
mtx_leave(&evar->ws_mtx);
return (0);
case FIOGETOWN:
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 $ */
/*
@ -1549,10 +1549,8 @@ process_continue(struct proc *p, int flag)
SCHED_ASSERT_LOCKED();
if (q->p_wchan == NULL)
setrunnable(q);
else {
atomic_clearbits_int(&q->p_flag, P_WSLEEP);
else
q->p_stat = SSLEEP;
}
/* 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)
return (0);
do {
/* if we're in deep, we need to unwind to the edge */
if (deep) {
if (pr->ps_flags & PS_SINGLEUNWIND)
int err = 0;
if (pr->ps_flags & PS_SINGLEUNWIND ||
pr->ps_flags & PS_SINGLEEXIT)
return (ERESTART);
if (pr->ps_flags & PS_SINGLEEXIT)
return (EINTR);
SCHED_LOCK();
if (p->p_stat != SSTOP)
err = EWOULDBLOCK;
SCHED_UNLOCK();
return (err);
}
do {
if (pr->ps_flags & PS_SINGLEEXIT) {
mtx_leave(&pr->ps_mtx);
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 $ */
/*
@ -376,15 +376,6 @@ sleep_finish(int timo, int do_sleep)
}
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) {
catch = 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.
* The 2nd call in sleep_finish() sets nostop = 1 and then stop
* signals can be ignored since the sleep is over and the process
* will stop in userret.
* The 2nd call in sleep_finish() sets after_sleep = 1. In this case
* any pending suspend event came in after the wakeup / unsleep and
* can therefor be ignored. Once the process hits userret the event
* will be picked up again.
*/
int
sleep_signal_check(struct proc *p, int nostop)
sleep_signal_check(struct proc *p, int after_sleep)
{
struct sigctx ctx;
int err, sig;
if ((err = single_thread_check(p, 1)) != 0)
if ((err = single_thread_check(p, 1)) != 0) {
if (err != EWOULDBLOCK)
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 (ctx.sig_stop) {
if (nostop)
return 0;
if (!after_sleep) {
p->p_p->ps_xsig = sig;
SCHED_LOCK();
proc_stop(p, 0);
SCHED_UNLOCK();
}
} else if (ctx.sig_intr && !ctx.sig_ignore)
return EINTR;
else
return ERESTART;
}
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 $ */
/*
@ -166,9 +166,6 @@ soalloc(const struct protosw *prp, int wait)
TAILQ_INIT(&so->so_q0);
TAILQ_INIT(&so->so_q);
so->so_snd.sb_flags |= SB_MTXLOCK;
so->so_rcv.sb_flags |= SB_MTXLOCK;
return (so);
}
@ -598,7 +595,6 @@ sosend(struct socket *so, struct mbuf *addr, struct uio *uio, struct mbuf *top,
size_t resid;
int error;
int atomic = sosendallatonce(so) || top;
int dosolock = ((so->so_snd.sb_flags & SB_MTXLOCK) == 0);
if (uio)
resid = uio->uio_resid;
@ -634,9 +630,7 @@ sosend(struct socket *so, struct mbuf *addr, struct uio *uio, struct mbuf *top,
restart:
if ((error = sblock(&so->so_snd, SBLOCKWAIT(flags))) != 0)
goto out;
if (dosolock)
solock_shared(so);
sb_mtx_lock(&so->so_snd);
mtx_enter(&so->so_snd.sb_mtx);
so->so_snd.sb_state |= SS_ISSENDING;
do {
if (so->so_snd.sb_state & SS_CANTSENDMORE)
@ -669,11 +663,9 @@ restart:
if (flags & MSG_DONTWAIT)
snderr(EWOULDBLOCK);
sbunlock(&so->so_snd);
error = sbwait(so, &so->so_snd);
error = sbwait(&so->so_snd);
so->so_snd.sb_state &= ~SS_ISSENDING;
sb_mtx_unlock(&so->so_snd);
if (dosolock)
sounlock_shared(so);
mtx_leave(&so->so_snd.sb_mtx);
if (error)
goto out;
goto restart;
@ -688,13 +680,9 @@ restart:
if (flags & MSG_EOR)
top->m_flags |= M_EOR;
} else {
sb_mtx_unlock(&so->so_snd);
if (dosolock)
sounlock_shared(so);
mtx_leave(&so->so_snd.sb_mtx);
error = m_getuio(&top, atomic, space, uio);
if (dosolock)
solock_shared(so);
sb_mtx_lock(&so->so_snd);
mtx_enter(&so->so_snd.sb_mtx);
if (error)
goto release;
space -= top->m_pkthdr.len;
@ -706,16 +694,14 @@ restart:
so->so_snd.sb_state &= ~SS_ISSENDING;
if (top && so->so_options & SO_ZEROIZE)
top->m_flags |= M_ZEROIZE;
sb_mtx_unlock(&so->so_snd);
if (!dosolock)
mtx_leave(&so->so_snd.sb_mtx);
solock_shared(so);
if (flags & MSG_OOB)
error = pru_sendoob(so, top, addr, control);
else
error = pru_send(so, top, addr, control);
if (!dosolock)
sounlock_shared(so);
sb_mtx_lock(&so->so_snd);
mtx_enter(&so->so_snd.sb_mtx);
clen = 0;
control = NULL;
top = NULL;
@ -726,9 +712,7 @@ restart:
release:
so->so_snd.sb_state &= ~SS_ISSENDING;
sb_mtx_unlock(&so->so_snd);
if (dosolock)
sounlock_shared(so);
mtx_leave(&so->so_snd.sb_mtx);
sbunlock(&so->so_snd);
out:
m_freem(top);
@ -865,7 +849,6 @@ soreceive(struct socket *so, struct mbuf **paddr, struct uio *uio,
const struct protosw *pr = so->so_proto;
struct mbuf *nextrecord;
size_t resid, orig_resid = uio->uio_resid;
int dosolock = ((so->so_rcv.sb_flags & SB_MTXLOCK) == 0);
mp = mp0;
if (paddr)
@ -898,9 +881,7 @@ bad:
restart:
if ((error = sblock(&so->so_rcv, SBLOCKWAIT(flags))) != 0)
return (error);
if (dosolock)
solock_shared(so);
sb_mtx_lock(&so->so_rcv);
mtx_enter(&so->so_rcv.sb_mtx);
m = so->so_rcv.sb_mb;
#ifdef SOCKET_SPLICE
@ -965,10 +946,8 @@ restart:
SBLASTMBUFCHK(&so->so_rcv, "soreceive sbwait 1");
sbunlock(&so->so_rcv);
error = sbwait(so, &so->so_rcv);
sb_mtx_unlock(&so->so_rcv);
if (dosolock)
sounlock_shared(so);
error = sbwait(&so->so_rcv);
mtx_leave(&so->so_rcv.sb_mtx);
if (error)
return (error);
goto restart;
@ -1037,15 +1016,11 @@ dontblock:
sbsync(&so->so_rcv, nextrecord);
if (controlp) {
if (pr->pr_domain->dom_externalize) {
sb_mtx_unlock(&so->so_rcv);
if (dosolock)
sounlock_shared(so);
mtx_leave(&so->so_rcv.sb_mtx);
error =
(*pr->pr_domain->dom_externalize)
(cm, controllen, flags);
if (dosolock)
solock_shared(so);
sb_mtx_lock(&so->so_rcv);
mtx_enter(&so->so_rcv.sb_mtx);
}
*controlp = cm;
} else {
@ -1054,9 +1029,9 @@ dontblock:
* through the read path rather than recv.
*/
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);
sb_mtx_lock(&so->so_rcv);
mtx_enter(&so->so_rcv.sb_mtx);
}
m_free(cm);
}
@ -1122,13 +1097,9 @@ dontblock:
SBLASTRECORDCHK(&so->so_rcv, "soreceive uiomove");
SBLASTMBUFCHK(&so->so_rcv, "soreceive uiomove");
resid = uio->uio_resid;
sb_mtx_unlock(&so->so_rcv);
if (dosolock)
sounlock_shared(so);
mtx_leave(&so->so_rcv.sb_mtx);
uio_error = uiomove(mtod(m, caddr_t) + moff, len, uio);
if (dosolock)
solock_shared(so);
sb_mtx_lock(&so->so_rcv);
mtx_enter(&so->so_rcv.sb_mtx);
if (uio_error)
uio->uio_resid = resid - len;
} else
@ -1210,10 +1181,8 @@ dontblock:
break;
SBLASTRECORDCHK(&so->so_rcv, "soreceive sbwait 2");
SBLASTMBUFCHK(&so->so_rcv, "soreceive sbwait 2");
if (sbwait(so, &so->so_rcv)) {
sb_mtx_unlock(&so->so_rcv);
if (dosolock)
sounlock_shared(so);
if (sbwait(&so->so_rcv)) {
mtx_leave(&so->so_rcv.sb_mtx);
sbunlock(&so->so_rcv);
return (0);
}
@ -1244,19 +1213,17 @@ dontblock:
SBLASTRECORDCHK(&so->so_rcv, "soreceive 4");
SBLASTMBUFCHK(&so->so_rcv, "soreceive 4");
if (pr->pr_flags & PR_WANTRCVD) {
sb_mtx_unlock(&so->so_rcv);
if (!dosolock)
mtx_leave(&so->so_rcv.sb_mtx);
solock_shared(so);
pru_rcvd(so);
if (!dosolock)
sounlock_shared(so);
sb_mtx_lock(&so->so_rcv);
mtx_enter(&so->so_rcv.sb_mtx);
}
}
if (orig_resid == uio->uio_resid && orig_resid &&
(flags & MSG_EOR) == 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);
goto restart;
}
@ -1267,9 +1234,7 @@ dontblock:
if (flagsp)
*flagsp |= flags;
release:
sb_mtx_unlock(&so->so_rcv);
if (dosolock)
sounlock_shared(so);
mtx_leave(&so->so_rcv.sb_mtx);
sbunlock(&so->so_rcv);
return (error);
}
@ -1937,19 +1902,16 @@ somove(struct socket *so, int wait)
void
sorwakeup(struct socket *so)
{
if ((so->so_rcv.sb_flags & SB_MTXLOCK) == 0)
soassertlocked_readonly(so);
#ifdef SOCKET_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)
task_add(sosplice_taskq, &so->so_splicetask);
if (isspliced(so)) {
sb_mtx_unlock(&so->so_rcv);
mtx_leave(&so->so_rcv.sb_mtx);
return;
}
sb_mtx_unlock(&so->so_rcv);
mtx_leave(&so->so_rcv.sb_mtx);
}
#endif
sowakeup(so, &so->so_rcv);
@ -1960,20 +1922,17 @@ sorwakeup(struct socket *so)
void
sowwakeup(struct socket *so)
{
if ((so->so_snd.sb_flags & SB_MTXLOCK) == 0)
soassertlocked_readonly(so);
#ifdef SOCKET_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)
task_add(sosplice_taskq,
&so->so_sp->ssp_soback->so_splicetask);
if (issplicedback(so)) {
sb_mtx_unlock(&so->so_snd);
mtx_leave(&so->so_snd.sb_mtx);
return;
}
sb_mtx_unlock(&so->so_snd);
mtx_leave(&so->so_snd.sb_mtx);
}
#endif
sowakeup(so, &so->so_snd);
@ -2059,10 +2018,7 @@ sosetopt(struct socket *so, int level, int optname, struct mbuf *m)
if ((long)cnt <= 0)
cnt = 1;
if (((sb->sb_flags & SB_MTXLOCK) == 0))
solock(so);
mtx_enter(&sb->sb_mtx);
switch (optname) {
case SO_SNDBUF:
case SO_RCVBUF:
@ -2084,10 +2040,7 @@ sosetopt(struct socket *so, int level, int optname, struct mbuf *m)
sb->sb_hiwat : cnt;
break;
}
mtx_leave(&sb->sb_mtx);
if (((sb->sb_flags & SB_MTXLOCK) == 0))
sounlock(so);
break;
}
@ -2403,13 +2356,10 @@ filt_soread(struct knote *kn, long hint)
int rv = 0;
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) {
short qlen = READ_ONCE(so->so_qlen);
if (so->so_rcv.sb_flags & SB_MTXLOCK)
soassertlocked_readonly(so);
kn->kn_data = qlen;
@ -2469,8 +2419,6 @@ filt_sowrite(struct knote *kn, long hint)
int rv;
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);
if (so->so_snd.sb_state & SS_CANTSENDMORE) {
@ -2502,8 +2450,6 @@ filt_soexcept(struct knote *kn, long hint)
int rv = 0;
MUTEX_ASSERT_LOCKED(&so->so_rcv.sb_mtx);
if ((so->so_rcv.sb_flags & SB_MTXLOCK) == 0)
soassertlocked_readonly(so);
#ifdef SOCKET_SPLICE
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 $ */
/*
@ -316,9 +316,6 @@ socantsendmore(struct socket *so)
void
socantrcvmore(struct socket *so)
{
if ((so->so_rcv.sb_flags & SB_MTXLOCK) == 0)
soassertlocked(so);
mtx_enter(&so->so_rcv.sb_mtx);
so->so_rcv.sb_state |= SS_CANTRCVMORE;
mtx_leave(&so->so_rcv.sb_mtx);
@ -482,25 +479,20 @@ sosleep_nsec(struct socket *so, void *ident, int prio, const char *wmesg,
}
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)
splassert_fail(0, RW_WRITE, __func__);
} else
soassertlocked(so);
}
/*
* Wait for data to arrive at/drain from a socket buffer.
*/
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;
if (sb->sb_flags & SB_MTXLOCK) {
MUTEX_ASSERT_LOCKED(&sb->sb_mtx);
sb->sb_flags |= SB_WAIT;
@ -508,16 +500,6 @@ sbwait(struct socket *so, struct sockbuf *sb)
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
sblock(struct sockbuf *sb, int flags)
{
@ -640,7 +622,7 @@ bad:
int
sbreserve(struct socket *so, struct sockbuf *sb, u_long cc)
{
sbmtxassertlocked(so, sb);
sbmtxassertlocked(sb);
if (cc == 0 || cc > sb_max)
return (1);
@ -787,7 +769,7 @@ sbappend(struct socket *so, struct sockbuf *sb, struct mbuf *m)
if (m == NULL)
return;
sbmtxassertlocked(so, sb);
sbmtxassertlocked(sb);
SBLASTRECORDCHK(sb, "sbappend 1");
if ((n = sb->sb_lastrecord) != NULL) {
@ -821,7 +803,7 @@ sbappend(struct socket *so, struct sockbuf *sb, struct mbuf *m)
void
sbappendstream(struct socket *so, struct sockbuf *sb, struct mbuf *m)
{
sbmtxassertlocked(so, sb);
sbmtxassertlocked(sb);
KDASSERT(m->m_nextpkt == NULL);
KASSERT(sb->sb_mb == sb->sb_lastrecord);
@ -867,7 +849,7 @@ sbappendrecord(struct socket *so, struct sockbuf *sb, struct mbuf *m0)
{
struct mbuf *m;
sbmtxassertlocked(so, sb);
sbmtxassertlocked(sb);
if (m0 == NULL)
return;
@ -902,7 +884,7 @@ sbappendaddr(struct socket *so, struct sockbuf *sb, const struct sockaddr *asa,
struct mbuf *m, *n, *nlast;
int space = asa->sa_len;
sbmtxassertlocked(so, sb);
sbmtxassertlocked(sb);
if (m0 && (m0->m_flags & M_PKTHDR) == 0)
panic("sbappendaddr");
@ -951,7 +933,7 @@ sbappendcontrol(struct socket *so, struct sockbuf *sb, struct mbuf *m0,
struct mbuf *m, *mlast, *n;
int eor = 0, space = 0;
sbmtxassertlocked(so, sb);
sbmtxassertlocked(sb);
if (control == NULL)
panic("sbappendcontrol");
@ -1078,7 +1060,7 @@ sbdrop(struct socket *so, struct sockbuf *sb, int len)
struct mbuf *m, *mn;
struct mbuf *next;
sbmtxassertlocked(so, sb);
sbmtxassertlocked(sb);
next = (m = sb->sb_mb) ? m->m_nextpkt : NULL;
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 $ */
/*
@ -2798,7 +2798,29 @@ if_getdata(struct ifnet *ifp, struct if_data *data)
{
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) {
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 $ */
/*
@ -110,6 +110,23 @@ struct if_clone {
.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.
*
@ -147,7 +164,20 @@ struct ifnet { /* and the entries */
short if_timer; /* time 'til if_watchdog called */
unsigned short if_flags; /* [N] up/down, broadcast, etc. */
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 */
uint32_t if_hardmtu; /* [d] maximum MTU device supports */
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 */
};
#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 {
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
};
#define if_ipackets if_data_counters[ifc_ipackets]
#define if_ierrors if_data_counters[ifc_ierrors]
#define if_opackets if_data_counters[ifc_opackets]
#define if_oerrors if_data_counters[ifc_oerrors]
#define if_collisions if_data_counters[ifc_collisions]
#define if_ibytes if_data_counters[ifc_ibytes]
#define if_obytes if_data_counters[ifc_obytes]
#define if_imcasts if_data_counters[ifc_imcasts]
#define if_omcasts if_data_counters[ifc_omcasts]
#define if_iqdrops if_data_counters[ifc_iqdrops]
#define if_oqdrops if_data_counters[ifc_oqdrops]
#define if_noproto if_data_counters[ifc_noproto]
/*
* 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 $ */
/*
@ -331,11 +331,11 @@ tcp_respond(struct tcpcb *tp, caddr_t template, struct tcphdr *th0,
th = (struct tcphdr *)(ip6 + 1);
tlen = sizeof(*ip6) + sizeof(*th);
if (th0) {
bcopy(template, ip6, sizeof(*ip6));
bcopy(th0, th, sizeof(*th));
memcpy(ip6, template, sizeof(*ip6));
memcpy(th, th0, sizeof(*th));
xchg(ip6->ip6_dst, ip6->ip6_src, struct in6_addr);
} else {
bcopy(template, ip6, tlen);
memcpy(ip6, template, tlen);
}
break;
#endif /* INET6 */
@ -344,11 +344,11 @@ tcp_respond(struct tcpcb *tp, caddr_t template, struct tcphdr *th0,
th = (struct tcphdr *)(ip + 1);
tlen = sizeof(*ip) + sizeof(*th);
if (th0) {
bcopy(template, ip, sizeof(*ip));
bcopy(th0, th, sizeof(*th));
memcpy(ip, template, sizeof(*ip));
memcpy(th, th0, sizeof(*th));
xchg(ip->ip_dst.s_addr, ip->ip_src.s_addr, u_int32_t);
} else {
bcopy(template, ip, tlen);
memcpy(ip, template, tlen);
}
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 $ */
/*-
@ -112,7 +112,6 @@ struct sockbuf {
#define SB_ASYNC 0x0002 /* ASYNC I/O, need signals */
#define SB_SPLICE 0x0004 /* buffer is splice source or drain */
#define SB_NOINTR 0x0008 /* operations not interruptible */
#define SB_MTXLOCK 0x0010 /* sblock() doesn't need solock() */
/*
* Kernel structure per socket.
@ -225,21 +224,7 @@ soref(struct socket *so)
#define isspliced(so) ((so)->so_sp && (so)->so_sp->ssp_socket)
#define issplicedback(so) ((so)->so_sp && (so)->so_sp->ssp_soback)
static inline void
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 *);
void sbmtxassertlocked(struct sockbuf *);
/*
* 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;
soassertlocked(so);
mtx_enter(&sb->sb_mtx);
rv = ((sb->sb_flags & (SB_WAIT|SB_ASYNC|SB_SPLICE)) != 0 ||
!klist_empty(&sb->sb_klist));
@ -269,10 +252,7 @@ sb_notify(struct socket *so, struct sockbuf *sb)
static inline long
sbspace_locked(struct socket *so, struct sockbuf *sb)
{
if (sb->sb_flags & SB_MTXLOCK)
sbmtxassertlocked(so, sb);
else
soassertlocked_readonly(so);
sbmtxassertlocked(sb);
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;
sb_mtx_lock(sb);
mtx_enter(&sb->sb_mtx);
ret = sbspace_locked(so, sb);
sb_mtx_unlock(sb);
mtx_leave(&sb->sb_mtx);
return ret;
}
@ -411,7 +391,7 @@ void sbrelease(struct socket *, struct sockbuf *);
int sbcheckreserve(u_long, u_long);
int sbchecklowmem(void);
int sbreserve(struct socket *, struct sockbuf *, u_long);
int sbwait(struct socket *, struct sockbuf *);
int sbwait(struct sockbuf *);
void soinit(void);
void soabort(struct socket *);
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 $ */
/*
@ -321,16 +321,9 @@ uvmfault_anonget(struct uvm_faultinfo *ufi, struct vm_amap *amap,
* The last unlock must be an atomic unlock and wait
* on the owner of page.
*/
if (pg->uobject) {
/* Owner of page is UVM object. */
uvmfault_unlockall(ufi, amap, NULL);
uvm_pagewait(pg, pg->uobject->vmobjlock,
"anonget1");
} else {
/* Owner of page is anon. */
KASSERT(pg->uobject == NULL);
uvmfault_unlockall(ufi, NULL, NULL);
uvm_pagewait(pg, anon->an_lock, "anonget2");
}
uvm_pagewait(pg, anon->an_lock, "anonget");
} else {
/*
* 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,
ufi->orig_rvaddr - ufi->entry->start) != anon) {
uvmfault_unlockall(ufi, amap, NULL);
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 succeeds, locks are still valid and locked.
* 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);
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>
@ -2572,7 +2572,7 @@ int
parse_capabilities(struct peer *peer, struct ibuf *buf, uint32_t *as)
{
struct ibuf capabuf;
uint16_t afi, nhafi, tmp16, gr_header;
uint16_t afi, nhafi, gr_header;
uint8_t capa_code, capa_len;
uint8_t safi, aid, role, flags;
@ -2616,6 +2616,7 @@ parse_capabilities(struct peer *peer, struct ibuf *buf, uint32_t *as)
break;
case CAPA_EXT_NEXTHOP:
while (ibuf_size(&capabuf) > 0) {
uint16_t tmp16;
if (ibuf_get_n16(&capabuf, &afi) == -1 ||
ibuf_get_n16(&capabuf, &tmp16) == -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));
break;
}
if (afi2aid(afi, tmp16, &aid) == -1 ||
safi = tmp16;
if (afi2aid(afi, safi, &aid) == -1 ||
!(aid == AID_INET || aid == AID_VPN_IPv4)) {
log_peer_warnx(&peer->conf,
"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>
@ -66,10 +66,15 @@ conn_new(struct session *s, struct connection_config *cc)
c->cid = arc4random();
c->config = *cc;
c->mine = initiator_conn_defaults;
if (s->config.HeaderDigest != 0)
c->mine.HeaderDigest = s->config.HeaderDigest;
if (s->config.DataDigest != 0)
c->mine.DataDigest = s->config.DataDigest;
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->tasks);
@ -113,6 +118,7 @@ conn_free(struct connection *c)
pdu_readbuf_free(&c->prbuf);
pdu_free_queue(&c->pdu_w);
event_del(&c->sev.ev);
event_del(&c->ev);
event_del(&c->wev);
if (c->fd != -1)
@ -262,7 +268,6 @@ do { \
(p)->key, (p)->value, err); \
errors++; \
} \
log_debug("SET_NUM: %s = %llu", #v, (u_int64_t)(x)->his.v); \
} \
} while (0)
@ -275,7 +280,18 @@ do { \
(p)->key, (p)->value, err); \
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)
@ -304,6 +320,8 @@ log_debug("conn_parse_kvp: %s = %s", k->key, k->value);
SET_BOOL(k, s, DataSequenceInOrder);
SET_NUM(k, s, ErrorRecoveryLevel, 0, 2);
SET_NUM(k, c, MaxRecvDataSegmentLength, 512, 16777215);
SET_DIGEST(k, c, HeaderDigest);
SET_DIGEST(k, c, DataDigest);
}
if (errors) {
@ -315,6 +333,7 @@ log_debug("conn_parse_kvp: %s = %s", k->key, k->value);
#undef SET_NUM
#undef SET_BOOL
#undef SET_DIGEST
int
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) {
log_warnx("connect(%s), lost socket",
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;
}
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) {
log_warn("bind(%s)",
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;
}
}
@ -456,7 +475,7 @@ c_do_connect(struct connection *c, enum c_event ev)
} else {
log_warn("connect(%s)",
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;
}
}
@ -477,7 +496,7 @@ int
c_do_loggedin(struct connection *c, enum c_event ev)
{
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;
}
@ -525,7 +544,7 @@ c_do_fail(struct connection *c, enum c_event ev)
taskq_cleanup(&c->tasks);
/* 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)
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>
@ -33,7 +33,7 @@
#include "iscsid.h"
#include "log.h"
struct initiator *initiator;
static struct initiator *initiator;
struct task_login {
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_logout_cb(struct connection *, void *, struct pdu *);
struct session_params initiator_sess_defaults;
struct connection_params initiator_conn_defaults;
struct initiator *
void
initiator_init(void)
{
if (!(initiator = calloc(1, sizeof(*initiator))))
@ -78,24 +77,34 @@ initiator_init(void)
initiator_conn_defaults = iscsi_conn_defaults;
initiator_sess_defaults.MaxConnections = ISCSID_DEF_CONNS;
initiator_conn_defaults.MaxRecvDataSegmentLength = 65536;
return initiator;
}
void
initiator_cleanup(struct initiator *i)
initiator_cleanup(void)
{
struct session *s;
while ((s = TAILQ_FIRST(&i->sessions)) != NULL) {
TAILQ_REMOVE(&i->sessions, s, entry);
while ((s = TAILQ_FIRST(&initiator->sessions)) != NULL) {
TAILQ_REMOVE(&initiator->sessions, s, entry);
session_cleanup(s);
}
free(initiator);
}
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;
@ -106,7 +115,7 @@ initiator_shutdown(struct initiator *i)
}
int
initiator_isdown(struct initiator *i)
initiator_isdown(void)
{
struct session *s;
int inprogres = 0;
@ -118,6 +127,49 @@ initiator_isdown(struct initiator *i)
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 *
initiator_t2s(u_int target)
{
@ -130,6 +182,12 @@ initiator_t2s(u_int target)
return NULL;
}
struct session_head *
initiator_get_sessions(void)
{
return &initiator->sessions;
}
void
initiator_login(struct connection *c)
{
@ -258,7 +316,7 @@ initiator_login_kvp(struct connection *c, u_int8_t stage)
switch (stage) {
case ISCSI_LOGIN_STG_SECNEG:
if (!(kvp = calloc(4, sizeof(*kvp))))
if (!(kvp = calloc(5, sizeof(*kvp))))
return NULL;
kvp[0].key = "AuthMethod";
kvp[0].value = "None";
@ -269,8 +327,10 @@ initiator_login_kvp(struct connection *c, u_int8_t stage)
kvp[2].key = "SessionType";
kvp[2].value = "Discovery";
} else {
kvp[2].key = "TargetName";
kvp[2].value = c->session->config.TargetName;
kvp[2].key = "SessionType";
kvp[2].value = "Normal";
kvp[3].key = "TargetName";
kvp[3].value = c->session->config.TargetName;
}
break;
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:
if (tl->reason == ISCSI_LOGOUT_CLOSE_SESS) {
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 {
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;
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>
.\"
@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
.Dd $Mdocdate: July 27 2015 $
.Dd $Mdocdate: January 21 2025 $
.Dt ISCSID 8
.Os
.Sh NAME
@ -74,26 +74,16 @@ socket used for communication with
.Xr iscsictl 8
.Sh STANDARDS
.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
.%R RFC 3721
.%T Internet Small Computer Systems Interface (iSCSI) Naming and Discovery
.Re
.Pp
.Rs
.%D April 2014
.%R RFC 7143
.%T Internet Small Computer System Interface (iSCSI) Protocol (Consolidated)
.Re
.Sh HISTORY
The
.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>
@ -38,7 +38,6 @@ void main_sig_handler(int, short, void *);
__dead void usage(void);
void shutdown_cb(int, short, void *);
extern struct initiator *initiator;
struct event exit_ev;
int exit_rounds;
#define ISCSI_EXIT_WAIT 5
@ -54,11 +53,13 @@ const struct session_params iscsi_sess_defaults = {
.ImmediateData = 1,
.DataPDUInOrder = 1,
.DataSequenceInOrder = 1,
.ErrorRecoveryLevel = 0
.ErrorRecoveryLevel = 0,
};
const struct connection_params iscsi_conn_defaults = {
.MaxRecvDataSegmentLength = 8192
.MaxRecvDataSegmentLength = 8192,
.HeaderDigest = DIGEST_NONE,
.DataDigest = DIGEST_NONE,
};
int
@ -146,13 +147,13 @@ main(int argc, char *argv[])
signal(SIGPIPE, SIG_IGN);
control_event_init();
initiator = initiator_init();
initiator_init();
event_dispatch();
/* do some cleanup on the way out */
control_cleanup(ctrlsock);
initiator_cleanup(initiator);
initiator_cleanup();
log_info("exiting.");
return 0;
}
@ -162,7 +163,7 @@ shutdown_cb(int fd, short event, void *arg)
{
struct timeval tv;
if (exit_rounds++ >= ISCSI_EXIT_WAIT || initiator_isdown(initiator))
if (exit_rounds++ >= ISCSI_EXIT_WAIT || initiator_isdown())
event_loopexit(NULL);
timerclear(&tv);
@ -182,7 +183,7 @@ main_sig_handler(int sig, short event, void *arg)
case SIGTERM:
case SIGINT:
case SIGHUP:
initiator_shutdown(initiator);
initiator_shutdown();
evtimer_set(&exit_ev, shutdown_cb, NULL);
timerclear(&tv);
if (evtimer_add(&exit_ev, &tv) == -1)
@ -209,6 +210,7 @@ iscsid_ctrl_dispatch(void *ch, struct pdu *pdu)
{
struct ctrlmsghdr *cmh;
struct initiator_config *ic;
struct session_head *sh;
struct session_config *sc;
struct session *s;
struct session_poll p = { 0 };
@ -226,7 +228,7 @@ iscsid_ctrl_dispatch(void *ch, struct pdu *pdu)
break;
}
ic = pdu_getbuf(pdu, NULL, 1);
memcpy(&initiator->config, ic, sizeof(initiator->config));
initiator_set_config(ic);
control_compose(ch, CTRL_SUCCESS, NULL, 0);
break;
case CTRL_SESSION_CONFIG:
@ -248,9 +250,9 @@ iscsid_ctrl_dispatch(void *ch, struct pdu *pdu)
else
sc->InitiatorName = NULL;
s = session_find(initiator, sc->SessionName);
s = initiator_find_session(sc->SessionName);
if (s == NULL) {
s = session_new(initiator, sc->SessionType);
s = initiator_new_session(sc->SessionType);
if (s == NULL) {
control_compose(ch, CTRL_FAILURE, NULL, 0);
goto done;
@ -259,7 +261,7 @@ iscsid_ctrl_dispatch(void *ch, struct pdu *pdu)
session_config(s, sc);
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);
break;
@ -278,10 +280,11 @@ iscsid_ctrl_dispatch(void *ch, struct pdu *pdu)
sizeof(struct vscsi_stats));
break;
case CTRL_SHOW_SUM:
control_compose(ch, CTRL_INITIATOR_CONFIG, &initiator->config,
sizeof(initiator->config));
ic = initiator_get_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];
bzero(cdv, sizeof(cdv));
@ -306,7 +309,8 @@ iscsid_ctrl_dispatch(void *ch, struct pdu *pdu)
control_compose(ch, CTRL_SUCCESS, NULL, 0);
break;
case CTRL_SESS_POLL:
TAILQ_FOREACH(s, &initiator->sessions, entry)
sh = initiator_get_sessions();
TAILQ_FOREACH(s, sh, entry)
poll_session(&p, s);
poll_finalize(&p);
control_compose(ch, CTRL_SESS_POLL, &p, sizeof(p));
@ -334,6 +338,8 @@ void
iscsi_merge_sess_params(struct session_params *res,
struct session_params *mine, struct session_params *his)
{
memset(res, 0, sizeof(*res));
MERGE_MIN(res, mine, his, MaxBurstLength);
MERGE_MIN(res, mine, his, FirstBurstLength);
MERGE_MAX(res, mine, his, DefaultTime2Wait);
@ -353,8 +359,26 @@ void
iscsi_merge_conn_params(struct connection_params *res,
struct connection_params *mine, struct connection_params *his)
{
int mask;
memset(res, 0, sizeof(*res));
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

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>
@ -181,6 +181,9 @@ struct session_config {
u_int8_t disabled;
};
#define DIGEST_NONE 0x1
#define DIGEST_CRC32C 0x2
#define SESSION_TYPE_NORMAL 0
#define SESSION_TYPE_DISCOVERY 1
@ -226,6 +229,7 @@ struct initiator {
};
struct sessev {
struct event ev;
struct session *sess;
struct connection *conn;
enum s_event event;
@ -233,13 +237,13 @@ struct sessev {
struct session {
TAILQ_ENTRY(session) entry;
struct sessev sev;
struct connection_head connections;
struct taskq tasks;
struct session_config config;
struct session_params mine;
struct session_params his;
struct session_params active;
struct initiator *initiator;
u_int32_t cmdseqnum;
u_int32_t itt;
u_int32_t isid_base; /* only 24 bits */
@ -264,6 +268,7 @@ struct session_poll {
struct connection {
struct event ev;
struct event wev;
struct sessev sev;
TAILQ_ENTRY(connection) entry;
struct connection_params mine;
struct connection_params his;
@ -323,11 +328,16 @@ void iscsi_merge_sess_params(struct session_params *,
void iscsi_merge_conn_params(struct connection_params *,
struct connection_params *, struct connection_params *);
struct initiator *initiator_init(void);
void initiator_cleanup(struct initiator *);
void initiator_shutdown(struct initiator *);
int initiator_isdown(struct initiator *);
void initiator_init(void);
void initiator_cleanup(void);
void initiator_set_config(struct initiator_config *);
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_head *initiator_get_sessions(void);
void initiator_login(struct connection *);
void initiator_discovery(struct session *);
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_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 *);
int session_shutdown(struct session *);
void session_config(struct session *, struct session_config *);
void session_task_issue(struct session *, struct task *);
void session_logout_issue(struct session *, struct task *);
void session_schedule(struct session *);
void session_fsm(struct session *, enum s_event, struct connection *,
unsigned int);
void session_fsm(struct sessev *, enum s_event, unsigned int);
void session_fsm_callback(int, short, void *);
void conn_new(struct session *, struct connection_config *);
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);
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_digest(const char *, const char **);
void pdu_free_queue(struct pduq *);
ssize_t pdu_read(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>
@ -193,23 +193,42 @@ text_to_bool(const char *buf, const char **errstrp)
{
int val = 0;
if (!strcmp(buf, "Yes")) {
if (strcmp(buf, "Yes") == 0)
val = 1;
errno = 0;
} else if (!strcmp(buf, "No"))
errno = 0;
else
errno = EINVAL;
if (errstrp != NULL) {
if (errno == 0)
*errstrp = NULL;
else
else if (strcmp(buf, "No") != 0) {
if (errstrp != NULL)
*errstrp = "invalid";
}
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.

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>
@ -35,7 +35,6 @@
#include "iscsid.h"
#include "log.h"
void session_fsm_callback(int, short, void *);
int sess_do_start(struct session *, struct sessev *);
int sess_do_conn_loggedin(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_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
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.
*/
void
session_fsm(struct session *s, enum s_event ev, struct connection *c,
unsigned int timeout)
session_fsm(struct sessev *sev, enum s_event event, unsigned int timeout)
{
struct session *s = sev->sess;
struct timeval tv;
struct sessev *sev;
log_debug("session_fsm[%s]: %s ev %s timeout %d",
s->config.SessionName, sess_state(s->state),
sess_event(ev), timeout);
sess_event(event), timeout);
if ((sev = malloc(sizeof(*sev))) == NULL)
fatal("session_fsm");
sev->conn = c;
sev->sess = s;
sev->event = ev;
sev->event = event;
timerclear(&tv);
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");
}
@ -276,8 +230,6 @@ session_fsm_callback(int fd, short event, void *arg)
sess_state(s->state), sess_event(sev->event));
fatalx("bjork bjork bjork");
}
free(sev);
log_debug("sess_fsm: done");
}
int
@ -286,7 +238,7 @@ sess_do_start(struct session *s, struct sessev *sev)
log_debug("new connection to %s",
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->his = 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;
}
session_fsm(s, SESS_EV_START, NULL, s->holdTimer);
session_fsm(&s->sev, SESS_EV_START, s->holdTimer);
/* exponential back-off on constant failure */
if (s->holdTimer < ISCSID_HOLD_TIME_MAX)
s->holdTimer = s->holdTimer ? s->holdTimer * 2 : 1;