sync with OpenBSD -current
This commit is contained in:
parent
d22f2a15f3
commit
f4a22ff4b2
@ -1,4 +1,4 @@
|
||||
.\" $OpenBSD: rktemp.4,v 1.4 2020/06/20 21:16:14 jmc Exp $
|
||||
.\" $OpenBSD: rktemp.4,v 1.5 2024/06/12 09:08:43 kettenis Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2016 Mark Kettenis <kettenis@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: June 20 2020 $
|
||||
.Dd $Mdocdate: June 12 2024 $
|
||||
.Dt RKTEMP 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -26,7 +26,7 @@
|
||||
The
|
||||
.Nm
|
||||
driver provides support for the temperature sensor found on the
|
||||
Rockchip RK3288, RK3328 and RK3399 SoCs.
|
||||
Rockchip RK3288, RK3308, RK3328, RK3399 RK356x and RK3588 SoCs.
|
||||
It configures the SoC to reset itself if the temperature raises above
|
||||
a certain temperature to protect it from damage caused by overheating.
|
||||
.Pp
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: cacheinfo.c,v 1.14 2024/05/08 18:00:55 guenther Exp $ */
|
||||
/* $OpenBSD: cacheinfo.c,v 1.15 2024/06/13 02:19:20 guenther Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2022 Jonathan Gray <jsg@openbsd.org>
|
||||
@ -246,8 +246,8 @@ intel_print_cacheinfo(struct cpu_info *ci, u_int fn)
|
||||
}
|
||||
/* print lower levels that were the same */
|
||||
for (i = 0; i < leaf; i++)
|
||||
intel_print_one_cache(ci, i, prev_cache[leaf][0],
|
||||
prev_cache[leaf][1], prev_cache[leaf][2]);
|
||||
intel_print_one_cache(ci, i, prev_cache[i][0],
|
||||
prev_cache[i][1], prev_cache[i][2]);
|
||||
/* print this (differing) level and higher levels */
|
||||
goto printit;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: conf.c,v 1.80 2024/06/11 09:21:32 jsg Exp $ */
|
||||
/* $OpenBSD: conf.c,v 1.81 2024/06/12 12:54:54 bluhm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994, 1995 Charles M. Hannum. All rights reserved.
|
||||
@ -98,6 +98,15 @@ int nblkdev = nitems(bdevsw);
|
||||
(dev_type_stop((*))) enodev, 0, \
|
||||
(dev_type_mmap((*))) enodev, 0, 0, seltrue_kqfilter }
|
||||
|
||||
/* open, close, ioctl */
|
||||
#define cdev_psp_init(c,n) { \
|
||||
dev_init(c,n,open), dev_init(c,n,close), \
|
||||
(dev_type_read((*))) enodev, \
|
||||
(dev_type_write((*))) enodev, \
|
||||
dev_init(c,n,ioctl), \
|
||||
(dev_type_stop((*))) enodev, 0, \
|
||||
(dev_type_mmap((*))) enodev, 0, 0, seltrue_kqfilter }
|
||||
|
||||
#define mmread mmrw
|
||||
#define mmwrite mmrw
|
||||
cdev_decl(mm);
|
||||
@ -143,6 +152,8 @@ cdev_decl(nvram);
|
||||
#include "drm.h"
|
||||
#include "viocon.h"
|
||||
cdev_decl(viocon);
|
||||
#include "ccp.h"
|
||||
cdev_decl(psp);
|
||||
|
||||
#include "wsdisplay.h"
|
||||
#include "wskbd.h"
|
||||
@ -281,6 +292,7 @@ struct cdevsw cdevsw[] =
|
||||
cdev_fido_init(NFIDO,fido), /* 98: FIDO/U2F security keys */
|
||||
cdev_pppx_init(NPPPX,pppac), /* 99: PPP Access Concentrator */
|
||||
cdev_ujoy_init(NUJOY,ujoy), /* 100: USB joystick/gamecontroller */
|
||||
cdev_psp_init(NCCP,psp), /* 101: PSP */
|
||||
};
|
||||
int nchrdev = nitems(cdevsw);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $OpenBSD: files,v 1.732 2024/05/29 13:56:49 mglocker Exp $
|
||||
# $OpenBSD: files,v 1.733 2024/06/12 12:54:54 bluhm Exp $
|
||||
# $NetBSD: files,v 1.87 1996/05/19 17:17:50 jonathan Exp $
|
||||
|
||||
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
|
||||
@ -467,7 +467,7 @@ file dev/usb/xhci.c xhci needs-flag
|
||||
|
||||
# AMD Cryptographic Co-processor
|
||||
device ccp
|
||||
file dev/ic/ccp.c ccp
|
||||
file dev/ic/ccp.c ccp needs-flag
|
||||
|
||||
# SDHC SD/MMC controller
|
||||
define sdhc
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: rktemp.c,v 1.12 2023/03/05 09:57:32 kettenis Exp $ */
|
||||
/* $OpenBSD: rktemp.c,v 1.13 2024/06/12 09:06:15 kettenis Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2017 Mark Kettenis <kettenis@openbsd.org>
|
||||
*
|
||||
@ -36,43 +36,38 @@
|
||||
#define TSADC_USER_CON_INTER_PD_SOC_SHIFT 6
|
||||
#define TSADC_AUTO_CON 0x0004
|
||||
#define TSADC_AUTO_CON_TSHUT_POLARITY (1 << 8)
|
||||
#define TSADC_AUTO_CON_SRC3_EN (1 << 7)
|
||||
#define TSADC_AUTO_CON_SRC2_EN (1 << 6)
|
||||
#define TSADC_AUTO_CON_SRC1_EN (1 << 5)
|
||||
#define TSADC_AUTO_CON_SRC0_EN (1 << 4)
|
||||
#define TSADC_AUTO_CON_SRC_EN(ch) (1 << ((ch) + 4))
|
||||
#define TSADC_AUTO_CON_TSADC_Q_SEL (1 << 1)
|
||||
#define TSADC_AUTO_CON_AUTO_EN (1 << 0)
|
||||
#define TSADC_INT_EN 0x0008
|
||||
#define TSADC_INT_EN_TSHUT_2CRU_EN_SRC3 (1 << 11)
|
||||
#define TSADC_INT_EN_TSHUT_2CRU_EN_SRC2 (1 << 10)
|
||||
#define TSADC_INT_EN_TSHUT_2CRU_EN_SRC1 (1 << 9)
|
||||
#define TSADC_INT_EN_TSHUT_2CRU_EN_SRC0 (1 << 8)
|
||||
#define TSADC_INT_EN_TSHUT_2GPIO_EN_SRC3 (1 << 7)
|
||||
#define TSADC_INT_EN_TSHUT_2GPIO_EN_SRC2 (1 << 6)
|
||||
#define TSADC_INT_EN_TSHUT_2GPIO_EN_SRC1 (1 << 5)
|
||||
#define TSADC_INT_EN_TSHUT_2GPIO_EN_SRC0 (1 << 4)
|
||||
#define TSADC_INT_EN_TSHUT_2CRU_EN_SRC(ch) (1 << ((ch) + 8))
|
||||
#define TSADC_INT_EN_TSHUT_2GPIO_EN_SRC(ch) (1 << ((ch) + 4))
|
||||
#define TSADC_INT_PD 0x000c
|
||||
#define TSADC_INT_PD_TSHUT_O_SRC0 (1 << 4)
|
||||
#define TSADC_INT_PD_TSHUT_O_SRC1 (1 << 5)
|
||||
#define TSADC_INT_PD_TSHUT_O_SRC2 (1 << 6)
|
||||
#define TSADC_INT_PD_TSHUT_O_SRC3 (1 << 7)
|
||||
#define TSADC_DATA0 0x0020
|
||||
#define TSADC_DATA1 0x0024
|
||||
#define TSADC_DATA2 0x0028
|
||||
#define TSADC_DATA3 0x002c
|
||||
#define TSADC_COMP0_INT 0x0030
|
||||
#define TSADC_COMP1_INT 0x0034
|
||||
#define TSADC_COMP2_INT 0x0038
|
||||
#define TSADC_COMP3_INT 0x003c
|
||||
#define TSADC_COMP0_SHUT 0x0040
|
||||
#define TSADC_COMP1_SHUT 0x0044
|
||||
#define TSADC_COMP2_SHUT 0x0048
|
||||
#define TSADC_COMP3_SHUT 0x004c
|
||||
#define TSADC_INT_PD_TSHUT_O_SRC(ch) (1 << ((ch) + 4))
|
||||
#define TSADC_DATA(ch) (0x0020 + (ch) * 4)
|
||||
#define TSADC_COMP_INT(ch) (0x0030 + (ch) * 4)
|
||||
#define TSADC_COMP_SHUT(ch) (0x0040 + (ch) * 4)
|
||||
#define TSADC_HIGHT_INT_DEBOUNCE 0x0060
|
||||
#define TSADC_HIGHT_TSHUT_DEBOUNCE 0x0064
|
||||
#define TSADC_AUTO_PERIOD 0x0068
|
||||
#define TSADC_AUTO_PERIOD_HT 0x006c
|
||||
|
||||
/* RK3588 */
|
||||
#define TSADC_V3_AUTO_SRC 0x000c
|
||||
#define TSADC_V3_AUTO_SRC_CH(ch) (1 << (ch))
|
||||
#define TSADC_V3_GPIO_EN 0x0018
|
||||
#define TSADC_V3_GPIO_EN_CH(ch) (1 << (ch))
|
||||
#define TSADC_V3_CRU_EN 0x001c
|
||||
#define TSADC_V3_CRU_EN_CH(ch) (1 << (ch))
|
||||
#define TSADC_V3_HLT_INT_PD 0x0024
|
||||
#define TSADC_V3_HT_INT_STATUS(ch) (1 << (ch))
|
||||
#define TSADC_V3_DATA(ch) (0x002c + (ch) * 4)
|
||||
#define TSADC_V3_COMP_SHUT(ch) (0x010c + (ch) * 4)
|
||||
#define TSADC_V3_HIGHT_INT_DEBOUNCE 0x014c
|
||||
#define TSADC_V3_HIGHT_TSHUT_DEBOUNCE 0x0150
|
||||
#define TSADC_V3_AUTO_PERIOD 0x0154
|
||||
#define TSADC_V3_AUTO_PERIOD_HT 0x0158
|
||||
|
||||
/* RK3568 */
|
||||
#define RK3568_GRF_TSADC_CON 0x0600
|
||||
#define RK3568_GRF_TSADC_EN (1 << 8)
|
||||
@ -248,16 +243,36 @@ const struct rktemp_entry rk3568_temps[] = {
|
||||
|
||||
const char *const rk3568_names[] = { "CPU", "GPU" };
|
||||
|
||||
/* RK3588 conversion table. */
|
||||
const struct rktemp_entry rk3588_temps[] = {
|
||||
{ -40000, 215 },
|
||||
{ 25000, 285 },
|
||||
{ 85000, 350 },
|
||||
{ 125000, 395 },
|
||||
};
|
||||
|
||||
const char *const rk3588_names[] = {
|
||||
"Top",
|
||||
"CPU (big0)",
|
||||
"CPU (big1)",
|
||||
"CPU (little)",
|
||||
"Center",
|
||||
"GPU",
|
||||
"NPU"
|
||||
};
|
||||
|
||||
struct rktemp_softc {
|
||||
struct device sc_dev;
|
||||
bus_space_tag_t sc_iot;
|
||||
bus_space_handle_t sc_ioh;
|
||||
int sc_node;
|
||||
|
||||
bus_size_t sc_data0;
|
||||
|
||||
const struct rktemp_entry *sc_temps;
|
||||
int sc_ntemps;
|
||||
|
||||
struct ksensor sc_sensors[3];
|
||||
struct ksensor sc_sensors[7];
|
||||
int sc_nsensors;
|
||||
struct ksensordev sc_sensordev;
|
||||
|
||||
@ -291,7 +306,8 @@ rktemp_match(struct device *parent, void *match, void *aux)
|
||||
OF_is_compatible(faa->fa_node, "rockchip,rk3308-tsadc") ||
|
||||
OF_is_compatible(faa->fa_node, "rockchip,rk3328-tsadc") ||
|
||||
OF_is_compatible(faa->fa_node, "rockchip,rk3399-tsadc") ||
|
||||
OF_is_compatible(faa->fa_node, "rockchip,rk3568-tsadc"));
|
||||
OF_is_compatible(faa->fa_node, "rockchip,rk3568-tsadc") ||
|
||||
OF_is_compatible(faa->fa_node, "rockchip,rk3588-tsadc"));
|
||||
}
|
||||
|
||||
void
|
||||
@ -301,8 +317,7 @@ rktemp_attach(struct device *parent, struct device *self, void *aux)
|
||||
struct fdt_attach_args *faa = aux;
|
||||
const char *const *names;
|
||||
uint32_t mode, polarity, temp;
|
||||
uint32_t auto_con, int_en;
|
||||
uint32_t inter_pd_soc;
|
||||
uint32_t auto_con, inter_pd_soc;
|
||||
int auto_period, auto_period_ht;
|
||||
int i;
|
||||
|
||||
@ -354,7 +369,7 @@ rktemp_attach(struct device *parent, struct device *self, void *aux)
|
||||
inter_pd_soc = 13;
|
||||
auto_period = 1875; /* 2.5 ms */
|
||||
auto_period_ht = 1875; /* 2.5 ms */
|
||||
} else {
|
||||
} else if (OF_is_compatible(sc->sc_node, "rockchip,rk3568-tsadc")) {
|
||||
sc->sc_temps = rk3568_temps;
|
||||
sc->sc_ntemps = nitems(rk3568_temps);
|
||||
sc->sc_nsensors = 2;
|
||||
@ -362,6 +377,14 @@ rktemp_attach(struct device *parent, struct device *self, void *aux)
|
||||
inter_pd_soc = 63; /* 97 us */
|
||||
auto_period = 1622; /* 2.5 ms */
|
||||
auto_period_ht = 1622; /* 2.5 ms */
|
||||
} else {
|
||||
sc->sc_temps = rk3588_temps;
|
||||
sc->sc_ntemps = nitems(rk3588_temps);
|
||||
sc->sc_nsensors = 7;
|
||||
names = rk3588_names;
|
||||
inter_pd_soc = 0;
|
||||
auto_period = 5000; /* 2.5 ms */
|
||||
auto_period_ht = 5000; /* 2.5 ms */
|
||||
}
|
||||
|
||||
pinctrl_byname(sc->sc_node, "init");
|
||||
@ -371,57 +394,110 @@ rktemp_attach(struct device *parent, struct device *self, void *aux)
|
||||
clock_enable(sc->sc_node, "apb_pclk");
|
||||
|
||||
/* Reset the TS-ADC controller block. */
|
||||
reset_assert(sc->sc_node, "tsadc-apb");
|
||||
reset_assert_all(sc->sc_node);
|
||||
delay(10);
|
||||
reset_deassert(sc->sc_node, "tsadc-apb");
|
||||
reset_deassert_all(sc->sc_node);
|
||||
|
||||
mode = OF_getpropint(sc->sc_node, "rockchip,hw-tshut-mode", 1);
|
||||
polarity = OF_getpropint(sc->sc_node, "rockchip,hw-tshut-polarity", 0);
|
||||
temp = OF_getpropint(sc->sc_node, "rockchip,hw-tshut-temp", 95000);
|
||||
|
||||
HWRITE4(sc, TSADC_USER_CON,
|
||||
inter_pd_soc << TSADC_USER_CON_INTER_PD_SOC_SHIFT);
|
||||
HWRITE4(sc, TSADC_AUTO_PERIOD, auto_period);
|
||||
HWRITE4(sc, TSADC_AUTO_PERIOD_HT, auto_period_ht);
|
||||
HWRITE4(sc, TSADC_HIGHT_INT_DEBOUNCE, 4);
|
||||
HWRITE4(sc, TSADC_HIGHT_TSHUT_DEBOUNCE, 4);
|
||||
if (OF_is_compatible(sc->sc_node, "rockchip,rk3588-tsadc")) {
|
||||
uint32_t gpio_en, cru_en;
|
||||
|
||||
if (OF_is_compatible(sc->sc_node, "rockchip,rk3568-tsadc"))
|
||||
rktemp_rk3568_init(sc);
|
||||
sc->sc_data0 = TSADC_V3_DATA(0);
|
||||
|
||||
HWRITE4(sc, TSADC_V3_AUTO_PERIOD, auto_period);
|
||||
HWRITE4(sc, TSADC_V3_AUTO_PERIOD_HT, auto_period_ht);
|
||||
HWRITE4(sc, TSADC_V3_HIGHT_INT_DEBOUNCE, 4);
|
||||
HWRITE4(sc, TSADC_V3_HIGHT_TSHUT_DEBOUNCE, 4);
|
||||
|
||||
auto_con = HREAD4(sc, TSADC_AUTO_CON);
|
||||
auto_con |= TSADC_AUTO_CON_TSADC_Q_SEL;
|
||||
if (polarity)
|
||||
auto_con |= TSADC_AUTO_CON_TSHUT_POLARITY;
|
||||
HWRITE4(sc, TSADC_AUTO_CON, auto_con);
|
||||
auto_con = TSADC_AUTO_CON_TSHUT_POLARITY << 16;
|
||||
if (polarity)
|
||||
auto_con = TSADC_AUTO_CON_TSHUT_POLARITY;
|
||||
HWRITE4(sc, TSADC_AUTO_CON, auto_con);
|
||||
|
||||
/* Set shutdown limit. */
|
||||
for (i = 0; i < sc->sc_nsensors; i++) {
|
||||
HWRITE4(sc, TSADC_COMP0_SHUT + i * 4,
|
||||
rktemp_calc_code(sc, temp));
|
||||
auto_con |= (TSADC_AUTO_CON_SRC0_EN << i);
|
||||
/* Set shutdown limit. */
|
||||
for (i = 0; i < sc->sc_nsensors; i++) {
|
||||
HWRITE4(sc, TSADC_V3_COMP_SHUT(i),
|
||||
rktemp_calc_code(sc, temp));
|
||||
HWRITE4(sc, TSADC_V3_AUTO_SRC,
|
||||
TSADC_V3_AUTO_SRC_CH(i) << 16 |
|
||||
TSADC_V3_AUTO_SRC_CH(i));
|
||||
}
|
||||
|
||||
/* Clear shutdown output status. */
|
||||
for (i = 0; i < sc->sc_nsensors; i++) {
|
||||
HWRITE4(sc, TSADC_V3_HLT_INT_PD,
|
||||
TSADC_V3_HT_INT_STATUS(i));
|
||||
}
|
||||
|
||||
/* Configure mode. */
|
||||
gpio_en = cru_en = 0;
|
||||
for (i = 0; i < sc->sc_nsensors; i++) {
|
||||
gpio_en |= TSADC_V3_GPIO_EN_CH(i) << 16;
|
||||
cru_en |= TSADC_V3_CRU_EN_CH(i) << 16;
|
||||
if (mode)
|
||||
gpio_en |= TSADC_V3_GPIO_EN_CH(i);
|
||||
else
|
||||
cru_en |= TSADC_V3_CRU_EN_CH(i);
|
||||
}
|
||||
HWRITE4(sc, TSADC_V3_GPIO_EN, gpio_en);
|
||||
HWRITE4(sc, TSADC_V3_CRU_EN, cru_en);
|
||||
} else {
|
||||
uint32_t int_en;
|
||||
|
||||
sc->sc_data0 = TSADC_DATA(0);
|
||||
|
||||
HWRITE4(sc, TSADC_USER_CON,
|
||||
inter_pd_soc << TSADC_USER_CON_INTER_PD_SOC_SHIFT);
|
||||
HWRITE4(sc, TSADC_AUTO_PERIOD, auto_period);
|
||||
HWRITE4(sc, TSADC_AUTO_PERIOD_HT, auto_period_ht);
|
||||
HWRITE4(sc, TSADC_HIGHT_INT_DEBOUNCE, 4);
|
||||
HWRITE4(sc, TSADC_HIGHT_TSHUT_DEBOUNCE, 4);
|
||||
|
||||
if (OF_is_compatible(sc->sc_node, "rockchip,rk3568-tsadc"))
|
||||
rktemp_rk3568_init(sc);
|
||||
|
||||
auto_con = HREAD4(sc, TSADC_AUTO_CON);
|
||||
auto_con |= TSADC_AUTO_CON_TSADC_Q_SEL;
|
||||
if (polarity)
|
||||
auto_con |= TSADC_AUTO_CON_TSHUT_POLARITY;
|
||||
HWRITE4(sc, TSADC_AUTO_CON, auto_con);
|
||||
|
||||
/* Set shutdown limit. */
|
||||
for (i = 0; i < sc->sc_nsensors; i++) {
|
||||
HWRITE4(sc, TSADC_COMP_SHUT(i),
|
||||
rktemp_calc_code(sc, temp));
|
||||
auto_con |= (TSADC_AUTO_CON_SRC_EN(i));
|
||||
}
|
||||
HWRITE4(sc, TSADC_AUTO_CON, auto_con);
|
||||
|
||||
/* Clear shutdown output status. */
|
||||
for (i = 0; i < sc->sc_nsensors; i++)
|
||||
HWRITE4(sc, TSADC_INT_PD, TSADC_INT_PD_TSHUT_O_SRC(i));
|
||||
|
||||
/* Configure mode. */
|
||||
int_en = HREAD4(sc, TSADC_INT_EN);
|
||||
for (i = 0; i < sc->sc_nsensors; i++) {
|
||||
if (mode)
|
||||
int_en |= TSADC_INT_EN_TSHUT_2GPIO_EN_SRC(i);
|
||||
else
|
||||
int_en |= TSADC_INT_EN_TSHUT_2CRU_EN_SRC(i);
|
||||
}
|
||||
HWRITE4(sc, TSADC_INT_EN, int_en);
|
||||
}
|
||||
HWRITE4(sc, TSADC_AUTO_CON, auto_con);
|
||||
|
||||
/* Clear shutdown output status. */
|
||||
for (i = 0; i < sc->sc_nsensors; i++)
|
||||
HWRITE4(sc, TSADC_INT_PD, (TSADC_INT_PD_TSHUT_O_SRC0 << i));
|
||||
|
||||
/* Configure mode. */
|
||||
int_en = HREAD4(sc, TSADC_INT_EN);
|
||||
for (i = 0; i < sc->sc_nsensors; i++) {
|
||||
if (mode)
|
||||
int_en |= (TSADC_INT_EN_TSHUT_2GPIO_EN_SRC0 << i);
|
||||
else
|
||||
int_en |= (TSADC_INT_EN_TSHUT_2CRU_EN_SRC0 << i);
|
||||
}
|
||||
HWRITE4(sc, TSADC_INT_EN, int_en);
|
||||
|
||||
pinctrl_byname(sc->sc_node, "default");
|
||||
|
||||
/* Finally turn on the ADC. */
|
||||
auto_con |= TSADC_AUTO_CON_AUTO_EN;
|
||||
HWRITE4(sc, TSADC_AUTO_CON, auto_con);
|
||||
if (OF_is_compatible(sc->sc_node, "rockchip,rk3588-tsadc")) {
|
||||
HWRITE4(sc, TSADC_AUTO_CON,
|
||||
TSADC_AUTO_CON_AUTO_EN << 16 | TSADC_AUTO_CON_AUTO_EN);
|
||||
} else {
|
||||
auto_con |= TSADC_AUTO_CON_AUTO_EN;
|
||||
HWRITE4(sc, TSADC_AUTO_CON, auto_con);
|
||||
}
|
||||
|
||||
/* Register sensors. */
|
||||
strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
|
||||
@ -557,7 +633,7 @@ rktemp_refresh_sensors(void *arg)
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sc->sc_nsensors; i++) {
|
||||
code = HREAD4(sc, TSADC_DATA0 + i * 4);
|
||||
code = HREAD4(sc, sc->sc_data0 + (i * 4));
|
||||
temp = rktemp_calc_temp(sc, code);
|
||||
sc->sc_sensors[i].value = 273150000 + 1000 * temp;
|
||||
if (rktemp_valid(sc, code))
|
||||
@ -577,7 +653,7 @@ rktemp_get_temperature(void *cookie, uint32_t *cells)
|
||||
if (idx >= sc->sc_nsensors)
|
||||
return THERMAL_SENSOR_MAX;
|
||||
|
||||
code = HREAD4(sc, TSADC_DATA0 + idx * 4);
|
||||
code = HREAD4(sc, sc->sc_data0 + (idx * 4));
|
||||
if (rktemp_valid(sc, code))
|
||||
return rktemp_calc_temp(sc, code);
|
||||
else
|
||||
|
603
sys/dev/ic/ccp.c
603
sys/dev/ic/ccp.c
@ -1,7 +1,8 @@
|
||||
/* $OpenBSD: ccp.c,v 1.3 2020/05/29 04:42:25 deraadt Exp $ */
|
||||
/* $OpenBSD: ccp.c,v 1.4 2024/06/12 12:54:54 bluhm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2018 David Gwynne <dlg@openbsd.org>
|
||||
* Copyright (c) 2023, 2024 Hans-Joerg Hoexer <hshoexer@genua.de>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -26,6 +27,12 @@
|
||||
|
||||
#include <machine/bus.h>
|
||||
|
||||
#ifdef __amd64__
|
||||
#include <sys/proc.h>
|
||||
#include <uvm/uvm.h>
|
||||
#include <crypto/xform.h>
|
||||
#endif
|
||||
|
||||
#include <dev/ic/ccpvar.h>
|
||||
|
||||
#define CCP_REG_TRNG 0xc
|
||||
@ -38,13 +45,23 @@ struct cfdriver ccp_cd = {
|
||||
DV_DULL
|
||||
};
|
||||
|
||||
#ifdef __amd64__
|
||||
struct ccp_softc *ccp_softc;
|
||||
|
||||
int psp_get_pstatus(struct psp_platform_status *);
|
||||
int psp_init(struct psp_init *);
|
||||
#endif
|
||||
|
||||
void
|
||||
ccp_attach(struct ccp_softc *sc)
|
||||
{
|
||||
timeout_set(&sc->sc_tick, ccp_rng, sc);
|
||||
ccp_rng(sc);
|
||||
|
||||
printf("\n");
|
||||
if (sc->sc_psp_attached)
|
||||
printf(", RNG\n");
|
||||
else
|
||||
printf(": RNG\n");
|
||||
}
|
||||
|
||||
static void
|
||||
@ -59,3 +76,585 @@ ccp_rng(void *arg)
|
||||
|
||||
timeout_add_msec(&sc->sc_tick, 100);
|
||||
}
|
||||
|
||||
#ifdef __amd64__
|
||||
int
|
||||
psp_sev_intr(struct ccp_softc *sc, uint32_t status)
|
||||
{
|
||||
if (!(status & PSP_CMDRESP_COMPLETE))
|
||||
return (0);
|
||||
|
||||
wakeup(sc);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
psp_attach(struct ccp_softc *sc)
|
||||
{
|
||||
struct psp_platform_status pst;
|
||||
struct psp_init init;
|
||||
size_t size;
|
||||
int nsegs;
|
||||
|
||||
if (!(sc->sc_capabilities & PSP_CAP_SEV))
|
||||
return (0);
|
||||
|
||||
rw_init(&sc->sc_lock, "ccp_lock");
|
||||
|
||||
/* create and map SEV command buffer */
|
||||
sc->sc_cmd_size = size = PAGE_SIZE;
|
||||
if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
|
||||
BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW | BUS_DMA_64BIT,
|
||||
&sc->sc_cmd_map) != 0)
|
||||
return (0);
|
||||
|
||||
if (bus_dmamem_alloc(sc->sc_dmat, size, 0, 0, &sc->sc_cmd_seg, 1,
|
||||
&nsegs, BUS_DMA_WAITOK | BUS_DMA_ZERO) != 0)
|
||||
goto fail_0;
|
||||
|
||||
if (bus_dmamem_map(sc->sc_dmat, &sc->sc_cmd_seg, nsegs, size,
|
||||
&sc->sc_cmd_kva, BUS_DMA_WAITOK) != 0)
|
||||
goto fail_1;
|
||||
|
||||
if (bus_dmamap_load(sc->sc_dmat, sc->sc_cmd_map, sc->sc_cmd_kva,
|
||||
size, NULL, BUS_DMA_WAITOK) != 0)
|
||||
goto fail_2;
|
||||
|
||||
sc->sc_sev_intr = psp_sev_intr;
|
||||
ccp_softc = sc;
|
||||
|
||||
if (psp_get_pstatus(&pst) || pst.state != 0)
|
||||
goto fail_3;
|
||||
|
||||
printf(", SEV");
|
||||
|
||||
/*
|
||||
* create and map Trusted Memory Region (TMR); size 1 Mbyte,
|
||||
* needs to be aligend to 1 Mbyte.
|
||||
*/
|
||||
sc->sc_tmr_size = size = PSP_TMR_SIZE;
|
||||
if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
|
||||
BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW | BUS_DMA_64BIT,
|
||||
&sc->sc_tmr_map) != 0)
|
||||
goto fail_3;
|
||||
|
||||
if (bus_dmamem_alloc(sc->sc_dmat, size, size, 0, &sc->sc_tmr_seg, 1,
|
||||
&nsegs, BUS_DMA_WAITOK | BUS_DMA_ZERO) != 0)
|
||||
goto fail_4;
|
||||
|
||||
if (bus_dmamem_map(sc->sc_dmat, &sc->sc_tmr_seg, nsegs, size,
|
||||
&sc->sc_tmr_kva, BUS_DMA_WAITOK) != 0)
|
||||
goto fail_5;
|
||||
|
||||
if (bus_dmamap_load(sc->sc_dmat, sc->sc_tmr_map, sc->sc_tmr_kva,
|
||||
size, NULL, BUS_DMA_WAITOK) != 0)
|
||||
goto fail_6;
|
||||
|
||||
memset(&init, 0, sizeof(init));
|
||||
init.enable_es = 1;
|
||||
init.tmr_length = PSP_TMR_SIZE;
|
||||
init.tmr_paddr = sc->sc_tmr_map->dm_segs[0].ds_addr;
|
||||
if (psp_init(&init))
|
||||
goto fail_7;
|
||||
|
||||
psp_get_pstatus(&pst);
|
||||
if ((pst.state == 1) && (pst.cfges_build & 0x1))
|
||||
printf(", SEV-ES");
|
||||
|
||||
sc->sc_psp_attached = 1;
|
||||
|
||||
return (1);
|
||||
|
||||
fail_7:
|
||||
bus_dmamap_unload(sc->sc_dmat, sc->sc_tmr_map);
|
||||
fail_6:
|
||||
bus_dmamem_unmap(sc->sc_dmat, sc->sc_tmr_kva, size);
|
||||
fail_5:
|
||||
bus_dmamem_free(sc->sc_dmat, &sc->sc_tmr_seg, 1);
|
||||
fail_4:
|
||||
bus_dmamap_destroy(sc->sc_dmat, sc->sc_tmr_map);
|
||||
fail_3:
|
||||
bus_dmamap_unload(sc->sc_dmat, sc->sc_cmd_map);
|
||||
fail_2:
|
||||
bus_dmamem_unmap(sc->sc_dmat, sc->sc_cmd_kva, size);
|
||||
fail_1:
|
||||
bus_dmamem_free(sc->sc_dmat, &sc->sc_cmd_seg, 1);
|
||||
fail_0:
|
||||
bus_dmamap_destroy(sc->sc_dmat, sc->sc_cmd_map);
|
||||
|
||||
ccp_softc = NULL;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
ccp_wait(struct ccp_softc *sc, uint32_t *status, int poll)
|
||||
{
|
||||
uint32_t cmdword;
|
||||
int count;
|
||||
|
||||
if (poll) {
|
||||
count = 0;
|
||||
while (count++ < 10) {
|
||||
cmdword = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
|
||||
PSP_REG_CMDRESP);
|
||||
if (cmdword & PSP_CMDRESP_RESPONSE)
|
||||
goto done;
|
||||
delay(5000);
|
||||
}
|
||||
|
||||
/* timeout */
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (tsleep_nsec(sc, PWAIT, "psp", SEC_TO_NSEC(1)) == EWOULDBLOCK)
|
||||
return (1);
|
||||
|
||||
done:
|
||||
if (status) {
|
||||
*status = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
|
||||
PSP_REG_CMDRESP);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
ccp_docmd(struct ccp_softc *sc, int cmd, uint64_t paddr)
|
||||
{
|
||||
uint32_t plo, phi, cmdword, status;
|
||||
|
||||
plo = ((paddr >> 0) & 0xffffffff);
|
||||
phi = ((paddr >> 32) & 0xffffffff);
|
||||
cmdword = (cmd & 0x3f) << 16;
|
||||
if (!cold)
|
||||
cmdword |= PSP_CMDRESP_IOC;
|
||||
|
||||
bus_space_write_4(sc->sc_iot, sc->sc_ioh, PSP_REG_ADDRLO, plo);
|
||||
bus_space_write_4(sc->sc_iot, sc->sc_ioh, PSP_REG_ADDRHI, phi);
|
||||
bus_space_write_4(sc->sc_iot, sc->sc_ioh, PSP_REG_CMDRESP, cmdword);
|
||||
|
||||
if (ccp_wait(sc, &status, cold))
|
||||
return (1);
|
||||
|
||||
/* Did PSP sent a response code? */
|
||||
if (status & PSP_CMDRESP_RESPONSE) {
|
||||
if ((status & PSP_STATUS_MASK) != PSP_STATUS_SUCCESS) {
|
||||
printf("%s: command failed: 0x%x\n", __func__,
|
||||
(status & PSP_STATUS_MASK));
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
psp_init(struct psp_init *uinit)
|
||||
{
|
||||
struct ccp_softc *sc = ccp_softc;
|
||||
struct psp_init *init;
|
||||
int ret;
|
||||
|
||||
init = (struct psp_init *)sc->sc_cmd_kva;
|
||||
bzero(init, sizeof(*init));
|
||||
|
||||
init->enable_es = uinit->enable_es;
|
||||
init->tmr_paddr = uinit->tmr_paddr;
|
||||
init->tmr_length = uinit->tmr_length;
|
||||
|
||||
ret = ccp_docmd(sc, PSP_CMD_INIT, sc->sc_cmd_map->dm_segs[0].ds_addr);
|
||||
|
||||
wbinvd_on_all_cpus();
|
||||
|
||||
if (ret != 0)
|
||||
return (EIO);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
psp_get_pstatus(struct psp_platform_status *ustatus)
|
||||
{
|
||||
struct ccp_softc *sc = ccp_softc;
|
||||
struct psp_platform_status *status;
|
||||
int ret;
|
||||
|
||||
status = (struct psp_platform_status *)sc->sc_cmd_kva;
|
||||
bzero(status, sizeof(*status));
|
||||
|
||||
ret = ccp_docmd(sc, PSP_CMD_PLATFORMSTATUS,
|
||||
sc->sc_cmd_map->dm_segs[0].ds_addr);
|
||||
|
||||
if (ret != 0)
|
||||
return (EIO);
|
||||
|
||||
bcopy(status, ustatus, sizeof(*ustatus));
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
psp_df_flush(void)
|
||||
{
|
||||
struct ccp_softc *sc = ccp_softc;
|
||||
int ret;
|
||||
|
||||
wbinvd_on_all_cpus();
|
||||
|
||||
ret = ccp_docmd(sc, PSP_CMD_DF_FLUSH, 0x0);
|
||||
|
||||
if (ret != 0)
|
||||
return (EIO);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
psp_decommission(struct psp_decommission *udecom)
|
||||
{
|
||||
struct ccp_softc *sc = ccp_softc;
|
||||
struct psp_decommission *decom;
|
||||
int ret;
|
||||
|
||||
decom = (struct psp_decommission *)sc->sc_cmd_kva;
|
||||
bzero(decom, sizeof(*decom));
|
||||
|
||||
decom->handle = udecom->handle;
|
||||
|
||||
ret = ccp_docmd(sc, PSP_CMD_DECOMMISSION,
|
||||
sc->sc_cmd_map->dm_segs[0].ds_addr);
|
||||
|
||||
if (ret != 0)
|
||||
return (EIO);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
psp_get_gstatus(struct psp_guest_status *ustatus)
|
||||
{
|
||||
struct ccp_softc *sc = ccp_softc;
|
||||
struct psp_guest_status *status;
|
||||
int ret;
|
||||
|
||||
status = (struct psp_guest_status *)sc->sc_cmd_kva;
|
||||
bzero(status, sizeof(*status));
|
||||
|
||||
status->handle = ustatus->handle;
|
||||
|
||||
ret = ccp_docmd(sc, PSP_CMD_GUESTSTATUS,
|
||||
sc->sc_cmd_map->dm_segs[0].ds_addr);
|
||||
|
||||
if (ret != 0)
|
||||
return (EIO);
|
||||
|
||||
ustatus->policy = status->policy;
|
||||
ustatus->asid = status->asid;
|
||||
ustatus->state = status->state;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
psp_launch_start(struct psp_launch_start *ustart)
|
||||
{
|
||||
struct ccp_softc *sc = ccp_softc;
|
||||
struct psp_launch_start *start;
|
||||
int ret;
|
||||
|
||||
start = (struct psp_launch_start *)sc->sc_cmd_kva;
|
||||
bzero(start, sizeof(*start));
|
||||
|
||||
start->handle = ustart->handle;
|
||||
start->policy = ustart->policy;
|
||||
|
||||
ret = ccp_docmd(sc, PSP_CMD_LAUNCH_START,
|
||||
sc->sc_cmd_map->dm_segs[0].ds_addr);
|
||||
|
||||
if (ret != 0)
|
||||
return (EIO);
|
||||
|
||||
/* If requested, return new handle. */
|
||||
if (ustart->handle == 0)
|
||||
ustart->handle = start->handle;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
psp_launch_update_data(struct psp_launch_update_data *ulud, struct proc *p)
|
||||
{
|
||||
struct ccp_softc *sc = ccp_softc;
|
||||
struct psp_launch_update_data *ludata;
|
||||
pmap_t pmap;
|
||||
vaddr_t v, next, end;
|
||||
size_t size, len, off;
|
||||
int ret;
|
||||
|
||||
/* Ensure AES_XTS_BLOCKSIZE alignment and multiplicity. */
|
||||
if ((ulud->paddr & (AES_XTS_BLOCKSIZE - 1)) != 0 ||
|
||||
(ulud->length % AES_XTS_BLOCKSIZE) != 0)
|
||||
return (EINVAL);
|
||||
|
||||
ludata = (struct psp_launch_update_data *)sc->sc_cmd_kva;
|
||||
bzero(ludata, sizeof(*ludata));
|
||||
|
||||
ludata->handle = ulud->handle;
|
||||
|
||||
/* Drain caches before we encrypt memory. */
|
||||
wbinvd_on_all_cpus();
|
||||
|
||||
/*
|
||||
* Launch update one physical page at a time. We could
|
||||
* optimise this for contiguous pages of physical memory.
|
||||
*
|
||||
* vmd(8) provides the guest physical address, thus convert
|
||||
* to system physical address.
|
||||
*/
|
||||
pmap = vm_map_pmap(&p->p_vmspace->vm_map);
|
||||
size = ulud->length;
|
||||
end = ulud->paddr + ulud->length;
|
||||
for (v = ulud->paddr; v < end; v = next) {
|
||||
off = v & PAGE_MASK;
|
||||
|
||||
len = MIN(PAGE_SIZE - off, size);
|
||||
|
||||
/* Wire mapping. */
|
||||
if (uvm_map_pageable(&p->p_vmspace->vm_map, v, v+len, FALSE, 0))
|
||||
return (EINVAL);
|
||||
if (!pmap_extract(pmap, v, (paddr_t *)&ludata->paddr))
|
||||
return (EINVAL);
|
||||
ludata->length = len;
|
||||
|
||||
ret = ccp_docmd(sc, PSP_CMD_LAUNCH_UPDATE_DATA,
|
||||
sc->sc_cmd_map->dm_segs[0].ds_addr);
|
||||
|
||||
if (ret != 0)
|
||||
return (EIO);
|
||||
|
||||
size -= len;
|
||||
next = v + len;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
psp_launch_measure(struct psp_launch_measure *ulm)
|
||||
{
|
||||
struct psp_launch_measure *lm;
|
||||
struct ccp_softc *sc = ccp_softc;
|
||||
int ret;
|
||||
uint64_t paddr;
|
||||
|
||||
if (ulm->measure_len != sizeof(ulm->psp_measure))
|
||||
return (EINVAL);
|
||||
|
||||
lm = (struct psp_launch_measure *)sc->sc_cmd_kva;
|
||||
bzero(lm, sizeof(*lm));
|
||||
|
||||
lm->handle = ulm->handle;
|
||||
paddr = sc->sc_cmd_map->dm_segs[0].ds_addr;
|
||||
lm->measure_paddr =
|
||||
paddr + offsetof(struct psp_launch_measure, psp_measure);
|
||||
lm->measure_len = sizeof(lm->psp_measure);
|
||||
|
||||
ret = ccp_docmd(sc, PSP_CMD_LAUNCH_MEASURE, paddr);
|
||||
|
||||
if (ret != 0 || lm->measure_len != ulm->measure_len)
|
||||
return (EIO);
|
||||
|
||||
bcopy(&lm->psp_measure, &ulm->psp_measure, ulm->measure_len);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
psp_launch_finish(struct psp_launch_finish *ulf)
|
||||
{
|
||||
struct ccp_softc *sc = ccp_softc;
|
||||
struct psp_launch_finish *lf;
|
||||
int ret;
|
||||
|
||||
lf = (struct psp_launch_finish *)sc->sc_cmd_kva;
|
||||
bzero(lf, sizeof(*lf));
|
||||
|
||||
lf->handle = ulf->handle;
|
||||
|
||||
ret = ccp_docmd(sc, PSP_CMD_LAUNCH_FINISH,
|
||||
sc->sc_cmd_map->dm_segs[0].ds_addr);
|
||||
|
||||
if (ret != 0)
|
||||
return (EIO);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
psp_attestation(struct psp_attestation *uat)
|
||||
{
|
||||
struct ccp_softc *sc = ccp_softc;
|
||||
struct psp_attestation *at;
|
||||
int ret;
|
||||
uint64_t paddr;
|
||||
|
||||
if (uat->attest_len != sizeof(uat->psp_report))
|
||||
return (EINVAL);
|
||||
|
||||
at = (struct psp_attestation *)sc->sc_cmd_kva;
|
||||
bzero(at, sizeof(*at));
|
||||
|
||||
at->handle = uat->handle;
|
||||
paddr = sc->sc_cmd_map->dm_segs[0].ds_addr;
|
||||
at->attest_paddr =
|
||||
paddr + offsetof(struct psp_attestation, psp_report);
|
||||
bcopy(uat->attest_nonce, at->attest_nonce, sizeof(at->attest_nonce));
|
||||
at->attest_len = sizeof(at->psp_report);
|
||||
|
||||
ret = ccp_docmd(sc, PSP_CMD_ATTESTATION, paddr);
|
||||
|
||||
if (ret != 0 || at->attest_len != uat->attest_len)
|
||||
return (EIO);
|
||||
|
||||
bcopy(&at->psp_report, &uat->psp_report, uat->attest_len);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
psp_activate(struct psp_activate *uact)
|
||||
{
|
||||
struct ccp_softc *sc = ccp_softc;
|
||||
struct psp_activate *act;
|
||||
int ret;
|
||||
|
||||
act = (struct psp_activate *)sc->sc_cmd_kva;
|
||||
bzero(act, sizeof(*act));
|
||||
|
||||
act->handle = uact->handle;
|
||||
act->asid = uact->asid;
|
||||
|
||||
ret = ccp_docmd(sc, PSP_CMD_ACTIVATE,
|
||||
sc->sc_cmd_map->dm_segs[0].ds_addr);
|
||||
|
||||
if (ret != 0)
|
||||
return (EIO);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
psp_deactivate(struct psp_deactivate *udeact)
|
||||
{
|
||||
struct ccp_softc *sc = ccp_softc;
|
||||
struct psp_deactivate *deact;
|
||||
int ret;
|
||||
|
||||
deact = (struct psp_deactivate *)sc->sc_cmd_kva;
|
||||
bzero(deact, sizeof(*deact));
|
||||
|
||||
deact->handle = udeact->handle;
|
||||
|
||||
ret = ccp_docmd(sc, PSP_CMD_DEACTIVATE,
|
||||
sc->sc_cmd_map->dm_segs[0].ds_addr);
|
||||
|
||||
if (ret != 0)
|
||||
return (EIO);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
psp_snp_get_pstatus(struct psp_snp_platform_status *ustatus)
|
||||
{
|
||||
struct ccp_softc *sc = ccp_softc;
|
||||
struct psp_snp_platform_status *status;
|
||||
int ret;
|
||||
|
||||
status = (struct psp_snp_platform_status *)sc->sc_cmd_kva;
|
||||
bzero(status, sizeof(*status));
|
||||
|
||||
ret = ccp_docmd(sc, PSP_CMD_SNP_PLATFORMSTATUS,
|
||||
sc->sc_cmd_map->dm_segs[0].ds_addr);
|
||||
|
||||
if (ret != 0)
|
||||
return (EIO);
|
||||
|
||||
bcopy(status, ustatus, sizeof(*ustatus));
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
pspopen(dev_t dev, int flag, int mode, struct proc *p)
|
||||
{
|
||||
if (ccp_softc == NULL)
|
||||
return (ENODEV);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
pspclose(dev_t dev, int flag, int mode, struct proc *p)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
pspioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
|
||||
{
|
||||
int ret;
|
||||
|
||||
rw_enter_write(&ccp_softc->sc_lock);
|
||||
|
||||
switch (cmd) {
|
||||
case PSP_IOC_GET_PSTATUS:
|
||||
ret = psp_get_pstatus((struct psp_platform_status *)data);
|
||||
break;
|
||||
case PSP_IOC_DF_FLUSH:
|
||||
ret = psp_df_flush();
|
||||
break;
|
||||
case PSP_IOC_DECOMMISSION:
|
||||
ret = psp_decommission((struct psp_decommission *)data);
|
||||
break;
|
||||
case PSP_IOC_GET_GSTATUS:
|
||||
ret = psp_get_gstatus((struct psp_guest_status *)data);
|
||||
break;
|
||||
case PSP_IOC_LAUNCH_START:
|
||||
ret = psp_launch_start((struct psp_launch_start *)data);
|
||||
break;
|
||||
case PSP_IOC_LAUNCH_UPDATE_DATA:
|
||||
ret = psp_launch_update_data(
|
||||
(struct psp_launch_update_data *)data, p);
|
||||
break;
|
||||
case PSP_IOC_LAUNCH_MEASURE:
|
||||
ret = psp_launch_measure((struct psp_launch_measure *)data);
|
||||
break;
|
||||
case PSP_IOC_LAUNCH_FINISH:
|
||||
ret = psp_launch_finish((struct psp_launch_finish *)data);
|
||||
break;
|
||||
case PSP_IOC_ATTESTATION:
|
||||
ret = psp_attestation((struct psp_attestation *)data);
|
||||
break;
|
||||
case PSP_IOC_ACTIVATE:
|
||||
ret = psp_activate((struct psp_activate *)data);
|
||||
break;
|
||||
case PSP_IOC_DEACTIVATE:
|
||||
ret = psp_deactivate((struct psp_deactivate *)data);
|
||||
break;
|
||||
case PSP_IOC_SNP_GET_PSTATUS:
|
||||
ret =
|
||||
psp_snp_get_pstatus((struct psp_snp_platform_status *)data);
|
||||
break;
|
||||
default:
|
||||
printf("%s: unkown ioctl code 0x%lx\n", __func__, cmd);
|
||||
ret = ENOTTY;
|
||||
}
|
||||
|
||||
rw_exit_write(&ccp_softc->sc_lock);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
#endif /* __amd64__ */
|
||||
|
@ -1,7 +1,8 @@
|
||||
/* $OpenBSD: ccpvar.h,v 1.1 2018/04/20 04:37:21 dlg Exp $ */
|
||||
/* $OpenBSD: ccpvar.h,v 1.2 2024/06/12 12:54:54 bluhm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2018 David Gwynne <dlg@openbsd.org>
|
||||
* Copyright (c) 2023, 2024 Hans-Joerg Hoexer <hshoexer@genua.de>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -24,6 +25,266 @@ struct ccp_softc {
|
||||
bus_space_handle_t sc_ioh;
|
||||
|
||||
struct timeout sc_tick;
|
||||
|
||||
bus_size_t sc_size;
|
||||
int sc_psp_attached;
|
||||
|
||||
#ifdef __amd64__
|
||||
bus_dma_tag_t sc_dmat;
|
||||
uint32_t sc_capabilities;
|
||||
int (*sc_sev_intr)(struct ccp_softc *, uint32_t);
|
||||
void * sc_ih;
|
||||
|
||||
bus_dmamap_t sc_cmd_map;
|
||||
bus_dma_segment_t sc_cmd_seg;
|
||||
size_t sc_cmd_size;
|
||||
caddr_t sc_cmd_kva;
|
||||
|
||||
bus_dmamap_t sc_tmr_map;
|
||||
bus_dma_segment_t sc_tmr_seg;
|
||||
size_t sc_tmr_size;
|
||||
caddr_t sc_tmr_kva;
|
||||
|
||||
struct rwlock sc_lock;
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef __amd64__
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/rwlock.h>
|
||||
|
||||
/* AMD 17h */
|
||||
#define PSP_REG_INTEN 0x10690
|
||||
#define PSP_REG_INTSTS 0x10694
|
||||
#define PSP_REG_CMDRESP 0x10980
|
||||
#define PSP_REG_ADDRLO 0x109e0
|
||||
#define PSP_REG_ADDRHI 0x109e4
|
||||
#define PSP_REG_CAPABILITIES 0x109fc
|
||||
|
||||
#define PSP_PSTATE_UNINIT 0x0
|
||||
#define PSP_PSTATE_INIT 0x1
|
||||
#define PSP_PSTATE_WORKING 0x2
|
||||
|
||||
#define PSP_GSTATE_UNINIT 0x0
|
||||
#define PSP_GSTATE_LUPDATE 0x1
|
||||
#define PSP_GSTATE_LSECRET 0x2
|
||||
#define PSP_GSTATE_RUNNING 0x3
|
||||
#define PSP_GSTATE_SUPDATE 0x4
|
||||
#define PSP_GSTATE_RUPDATE 0x5
|
||||
#define PSP_GSTATE_SENT 0x6
|
||||
|
||||
#define PSP_CAP_SEV (1 << 0)
|
||||
#define PSP_CAP_TEE (1 << 1)
|
||||
#define PSP_CAP_DBC_THRU_EXT (1 << 2)
|
||||
#define PSP_CAP_SECURITY_REPORTING (1 << 7)
|
||||
#define PSP_CAP_SECURITY_FUSED_PART (1 << 8)
|
||||
#define PSP_CAP_SECURITY_DEBUG_LOCK_ON (1 << 10)
|
||||
#define PSP_CAP_SECURITY_TSME_STATUS (1 << 13)
|
||||
#define PSP_CAP_SECURITY_ANTI_ROLLBACK_STATUS (1 << 15)
|
||||
#define PSP_CAP_SECURITY_RPMC_PRODUCTION_ENABLED (1 << 16)
|
||||
#define PSP_CAP_SECURITY_RPMC_SPIROM_AVAILABLE (1 << 17)
|
||||
#define PSP_CAP_SECURITY_HSP_TPM_AVAILABLE (1 << 18)
|
||||
#define PSP_CAP_SECURITY_ROM_ARMOR_ENFORCED (1 << 19)
|
||||
|
||||
#define PSP_CAP_BITS "\20\001SEV\002TEE\003DBC_THRU_EXT\010REPORTING\011FUSED_PART\013DEBUG_LOCK_ON\016TSME_STATUS\020ANTI_ROLLBACK_STATUS\021RPMC_PRODUCTION_ENABLED\022RPMC_SPIROM_AVAILABLE\023HSP_TPM_AVAILABLE\024ROM_ARMOR_ENFORCED"
|
||||
|
||||
#define PSP_CMDRESP_IOC (1 << 0)
|
||||
#define PSP_CMDRESP_COMPLETE (1 << 1)
|
||||
#define PSP_CMDRESP_RESPONSE (1 << 31)
|
||||
|
||||
#define PSP_STATUS_MASK 0xffff
|
||||
#define PSP_STATUS_SUCCESS 0x0000
|
||||
#define PSP_STATUS_INVALID_PLATFORM_STATE 0x0001
|
||||
|
||||
#define PSP_TMR_SIZE (1024*1024) /* 1 Mb */
|
||||
|
||||
#define PSP_SUCCESS 0x0000
|
||||
#define PSP_INVALID_ADDRESS 0x0009
|
||||
|
||||
/* Selection of PSP commands of the SEV API Version 0.24 */
|
||||
|
||||
#define PSP_CMD_INIT 0x1
|
||||
#define PSP_CMD_PLATFORMSTATUS 0x4
|
||||
#define PSP_CMD_DF_FLUSH 0xa
|
||||
#define PSP_CMD_DECOMMISSION 0x20
|
||||
#define PSP_CMD_ACTIVATE 0x21
|
||||
#define PSP_CMD_DEACTIVATE 0x22
|
||||
#define PSP_CMD_GUESTSTATUS 0x23
|
||||
#define PSP_CMD_LAUNCH_START 0x30
|
||||
#define PSP_CMD_LAUNCH_UPDATE_DATA 0x31
|
||||
#define PSP_CMD_LAUNCH_MEASURE 0x33
|
||||
#define PSP_CMD_LAUNCH_FINISH 0x35
|
||||
#define PSP_CMD_ATTESTATION 0x36
|
||||
|
||||
struct psp_platform_status {
|
||||
/* Output parameters from PSP_CMD_PLATFORMSTATUS */
|
||||
uint8_t api_major;
|
||||
uint8_t api_minor;
|
||||
uint8_t state;
|
||||
uint8_t owner;
|
||||
uint32_t cfges_build;
|
||||
uint32_t guest_count;
|
||||
} __packed;
|
||||
|
||||
struct psp_guest_status {
|
||||
/* Input parameter for PSP_CMD_GUESTSTATUS */
|
||||
uint32_t handle;
|
||||
|
||||
/* Output parameters from PSP_CMD_GUESTSTATUS */
|
||||
uint32_t policy;
|
||||
uint32_t asid;
|
||||
uint8_t state;
|
||||
} __packed;
|
||||
|
||||
struct psp_launch_start {
|
||||
/* Input/Output parameter for PSP_CMD_LAUNCH_START */
|
||||
uint32_t handle;
|
||||
|
||||
/* Input parameters for PSP_CMD_LAUNCH_START */
|
||||
uint32_t policy;
|
||||
|
||||
/* The following input parameters are not used yet */
|
||||
uint64_t dh_cert_paddr;
|
||||
uint32_t dh_cert_len;
|
||||
uint32_t reserved;
|
||||
uint64_t session_paddr;
|
||||
uint32_t session_len;
|
||||
} __packed;
|
||||
|
||||
struct psp_launch_update_data {
|
||||
/* Input parameters for PSP_CMD_LAUNCH_UPDATE_DATA */
|
||||
uint32_t handle;
|
||||
uint32_t reserved;
|
||||
uint64_t paddr;
|
||||
uint32_t length;
|
||||
} __packed;
|
||||
|
||||
struct psp_measure {
|
||||
/* Output buffer for PSP_CMD_LAUNCH_MEASURE */
|
||||
uint8_t measure[32];
|
||||
uint8_t measure_nonce[16];
|
||||
} __packed;
|
||||
|
||||
struct psp_launch_measure {
|
||||
/* Input parameters for PSP_CMD_LAUNCH_MEASURE */
|
||||
uint32_t handle;
|
||||
uint32_t reserved;
|
||||
uint64_t measure_paddr;
|
||||
|
||||
/* Input/output parameter for PSP_CMD_LAUNCH_MEASURE */
|
||||
uint32_t measure_len;
|
||||
uint32_t padding;
|
||||
|
||||
/* Output buffer from PSP_CMD_LAUNCH_MEASURE */
|
||||
struct psp_measure psp_measure; /* 64bit aligned */
|
||||
#define measure psp_measure.measure
|
||||
#define measure_nonce psp_measure.measure_nonce
|
||||
} __packed;
|
||||
|
||||
struct psp_launch_finish {
|
||||
/* Input parameter for PSP_CMD_LAUNCH_FINISH */
|
||||
uint32_t handle;
|
||||
} __packed;
|
||||
|
||||
struct psp_report {
|
||||
/* Output buffer for PSP_CMD_ATTESTATION */
|
||||
uint8_t report_nonce[16];
|
||||
uint8_t report_launch_digest[32];
|
||||
uint32_t report_policy;
|
||||
uint32_t report_sig_usage;
|
||||
uint32_t report_sig_algo;
|
||||
uint32_t reserved2;
|
||||
uint8_t report_sig1[144];
|
||||
} __packed;
|
||||
|
||||
struct psp_attestation {
|
||||
/* Input parameters for PSP_CMD_ATTESTATION */
|
||||
uint32_t handle;
|
||||
uint32_t reserved;
|
||||
uint64_t attest_paddr;
|
||||
uint8_t attest_nonce[16];
|
||||
|
||||
/* Input/output parameter from PSP_CMD_ATTESTATION */
|
||||
uint32_t attest_len;
|
||||
uint32_t padding;
|
||||
|
||||
/* Output parameter from PSP_CMD_ATTESTATION */
|
||||
struct psp_report psp_report; /* 64bit aligned */
|
||||
#define report_nonce psp_report.report_nonce
|
||||
#define report_launch_digest psp_report.report_launch_digest
|
||||
#define report_policy psp_report.report_policy
|
||||
#define report_sig_usage psp_report.report_sig_usage;
|
||||
#define report_report_sig_alg psp_report.report_sig_algo;
|
||||
#define report_report_sig1 psp_report.report_sig1;
|
||||
} __packed;
|
||||
|
||||
struct psp_activate {
|
||||
/* Input parameters for PSP_CMD_ACTIVATE */
|
||||
uint32_t handle;
|
||||
uint32_t asid;
|
||||
} __packed;
|
||||
|
||||
struct psp_deactivate {
|
||||
/* Input parameter for PSP_CMD_DEACTIVATE */
|
||||
uint32_t handle;
|
||||
} __packed;
|
||||
|
||||
struct psp_decommission {
|
||||
/* Input parameter for PSP_CMD_DECOMMISSION */
|
||||
uint32_t handle;
|
||||
} __packed;
|
||||
|
||||
struct psp_init {
|
||||
/* Output parameters from PSP_CMD_INIT */
|
||||
uint32_t enable_es;
|
||||
uint32_t reserved;
|
||||
uint64_t tmr_paddr;
|
||||
uint32_t tmr_length;
|
||||
} __packed;
|
||||
|
||||
|
||||
/* Selection of PSP commands of the SEV-SNP ABI Version 1.55 */
|
||||
|
||||
#define PSP_CMD_SNP_PLATFORMSTATUS 0x81
|
||||
|
||||
struct psp_snp_platform_status {
|
||||
uint8_t api_major;
|
||||
uint8_t api_minor;
|
||||
uint8_t state;
|
||||
uint8_t is_rmp_init;
|
||||
uint32_t build;
|
||||
uint32_t features;
|
||||
uint32_t guest_count;
|
||||
uint64_t current_tcb;
|
||||
uint64_t reported_tcb;
|
||||
} __packed;
|
||||
|
||||
#define PSP_IOC_GET_PSTATUS _IOR('P', 0, struct psp_platform_status)
|
||||
#define PSP_IOC_DF_FLUSH _IO('P', 1)
|
||||
#define PSP_IOC_DECOMMISSION _IOW('P', 2, struct psp_decommission)
|
||||
#define PSP_IOC_GET_GSTATUS _IOWR('P', 3, struct psp_guest_status)
|
||||
#define PSP_IOC_LAUNCH_START _IOWR('P', 4, struct psp_launch_start)
|
||||
#define PSP_IOC_LAUNCH_UPDATE_DATA \
|
||||
_IOW('P', 5, struct psp_launch_update_data)
|
||||
#define PSP_IOC_LAUNCH_MEASURE _IOWR('P', 6, struct psp_launch_measure)
|
||||
#define PSP_IOC_LAUNCH_FINISH _IOW('P', 7, struct psp_launch_finish)
|
||||
#define PSP_IOC_ATTESTATION _IOWR('P', 8, struct psp_attestation)
|
||||
#define PSP_IOC_ACTIVATE _IOW('P', 9, struct psp_activate)
|
||||
#define PSP_IOC_DEACTIVATE _IOW('P', 10, struct psp_deactivate)
|
||||
#define PSP_IOC_SNP_GET_PSTATUS _IOR('P', 11, struct psp_snp_platform_status)
|
||||
#endif /* __amd64__ */
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
void ccp_attach(struct ccp_softc *);
|
||||
|
||||
#ifdef __amd64__
|
||||
int psp_attach(struct ccp_softc *);
|
||||
|
||||
int pspclose(dev_t, int, int, struct proc *);
|
||||
int pspopen(dev_t, int, int, struct proc *);
|
||||
int pspioctl(dev_t, u_long, caddr_t, int, struct proc *);
|
||||
#endif
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: ccp_pci.c,v 1.9 2024/05/24 06:02:53 jsg Exp $ */
|
||||
/* $OpenBSD: ccp_pci.c,v 1.10 2024/06/12 12:54:54 bluhm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2018 David Gwynne <dlg@openbsd.org>
|
||||
@ -33,6 +33,11 @@
|
||||
int ccp_pci_match(struct device *, void *, void *);
|
||||
void ccp_pci_attach(struct device *, struct device *, void *);
|
||||
|
||||
#ifdef __amd64__
|
||||
void psp_pci_attach(struct device *, struct device *, void *);
|
||||
int psp_pci_intr(void *);
|
||||
#endif
|
||||
|
||||
const struct cfattach ccp_pci_ca = {
|
||||
sizeof(struct ccp_softc),
|
||||
ccp_pci_match,
|
||||
@ -69,10 +74,67 @@ ccp_pci_attach(struct device *parent, struct device *self, void *aux)
|
||||
}
|
||||
|
||||
if (pci_mapreg_map(pa, CCP_PCI_BAR, memtype, 0,
|
||||
&sc->sc_iot, &sc->sc_ioh, NULL, NULL, 0) != 0) {
|
||||
&sc->sc_iot, &sc->sc_ioh, NULL, &sc->sc_size, 0) != 0) {
|
||||
printf(": cannot map registers\n");
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef __amd64__
|
||||
psp_pci_attach(parent, self, aux);
|
||||
#endif
|
||||
|
||||
ccp_attach(sc);
|
||||
}
|
||||
|
||||
#ifdef __amd64__
|
||||
void
|
||||
psp_pci_attach(struct device *parent, struct device *self, void *aux)
|
||||
{
|
||||
struct ccp_softc *sc = (struct ccp_softc *)self;
|
||||
struct pci_attach_args *pa = aux;
|
||||
pci_intr_handle_t ih;
|
||||
const char *intrstr = NULL;
|
||||
|
||||
sc->sc_dmat = pa->pa_dmat;
|
||||
|
||||
sc->sc_capabilities = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
|
||||
PSP_REG_CAPABILITIES);
|
||||
|
||||
/* clear and disable interrupts */
|
||||
bus_space_write_4(sc->sc_iot, sc->sc_ioh, PSP_REG_INTEN, 0);
|
||||
bus_space_write_4(sc->sc_iot, sc->sc_ioh, PSP_REG_INTSTS, -1);
|
||||
|
||||
if (pci_intr_map_msix(pa, 0, &ih) != 0 &&
|
||||
pci_intr_map_msi(pa, &ih) != 0 && pci_intr_map(pa, &ih) != 0) {
|
||||
printf(": couldn't map interrupt\n");
|
||||
bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_size);
|
||||
return;
|
||||
}
|
||||
|
||||
intrstr = pci_intr_string(pa->pa_pc, ih);
|
||||
sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, psp_pci_intr,
|
||||
sc, sc->sc_dev.dv_xname);
|
||||
if (sc->sc_ih != NULL)
|
||||
printf(": %s", intrstr);
|
||||
|
||||
if (psp_attach(sc)) {
|
||||
/* enable interrupts */
|
||||
bus_space_write_4(sc->sc_iot, sc->sc_ioh, PSP_REG_INTEN, -1);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
psp_pci_intr(void *arg)
|
||||
{
|
||||
struct ccp_softc *sc = arg;
|
||||
uint32_t status;
|
||||
|
||||
status = bus_space_read_4(sc->sc_iot, sc->sc_ioh, PSP_REG_INTSTS);
|
||||
bus_space_write_4(sc->sc_iot, sc->sc_ioh, PSP_REG_INTSTS, status);
|
||||
|
||||
if (sc->sc_sev_intr)
|
||||
return (sc->sc_sev_intr(sc, status));
|
||||
|
||||
return (1);
|
||||
}
|
||||
#endif /* __amd64__ */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: servconf.c,v 1.410 2024/06/11 00:36:20 djm Exp $ */
|
||||
/* $OpenBSD: servconf.c,v 1.411 2024/06/12 22:36:00 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
@ -147,8 +147,10 @@ initialize_server_options(ServerOptions *options)
|
||||
options->per_source_masklen_ipv6 = -1;
|
||||
options->per_source_penalty_exempt = NULL;
|
||||
options->per_source_penalty.enabled = -1;
|
||||
options->per_source_penalty.max_sources = -1;
|
||||
options->per_source_penalty.max_sources4 = -1;
|
||||
options->per_source_penalty.max_sources6 = -1;
|
||||
options->per_source_penalty.overflow_mode = -1;
|
||||
options->per_source_penalty.overflow_mode6 = -1;
|
||||
options->per_source_penalty.penalty_crash = -1;
|
||||
options->per_source_penalty.penalty_authfail = -1;
|
||||
options->per_source_penalty.penalty_noauth = -1;
|
||||
@ -389,10 +391,14 @@ fill_default_server_options(ServerOptions *options)
|
||||
options->per_source_masklen_ipv6 = 128;
|
||||
if (options->per_source_penalty.enabled == -1)
|
||||
options->per_source_penalty.enabled = 1;
|
||||
if (options->per_source_penalty.max_sources == -1)
|
||||
options->per_source_penalty.max_sources = 65536;
|
||||
if (options->per_source_penalty.max_sources4 == -1)
|
||||
options->per_source_penalty.max_sources4 = 65536;
|
||||
if (options->per_source_penalty.max_sources6 == -1)
|
||||
options->per_source_penalty.max_sources6 = 65536;
|
||||
if (options->per_source_penalty.overflow_mode == -1)
|
||||
options->per_source_penalty.overflow_mode = PER_SOURCE_PENALTY_OVERFLOW_PERMISSIVE;
|
||||
if (options->per_source_penalty.overflow_mode6 == -1)
|
||||
options->per_source_penalty.overflow_mode6 = options->per_source_penalty.overflow_mode;
|
||||
if (options->per_source_penalty.penalty_crash == -1)
|
||||
options->per_source_penalty.penalty_crash = 90;
|
||||
if (options->per_source_penalty.penalty_grace == -1)
|
||||
@ -1971,9 +1977,14 @@ process_server_config_line_depth(ServerOptions *options, char *line,
|
||||
} else if (strncmp(arg, "min:", 4) == 0) {
|
||||
p = arg + 4;
|
||||
intptr = &options->per_source_penalty.penalty_min;
|
||||
} else if (strncmp(arg, "max-sources:", 12) == 0) {
|
||||
intptr = &options->per_source_penalty.max_sources;
|
||||
if ((errstr = atoi_err(arg+12, &value)) != NULL)
|
||||
} else if (strncmp(arg, "max-sources4:", 13) == 0) {
|
||||
intptr = &options->per_source_penalty.max_sources4;
|
||||
if ((errstr = atoi_err(arg+13, &value)) != NULL)
|
||||
fatal("%s line %d: %s value %s.",
|
||||
filename, linenum, keyword, errstr);
|
||||
} else if (strncmp(arg, "max-sources6:", 13) == 0) {
|
||||
intptr = &options->per_source_penalty.max_sources6;
|
||||
if ((errstr = atoi_err(arg+13, &value)) != NULL)
|
||||
fatal("%s line %d: %s value %s.",
|
||||
filename, linenum, keyword, errstr);
|
||||
} else if (strcmp(arg, "overflow:deny-all") == 0) {
|
||||
@ -1982,6 +1993,12 @@ process_server_config_line_depth(ServerOptions *options, char *line,
|
||||
} else if (strcmp(arg, "overflow:permissive") == 0) {
|
||||
intptr = &options->per_source_penalty.overflow_mode;
|
||||
value = PER_SOURCE_PENALTY_OVERFLOW_PERMISSIVE;
|
||||
} else if (strcmp(arg, "overflow6:deny-all") == 0) {
|
||||
intptr = &options->per_source_penalty.overflow_mode6;
|
||||
value = PER_SOURCE_PENALTY_OVERFLOW_DENY_ALL;
|
||||
} else if (strcmp(arg, "overflow6:permissive") == 0) {
|
||||
intptr = &options->per_source_penalty.overflow_mode6;
|
||||
value = PER_SOURCE_PENALTY_OVERFLOW_PERMISSIVE;
|
||||
} else {
|
||||
fatal("%s line %d: unsupported %s keyword %s",
|
||||
filename, linenum, keyword, arg);
|
||||
@ -3218,16 +3235,21 @@ dump_config(ServerOptions *o)
|
||||
|
||||
if (o->per_source_penalty.enabled) {
|
||||
printf("persourcepenalties crash:%d authfail:%d noauth:%d "
|
||||
"grace-exceeded:%d max:%d min:%d max-sources:%d "
|
||||
"overflow:%s\n", o->per_source_penalty.penalty_crash,
|
||||
"grace-exceeded:%d max:%d min:%d max-sources4:%d "
|
||||
"max-sources6:%d overflow:%s overflow6:%s\n",
|
||||
o->per_source_penalty.penalty_crash,
|
||||
o->per_source_penalty.penalty_authfail,
|
||||
o->per_source_penalty.penalty_noauth,
|
||||
o->per_source_penalty.penalty_grace,
|
||||
o->per_source_penalty.penalty_max,
|
||||
o->per_source_penalty.penalty_min,
|
||||
o->per_source_penalty.max_sources,
|
||||
o->per_source_penalty.max_sources4,
|
||||
o->per_source_penalty.max_sources6,
|
||||
o->per_source_penalty.overflow_mode ==
|
||||
PER_SOURCE_PENALTY_OVERFLOW_DENY_ALL ?
|
||||
"deny-all" : "permissive",
|
||||
o->per_source_penalty.overflow_mode6 ==
|
||||
PER_SOURCE_PENALTY_OVERFLOW_DENY_ALL ?
|
||||
"deny-all" : "permissive");
|
||||
} else
|
||||
printf("persourcepenalties no\n");
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: servconf.h,v 1.164 2024/06/06 17:15:25 djm Exp $ */
|
||||
/* $OpenBSD: servconf.h,v 1.165 2024/06/12 22:36:00 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -69,8 +69,10 @@ struct listenaddr {
|
||||
#define PER_SOURCE_PENALTY_OVERFLOW_PERMISSIVE 2
|
||||
struct per_source_penalty {
|
||||
int enabled;
|
||||
int max_sources;
|
||||
int max_sources4;
|
||||
int max_sources6;
|
||||
int overflow_mode;
|
||||
int overflow_mode6;
|
||||
int penalty_crash;
|
||||
int penalty_grace;
|
||||
int penalty_authfail;
|
||||
|
@ -59,11 +59,11 @@ struct penalty {
|
||||
};
|
||||
static int penalty_addr_cmp(struct penalty *a, struct penalty *b);
|
||||
static int penalty_expiry_cmp(struct penalty *a, struct penalty *b);
|
||||
RB_HEAD(penalties_by_addr, penalty) penalties_by_addr;
|
||||
RB_HEAD(penalties_by_expiry, penalty) penalties_by_expiry;
|
||||
RB_HEAD(penalties_by_addr, penalty) penalties_by_addr4, penalties_by_addr6;
|
||||
RB_HEAD(penalties_by_expiry, penalty) penalties_by_expiry4, penalties_by_expiry6;
|
||||
RB_GENERATE_STATIC(penalties_by_addr, penalty, by_addr, penalty_addr_cmp)
|
||||
RB_GENERATE_STATIC(penalties_by_expiry, penalty, by_expiry, penalty_expiry_cmp)
|
||||
static size_t npenalties;
|
||||
static size_t npenalties4, npenalties6;
|
||||
|
||||
static int
|
||||
srclimit_mask_addr(const struct xaddr *addr, int bits, struct xaddr *masked)
|
||||
@ -104,10 +104,14 @@ srclimit_init(int max, int persource, int ipv4len, int ipv6len,
|
||||
ipv6_masklen = ipv6len;
|
||||
max_persource = persource;
|
||||
penalty_cfg = *penalty_conf;
|
||||
if (penalty_cfg.max_sources4 < 0 || penalty_cfg.max_sources6 < 0)
|
||||
fatal_f("invalid max_sources"); /* shouldn't happen */
|
||||
penalty_exempt = penalty_exempt_conf == NULL ?
|
||||
NULL : xstrdup(penalty_exempt_conf);
|
||||
RB_INIT(&penalties_by_addr);
|
||||
RB_INIT(&penalties_by_expiry);
|
||||
RB_INIT(&penalties_by_addr4);
|
||||
RB_INIT(&penalties_by_expiry4);
|
||||
RB_INIT(&penalties_by_addr6);
|
||||
RB_INIT(&penalties_by_expiry6);
|
||||
if (max_persource == INT_MAX) /* no limit */
|
||||
return;
|
||||
debug("%s: max connections %d, per source %d, masks %d,%d", __func__,
|
||||
@ -206,26 +210,36 @@ penalty_expiry_cmp(struct penalty *a, struct penalty *b)
|
||||
}
|
||||
|
||||
static void
|
||||
expire_penalties(time_t now)
|
||||
expire_penalties_from_tree(time_t now, const char *t,
|
||||
struct penalties_by_expiry *by_expiry,
|
||||
struct penalties_by_addr *by_addr, size_t *npenaltiesp)
|
||||
{
|
||||
struct penalty *penalty, *tmp;
|
||||
|
||||
/* XXX avoid full scan of tree, e.g. min-heap */
|
||||
RB_FOREACH_SAFE(penalty, penalties_by_expiry,
|
||||
&penalties_by_expiry, tmp) {
|
||||
RB_FOREACH_SAFE(penalty, penalties_by_expiry, by_expiry, tmp) {
|
||||
if (penalty->expiry >= now)
|
||||
break;
|
||||
if (RB_REMOVE(penalties_by_expiry, &penalties_by_expiry,
|
||||
if (RB_REMOVE(penalties_by_expiry, by_expiry,
|
||||
penalty) != penalty ||
|
||||
RB_REMOVE(penalties_by_addr, &penalties_by_addr,
|
||||
RB_REMOVE(penalties_by_addr, by_addr,
|
||||
penalty) != penalty)
|
||||
fatal_f("internal error: penalty tables corrupt");
|
||||
fatal_f("internal error: %s penalty table corrupt", t);
|
||||
free(penalty);
|
||||
if (npenalties-- == 0)
|
||||
fatal_f("internal error: npenalties underflow");
|
||||
if ((*npenaltiesp)-- == 0)
|
||||
fatal_f("internal error: %s npenalties underflow", t);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
expire_penalties(time_t now)
|
||||
{
|
||||
expire_penalties_from_tree(now, "ipv4",
|
||||
&penalties_by_expiry4, &penalties_by_addr4, &npenalties4);
|
||||
expire_penalties_from_tree(now, "ipv6",
|
||||
&penalties_by_expiry6, &penalties_by_addr6, &npenalties6);
|
||||
}
|
||||
|
||||
static void
|
||||
addr_masklen_ntop(struct xaddr *addr, int masklen, char *s, size_t slen)
|
||||
{
|
||||
@ -245,8 +259,10 @@ srclimit_penalty_check_allow(int sock, const char **reason)
|
||||
struct xaddr addr;
|
||||
struct penalty find, *penalty;
|
||||
time_t now;
|
||||
int bits;
|
||||
int bits, max_sources, overflow_mode;
|
||||
char addr_s[NI_MAXHOST];
|
||||
struct penalties_by_addr *by_addr;
|
||||
size_t npenalties;
|
||||
|
||||
if (!penalty_cfg.enabled)
|
||||
return 1;
|
||||
@ -259,8 +275,17 @@ srclimit_penalty_check_allow(int sock, const char **reason)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (npenalties >= (size_t)penalty_cfg.max_sources &&
|
||||
penalty_cfg.overflow_mode == PER_SOURCE_PENALTY_OVERFLOW_DENY_ALL) {
|
||||
now = monotime();
|
||||
expire_penalties(now);
|
||||
by_addr = addr.af == AF_INET ?
|
||||
&penalties_by_addr4 : &penalties_by_addr6;
|
||||
max_sources = addr.af == AF_INET ?
|
||||
penalty_cfg.max_sources4 : penalty_cfg.max_sources6;
|
||||
overflow_mode = addr.af == AF_INET ?
|
||||
penalty_cfg.overflow_mode : penalty_cfg.overflow_mode6;
|
||||
npenalties = addr.af == AF_INET ? npenalties4 : npenalties6;
|
||||
if (npenalties >= (size_t)max_sources &&
|
||||
overflow_mode == PER_SOURCE_PENALTY_OVERFLOW_DENY_ALL) {
|
||||
*reason = "too many penalised addresses";
|
||||
return 0;
|
||||
}
|
||||
@ -268,9 +293,7 @@ srclimit_penalty_check_allow(int sock, const char **reason)
|
||||
memset(&find, 0, sizeof(find));
|
||||
if (srclimit_mask_addr(&addr, bits, &find.addr) != 0)
|
||||
return 1;
|
||||
now = monotime();
|
||||
if ((penalty = RB_FIND(penalties_by_addr,
|
||||
&penalties_by_addr, &find)) == NULL)
|
||||
if ((penalty = RB_FIND(penalties_by_addr, by_addr, &find)) == NULL)
|
||||
return 1; /* no penalty */
|
||||
if (penalty->expiry < now) {
|
||||
expire_penalties(now);
|
||||
@ -283,38 +306,52 @@ srclimit_penalty_check_allow(int sock, const char **reason)
|
||||
}
|
||||
|
||||
static void
|
||||
srclimit_remove_expired_penalties(void)
|
||||
srclimit_early_expire_penalties_from_tree(const char *t,
|
||||
struct penalties_by_expiry *by_expiry,
|
||||
struct penalties_by_addr *by_addr, size_t *npenaltiesp, size_t max_sources)
|
||||
{
|
||||
struct penalty *p = NULL;
|
||||
int bits;
|
||||
char s[NI_MAXHOST + 4];
|
||||
|
||||
/* Delete the soonest-to-expire penalties. */
|
||||
while (npenalties > (size_t)penalty_cfg.max_sources) {
|
||||
if ((p = RB_MIN(penalties_by_expiry,
|
||||
&penalties_by_expiry)) == NULL)
|
||||
fatal_f("internal error: penalty tables corrupt (find)");
|
||||
while (*npenaltiesp > max_sources) {
|
||||
if ((p = RB_MIN(penalties_by_expiry, by_expiry)) == NULL)
|
||||
fatal_f("internal error: %s table corrupt (find)", t);
|
||||
bits = p->addr.af == AF_INET ? ipv4_masklen : ipv6_masklen;
|
||||
addr_masklen_ntop(&p->addr, bits, s, sizeof(s));
|
||||
debug3_f("overflow, remove %s", s);
|
||||
if (RB_REMOVE(penalties_by_expiry,
|
||||
&penalties_by_expiry, p) != p ||
|
||||
RB_REMOVE(penalties_by_addr, &penalties_by_addr, p) != p)
|
||||
fatal_f("internal error: penalty tables corrupt (remove)");
|
||||
debug3_f("%s overflow, remove %s", t, s);
|
||||
if (RB_REMOVE(penalties_by_expiry, by_expiry, p) != p ||
|
||||
RB_REMOVE(penalties_by_addr, by_addr, p) != p)
|
||||
fatal_f("internal error: %s table corrupt (remove)", t);
|
||||
free(p);
|
||||
npenalties--;
|
||||
(*npenaltiesp)--;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
srclimit_early_expire_penalties(void)
|
||||
{
|
||||
srclimit_early_expire_penalties_from_tree("ipv4",
|
||||
&penalties_by_expiry4, &penalties_by_addr4, &npenalties4,
|
||||
(size_t)penalty_cfg.max_sources4);
|
||||
srclimit_early_expire_penalties_from_tree("ipv6",
|
||||
&penalties_by_expiry6, &penalties_by_addr6, &npenalties6,
|
||||
(size_t)penalty_cfg.max_sources6);
|
||||
}
|
||||
|
||||
void
|
||||
srclimit_penalise(struct xaddr *addr, int penalty_type)
|
||||
{
|
||||
struct xaddr masked;
|
||||
struct penalty *penalty, *existing;
|
||||
struct penalty *penalty = NULL, *existing = NULL;
|
||||
time_t now;
|
||||
int bits, penalty_secs;
|
||||
int bits, penalty_secs, max_sources = 0, overflow_mode;
|
||||
char addrnetmask[NI_MAXHOST + 4];
|
||||
const char *reason = NULL;
|
||||
const char *reason = NULL, *t;
|
||||
size_t *npenaltiesp = NULL;
|
||||
struct penalties_by_addr *by_addr = NULL;
|
||||
struct penalties_by_expiry *by_expiry = NULL;
|
||||
|
||||
if (!penalty_cfg.enabled)
|
||||
return;
|
||||
@ -356,9 +393,19 @@ srclimit_penalise(struct xaddr *addr, int penalty_type)
|
||||
|
||||
now = monotime();
|
||||
expire_penalties(now);
|
||||
if (npenalties > (size_t)penalty_cfg.max_sources &&
|
||||
penalty_cfg.overflow_mode == PER_SOURCE_PENALTY_OVERFLOW_DENY_ALL) {
|
||||
verbose_f("penalty table full, cannot penalise %s for %s",
|
||||
by_expiry = addr->af == AF_INET ?
|
||||
&penalties_by_expiry4 : &penalties_by_expiry6;
|
||||
by_addr = addr->af == AF_INET ?
|
||||
&penalties_by_addr4 : &penalties_by_addr6;
|
||||
max_sources = addr->af == AF_INET ?
|
||||
penalty_cfg.max_sources4 : penalty_cfg.max_sources6;
|
||||
overflow_mode = addr->af == AF_INET ?
|
||||
penalty_cfg.overflow_mode : penalty_cfg.overflow_mode6;
|
||||
npenaltiesp = addr->af == AF_INET ? &npenalties4 : &npenalties6;
|
||||
t = addr->af == AF_INET ? "ipv4" : "ipv6";
|
||||
if (*npenaltiesp > (size_t)max_sources &&
|
||||
overflow_mode == PER_SOURCE_PENALTY_OVERFLOW_DENY_ALL) {
|
||||
verbose_f("%s penalty table full, cannot penalise %s for %s", t,
|
||||
addrnetmask, reason);
|
||||
return;
|
||||
}
|
||||
@ -367,48 +414,48 @@ srclimit_penalise(struct xaddr *addr, int penalty_type)
|
||||
penalty->addr = masked;
|
||||
penalty->expiry = now + penalty_secs;
|
||||
penalty->reason = reason;
|
||||
if ((existing = RB_INSERT(penalties_by_addr, &penalties_by_addr,
|
||||
if ((existing = RB_INSERT(penalties_by_addr, by_addr,
|
||||
penalty)) == NULL) {
|
||||
/* penalty didn't previously exist */
|
||||
if (penalty_secs > penalty_cfg.penalty_min)
|
||||
penalty->active = 1;
|
||||
if (RB_INSERT(penalties_by_expiry, &penalties_by_expiry,
|
||||
penalty) != NULL)
|
||||
fatal_f("internal error: penalty tables corrupt");
|
||||
verbose_f("%s: new %s penalty of %d seconds for %s",
|
||||
if (RB_INSERT(penalties_by_expiry, by_expiry, penalty) != NULL)
|
||||
fatal_f("internal error: %s penalty tables corrupt", t);
|
||||
verbose_f("%s: new %s %s penalty of %d seconds for %s", t,
|
||||
addrnetmask, penalty->active ? "active" : "deferred",
|
||||
penalty_secs, reason);
|
||||
if (++npenalties > (size_t)penalty_cfg.max_sources)
|
||||
srclimit_remove_expired_penalties(); /* permissive */
|
||||
if (++(*npenaltiesp) > (size_t)max_sources)
|
||||
srclimit_early_expire_penalties(); /* permissive */
|
||||
return;
|
||||
}
|
||||
debug_f("%s penalty for %s already exists, %lld seconds remaining",
|
||||
existing->active ? "active" : "inactive",
|
||||
debug_f("%s penalty for %s %s already exists, %lld seconds remaining",
|
||||
existing->active ? "active" : "inactive", t,
|
||||
addrnetmask, (long long)(existing->expiry - now));
|
||||
/* Expiry information is about to change, remove from tree */
|
||||
if (RB_REMOVE(penalties_by_expiry, &penalties_by_expiry,
|
||||
existing) != existing)
|
||||
fatal_f("internal error: penalty tables corrupt (remove)");
|
||||
if (RB_REMOVE(penalties_by_expiry, by_expiry, existing) != existing)
|
||||
fatal_f("internal error: %s penalty table corrupt (remove)", t);
|
||||
/* An entry already existed. Accumulate penalty up to maximum */
|
||||
existing->expiry += penalty_secs;
|
||||
if (existing->expiry - now > penalty_cfg.penalty_max)
|
||||
existing->expiry = now + penalty_cfg.penalty_max;
|
||||
if (existing->expiry - now > penalty_cfg.penalty_min &&
|
||||
!existing->active) {
|
||||
verbose_f("%s: activating penalty of %lld seconds for %s",
|
||||
addrnetmask, (long long)(existing->expiry - now), reason);
|
||||
verbose_f("%s: activating %s penalty of %lld seconds for %s",
|
||||
addrnetmask, t, (long long)(existing->expiry - now),
|
||||
reason);
|
||||
existing->active = 1;
|
||||
}
|
||||
existing->reason = penalty->reason;
|
||||
free(penalty);
|
||||
penalty = NULL;
|
||||
/* Re-insert into expiry tree */
|
||||
if (RB_INSERT(penalties_by_expiry, &penalties_by_expiry,
|
||||
existing) != NULL)
|
||||
fatal_f("internal error: penalty tables corrupt (insert)");
|
||||
if (RB_INSERT(penalties_by_expiry, by_expiry, existing) != NULL)
|
||||
fatal_f("internal error: %s penalty table corrupt (insert)", t);
|
||||
}
|
||||
|
||||
void
|
||||
srclimit_penalty_info(void)
|
||||
static void
|
||||
srclimit_penalty_info_for_tree(const char *t,
|
||||
struct penalties_by_expiry *by_expiry, size_t npenalties)
|
||||
{
|
||||
struct penalty *p = NULL;
|
||||
int bits;
|
||||
@ -416,8 +463,8 @@ srclimit_penalty_info(void)
|
||||
time_t now;
|
||||
|
||||
now = monotime();
|
||||
logit("%zu active penalties", npenalties);
|
||||
RB_FOREACH(p, penalties_by_expiry, &penalties_by_expiry) {
|
||||
logit("%zu active %s penalties", npenalties, t);
|
||||
RB_FOREACH(p, penalties_by_expiry, by_expiry) {
|
||||
bits = p->addr.af == AF_INET ? ipv4_masklen : ipv6_masklen;
|
||||
addr_masklen_ntop(&p->addr, bits, s, sizeof(s));
|
||||
if (p->expiry < now)
|
||||
@ -428,3 +475,12 @@ srclimit_penalty_info(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
srclimit_penalty_info(void)
|
||||
{
|
||||
srclimit_penalty_info_for_tree("ipv4",
|
||||
&penalties_by_expiry4, npenalties4);
|
||||
srclimit_penalty_info_for_tree("ipv6",
|
||||
&penalties_by_expiry6, npenalties6);
|
||||
}
|
||||
|
@ -33,8 +33,8 @@
|
||||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $OpenBSD: sshd_config.5,v 1.360 2024/06/11 05:24:39 jmc Exp $
|
||||
.Dd $Mdocdate: June 11 2024 $
|
||||
.\" $OpenBSD: sshd_config.5,v 1.361 2024/06/12 22:36:00 djm Exp $
|
||||
.Dd $Mdocdate: June 12 2024 $
|
||||
.Dt SSHD_CONFIG 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -1604,12 +1604,14 @@ Repeated penalties will accumulate up to this maximum.
|
||||
.It Cm min:duration
|
||||
Specifies the minimum penalty that must accrue before enforcement begins
|
||||
(default: 15s).
|
||||
.It Cm max-sources:number
|
||||
Specifies the maximum number of penalise client address ranges to track
|
||||
(default: 65536).
|
||||
.It Cm max-sources4:number max-sources6:number
|
||||
Specifies the maximum number of client IPv4 and IPv6 address ranges to
|
||||
track for penalties (default: 65536 for both).
|
||||
.It Cm overflow:mode
|
||||
Controls how the server behaves when
|
||||
.Cm max-sources
|
||||
.Cm max-sources4
|
||||
or
|
||||
.Cm max-sources6
|
||||
is exceeded.
|
||||
There are two operating modes:
|
||||
.Cm deny-all ,
|
||||
@ -1619,6 +1621,14 @@ until a penalty expires, and
|
||||
.Cm permissive ,
|
||||
which allows new connections by removing existing penalties early
|
||||
(default: permissive).
|
||||
Note that client penalties below the
|
||||
.Cm min
|
||||
threshold count against the total number of tracked penalties.
|
||||
IPv4 and IPv6 addresses are tracked separately, so an overflow in one will
|
||||
not affect the other.
|
||||
.It Cm overflow6:mode
|
||||
Allows specifying a different overflow mode for IPv6 addresses.
|
||||
The default it to use the same overflow mode as was specified for IPv4.
|
||||
.El
|
||||
.It Cm PerSourcePenaltyExemptList
|
||||
Specifies a comma-separated list of addresses to exempt from penalties.
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: cert.c,v 1.147 2024/06/12 04:01:20 tb Exp $ */
|
||||
/* $OpenBSD: cert.c,v 1.148 2024/06/12 10:03:09 tb Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2022 Theo Buehler <tb@openbsd.org>
|
||||
* Copyright (c) 2021 Job Snijders <job@openbsd.org>
|
||||
@ -34,7 +34,7 @@ extern ASN1_OBJECT *carepo_oid; /* 1.3.6.1.5.5.7.48.5 (caRepository) */
|
||||
extern ASN1_OBJECT *manifest_oid; /* 1.3.6.1.5.5.7.48.10 (rpkiManifest) */
|
||||
extern ASN1_OBJECT *notify_oid; /* 1.3.6.1.5.5.7.48.13 (rpkiNotify) */
|
||||
|
||||
static int certid = TALSZ_MAX;
|
||||
int certid = TALSZ_MAX;
|
||||
|
||||
/*
|
||||
* Append an IP address structure to our list of results.
|
||||
@ -1271,8 +1271,12 @@ auth_insert(const char *fn, struct auth_tree *auths, struct cert *cert,
|
||||
cert->certid = cert->talid;
|
||||
} else {
|
||||
cert->certid = ++certid;
|
||||
if (certid > CERTID_MAX)
|
||||
errx(1, "%s: too many certificates in store", fn);
|
||||
if (certid > CERTID_MAX) {
|
||||
if (certid == CERTID_MAX + 1)
|
||||
warnx("%s: too many certificates in store", fn);
|
||||
free(na);
|
||||
return NULL;
|
||||
}
|
||||
na->depth = issuer->depth + 1;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: crl.c,v 1.40 2024/06/11 15:33:46 tb Exp $ */
|
||||
/* $OpenBSD: crl.c,v 1.41 2024/06/12 10:03:09 tb Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2024 Theo Buehler <tb@openbsd.org>
|
||||
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
@ -296,9 +296,6 @@ crl_get(struct crl_tree *crlt, const struct auth *a)
|
||||
{
|
||||
struct crl find;
|
||||
|
||||
if (a == NULL)
|
||||
return NULL;
|
||||
|
||||
find.aki = a->cert->ski;
|
||||
find.mftpath = a->cert->mft;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: filemode.c,v 1.45 2024/06/08 13:34:59 tb Exp $ */
|
||||
/* $OpenBSD: filemode.c,v 1.46 2024/06/12 10:03:09 tb Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2019 Claudio Jeker <claudio@openbsd.org>
|
||||
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
@ -191,6 +191,10 @@ parse_load_certchain(char *uri)
|
||||
for (i = 0; i < MAX_CERT_DEPTH; i++) {
|
||||
if ((cert = uripath_lookup(uri)) != NULL) {
|
||||
a = auth_find(&auths, cert->certid);
|
||||
if (a == NULL) {
|
||||
warnx("failed to find issuer for %s", uri);
|
||||
goto fail;
|
||||
}
|
||||
break;
|
||||
}
|
||||
filestack[i] = uri;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: parser.c,v 1.140 2024/06/10 11:49:29 tb Exp $ */
|
||||
/* $OpenBSD: parser.c,v 1.141 2024/06/12 10:03:09 tb Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2019 Claudio Jeker <claudio@openbsd.org>
|
||||
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
@ -38,6 +38,8 @@
|
||||
|
||||
#include "extern.h"
|
||||
|
||||
extern int certid;
|
||||
|
||||
static X509_STORE_CTX *ctx;
|
||||
static struct auth_tree auths = RB_INITIALIZER(&auths);
|
||||
static struct crl_tree crlt = RB_INITIALIZER(&crlt);
|
||||
@ -98,7 +100,9 @@ find_issuer(const char *fn, int id, const char *aki, const char *mftaki)
|
||||
|
||||
a = auth_find(&auths, id);
|
||||
if (a == NULL) {
|
||||
warnx("%s: RFC 6487: unknown cert with SKI %s", fn, aki);
|
||||
if (certid <= CERTID_MAX)
|
||||
warnx("%s: RFC 6487: unknown cert with SKI %s", fn,
|
||||
aki);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -171,6 +175,11 @@ proc_parser_roa(char *file, const unsigned char *der, size_t len,
|
||||
return NULL;
|
||||
|
||||
a = find_issuer(file, entp->certid, roa->aki, entp->mftaki);
|
||||
if (a == NULL) {
|
||||
X509_free(x509);
|
||||
roa_free(roa);
|
||||
return NULL;
|
||||
}
|
||||
crl = crl_get(&crlt, a);
|
||||
|
||||
if (!valid_x509(file, ctx, x509, a, crl, &errstr)) {
|
||||
@ -206,6 +215,11 @@ proc_parser_spl(char *file, const unsigned char *der, size_t len,
|
||||
return NULL;
|
||||
|
||||
a = find_issuer(file, entp->certid, spl->aki, entp->mftaki);
|
||||
if (a == NULL) {
|
||||
X509_free(x509);
|
||||
spl_free(spl);
|
||||
return NULL;
|
||||
}
|
||||
crl = crl_get(&crlt, a);
|
||||
|
||||
if (!valid_x509(file, ctx, x509, a, crl, &errstr)) {
|
||||
@ -370,6 +384,8 @@ proc_parser_mft_pre(struct entity *entp, char *file, struct crl **crl,
|
||||
*crl = parse_load_crl_from_mft(entp, mft, DIR_VALID, crlfile);
|
||||
|
||||
a = find_issuer(file, entp->certid, mft->aki, NULL);
|
||||
if (a == NULL)
|
||||
goto err;
|
||||
if (!valid_x509(file, ctx, x509, a, *crl, errstr))
|
||||
goto err;
|
||||
X509_free(x509);
|
||||
@ -494,7 +510,8 @@ proc_parser_mft(struct entity *entp, struct mft **mp, char **crlfile,
|
||||
err2 = err1;
|
||||
if (err2 == NULL)
|
||||
err2 = "no valid manifest available";
|
||||
warnx("%s: %s", file2, err2);
|
||||
if (certid <= CERTID_MAX)
|
||||
warnx("%s: %s", file2, err2);
|
||||
}
|
||||
|
||||
mft_free(mft1);
|
||||
@ -542,6 +559,10 @@ proc_parser_cert(char *file, const unsigned char *der, size_t len,
|
||||
return NULL;
|
||||
|
||||
a = find_issuer(file, entp->certid, cert->aki, entp->mftaki);
|
||||
if (a == NULL) {
|
||||
cert_free(cert);
|
||||
return NULL;
|
||||
}
|
||||
crl = crl_get(&crlt, a);
|
||||
|
||||
if (!valid_x509(file, ctx, cert->x509, a, crl, &errstr) ||
|
||||
@ -684,6 +705,11 @@ proc_parser_gbr(char *file, const unsigned char *der, size_t len,
|
||||
return NULL;
|
||||
|
||||
a = find_issuer(file, entp->certid, gbr->aki, entp->mftaki);
|
||||
if (a == NULL) {
|
||||
X509_free(x509);
|
||||
gbr_free(gbr);
|
||||
return NULL;
|
||||
}
|
||||
crl = crl_get(&crlt, a);
|
||||
|
||||
if (!valid_x509(file, ctx, x509, a, crl, &errstr)) {
|
||||
@ -716,6 +742,11 @@ proc_parser_aspa(char *file, const unsigned char *der, size_t len,
|
||||
return NULL;
|
||||
|
||||
a = find_issuer(file, entp->certid, aspa->aki, entp->mftaki);
|
||||
if (a == NULL) {
|
||||
X509_free(x509);
|
||||
aspa_free(aspa);
|
||||
return NULL;
|
||||
}
|
||||
crl = crl_get(&crlt, a);
|
||||
|
||||
if (!valid_x509(file, ctx, x509, a, crl, &errstr)) {
|
||||
@ -751,6 +782,8 @@ proc_parser_tak(char *file, const unsigned char *der, size_t len,
|
||||
return NULL;
|
||||
|
||||
a = find_issuer(file, entp->certid, tak->aki, entp->mftaki);
|
||||
if (a == NULL)
|
||||
goto out;
|
||||
crl = crl_get(&crlt, a);
|
||||
|
||||
if (!valid_x509(file, ctx, x509, a, crl, &errstr)) {
|
||||
@ -1076,5 +1109,8 @@ proc_parser(int fd)
|
||||
|
||||
ibuf_free(inbuf);
|
||||
|
||||
if (certid > CERTID_MAX)
|
||||
errx(1, "processing incomplete: too many certificates");
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: validate.c,v 1.74 2024/05/20 15:51:43 claudio Exp $ */
|
||||
/* $OpenBSD: validate.c,v 1.75 2024/06/12 10:03:09 tb Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
@ -304,9 +304,6 @@ build_chain(const struct auth *a, STACK_OF(X509) **intermediates,
|
||||
*intermediates = NULL;
|
||||
*root = NULL;
|
||||
|
||||
if (a == NULL)
|
||||
return;
|
||||
|
||||
if ((*intermediates = sk_X509_new_null()) == NULL)
|
||||
err(1, "sk_X509_new_null");
|
||||
if ((*root = sk_X509_new_null()) == NULL)
|
||||
|
Loading…
Reference in New Issue
Block a user