sync with OpenBSD -current

This commit is contained in:
purplerain 2024-06-13 03:03:45 +00:00
parent d22f2a15f3
commit f4a22ff4b2
Signed by: purplerain
GPG Key ID: F42C07F07E2E35B7
17 changed files with 1316 additions and 178 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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__ */

View File

@ -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 */

View File

@ -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__ */

View File

@ -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");

View File

@ -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;

View File

@ -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);
}

View File

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

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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);
}

View File

@ -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)