sync with OpenBSD -current

This commit is contained in:
purplerain 2024-08-16 01:44:06 +00:00
parent e247f83c76
commit b5dda3c267
Signed by: purplerain
GPG key ID: F42C07F07E2E35B7
69 changed files with 3745 additions and 3354 deletions

View file

@ -1,4 +1,4 @@
/* $OpenBSD: ftree.c,v 1.42 2019/06/28 13:34:59 deraadt Exp $ */ /* $OpenBSD: ftree.c,v 1.43 2024/08/15 00:47:44 guenther Exp $ */
/* $NetBSD: ftree.c,v 1.4 1995/03/21 09:07:21 cgd Exp $ */ /* $NetBSD: ftree.c,v 1.4 1995/03/21 09:07:21 cgd Exp $ */
/*- /*-
@ -52,8 +52,7 @@
*/ */
typedef struct ftree { typedef struct ftree {
char *fname; /* file tree name */ char *fname; /* file tree name */
int refcnt; /* has tree had a selected file? */ int refcnt; /* had a selected (or skipped) file? */
int newercnt; /* skipped due to -u/-D */
int chflg; /* change directory flag */ int chflg; /* change directory flag */
struct ftree *fow; /* pointer to next entry on list */ struct ftree *fow; /* pointer to next entry on list */
} FTREE; } FTREE;
@ -173,7 +172,6 @@ ftree_add(char *str, int chflg)
str[len] = '\0'; str[len] = '\0';
ft->fname = str; ft->fname = str;
ft->refcnt = 0; ft->refcnt = 0;
ft->newercnt = 0;
ft->chflg = chflg; ft->chflg = chflg;
ft->fow = NULL; ft->fow = NULL;
if (fthead == NULL) { if (fthead == NULL) {
@ -228,7 +226,7 @@ ftree_skipped_newer(ARCHD *arcn)
{ {
/* skipped due to -u/-D, mark accordingly */ /* skipped due to -u/-D, mark accordingly */
if (ftcur != NULL) if (ftcur != NULL)
ftcur->newercnt = 1; ftcur->refcnt = 1;
} }
/* /*
@ -254,7 +252,7 @@ ftree_chk(void)
* that never had a match * that never had a match
*/ */
for (ft = fthead; ft != NULL; ft = ft->fow) { for (ft = fthead; ft != NULL; ft = ft->fow) {
if ((ft->refcnt > 0) || ft->newercnt > 0 || ft->chflg) if ((ft->refcnt > 0) || ft->chflg)
continue; continue;
if (wban == 0) { if (wban == 0) {
paxwarn(1,"WARNING! These file names were not selected:"); paxwarn(1,"WARNING! These file names were not selected:");

View file

@ -1,4 +1,4 @@
/* $OpenBSD: test.c,v 1.21 2024/06/18 16:41:39 schwarze Exp $ */ /* $OpenBSD: test.c,v 1.22 2024/08/15 06:27:24 guenther Exp $ */
/* $NetBSD: test.c,v 1.15 1995/03/21 07:04:06 cgd Exp $ */ /* $NetBSD: test.c,v 1.15 1995/03/21 07:04:06 cgd Exp $ */
/* /*
@ -424,19 +424,6 @@ filstat(char *nm, enum token mode)
struct stat s; struct stat s;
mode_t i; mode_t i;
if (mode == FILSYM) {
#ifdef S_IFLNK
if (lstat(nm, &s) == 0) {
i = S_IFLNK;
goto filetype;
}
#endif
return 0;
}
if (stat(nm, &s) != 0)
return 0;
switch (mode) { switch (mode) {
case FILRD: case FILRD:
return access(nm, R_OK) == 0; return access(nm, R_OK) == 0;
@ -446,6 +433,22 @@ filstat(char *nm, enum token mode)
return access(nm, X_OK) == 0; return access(nm, X_OK) == 0;
case FILEXIST: case FILEXIST:
return access(nm, F_OK) == 0; return access(nm, F_OK) == 0;
default:
break;
}
if (mode == FILSYM) {
if (lstat(nm, &s) == 0) {
i = S_IFLNK;
goto filetype;
}
return 0;
}
if (stat(nm, &s) != 0)
return 0;
switch (mode) {
case FILREG: case FILREG:
i = S_IFREG; i = S_IFREG;
goto filetype; goto filetype;
@ -459,19 +462,11 @@ filstat(char *nm, enum token mode)
i = S_IFBLK; i = S_IFBLK;
goto filetype; goto filetype;
case FILFIFO: case FILFIFO:
#ifdef S_IFIFO
i = S_IFIFO; i = S_IFIFO;
goto filetype; goto filetype;
#else
return 0;
#endif
case FILSOCK: case FILSOCK:
#ifdef S_IFSOCK
i = S_IFSOCK; i = S_IFSOCK;
goto filetype; goto filetype;
#else
return 0;
#endif
case FILSUID: case FILSUID:
i = S_ISUID; i = S_ISUID;
goto filebit; goto filebit;

View file

@ -357,6 +357,8 @@
./usr/include/dev/ic/qlwvar.h ./usr/include/dev/ic/qlwvar.h
./usr/include/dev/ic/qwxreg.h ./usr/include/dev/ic/qwxreg.h
./usr/include/dev/ic/qwxvar.h ./usr/include/dev/ic/qwxvar.h
./usr/include/dev/ic/qwzreg.h
./usr/include/dev/ic/qwzvar.h
./usr/include/dev/ic/r92creg.h ./usr/include/dev/ic/r92creg.h
./usr/include/dev/ic/ramdac.h ./usr/include/dev/ic/ramdac.h
./usr/include/dev/ic/revar.h ./usr/include/dev/ic/revar.h

View file

@ -1,5 +1,5 @@
#!/bin/ksh #!/bin/ksh
# $OpenBSD: check_sym,v 1.11 2022/01/03 03:40:48 guenther Exp $ # $OpenBSD: check_sym,v 1.12 2024/08/15 01:25:13 guenther Exp $
# #
# Copyright (c) 2016,2019,2022 Philip Guenther <guenther@openbsd.org> # Copyright (c) 2016,2019,2022 Philip Guenther <guenther@openbsd.org>
# #
@ -17,10 +17,10 @@
# #
# #
# check_sym -- compare the symbols and external function references in two # check_sym -- compare the symbols and external function references in two
# versions of a shared library # versions of a library
# #
# SYNOPSIS # SYNOPSIS
# check_sym [-chkv] [old [new]] # check_sym [-chkSv] [old [new]]
# #
# DESCRIPTION # DESCRIPTION
# Library developers need to be aware when they have changed the # Library developers need to be aware when they have changed the
@ -33,6 +33,8 @@
# In each case, additions and removals are reported; for exported # In each case, additions and removals are reported; for exported
# symbols it also reports when a symbol is weakened or strengthened. # symbols it also reports when a symbol is weakened or strengthened.
# #
# With the -S option, a similar analysis is done but for the static lib.
#
# The shared libraries to compare can be specified on the # The shared libraries to compare can be specified on the
# command-line. Otherwise, check_sym expects to be run from the # command-line. Otherwise, check_sym expects to be run from the
# source directory of a library with a shlib_version file specifying # source directory of a library with a shlib_version file specifying
@ -50,7 +52,7 @@
# files left behind by the -k option can be cleaned up by invoking # files left behind by the -k option can be cleaned up by invoking
# check_syms with the -c option. # check_syms with the -c option.
# #
# The -v option enables verbose output. # The -v option enables verbose output, showing relocation counts.
# #
# The *basic* rules of thumb for library versions are: if you # The *basic* rules of thumb for library versions are: if you
# * stop exporting a symbol, or # * stop exporting a symbol, or
@ -81,7 +83,7 @@
get_lib_name() get_lib_name()
{ {
sed -n 's/^[ ]*LIB[ ]*=[ ]*\([^ ]*\).*/\1/p' "$@" sed -n '/^[ ]*LIB[ ]*=/{ s/^[^=]*=[ ]*\([^ ]*\).*/\1/p; q;}' "$@"
} }
pick_highest() pick_highest()
@ -104,31 +106,205 @@ pick_highest()
[[ $old != "" ]] [[ $old != "" ]]
} }
fail() { echo "$*" >&2; exit 1; }
usage() usage()
{ {
usage="usage: check_sym [-chkv] [old [new]]" usage="usage: check_sym [-chkSv] [old [new]]"
if [[ $# -gt 0 ]] [[ $# -eq 0 ]] || fail "check_sym: $*
then $usage"
echo "check_sym: $@
$usage" >&2
exit 1
fi
echo "$usage" echo "$usage"
exit 0 exit 0
} }
#
# Output helpers
#
data_sym_changes()
{
join "$@" | awk '$2 != $3 { print $1 " " $2 " --> " $3 }'
}
output_if_not_empty()
{
leader=$1
shift
if "$@" | grep -q .
then
echo "$leader"
"$@" | sed 's:^: :'
echo
fi
}
#
# Dynamic library routines
#
dynamic_collect()
{
readelf -sW $old | filt_symtab > $odir/Ds1
readelf -sW $new | filt_symtab > $odir/Ds2
readelf -rW $old > $odir/r1
readelf -rW $new > $odir/r2
case $(readelf -h $new | grep '^ *Machine:') in
*MIPS*) cpu=mips64
gotsym1=$(readelf -d $old | awk '$2 ~ /MIPS_GOTSYM/{print $3}')
gotsym2=$(readelf -d $new | awk '$2 ~ /MIPS_GOTSYM/{print $3}')
;;
*HPPA*) cpu=hppa;;
*) cpu=dontcare;;
esac
}
jump_slots()
{
case $cpu in
hppa) awk '/IPLT/ && $5 != ""{print $5}' r$1
;;
mips64) # the $((gotsym$1)) converts hex to decimal
awk -v g=$((gotsym$1)) \
'/^Symbol table ..symtab/{exit}
$6 == "PROTECTED" { next }
$1+0 >= g && $4 == "FUNC" {print $8}' Ds$1
;;
*) awk '/JU*MP_SL/ && $5 != ""{print $5}' r$1
;;
esac | sort -o j$1
}
dynamic_sym()
{
awk -v s=$1 '/^Symbol table ..symtab/{exit}
! /^ *[1-9]/ {next}
$5 == "LOCAL" {next}
$7 == "UND" {print $8 | ("sort -o DU" s); next }
$5 == "GLOBAL" {print $8 | ("sort -o DS" s) }
$5 == "WEAK" {print $8 | ("sort -o DW" s) }
$4 == "OBJECT" {print $8, $3 | ("sort -o DO" s) }
{print $8 | ("sort -o D" s)
print $4, $5, $6, $8}' Ds$1 | sort -o d$1
}
static_sym()
{
awk '/^Symbol table ..symtab/{s=1}
/LOCAL/{next}
s&&/^ *[1-9]/{print $4, $5, $6, $8}' Ds$1 | sort -o s$1
}
dynamic_analysis()
{
jump_slots $1
dynamic_sym $1
#static_sym $1
comm -23 j$1 DU$1 >J$1
return 0
}
dynamic_output()
{
if cmp -s d[12] && cmp -s DO[12]
then
printf "No dynamic export changes\n"
else
printf "Dynamic export changes:\n"
output_if_not_empty "added:" comm -13 D[12]
output_if_not_empty "removed:" comm -23 D[12]
output_if_not_empty "weakened:" comm -12 DS1 DW2
output_if_not_empty "strengthened:" comm -12 DW1 DS2
output_if_not_empty "data object sizes changes:" \
data_sym_changes DO[12]
fi
if ! cmp -s DU[12]
then
printf "External reference changes:\n"
output_if_not_empty "added:" comm -13 DU[12]
output_if_not_empty "removed:" comm -23 DU[12]
fi
if $verbose; then
printf "\nReloc counts:\nbefore:\n"
grep ^R r1
printf "\nafter:\n"
grep ^R r2
fi
output_if_not_empty "PLT added:" comm -13 J[12]
output_if_not_empty "PLT removed:" comm -23 J[12]
}
#
# Static library routines
#
static_collect()
{
readelf -sW $old | filt_ret | filt_symtab > $odir/Ss1
readelf -sW $new | filt_ret | filt_symtab > $odir/Ss2
}
static_analysis()
{
awk -v s=$1 '!/^ *[1-9]/{next}
$5 == "LOCAL" {next}
$7 == "UND" {print $8 | ("sort -uo SU" s); next }
$6 == "HIDDEN" {print $8 | ("sort -uo SH" s) }
$5 == "GLOBAL" {print $8 | ("sort -o SS" s) }
$5 == "WEAK" {print $8 | ("sort -o SW" s) }
$4 == "OBJECT" {print $8, $3 | ("sort -o SO" s) }
{print $8 | ("sort -o S" s)
print $4, $5, $6, $8}' Ss$1 | sort -o s$1
grep -v '^_' SH$1 >Sh$1 || :
}
static_output()
{
output_if_not_empty "hidden but not reserved:" comm -13 Sh[12]
if cmp -s s[12] && cmp -s SO[12]
then
printf "No static export changes\n"
else
printf "Static export changes:\n"
output_if_not_empty "added:" comm -13 S[12]
output_if_not_empty "removed:" comm -23 S[12]
output_if_not_empty "weakened:" comm -12 SS1 SW2
output_if_not_empty "strengthened:" comm -12 SW1 SS2
output_if_not_empty "data object sizes changes:" \
data_sym_changes SO[12]
fi
if ! cmp -s SU[12]
then
printf "External reference changes:\n"
output_if_not_empty "added:" comm -13 SU[12]
output_if_not_empty "removed:" comm -23 SU[12]
fi
}
unset odir unset odir
file_list={D{,S,W,O},J,S,U,d,j,r,s}{1,2} file_list={D{,O,S,s,W,U},J,d,j,r}{1,2}
static_file_list={S{,H,h,O,S,U,W},U,s}{1,2}
keep_temp=false keep_temp=false
dynamic=true
static=false
verbose=false verbose=false
while getopts :chkv opt "$@"
do_static() { static=true dynamic=false file_list=$static_file_list; }
while getopts :chkSv opt "$@"
do do
case $opt in case $opt in
c) rm -f /tmp/$file_list c) rm -f /tmp/$file_list
exit 0;; exit 0;;
h) usage;; h) usage;;
k) keep_temp=true;; k) keep_temp=true;;
S) do_static;;
v) verbose=true;; v) verbose=true;;
\?) usage "unknown option -- $OPTARG";; \?) usage "unknown option -- $OPTARG";;
esac esac
@ -137,17 +313,30 @@ shift $((OPTIND - 1))
[[ $# -gt 2 ]] && usage "too many arguments" [[ $# -gt 2 ]] && usage "too many arguments"
# Old library? # Old library?
if [[ $1 = ?(*/)lib*.so* ]] if ! $static && [[ $1 = ?(*/)lib*.so* ]]
then then
if [[ ! -f $1 ]] [[ -f $1 ]] || fail "$1 doesn't exist"
then
echo "$1 doesn't exist" >&2
exit 1
fi
old=$1 old=$1
lib=${old##*/} lib=${old##*/}
lib=${lib%%.so.*} lib=${lib%%.so.*}
shift shift
elif [[ $1 = ?(*/)lib*.a ]]
then
# woo hoo, static library mode
do_static
if [[ -f $1 ]]
then
old=$1
lib=${old##*/}
elif [[ $1 = lib*.a && -f /usr/lib/$1 ]]
then
old=/usr/lib/$1
lib=$1
else
fail "$1 doesn't exist"
fi
lib=${lib%%.a}
shift
else else
# try determining it from the current directory # try determining it from the current directory
if [[ -f Makefile ]] && lib=$(get_lib_name Makefile) && if [[ -f Makefile ]] && lib=$(get_lib_name Makefile) &&
@ -160,35 +349,39 @@ else
# Is there a copy of that lib in the current directory? # Is there a copy of that lib in the current directory?
# If so, use the highest numbered one # If so, use the highest numbered one
if ! pick_highest $lib.so.* && ! pick_highest /usr/lib/$lib.so.* if ! $static &&
! pick_highest $lib.so.* &&
! pick_highest /usr/lib/$lib.so.*
then then
echo "unable to find $lib.so.*" >&2 fail "unable to find $lib.so.*"
exit 1 elif $static
then
old=/usr/lib/${lib}.a
[[ -f $old ]] || fail "$old doesn't exist"
fi fi
fi fi
# New library? # New library?
if [[ $1 = ?(*/)lib*.so* ]] if [[ $1 = ?(*/)lib*.so* ]] ||
{ $static && [[ $1 = ?(*/)lib*.a ]]; }
then then
new=$1 new=$1
shift shift
elif $static
then
new=obj/${lib}.a
else else
# Dig info out of the just built library # Dig info out of the just built library
. ./shlib_version . ./shlib_version
new=obj/${lib}.so.${major}.${minor} new=obj/${lib}.so.${major}.${minor}
fi fi
if [[ ! -f $new ]] [[ -f $new ]] || fail "$new doesn't exist"
then
echo "$new doesn't exist" >&2
exit 1
fi
# Filter the output of readelf -s to be easier to parse by removing a # Filter the output of readelf -s to be easier to parse by removing a
# field that only appears on some symbols: [<other>: 88] # field that only appears on some symbols: [<other>: 88]
# Not really arch-specific, but I've only seen it on alpha # Not really arch-specific, but I've only seen it on alpha
filt_symtab() { filt_symtab() { sed 's/\[<other>: [0-9a-f]*\]//'; }
sed 's/\[<other>: [0-9a-f]*\]//' filt_ret() { egrep -v ' (__retguard_[0-9]+|__llvm_retpoline_[a-z]+[0-9]*)$'; }
}
if $keep_temp if $keep_temp
then then
@ -210,112 +403,29 @@ do
done done
set +C set +C
readelf -rW $old > $odir/r1
readelf -rW $new > $odir/r2
readelf -sW $old | filt_symtab > $odir/s1 #
readelf -sW $new | filt_symtab > $odir/s2 # Collect data
#
$dynamic && dynamic_collect
case $(readelf -h $new | grep '^ *Machine:') in $static && static_collect
*MIPS*) cpu=mips64;;
*HPPA*) cpu=hppa;;
*) cpu=dontcare;;
esac
if [[ $cpu = mips64 ]]
then
gotsym1=$(readelf -d $old | awk '$2 ~ /MIPS_GOTSYM/{print $3}')
gotsym2=$(readelf -d $new | awk '$2 ~ /MIPS_GOTSYM/{print $3}')
fi
# Now that we're done accessing $old and $new (which could be # Now that we're done accessing $old and $new (which could be
# relative paths), chdir into our work directory, whatever it is # relative paths), chdir into our work directory, whatever it is
cd $odir cd $odir
jump_slots() { #
case $cpu in # Do The Job
hppa) awk '/IPLT/ && $5 != ""{print $5}' r$1 #
;;
mips64) # the $((gotsym$1)) converts hex to decimal
awk -v g=$((gotsym$1)) \
'/^Symbol table ..symtab/{exit}
$6 == "PROTECTED" { next }
$1+0 >= g && $4 == "FUNC" {print $8}' s$1
;;
*) awk '/JU*MP_SL/ && $5 != ""{print $5}' r$1
;;
esac | sort -o j$1
}
dynamic_sym() {
awk -v s=$1 '/^Symbol table ..symtab/{exit}
! /^ *[1-9]/ {next}
$7 == "UND" {print $8 | ("sort -o U" s); next }
$5 == "GLOBAL" {print $8 | ("sort -o DS" s) }
$5 == "WEAK" {print $8 | ("sort -o DW" s) }
$5 != "LOCAL" {print $8 | ("sort -o D" s) }
$5 != "LOCAL" && $4 == "OBJECT" {
print $8, $3 | ("sort -o DO" s) }
{print $4, $5, $6, $8}' s$1 | sort -o d$1
}
static_sym() {
awk '/^Symbol table ..symtab/{s=1}
/LOCAL/{next}
s&&/^ *[1-9]/{print $4, $5, $6, $8}' s$1 | sort -o S$1
}
data_sym_changes() {
join "$@" | awk '$2 != $3 { print $1 " " $2 " --> " $3 }'
}
output_if_not_empty() {
leader=$1
shift
if "$@" | grep -q .
then
echo "$leader"
"$@" | sed 's:^: :'
echo
fi
}
for i in 1 2 for i in 1 2
do do
jump_slots $i $dynamic && dynamic_analysis $i
dynamic_sym $i $static && static_analysis $i
static_sym $i
comm -23 j$i U$i >J$i
done done
echo "$old --> $new" {
if cmp -s d[12] && cmp -s DO[12] echo "$old --> $new"
then $dynamic && dynamic_output
printf "No dynamic export changes\n" $static && static_output
else }
printf "Dynamic export changes:\n"
output_if_not_empty "added:" comm -13 D[12]
output_if_not_empty "removed:" comm -23 D[12]
output_if_not_empty "weakened:" comm -12 DS1 DW2
output_if_not_empty "strengthened:" comm -12 DW1 DS2
output_if_not_empty "data object sizes changes:" \
data_sym_changes DO[12]
fi
if ! cmp -s U[12]
then
printf "External reference changes:\n"
output_if_not_empty "added:" comm -13 U[12]
output_if_not_empty "removed:" comm -23 U[12]
fi
if $verbose; then
printf "\nReloc counts:\nbefore:\n"
grep ^R r1
printf "\nafter:\n"
grep ^R r2
fi
output_if_not_empty "PLT added:" comm -13 J1 J2
output_if_not_empty "PLT removed:" comm -23 J1 J2

View file

@ -63,8 +63,6 @@ t_ptrace_wait4 -
t_ptrace_wait6 - not implemented t_ptrace_wait6 - not implemented
t_ptrace_waitid - t_ptrace_waitid -
t_ptrace_waitpid - t_ptrace_waitpid -
t_recvmmsg - not implemented, not POSIX
t_sendmmsg - not implemented, not POSIX
t_sigqueue - not implemented, added in POSIX.1-2004 t_sigqueue - not implemented, added in POSIX.1-2004
t_sigtimedwait - not implemented, added in POSIX.1-2004 t_sigtimedwait - not implemented, added in POSIX.1-2004
t_swapcontext - not available, removed in POSIX.1-2008 t_swapcontext - not available, removed in POSIX.1-2008

View file

@ -1,4 +1,4 @@
/* $OpenBSD: common.c,v 1.5 2021/12/14 21:25:27 deraadt Exp $ */ /* $OpenBSD: common.c,v 1.6 2024/08/15 00:52:23 djm Exp $ */
/* /*
* Helpers for key API tests * Helpers for key API tests
* *
@ -78,8 +78,8 @@ rsa_n(struct sshkey *k)
const BIGNUM *n = NULL; const BIGNUM *n = NULL;
ASSERT_PTR_NE(k, NULL); ASSERT_PTR_NE(k, NULL);
ASSERT_PTR_NE(k->rsa, NULL); ASSERT_PTR_NE(k->pkey, NULL);
RSA_get0_key(k->rsa, &n, NULL, NULL); RSA_get0_key(EVP_PKEY_get0_RSA(k->pkey), &n, NULL, NULL);
return n; return n;
} }
@ -89,8 +89,8 @@ rsa_e(struct sshkey *k)
const BIGNUM *e = NULL; const BIGNUM *e = NULL;
ASSERT_PTR_NE(k, NULL); ASSERT_PTR_NE(k, NULL);
ASSERT_PTR_NE(k->rsa, NULL); ASSERT_PTR_NE(k->pkey, NULL);
RSA_get0_key(k->rsa, NULL, &e, NULL); RSA_get0_key(EVP_PKEY_get0_RSA(k->pkey), NULL, &e, NULL);
return e; return e;
} }
@ -100,8 +100,8 @@ rsa_p(struct sshkey *k)
const BIGNUM *p = NULL; const BIGNUM *p = NULL;
ASSERT_PTR_NE(k, NULL); ASSERT_PTR_NE(k, NULL);
ASSERT_PTR_NE(k->rsa, NULL); ASSERT_PTR_NE(EVP_PKEY_get0_RSA(k->pkey), NULL);
RSA_get0_factors(k->rsa, &p, NULL); RSA_get0_factors(EVP_PKEY_get0_RSA(k->pkey), &p, NULL);
return p; return p;
} }
@ -111,8 +111,8 @@ rsa_q(struct sshkey *k)
const BIGNUM *q = NULL; const BIGNUM *q = NULL;
ASSERT_PTR_NE(k, NULL); ASSERT_PTR_NE(k, NULL);
ASSERT_PTR_NE(k->rsa, NULL); ASSERT_PTR_NE(EVP_PKEY_get0_RSA(k->pkey), NULL);
RSA_get0_factors(k->rsa, NULL, &q); RSA_get0_factors(EVP_PKEY_get0_RSA(k->pkey), NULL, &q);
return q; return q;
} }

View file

@ -1,4 +1,4 @@
/* $OpenBSD: test_file.c,v 1.11 2024/01/11 01:45:58 djm Exp $ */ /* $OpenBSD: test_file.c,v 1.12 2024/08/15 00:52:23 djm Exp $ */
/* /*
* Regress test for sshkey.h key management API * Regress test for sshkey.h key management API
* *
@ -258,11 +258,12 @@ sshkey_file_tests(void)
sshbuf_free(buf); sshbuf_free(buf);
a = load_bignum("ecdsa_1.param.priv"); a = load_bignum("ecdsa_1.param.priv");
b = load_bignum("ecdsa_1.param.pub"); b = load_bignum("ecdsa_1.param.pub");
c = EC_POINT_point2bn(EC_KEY_get0_group(k1->ecdsa), c = EC_POINT_point2bn(EC_KEY_get0_group(EVP_PKEY_get0_EC_KEY(k1->pkey)),
EC_KEY_get0_public_key(k1->ecdsa), POINT_CONVERSION_UNCOMPRESSED, EC_KEY_get0_public_key(EVP_PKEY_get0_EC_KEY(k1->pkey)),
NULL, NULL); POINT_CONVERSION_UNCOMPRESSED, NULL, NULL);
ASSERT_PTR_NE(c, NULL); ASSERT_PTR_NE(c, NULL);
ASSERT_BIGNUM_EQ(EC_KEY_get0_private_key(k1->ecdsa), a); ASSERT_BIGNUM_EQ(
EC_KEY_get0_private_key(EVP_PKEY_get0_EC_KEY(k1->pkey)), a);
ASSERT_BIGNUM_EQ(b, c); ASSERT_BIGNUM_EQ(b, c);
BN_free(a); BN_free(a);
BN_free(b); BN_free(b);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: test_sshkey.c,v 1.24 2024/01/11 01:45:58 djm Exp $ */ /* $OpenBSD: test_sshkey.c,v 1.25 2024/08/15 00:52:23 djm Exp $ */
/* /*
* Regress test for sshkey.h key management API * Regress test for sshkey.h key management API
* *
@ -188,7 +188,7 @@ sshkey_tests(void)
TEST_START("new/free KEY_RSA"); TEST_START("new/free KEY_RSA");
k1 = sshkey_new(KEY_RSA); k1 = sshkey_new(KEY_RSA);
ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(k1, NULL);
ASSERT_PTR_NE(k1->rsa, NULL); ASSERT_PTR_NE(k1->pkey, NULL);
sshkey_free(k1); sshkey_free(k1);
TEST_DONE(); TEST_DONE();
@ -204,7 +204,7 @@ sshkey_tests(void)
TEST_START("new/free KEY_ECDSA"); TEST_START("new/free KEY_ECDSA");
k1 = sshkey_new(KEY_ECDSA); k1 = sshkey_new(KEY_ECDSA);
ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(k1, NULL);
ASSERT_PTR_EQ(k1->ecdsa, NULL); /* Can't allocate without NID */ ASSERT_PTR_EQ(k1->pkey, NULL); /* Can't allocate without NID */
sshkey_free(k1); sshkey_free(k1);
TEST_DONE(); TEST_DONE();
@ -250,7 +250,7 @@ sshkey_tests(void)
SSH_ERR_KEY_LENGTH); SSH_ERR_KEY_LENGTH);
ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1024, &kr), 0); ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1024, &kr), 0);
ASSERT_PTR_NE(kr, NULL); ASSERT_PTR_NE(kr, NULL);
ASSERT_PTR_NE(kr->rsa, NULL); ASSERT_PTR_NE(EVP_PKEY_get0_RSA(kr->pkey), NULL);
ASSERT_PTR_NE(rsa_n(kr), NULL); ASSERT_PTR_NE(rsa_n(kr), NULL);
ASSERT_PTR_NE(rsa_e(kr), NULL); ASSERT_PTR_NE(rsa_e(kr), NULL);
ASSERT_PTR_NE(rsa_p(kr), NULL); ASSERT_PTR_NE(rsa_p(kr), NULL);
@ -270,9 +270,11 @@ sshkey_tests(void)
TEST_START("generate KEY_ECDSA"); TEST_START("generate KEY_ECDSA");
ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 256, &ke), 0); ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 256, &ke), 0);
ASSERT_PTR_NE(ke, NULL); ASSERT_PTR_NE(ke, NULL);
ASSERT_PTR_NE(ke->ecdsa, NULL); ASSERT_PTR_NE(EVP_PKEY_get0_EC_KEY(ke->pkey), NULL);
ASSERT_PTR_NE(EC_KEY_get0_public_key(ke->ecdsa), NULL); ASSERT_PTR_NE(EC_KEY_get0_public_key(EVP_PKEY_get0_EC_KEY(ke->pkey)),
ASSERT_PTR_NE(EC_KEY_get0_private_key(ke->ecdsa), NULL); NULL);
ASSERT_PTR_NE(EC_KEY_get0_private_key(EVP_PKEY_get0_EC_KEY(ke->pkey)),
NULL);
TEST_DONE(); TEST_DONE();
TEST_START("generate KEY_ED25519"); TEST_START("generate KEY_ED25519");
@ -288,7 +290,7 @@ sshkey_tests(void)
ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(k1, NULL);
ASSERT_PTR_NE(kr, k1); ASSERT_PTR_NE(kr, k1);
ASSERT_INT_EQ(k1->type, KEY_RSA); ASSERT_INT_EQ(k1->type, KEY_RSA);
ASSERT_PTR_NE(k1->rsa, NULL); ASSERT_PTR_NE(EVP_PKEY_get0_RSA(k1->pkey), NULL);
ASSERT_PTR_NE(rsa_n(k1), NULL); ASSERT_PTR_NE(rsa_n(k1), NULL);
ASSERT_PTR_NE(rsa_e(k1), NULL); ASSERT_PTR_NE(rsa_e(k1), NULL);
ASSERT_PTR_EQ(rsa_p(k1), NULL); ASSERT_PTR_EQ(rsa_p(k1), NULL);
@ -321,10 +323,12 @@ sshkey_tests(void)
ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(k1, NULL);
ASSERT_PTR_NE(ke, k1); ASSERT_PTR_NE(ke, k1);
ASSERT_INT_EQ(k1->type, KEY_ECDSA); ASSERT_INT_EQ(k1->type, KEY_ECDSA);
ASSERT_PTR_NE(k1->ecdsa, NULL); ASSERT_PTR_NE(EVP_PKEY_get0_EC_KEY(k1->pkey), NULL);
ASSERT_INT_EQ(k1->ecdsa_nid, ke->ecdsa_nid); ASSERT_INT_EQ(k1->ecdsa_nid, ke->ecdsa_nid);
ASSERT_PTR_NE(EC_KEY_get0_public_key(ke->ecdsa), NULL); ASSERT_PTR_NE(EC_KEY_get0_public_key(EVP_PKEY_get0_EC_KEY(ke->pkey)),
ASSERT_PTR_EQ(EC_KEY_get0_private_key(k1->ecdsa), NULL); NULL);
ASSERT_PTR_EQ(EC_KEY_get0_private_key(EVP_PKEY_get0_EC_KEY(k1->pkey)),
NULL);
TEST_DONE(); TEST_DONE();
TEST_START("equal KEY_ECDSA/demoted KEY_ECDSA"); TEST_START("equal KEY_ECDSA/demoted KEY_ECDSA");

View file

@ -1,5 +1,5 @@
flags: * = Valid, > = Selected, I = via IBGP, A = Announced, flags: * = Valid, > = Selected, I = via IBGP, A = Announced,
S = Stale, E = Error S = Stale, E = Error, F = Filtered
origin validation state: N = not-found, V = valid, ! = invalid origin validation state: N = not-found, V = valid, ! = invalid
aspa validation state: ? = unknown, V = valid, ! = invalid aspa validation state: ? = unknown, V = valid, ! = invalid
origin: i = IGP, e = EGP, ? = Incomplete origin: i = IGP, e = EGP, ? = Incomplete

View file

@ -1,5 +1,5 @@
flags: * = Valid, > = Selected, I = via IBGP, A = Announced, flags: * = Valid, > = Selected, I = via IBGP, A = Announced,
S = Stale, E = Error S = Stale, E = Error, F = Filtered
origin validation state: N = not-found, V = valid, ! = invalid origin validation state: N = not-found, V = valid, ! = invalid
aspa validation state: ? = unknown, V = valid, ! = invalid aspa validation state: ? = unknown, V = valid, ! = invalid
origin: i = IGP, e = EGP, ? = Incomplete origin: i = IGP, e = EGP, ? = Incomplete

View file

@ -1,5 +1,5 @@
flags: * = Valid, > = Selected, I = via IBGP, A = Announced, flags: * = Valid, > = Selected, I = via IBGP, A = Announced,
S = Stale, E = Error S = Stale, E = Error, F = Filtered
origin validation state: N = not-found, V = valid, ! = invalid origin validation state: N = not-found, V = valid, ! = invalid
aspa validation state: ? = unknown, V = valid, ! = invalid aspa validation state: ? = unknown, V = valid, ! = invalid
origin: i = IGP, e = EGP, ? = Incomplete origin: i = IGP, e = EGP, ? = Incomplete

View file

@ -1,5 +1,5 @@
flags: * = Valid, > = Selected, I = via IBGP, A = Announced, flags: * = Valid, > = Selected, I = via IBGP, A = Announced,
S = Stale, E = Error S = Stale, E = Error, F = Filtered
origin validation state: N = not-found, V = valid, ! = invalid origin validation state: N = not-found, V = valid, ! = invalid
aspa validation state: ? = unknown, V = valid, ! = invalid aspa validation state: ? = unknown, V = valid, ! = invalid
origin: i = IGP, e = EGP, ? = Incomplete origin: i = IGP, e = EGP, ? = Incomplete

View file

@ -1,5 +1,5 @@
flags: * = Valid, > = Selected, I = via IBGP, A = Announced, flags: * = Valid, > = Selected, I = via IBGP, A = Announced,
S = Stale, E = Error S = Stale, E = Error, F = Filtered
origin validation state: N = not-found, V = valid, ! = invalid origin validation state: N = not-found, V = valid, ! = invalid
aspa validation state: ? = unknown, V = valid, ! = invalid aspa validation state: ? = unknown, V = valid, ! = invalid
origin: i = IGP, e = EGP, ? = Incomplete origin: i = IGP, e = EGP, ? = Incomplete

View file

@ -1,5 +1,5 @@
flags: * = Valid, > = Selected, I = via IBGP, A = Announced, flags: * = Valid, > = Selected, I = via IBGP, A = Announced,
S = Stale, E = Error S = Stale, E = Error, F = Filtered
origin validation state: N = not-found, V = valid, ! = invalid origin validation state: N = not-found, V = valid, ! = invalid
aspa validation state: ? = unknown, V = valid, ! = invalid aspa validation state: ? = unknown, V = valid, ! = invalid
origin: i = IGP, e = EGP, ? = Incomplete origin: i = IGP, e = EGP, ? = Incomplete

View file

@ -1,4 +1,4 @@
.\" $OpenBSD: bpf.4,v 1.46 2024/08/05 23:56:10 dlg Exp $ .\" $OpenBSD: bpf.4,v 1.47 2024/08/15 12:20:20 dlg Exp $
.\" $NetBSD: bpf.4,v 1.7 1995/09/27 18:31:50 thorpej Exp $ .\" $NetBSD: bpf.4,v 1.7 1995/09/27 18:31:50 thorpej Exp $
.\" .\"
.\" Copyright (c) 1990 The Regents of the University of California. .\" Copyright (c) 1990 The Regents of the University of California.
@ -23,7 +23,7 @@
.\" This document is derived in part from the enet man page (enet.4) .\" This document is derived in part from the enet man page (enet.4)
.\" distributed with 4.3BSD Unix. .\" distributed with 4.3BSD Unix.
.\" .\"
.Dd $Mdocdate: August 5 2024 $ .Dd $Mdocdate: August 15 2024 $
.Dt BPF 4 .Dt BPF 4
.Os .Os
.Sh NAME .Sh NAME
@ -318,6 +318,7 @@ readable.
The maximum wait time that can be set is 5 minutes (300 seconds). The maximum wait time that can be set is 5 minutes (300 seconds).
.Pp .Pp
.It Dv BIOCSETF Fa "struct bpf_program *" .It Dv BIOCSETF Fa "struct bpf_program *"
.It Dv BIOCSETFNR Fa "struct bpf_program *"
Sets the filter program used by the kernel to discard uninteresting packets. Sets the filter program used by the kernel to discard uninteresting packets.
An array of instructions and its length are passed in using the following An array of instructions and its length are passed in using the following
structure: structure:
@ -335,9 +336,11 @@ field, while its length in units of
is given by the is given by the
.Fa bf_len .Fa bf_len
field. field.
Also, the actions of If
.Dv BIOCSETF
is used, the actions of
.Dv BIOCFLUSH .Dv BIOCFLUSH
are performed. are also performed.
.Pp .Pp
See section See section
.Sx FILTER MACHINE .Sx FILTER MACHINE
@ -350,8 +353,6 @@ network.
See See
.Dv BIOCSETF .Dv BIOCSETF
for a description of the filter program. for a description of the filter program.
This ioctl also acts as
.Dv BIOCFLUSH .
.Pp .Pp
Note that the filter operates on the packet data written to the descriptor. Note that the filter operates on the packet data written to the descriptor.
If the If the

View file

@ -1,4 +1,4 @@
.\" $OpenBSD: bsd.port.mk.5,v 1.644 2023/11/11 10:46:37 espie Exp $ .\" $OpenBSD: bsd.port.mk.5,v 1.646 2024/08/15 09:46:39 tb Exp $
.\" .\"
.\" Copyright (c) 2000-2008 Marc Espie .\" Copyright (c) 2000-2008 Marc Espie
.\" .\"
@ -24,7 +24,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\" .\"
.Dd $Mdocdate: November 11 2023 $ .Dd $Mdocdate: August 15 2024 $
.Dt BSD.PORT.MK 5 .Dt BSD.PORT.MK 5
.Os .Os
.Sh NAME .Sh NAME
@ -1843,6 +1843,20 @@ package and
to perform introspection and obtain to perform introspection and obtain
.Nm Ns 's .Nm Ns 's
default values for variables without needing to access any specific port. default values for variables without needing to access any specific port.
.It Ev DWZ
Command line invocation of
.Xr dwz 1
to shrink debug information while building debug packages.
Defaults to
.Sq dwz -L 100000000
Can be set to
.Sq \&:
to not run
.Xr dwz 1
at all.
See
.Sx THE DEBUG_PACKAGES INFRASTRUCTURE
for details.
.It Ev ECHO_MSG .It Ev ECHO_MSG
User settings. User settings.
Used to display Used to display
@ -3136,7 +3150,7 @@ Actually lives in
Set to Set to
.Sq Yes .Sq Yes
to randomize tree traversal, as used by to randomize tree traversal, as used by
.Xr dbp 1 Ns 's Fl r .Xr dpb 1 Ns 's Fl r
option. option.
Defaults to Defaults to
.Sq \&No Ns . .Sq \&No Ns .
@ -3671,10 +3685,9 @@ bfd's
.Xr ld 1 .Xr ld 1
.Pc . .Pc .
.Sq ports .Sq ports
force the use of forces the use of
.Xr ld.lld 1 .Xr ld.lld 1
from lang/clang module. from lang/clang module.
.Pc
Defaults to the appropriate value for the current architecture Defaults to the appropriate value for the current architecture
.Po .Po
see see
@ -3961,7 +3974,7 @@ target ,
.Xr build-debug-info 1 .Xr build-debug-info 1
will be invoked to deduce debug packing-lists from the normal packing-lists, will be invoked to deduce debug packing-lists from the normal packing-lists,
and some extra makefile rules will be invoked to set aside the debug and some extra makefile rules will be invoked to set aside the debug
information. information, and shrink it by processing it through ${DWZ}.
.Pp .Pp
Then each normal package will have a "shadow" debug-* package built alongside Then each normal package will have a "shadow" debug-* package built alongside
it, with the exact same package signature, except it will also be tied closely it, with the exact same package signature, except it will also be tied closely

View file

@ -1,4 +1,4 @@
/* $OpenBSD: acpisurface.c,v 1.2 2022/04/06 18:59:27 naddy Exp $ */ /* $OpenBSD: acpisurface.c,v 1.3 2024/08/15 17:30:40 deraadt Exp $ */
/* /*
* Copyright (c) 2018 Mike Larkin <mlarkin@openbsd.org> * Copyright (c) 2018 Mike Larkin <mlarkin@openbsd.org>
* *
@ -136,7 +136,7 @@ surface_hotkey(struct aml_node *node, int notify_type, void *arg)
case SURFACE_POWER_BUTTON_RELEASED: case SURFACE_POWER_BUTTON_RELEASED:
DPRINTF("%s: power button released\n", __func__); DPRINTF("%s: power button released\n", __func__);
acpi_addtask(sc->sc_acpi, acpi_powerdown_task, acpi_addtask(sc->sc_acpi, acpi_powerdown_task,
sc->sc_acpi, 0); sc->sc_acpi, 0);
break; break;
case SURFACE_WINDOWS_KEY_PRESSED: case SURFACE_WINDOWS_KEY_PRESSED:
DPRINTF("%s: windows key pressed\n", __func__); DPRINTF("%s: windows key pressed\n", __func__);

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
/* $OpenBSD: qwzvar.h,v 1.1 2024/08/14 14:40:46 patrick Exp $ */ /* $OpenBSD: qwzvar.h,v 1.4 2024/08/16 00:26:54 patrick Exp $ */
/* /*
* Copyright (c) 2018-2019 The Linux Foundation. * Copyright (c) 2018-2019 The Linux Foundation.
@ -64,6 +64,7 @@ struct ath12k_hw_ring_mask {
uint8_t reo_status[ATH12K_EXT_IRQ_GRP_NUM_MAX]; uint8_t reo_status[ATH12K_EXT_IRQ_GRP_NUM_MAX];
uint8_t rxdma2host[ATH12K_EXT_IRQ_GRP_NUM_MAX]; uint8_t rxdma2host[ATH12K_EXT_IRQ_GRP_NUM_MAX];
uint8_t host2rxdma[ATH12K_EXT_IRQ_GRP_NUM_MAX]; uint8_t host2rxdma[ATH12K_EXT_IRQ_GRP_NUM_MAX];
uint8_t tx_mon_dest[ATH12K_EXT_IRQ_GRP_NUM_MAX];
}; };
#define ATH12K_FW_DIR "qwz" #define ATH12K_FW_DIR "qwz"
@ -74,7 +75,6 @@ struct ath12k_hw_ring_mask {
#define ATH12K_DEFAULT_CAL_FILE "caldata" #define ATH12K_DEFAULT_CAL_FILE "caldata"
#define ATH12K_AMSS_FILE "amss" #define ATH12K_AMSS_FILE "amss"
#define ATH12K_M3_FILE "m3" #define ATH12K_M3_FILE "m3"
#define ATH12K_REGDB_FILE "regdb"
#define QWZ_FW_BUILD_ID_MASK "QC_IMAGE_VERSION_STRING=" #define QWZ_FW_BUILD_ID_MASK "QC_IMAGE_VERSION_STRING="
@ -88,29 +88,36 @@ struct ath12k_hw_tcl2wbm_rbm_map {
* enum hal_rx_buf_return_buf_manager * enum hal_rx_buf_return_buf_manager
* *
* @HAL_RX_BUF_RBM_WBM_IDLE_BUF_LIST: Buffer returned to WBM idle buffer list * @HAL_RX_BUF_RBM_WBM_IDLE_BUF_LIST: Buffer returned to WBM idle buffer list
* @HAL_RX_BUF_RBM_WBM_IDLE_DESC_LIST: Descriptor returned to WBM idle * @HAL_RX_BUF_RBM_WBM_CHIP0_IDLE_DESC_LIST: Descriptor returned to WBM idle
* descriptor list. * descriptor list, where the chip 0 WBM is chosen in case of a
* multi-chip config
* @HAL_RX_BUF_RBM_FW_BM: Buffer returned to FW * @HAL_RX_BUF_RBM_FW_BM: Buffer returned to FW
* @HAL_RX_BUF_RBM_SW0_BM: For Tx completion -- returned to host * @HAL_RX_BUF_RBM_SW0_BM: For Tx completion -- returned to host
* @HAL_RX_BUF_RBM_SW1_BM: For Tx completion -- returned to host * @HAL_RX_BUF_RBM_SW1_BM: For Tx completion -- returned to host
* @HAL_RX_BUF_RBM_SW2_BM: For Tx completion -- returned to host * @HAL_RX_BUF_RBM_SW2_BM: For Tx completion -- returned to host
* @HAL_RX_BUF_RBM_SW3_BM: For Rx release -- returned to host * @HAL_RX_BUF_RBM_SW3_BM: For Rx release -- returned to host
* @HAL_RX_BUF_RBM_SW4_BM: For Tx completion -- returned to host
* @HAL_RX_BUF_RBM_SW5_BM: For ring 5 -- returned to host
* @HAL_RX_BUF_RBM_SW6_BM: For ring 6 -- returned to host
*/ */
enum hal_rx_buf_return_buf_manager { enum hal_rx_buf_return_buf_manager {
HAL_RX_BUF_RBM_WBM_IDLE_BUF_LIST, HAL_RX_BUF_RBM_WBM_IDLE_BUF_LIST,
HAL_RX_BUF_RBM_WBM_IDLE_DESC_LIST, HAL_RX_BUF_RBM_WBM_CHIP0_IDLE_DESC_LIST,
HAL_RX_BUF_RBM_FW_BM, HAL_RX_BUF_RBM_FW_BM,
HAL_RX_BUF_RBM_SW0_BM, HAL_RX_BUF_RBM_SW0_BM,
HAL_RX_BUF_RBM_SW1_BM, HAL_RX_BUF_RBM_SW1_BM,
HAL_RX_BUF_RBM_SW2_BM, HAL_RX_BUF_RBM_SW2_BM,
HAL_RX_BUF_RBM_SW3_BM, HAL_RX_BUF_RBM_SW3_BM,
HAL_RX_BUF_RBM_SW4_BM, HAL_RX_BUF_RBM_SW4_BM,
HAL_RX_BUF_RBM_SW5_BM,
HAL_RX_BUF_RBM_SW6_BM,
}; };
struct ath12k_hw_hal_params { struct ath12k_hw_hal_params {
enum hal_rx_buf_return_buf_manager rx_buf_rbm; enum hal_rx_buf_return_buf_manager rx_buf_rbm;
const struct ath12k_hw_tcl2wbm_rbm_map *tcl2wbm_rbm_map; const struct ath12k_hw_tcl2wbm_rbm_map *tcl2wbm_rbm_map;
uint32_t wbm2sw_cc_enable;
}; };
struct hal_tx_info { struct hal_tx_info {
@ -190,6 +197,7 @@ struct ath12k_hw_params {
bool rxdma1_enable; bool rxdma1_enable;
int num_rxmda_per_pdev; int num_rxmda_per_pdev;
int num_rxdma_dst_ring;
bool rx_mac_buf_ring; bool rx_mac_buf_ring;
bool vdev_start_delay; bool vdev_start_delay;
bool htt_peer_map_v2; bool htt_peer_map_v2;
@ -210,37 +218,24 @@ struct ath12k_hw_params {
bool supports_shadow_regs; bool supports_shadow_regs;
bool idle_ps; bool idle_ps;
bool supports_sta_ps; bool supports_sta_ps;
bool cold_boot_calib;
bool cbcal_restart_fw;
int fw_mem_mode;
uint32_t num_vdevs; uint32_t num_vdevs;
uint32_t num_peers; uint32_t num_peers;
bool supports_suspend; bool supports_suspend;
uint32_t hal_desc_sz; uint32_t hal_desc_sz;
bool supports_regdb;
bool fix_l1ss; bool fix_l1ss;
bool credit_flow; bool credit_flow;
uint8_t max_tx_ring; uint8_t max_tx_ring;
const struct ath12k_hw_hal_params *hal_params; const struct ath12k_hw_hal_params *hal_params;
uint64_t qmi_cnss_feature_bitmap;
#if notyet #if notyet
bool supports_dynamic_smps_6ghz; bool supports_dynamic_smps_6ghz;
bool alloc_cacheable_memory; bool alloc_cacheable_memory;
bool supports_rssi_stats; bool supports_rssi_stats;
#endif #endif
bool fw_wmi_diag_event;
bool current_cc_support; bool current_cc_support;
bool dbr_debug_support; bool dbr_debug_support;
bool global_reset;
#ifdef notyet #ifdef notyet
const struct cfg80211_sar_capa *bios_sar_capa; const struct cfg80211_sar_capa *bios_sar_capa;
#endif
bool m3_fw_support;
bool fixed_bdf_addr;
bool fixed_mem_region;
bool static_window_map;
bool hybrid_bus_type;
bool fixed_fw_mem;
#if notyet
bool support_off_channel_tx; bool support_off_channel_tx;
bool supports_multi_bssid; bool supports_multi_bssid;
@ -312,21 +307,9 @@ struct ath12k_hw_ops {
#endif #endif
}; };
extern const struct ath12k_hw_ops ipq8074_ops; extern const struct ath12k_hw_ring_mask ath12k_hw_ring_mask_wcn7850;
extern const struct ath12k_hw_ops ipq6018_ops;
extern const struct ath12k_hw_ops qca6390_ops;
extern const struct ath12k_hw_ops qcn9074_ops;
extern const struct ath12k_hw_ops wcn6855_ops;
extern const struct ath12k_hw_ops wcn6750_ops;
extern const struct ath12k_hw_ring_mask ath12k_hw_ring_mask_ipq8074;
extern const struct ath12k_hw_ring_mask ath12k_hw_ring_mask_qca6390;
extern const struct ath12k_hw_ring_mask ath12k_hw_ring_mask_qcn9074;
extern const struct ath12k_hw_ring_mask ath12k_hw_ring_mask_wcn6750;
struct ath12k_hw_regs { struct ath12k_hw_regs {
uint32_t hal_tcl1_ring_base_lsb;
uint32_t hal_tcl1_ring_base_msb;
uint32_t hal_tcl1_ring_id; uint32_t hal_tcl1_ring_id;
uint32_t hal_tcl1_ring_misc; uint32_t hal_tcl1_ring_misc;
uint32_t hal_tcl1_ring_tp_addr_lsb; uint32_t hal_tcl1_ring_tp_addr_lsb;
@ -336,11 +319,38 @@ struct ath12k_hw_regs {
uint32_t hal_tcl1_ring_msi1_base_lsb; uint32_t hal_tcl1_ring_msi1_base_lsb;
uint32_t hal_tcl1_ring_msi1_base_msb; uint32_t hal_tcl1_ring_msi1_base_msb;
uint32_t hal_tcl1_ring_msi1_data; uint32_t hal_tcl1_ring_msi1_data;
uint32_t hal_tcl2_ring_base_lsb;
uint32_t hal_tcl_ring_base_lsb; uint32_t hal_tcl_ring_base_lsb;
uint32_t hal_tcl_status_ring_base_lsb; uint32_t hal_tcl_status_ring_base_lsb;
uint32_t hal_wbm_idle_ring_base_lsb;
uint32_t hal_wbm_idle_ring_misc_addr;
uint32_t hal_wbm_r0_idle_list_cntl_addr;
uint32_t hal_wbm_r0_idle_list_size_addr;
uint32_t hal_wbm_scattered_ring_base_lsb;
uint32_t hal_wbm_scattered_ring_base_msb;
uint32_t hal_wbm_scattered_desc_head_info_ix0;
uint32_t hal_wbm_scattered_desc_head_info_ix1;
uint32_t hal_wbm_scattered_desc_tail_info_ix0;
uint32_t hal_wbm_scattered_desc_tail_info_ix1;
uint32_t hal_wbm_scattered_desc_ptr_hp_addr;
uint32_t hal_wbm_sw_release_ring_base_lsb;
uint32_t hal_wbm_sw1_release_ring_base_lsb;
uint32_t hal_wbm0_release_ring_base_lsb;
uint32_t hal_wbm1_release_ring_base_lsb;
uint32_t pcie_qserdes_sysclk_en_sel;
uint32_t pcie_pcs_osc_dtct_config_base;
uint32_t hal_ppe_rel_ring_base;
uint32_t hal_reo2_ring_base;
uint32_t hal_reo1_misc_ctrl_addr;
uint32_t hal_reo1_sw_cookie_cfg0;
uint32_t hal_reo1_sw_cookie_cfg1;
uint32_t hal_reo1_qdesc_lut_base0;
uint32_t hal_reo1_qdesc_lut_base1;
uint32_t hal_reo1_ring_base_lsb; uint32_t hal_reo1_ring_base_lsb;
uint32_t hal_reo1_ring_base_msb; uint32_t hal_reo1_ring_base_msb;
uint32_t hal_reo1_ring_id; uint32_t hal_reo1_ring_id;
@ -351,53 +361,22 @@ struct ath12k_hw_regs {
uint32_t hal_reo1_ring_msi1_base_lsb; uint32_t hal_reo1_ring_msi1_base_lsb;
uint32_t hal_reo1_ring_msi1_base_msb; uint32_t hal_reo1_ring_msi1_base_msb;
uint32_t hal_reo1_ring_msi1_data; uint32_t hal_reo1_ring_msi1_data;
uint32_t hal_reo2_ring_base_lsb; uint32_t hal_reo1_aging_thres_ix0;
uint32_t hal_reo1_aging_thresh_ix_0; uint32_t hal_reo1_aging_thres_ix1;
uint32_t hal_reo1_aging_thresh_ix_1; uint32_t hal_reo1_aging_thres_ix2;
uint32_t hal_reo1_aging_thresh_ix_2; uint32_t hal_reo1_aging_thres_ix3;
uint32_t hal_reo1_aging_thresh_ix_3;
uint32_t hal_reo1_ring_hp; uint32_t hal_reo2_sw0_ring_base;
uint32_t hal_reo1_ring_tp;
uint32_t hal_reo2_ring_hp;
uint32_t hal_reo_tcl_ring_base_lsb; uint32_t hal_sw2reo_ring_base;
uint32_t hal_reo_tcl_ring_hp; uint32_t hal_sw2reo1_ring_base;
uint32_t hal_reo_status_ring_base_lsb; uint32_t hal_reo_cmd_ring_base;
uint32_t hal_reo_status_hp;
uint32_t hal_reo_cmd_ring_base_lsb; uint32_t hal_reo_status_ring_base;
uint32_t hal_reo_cmd_ring_hp;
uint32_t hal_sw2reo_ring_base_lsb;
uint32_t hal_sw2reo_ring_hp;
uint32_t hal_seq_wcss_umac_ce0_src_reg;
uint32_t hal_seq_wcss_umac_ce0_dst_reg;
uint32_t hal_seq_wcss_umac_ce1_src_reg;
uint32_t hal_seq_wcss_umac_ce1_dst_reg;
uint32_t hal_wbm_idle_link_ring_base_lsb;
uint32_t hal_wbm_idle_link_ring_misc;
uint32_t hal_wbm_release_ring_base_lsb;
uint32_t hal_wbm0_release_ring_base_lsb;
uint32_t hal_wbm1_release_ring_base_lsb;
uint32_t pcie_qserdes_sysclk_en_sel;
uint32_t pcie_pcs_osc_dtct_config_base;
uint32_t hal_shadow_base_addr;
uint32_t hal_reo1_misc_ctl;
}; };
extern const struct ath12k_hw_regs ipq8074_regs; extern const struct ath12k_hw_regs wcn7850_regs;
extern const struct ath12k_hw_regs qca6390_regs;
extern const struct ath12k_hw_regs qcn9074_regs;
extern const struct ath12k_hw_regs wcn6855_regs;
extern const struct ath12k_hw_regs wcn6750_regs;
enum ath12k_dev_flags { enum ath12k_dev_flags {
ATH12K_CAC_RUNNING, ATH12K_CAC_RUNNING,
@ -647,9 +626,19 @@ enum hal_ring_type {
HAL_RXDMA_MONITOR_DST, HAL_RXDMA_MONITOR_DST,
HAL_RXDMA_MONITOR_DESC, HAL_RXDMA_MONITOR_DESC,
HAL_RXDMA_DIR_BUF, HAL_RXDMA_DIR_BUF,
HAL_PPE2TCL,
HAL_PPE_RELEASE,
HAL_TX_MONITOR_BUF,
HAL_TX_MONITOR_DST,
HAL_MAX_RING_TYPES, HAL_MAX_RING_TYPES,
}; };
enum hal_srng_mac_type {
ATH12K_HAL_SRNG_UMAC,
ATH12K_HAL_SRNG_DMAC,
ATH12K_HAL_SRNG_PMAC
};
/* HW SRNG configuration table */ /* HW SRNG configuration table */
struct hal_srng_config { struct hal_srng_config {
int start_ring_id; int start_ring_id;
@ -657,7 +646,7 @@ struct hal_srng_config {
uint16_t entry_size; uint16_t entry_size;
uint32_t reg_start[HAL_SRNG_NUM_REG_GRP]; uint32_t reg_start[HAL_SRNG_NUM_REG_GRP];
uint16_t reg_size[HAL_SRNG_NUM_REG_GRP]; uint16_t reg_size[HAL_SRNG_NUM_REG_GRP];
uint8_t lmac_ring; enum hal_srng_mac_type mac_type;
enum hal_srng_dir ring_dir; enum hal_srng_dir ring_dir;
uint32_t max_size; uint32_t max_size;
}; };
@ -767,7 +756,7 @@ struct ath12k_hal {
struct hal_srng srng_list[HAL_SRNG_RING_ID_MAX]; struct hal_srng srng_list[HAL_SRNG_RING_ID_MAX];
/* SRNG configuration table */ /* SRNG configuration table */
struct hal_srng_config srng_config[QWZ_NUM_SRNG_CFG]; struct hal_srng_config *srng_config;
/* Remote pointer memory for HW/FW updates */ /* Remote pointer memory for HW/FW updates */
struct qwz_dmamem *rdpmem; struct qwz_dmamem *rdpmem;
@ -837,7 +826,6 @@ struct ce_attr {
unsigned int dest_nentries; unsigned int dest_nentries;
void (*recv_cb)(struct qwz_softc *, struct mbuf *); void (*recv_cb)(struct qwz_softc *, struct mbuf *);
void (*send_cb)(struct qwz_softc *, struct mbuf *);
}; };
#define CE_DESC_RING_ALIGN 8 #define CE_DESC_RING_ALIGN 8
@ -982,6 +970,12 @@ struct qwz_dp_htt_wbm_tx_status {
#define DP_RXDMA_MONITOR_BUF_RING_SIZE 4096 #define DP_RXDMA_MONITOR_BUF_RING_SIZE 4096
#define DP_RXDMA_MONITOR_DST_RING_SIZE 2048 #define DP_RXDMA_MONITOR_DST_RING_SIZE 2048
#define DP_RXDMA_MONITOR_DESC_RING_SIZE 4096 #define DP_RXDMA_MONITOR_DESC_RING_SIZE 4096
#define DP_TX_MONITOR_BUF_RING_SIZE 4096
#define DP_TX_MONITOR_DEST_RING_SIZE 2048
#define DP_TX_MONITOR_BUF_SIZE 2048
#define DP_TX_MONITOR_BUF_SIZE_MIN 48
#define DP_TX_MONITOR_BUF_SIZE_MAX 8192
#define DP_RX_RELEASE_RING_NUM 3 #define DP_RX_RELEASE_RING_NUM 3
@ -999,6 +993,74 @@ struct qwz_dp_htt_wbm_tx_status {
#define DP_TX_DESC_ID_MSDU_ID GENMASK(18, 2) #define DP_TX_DESC_ID_MSDU_ID GENMASK(18, 2)
#define DP_TX_DESC_ID_POOL_ID GENMASK(20, 19) #define DP_TX_DESC_ID_POOL_ID GENMASK(20, 19)
#define ATH12K_NUM_POOL_TX_DESC 32768
/* TODO: revisit this count during testing */
#define ATH12K_RX_DESC_COUNT (12288)
#define ATH12K_PAGE_SIZE PAGE_SIZE
/* Total 1024 entries in PPT, i.e 4K/4 considering 4K aligned
* SPT pages which makes lower 12bits 0
*/
#define ATH12K_MAX_PPT_ENTRIES 1024
/* Total 512 entries in a SPT, i.e 4K Page/8 */
#define ATH12K_MAX_SPT_ENTRIES 512
#define ATH12K_NUM_RX_SPT_PAGES ((ATH12K_RX_DESC_COUNT) / ATH12K_MAX_SPT_ENTRIES)
#define ATH12K_TX_SPT_PAGES_PER_POOL (ATH12K_NUM_POOL_TX_DESC / \
ATH12K_MAX_SPT_ENTRIES)
#define ATH12K_NUM_TX_SPT_PAGES (ATH12K_TX_SPT_PAGES_PER_POOL * ATH12K_HW_MAX_QUEUES)
#define ATH12K_NUM_SPT_PAGES (ATH12K_NUM_RX_SPT_PAGES + ATH12K_NUM_TX_SPT_PAGES)
#define ATH12K_TX_SPT_PAGE_OFFSET 0
#define ATH12K_RX_SPT_PAGE_OFFSET ATH12K_NUM_TX_SPT_PAGES
/* The SPT pages are divided for RX and TX, first block for RX
* and remaining for TX
*/
#define ATH12K_NUM_TX_SPT_PAGE_START ATH12K_NUM_RX_SPT_PAGES
#define ATH12K_DP_RX_DESC_MAGIC 0xBABABABA
/* 4K aligned address have last 12 bits set to 0, this check is done
* so that two spt pages address can be stored per 8bytes
* of CMEM (PPT)
*/
#define ATH12K_SPT_4K_ALIGN_CHECK 0xFFF
#define ATH12K_SPT_4K_ALIGN_OFFSET 12
#define ATH12K_PPT_ADDR_OFFSET(ppt_index) (4 * (ppt_index))
/* To indicate HW of CMEM address, b0-31 are cmem base received via QMI */
#define ATH12K_CMEM_ADDR_MSB 0x10
/* Of 20 bits cookie, b0-b8 is to indicate SPT offset and b9-19 for PPT */
#define ATH12K_CC_SPT_MSB 8
#define ATH12K_CC_PPT_MSB 19
#define ATH12K_CC_PPT_SHIFT 9
#define ATH12K_DP_CC_COOKIE_SPT GENMASK(8, 0)
#define ATH12K_DP_CC_COOKIE_PPT GENMASK(19, 9)
#define DP_REO_QREF_NUM GENMASK(31, 16)
#define DP_MAX_PEER_ID 2047
/* Total size of the LUT is based on 2K peers, each having reference
* for 17tids, note each entry is of type ath12k_reo_queue_ref
* hence total size is 2048 * 17 * 8 = 278528
*/
#define DP_REOQ_LUT_SIZE 278528
/* Invalid TX Bank ID value */
#define DP_INVALID_BANK_ID -1
struct ath12k_dp_tx_bank_profile {
uint8_t is_configured;
uint32_t num_users;
uint32_t bank_config;
};
struct qwz_hp_update_timer { struct qwz_hp_update_timer {
struct timeout timer; struct timeout timer;
int started; int started;
@ -1010,6 +1072,29 @@ struct qwz_hp_update_timer {
struct qwz_softc *sc; struct qwz_softc *sc;
}; };
struct ath12k_rx_desc_info {
TAILQ_ENTRY(ath12k_rx_desc_info) entry;
// struct sk_buff *skb;
uint32_t cookie;
uint32_t magic;
uint8_t in_use : 1,
reserved : 7;
};
struct ath12k_tx_desc_info {
TAILQ_ENTRY(ath12k_tx_desc_info) entry;
// struct sk_buff *skb;
uint32_t desc_id; /* Cookie */
uint8_t mac_id;
uint8_t pool_id;
};
struct ath12k_spt_info {
struct qwz_dmamem *mem;
struct ath12k_rx_desc_info *rxbaddr[ATH12K_NUM_RX_SPT_PAGES];
struct ath12k_tx_desc_info *txbaddr[ATH12K_NUM_TX_SPT_PAGES];
};
struct dp_rx_tid { struct dp_rx_tid {
uint8_t tid; uint8_t tid;
struct qwz_dmamem *mem; struct qwz_dmamem *mem;
@ -1089,6 +1174,14 @@ struct dp_link_desc_bank {
#define DP_LINK_DESC_ALLOC_SIZE_THRESH 0x200000 #define DP_LINK_DESC_ALLOC_SIZE_THRESH 0x200000
#define DP_LINK_DESC_BANKS_MAX 8 #define DP_LINK_DESC_BANKS_MAX 8
#define DP_LINK_DESC_START 0x4000
#define DP_LINK_DESC_SHIFT 3
#define DP_LINK_DESC_COOKIE_SET(id, page) \
((((id) + DP_LINK_DESC_START) << DP_LINK_DESC_SHIFT) | (page))
#define DP_LINK_DESC_BANK_MASK GENMASK(2, 0)
struct hal_wbm_idle_scatter_list { struct hal_wbm_idle_scatter_list {
struct qwz_dmamem *mem; struct qwz_dmamem *mem;
bus_addr_t paddr; bus_addr_t paddr;
@ -1131,6 +1224,19 @@ struct qwz_dp {
#endif #endif
struct qwz_hp_update_timer reo_cmd_timer; struct qwz_hp_update_timer reo_cmd_timer;
struct qwz_hp_update_timer tx_ring_timer[DP_TCL_NUM_RING_MAX]; struct qwz_hp_update_timer tx_ring_timer[DP_TCL_NUM_RING_MAX];
struct ath12k_spt_info *spt_info;
uint32_t num_spt_pages;
TAILQ_HEAD(,ath12k_rx_desc_info) rx_desc_free_list;
#ifdef notyet
/* protects the free desc list */
spinlock_t rx_desc_lock;
#endif
TAILQ_HEAD(,ath12k_tx_desc_info) tx_desc_free_list[ATH12K_HW_MAX_QUEUES];
TAILQ_HEAD(,ath12k_tx_desc_info) tx_desc_used_list[ATH12K_HW_MAX_QUEUES];
#ifdef notyet
/* protects the free and used desc lists */
spinlock_t tx_desc_lock[ATH12K_HW_MAX_QUEUES];
#endif
}; };
#define ATH12K_SHADOW_DP_TIMER_INTERVAL 20 #define ATH12K_SHADOW_DP_TIMER_INTERVAL 20
@ -1143,7 +1249,7 @@ struct qwz_ce_pipe {
unsigned int buf_sz; unsigned int buf_sz;
unsigned int rx_buf_needed; unsigned int rx_buf_needed;
void (*send_cb)(struct qwz_softc *, struct mbuf *); int (*send_cb)(struct qwz_ce_pipe *pipe);
void (*recv_cb)(struct qwz_softc *, struct mbuf *); void (*recv_cb)(struct qwz_softc *, struct mbuf *);
#ifdef notyet #ifdef notyet
@ -1171,8 +1277,8 @@ struct qwz_ce {
struct qwz_qmi_ce_cfg { struct qwz_qmi_ce_cfg {
const uint8_t *shadow_reg; const uint8_t *shadow_reg;
int shadow_reg_len; int shadow_reg_len;
uint32_t *shadow_reg_v2; uint32_t *shadow_reg_v3;
uint32_t shadow_reg_v2_len; uint32_t shadow_reg_v3_len;
}; };
struct qwz_qmi_target_info { struct qwz_qmi_target_info {
@ -1187,6 +1293,11 @@ struct qwz_qmi_target_info {
char bdf_ext[ATH12K_QMI_BDF_EXT_STR_LENGTH]; char bdf_ext[ATH12K_QMI_BDF_EXT_STR_LENGTH];
}; };
struct qwz_qmi_dev_mem_info {
uint64_t start;
uint64_t size;
};
enum ath12k_bdf_search { enum ath12k_bdf_search {
ATH12K_BDF_SEARCH_DEFAULT, ATH12K_BDF_SEARCH_DEFAULT,
ATH12K_BDF_SEARCH_BUS_AND_BOARD, ATH12K_BDF_SEARCH_BUS_AND_BOARD,
@ -1631,7 +1742,8 @@ struct qwz_pdev_dp {
struct dp_rxdma_ring rx_refill_buf_ring; struct dp_rxdma_ring rx_refill_buf_ring;
struct dp_srng rx_mac_buf_ring[MAX_RXDMA_PER_PDEV]; struct dp_srng rx_mac_buf_ring[MAX_RXDMA_PER_PDEV];
struct dp_srng rxdma_err_dst_ring[MAX_RXDMA_PER_PDEV]; struct dp_srng rxdma_err_dst_ring[MAX_RXDMA_PER_PDEV];
struct dp_srng rxdma_mon_dst_ring; struct dp_srng rxdma_mon_dst_ring[MAX_RXDMA_PER_PDEV];
struct dp_srng tx_mon_dst_ring[MAX_RXDMA_PER_PDEV];
struct dp_srng rxdma_mon_desc_ring; struct dp_srng rxdma_mon_desc_ring;
struct dp_rxdma_ring rxdma_mon_buf_ring; struct dp_rxdma_ring rxdma_mon_buf_ring;
struct dp_rxdma_ring rx_mon_status_refill_ring[MAX_RXDMA_PER_PDEV]; struct dp_rxdma_ring rx_mon_status_refill_ring[MAX_RXDMA_PER_PDEV];
@ -1810,11 +1922,10 @@ struct qwz_softc {
struct { struct {
u_char *data; u_char *data;
size_t size; size_t size;
} fw_img[4]; } fw_img[3];
#define QWZ_FW_AMSS 0 #define QWZ_FW_AMSS 0
#define QWZ_FW_BOARD 1 #define QWZ_FW_BOARD 1
#define QWZ_FW_M3 2 #define QWZ_FW_M3 2
#define QWZ_FW_REGDB 3
int sc_tx_timer; int sc_tx_timer;
uint32_t qfullmsk; uint32_t qfullmsk;
@ -1839,6 +1950,7 @@ struct qwz_softc {
int qmi_cal_done; int qmi_cal_done;
struct qwz_qmi_ce_cfg qmi_ce_cfg; struct qwz_qmi_ce_cfg qmi_ce_cfg;
struct qwz_qmi_target_info qmi_target; struct qwz_qmi_target_info qmi_target;
struct qwz_qmi_dev_mem_info qmi_dev_mem[ATH12K_QMI_WLFW_MAX_DEV_MEM_NUM_V01];
struct ath12k_targ_cap target_caps; struct ath12k_targ_cap target_caps;
int num_radios; int num_radios;
uint32_t cc_freq_hz; uint32_t cc_freq_hz;
@ -1888,7 +2000,7 @@ struct qwz_softc {
struct qwz_dmamem *fwmem; struct qwz_dmamem *fwmem;
int expect_fwmem_req; int expect_fwmem_req;
int fwmem_ready; int fwmem_ready;
int fw_init_done; int fw_ready;
int ctl_resp; int ctl_resp;
@ -1901,6 +2013,7 @@ struct qwz_softc {
struct qwz_ops ops; struct qwz_ops ops;
bus_dma_tag_t sc_dmat; bus_dma_tag_t sc_dmat;
enum ath12k_hw_rev sc_hw_rev; enum ath12k_hw_rev sc_hw_rev;
int static_window_map;
struct qwz_device_id id; struct qwz_device_id id;
char sc_bus_str[4]; /* "pci" or "ahb" */ char sc_bus_str[4]; /* "pci" or "ahb" */
int num_msivec; int num_msivec;

View file

@ -3593,6 +3593,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
rw_init(&adev->grbm_idx_mutex, "grbmidx"); rw_init(&adev->grbm_idx_mutex, "grbmidx");
rw_init(&adev->mn_lock, "agpumn"); rw_init(&adev->mn_lock, "agpumn");
rw_init(&adev->virt.vf_errors.lock, "vferr"); rw_init(&adev->virt.vf_errors.lock, "vferr");
rw_init(&adev->virt.rlcg_reg_lock, "vrlcg");
hash_init(adev->mn_hash); hash_init(adev->mn_hash);
rw_init(&adev->psp.mutex, "agpsp"); rw_init(&adev->psp.mutex, "agpsp");
rw_init(&adev->notifier_lock, "agnf"); rw_init(&adev->notifier_lock, "agnf");

View file

@ -258,9 +258,8 @@ amdgpu_job_prepare_job(struct drm_sched_job *sched_job,
struct dma_fence *fence = NULL; struct dma_fence *fence = NULL;
int r; int r;
/* Ignore soft recovered fences here */
r = drm_sched_entity_error(s_entity); r = drm_sched_entity_error(s_entity);
if (r && r != -ENODATA) if (r)
goto error; goto error;
if (!fence && job->gang_submit) if (!fence && job->gang_submit)

View file

@ -334,7 +334,7 @@ static ssize_t ta_if_invoke_debugfs_write(struct file *fp, const char *buf, size
set_ta_context_funcs(psp, ta_type, &context); set_ta_context_funcs(psp, ta_type, &context);
if (!context->initialized) { if (!context || !context->initialized) {
dev_err(adev->dev, "TA is not initialized\n"); dev_err(adev->dev, "TA is not initialized\n");
ret = -EINVAL; ret = -EINVAL;
goto err_free_shared_buf; goto err_free_shared_buf;

View file

@ -1800,12 +1800,15 @@ static void amdgpu_ras_interrupt_process_handler(struct work_struct *work)
int amdgpu_ras_interrupt_dispatch(struct amdgpu_device *adev, int amdgpu_ras_interrupt_dispatch(struct amdgpu_device *adev,
struct ras_dispatch_if *info) struct ras_dispatch_if *info)
{ {
struct ras_manager *obj = amdgpu_ras_find_obj(adev, &info->head); struct ras_manager *obj;
struct ras_ih_data *data = &obj->ih_data; struct ras_ih_data *data;
obj = amdgpu_ras_find_obj(adev, &info->head);
if (!obj) if (!obj)
return -EINVAL; return -EINVAL;
data = &obj->ih_data;
if (data->inuse == 0) if (data->inuse == 0)
return 0; return 0;

View file

@ -1004,6 +1004,9 @@ static u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v
scratch_reg1 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg1; scratch_reg1 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg1;
scratch_reg2 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg2; scratch_reg2 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg2;
scratch_reg3 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg3; scratch_reg3 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg3;
mutex_lock(&adev->virt.rlcg_reg_lock);
if (reg_access_ctrl->spare_int) if (reg_access_ctrl->spare_int)
spare_int = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->spare_int; spare_int = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->spare_int;
@ -1059,6 +1062,9 @@ static u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v
} }
ret = readl(scratch_reg0); ret = readl(scratch_reg0);
mutex_unlock(&adev->virt.rlcg_reg_lock);
return ret; return ret;
} }

View file

@ -263,6 +263,8 @@ struct amdgpu_virt {
/* the ucode id to signal the autoload */ /* the ucode id to signal the autoload */
uint32_t autoload_ucode_id; uint32_t autoload_ucode_id;
struct rwlock rlcg_reg_lock;
}; };
struct amdgpu_video_codec_info; struct amdgpu_video_codec_info;

View file

@ -102,6 +102,11 @@ static int amdgpu_vm_sdma_prepare(struct amdgpu_vm_update_params *p,
if (!r) if (!r)
r = amdgpu_sync_push_to_job(&sync, p->job); r = amdgpu_sync_push_to_job(&sync, p->job);
amdgpu_sync_free(&sync); amdgpu_sync_free(&sync);
if (r) {
p->num_dw_left = 0;
amdgpu_job_free(p->job);
}
return r; return r;
} }

View file

@ -2632,7 +2632,8 @@ static int dm_suspend(void *handle)
dm->cached_dc_state = dc_copy_state(dm->dc->current_state); dm->cached_dc_state = dc_copy_state(dm->dc->current_state);
dm_gpureset_toggle_interrupts(adev, dm->cached_dc_state, false); if (dm->cached_dc_state)
dm_gpureset_toggle_interrupts(adev, dm->cached_dc_state, false);
amdgpu_dm_commit_zero_streams(dm->dc); amdgpu_dm_commit_zero_streams(dm->dc);
@ -6487,7 +6488,8 @@ static void create_eml_sink(struct amdgpu_dm_connector *aconnector)
aconnector->dc_sink = aconnector->dc_link->local_sink ? aconnector->dc_sink = aconnector->dc_link->local_sink ?
aconnector->dc_link->local_sink : aconnector->dc_link->local_sink :
aconnector->dc_em_sink; aconnector->dc_em_sink;
dc_sink_retain(aconnector->dc_sink); if (aconnector->dc_sink)
dc_sink_retain(aconnector->dc_sink);
} }
} }
@ -7300,7 +7302,8 @@ static int amdgpu_dm_connector_get_modes(struct drm_connector *connector)
drm_add_modes_noedid(connector, 1920, 1080); drm_add_modes_noedid(connector, 1920, 1080);
} else { } else {
amdgpu_dm_connector_ddc_get_modes(connector, edid); amdgpu_dm_connector_ddc_get_modes(connector, edid);
amdgpu_dm_connector_add_common_modes(encoder, connector); if (encoder)
amdgpu_dm_connector_add_common_modes(encoder, connector);
amdgpu_dm_connector_add_freesync_modes(connector, edid); amdgpu_dm_connector_add_freesync_modes(connector, edid);
} }
amdgpu_dm_fbc_init(connector); amdgpu_dm_fbc_init(connector);

View file

@ -1266,6 +1266,9 @@ static bool is_dsc_need_re_compute(
} }
} }
if (new_stream_on_link_num == 0)
return false;
/* check current_state if there stream on link but it is not in /* check current_state if there stream on link but it is not in
* new request state * new request state
*/ */

View file

@ -162,7 +162,12 @@ static void set_hpo_fixed_vs_pe_retimer_dp_link_test_pattern(struct dc_link *lin
link_res->hpo_dp_link_enc->funcs->set_link_test_pattern( link_res->hpo_dp_link_enc->funcs->set_link_test_pattern(
link_res->hpo_dp_link_enc, tp_params); link_res->hpo_dp_link_enc, tp_params);
} }
link->dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_SET_SOURCE_PATTERN); link->dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_SET_SOURCE_PATTERN);
// Give retimer extra time to lock before updating DP_TRAINING_PATTERN_SET to TPS1
if (tp_params->dp_phy_pattern == DP_TEST_PATTERN_128b_132b_TPS1_TRAINING_MODE)
drm_msleep(30);
} }
static void set_hpo_fixed_vs_pe_retimer_dp_lane_settings(struct dc_link *link, static void set_hpo_fixed_vs_pe_retimer_dp_lane_settings(struct dc_link *link,

View file

@ -927,7 +927,7 @@ static int pp_dpm_switch_power_profile(void *handle,
enum PP_SMC_POWER_PROFILE type, bool en) enum PP_SMC_POWER_PROFILE type, bool en)
{ {
struct pp_hwmgr *hwmgr = handle; struct pp_hwmgr *hwmgr = handle;
long workload; long workload[1];
uint32_t index; uint32_t index;
if (!hwmgr || !hwmgr->pm_en) if (!hwmgr || !hwmgr->pm_en)
@ -945,12 +945,12 @@ static int pp_dpm_switch_power_profile(void *handle,
hwmgr->workload_mask &= ~(1 << hwmgr->workload_prority[type]); hwmgr->workload_mask &= ~(1 << hwmgr->workload_prority[type]);
index = fls(hwmgr->workload_mask); index = fls(hwmgr->workload_mask);
index = index > 0 && index <= Workload_Policy_Max ? index - 1 : 0; index = index > 0 && index <= Workload_Policy_Max ? index - 1 : 0;
workload = hwmgr->workload_setting[index]; workload[0] = hwmgr->workload_setting[index];
} else { } else {
hwmgr->workload_mask |= (1 << hwmgr->workload_prority[type]); hwmgr->workload_mask |= (1 << hwmgr->workload_prority[type]);
index = fls(hwmgr->workload_mask); index = fls(hwmgr->workload_mask);
index = index <= Workload_Policy_Max ? index - 1 : 0; index = index <= Workload_Policy_Max ? index - 1 : 0;
workload = hwmgr->workload_setting[index]; workload[0] = hwmgr->workload_setting[index];
} }
if (type == PP_SMC_POWER_PROFILE_COMPUTE && if (type == PP_SMC_POWER_PROFILE_COMPUTE &&
@ -960,7 +960,7 @@ static int pp_dpm_switch_power_profile(void *handle,
} }
if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL)
hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, &workload, 0); hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, workload, 0);
return 0; return 0;
} }

View file

@ -269,7 +269,7 @@ int psm_adjust_power_state_dynamic(struct pp_hwmgr *hwmgr, bool skip_display_set
struct pp_power_state *new_ps) struct pp_power_state *new_ps)
{ {
uint32_t index; uint32_t index;
long workload; long workload[1];
if (hwmgr->not_vf) { if (hwmgr->not_vf) {
if (!skip_display_settings) if (!skip_display_settings)
@ -294,10 +294,10 @@ int psm_adjust_power_state_dynamic(struct pp_hwmgr *hwmgr, bool skip_display_set
if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) { if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) {
index = fls(hwmgr->workload_mask); index = fls(hwmgr->workload_mask);
index = index > 0 && index <= Workload_Policy_Max ? index - 1 : 0; index = index > 0 && index <= Workload_Policy_Max ? index - 1 : 0;
workload = hwmgr->workload_setting[index]; workload[0] = hwmgr->workload_setting[index];
if (hwmgr->power_profile_mode != workload && hwmgr->hwmgr_func->set_power_profile_mode) if (hwmgr->power_profile_mode != workload[0] && hwmgr->hwmgr_func->set_power_profile_mode)
hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, &workload, 0); hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, workload, 0);
} }
return 0; return 0;

View file

@ -2957,6 +2957,7 @@ static int smu7_update_edc_leakage_table(struct pp_hwmgr *hwmgr)
static int smu7_hwmgr_backend_init(struct pp_hwmgr *hwmgr) static int smu7_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
{ {
struct amdgpu_device *adev = hwmgr->adev;
struct smu7_hwmgr *data; struct smu7_hwmgr *data;
int result = 0; int result = 0;
@ -2993,40 +2994,37 @@ static int smu7_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
/* Initalize Dynamic State Adjustment Rule Settings */ /* Initalize Dynamic State Adjustment Rule Settings */
result = phm_initializa_dynamic_state_adjustment_rule_settings(hwmgr); result = phm_initializa_dynamic_state_adjustment_rule_settings(hwmgr);
if (0 == result) { if (result)
struct amdgpu_device *adev = hwmgr->adev; goto fail;
data->is_tlu_enabled = false; data->is_tlu_enabled = false;
hwmgr->platform_descriptor.hardwareActivityPerformanceLevels = hwmgr->platform_descriptor.hardwareActivityPerformanceLevels =
SMU7_MAX_HARDWARE_POWERLEVELS; SMU7_MAX_HARDWARE_POWERLEVELS;
hwmgr->platform_descriptor.hardwarePerformanceLevels = 2; hwmgr->platform_descriptor.hardwarePerformanceLevels = 2;
hwmgr->platform_descriptor.minimumClocksReductionPercentage = 50; hwmgr->platform_descriptor.minimumClocksReductionPercentage = 50;
data->pcie_gen_cap = adev->pm.pcie_gen_mask; data->pcie_gen_cap = adev->pm.pcie_gen_mask;
if (data->pcie_gen_cap & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) if (data->pcie_gen_cap & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)
data->pcie_spc_cap = 20; data->pcie_spc_cap = 20;
else else
data->pcie_spc_cap = 16; data->pcie_spc_cap = 16;
data->pcie_lane_cap = adev->pm.pcie_mlw_mask; data->pcie_lane_cap = adev->pm.pcie_mlw_mask;
hwmgr->platform_descriptor.vbiosInterruptId = 0x20000400; /* IRQ_SOURCE1_SW_INT */ hwmgr->platform_descriptor.vbiosInterruptId = 0x20000400; /* IRQ_SOURCE1_SW_INT */
/* The true clock step depends on the frequency, typically 4.5 or 9 MHz. Here we use 5. */ /* The true clock step depends on the frequency, typically 4.5 or 9 MHz. Here we use 5. */
hwmgr->platform_descriptor.clockStep.engineClock = 500; hwmgr->platform_descriptor.clockStep.engineClock = 500;
hwmgr->platform_descriptor.clockStep.memoryClock = 500; hwmgr->platform_descriptor.clockStep.memoryClock = 500;
smu7_thermal_parameter_init(hwmgr); smu7_thermal_parameter_init(hwmgr);
} else {
/* Ignore return value in here, we are cleaning up a mess. */
smu7_hwmgr_backend_fini(hwmgr);
}
result = smu7_update_edc_leakage_table(hwmgr); result = smu7_update_edc_leakage_table(hwmgr);
if (result) { if (result)
smu7_hwmgr_backend_fini(hwmgr); goto fail;
return result;
}
return 0; return 0;
fail:
smu7_hwmgr_backend_fini(hwmgr);
return result;
} }
static int smu7_force_dpm_highest(struct pp_hwmgr *hwmgr) static int smu7_force_dpm_highest(struct pp_hwmgr *hwmgr)
@ -3316,8 +3314,7 @@ static int smu7_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
const struct pp_power_state *current_ps) const struct pp_power_state *current_ps)
{ {
struct amdgpu_device *adev = hwmgr->adev; struct amdgpu_device *adev = hwmgr->adev;
struct smu7_power_state *smu7_ps = struct smu7_power_state *smu7_ps;
cast_phw_smu7_power_state(&request_ps->hardware);
uint32_t sclk; uint32_t sclk;
uint32_t mclk; uint32_t mclk;
struct PP_Clocks minimum_clocks = {0}; struct PP_Clocks minimum_clocks = {0};
@ -3334,6 +3331,10 @@ static int smu7_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
uint32_t latency; uint32_t latency;
bool latency_allowed = false; bool latency_allowed = false;
smu7_ps = cast_phw_smu7_power_state(&request_ps->hardware);
if (!smu7_ps)
return -EINVAL;
data->battery_state = (PP_StateUILabel_Battery == data->battery_state = (PP_StateUILabel_Battery ==
request_ps->classification.ui_label); request_ps->classification.ui_label);
data->mclk_ignore_signal = false; data->mclk_ignore_signal = false;

View file

@ -1065,16 +1065,18 @@ static int smu8_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
struct pp_power_state *prequest_ps, struct pp_power_state *prequest_ps,
const struct pp_power_state *pcurrent_ps) const struct pp_power_state *pcurrent_ps)
{ {
struct smu8_power_state *smu8_ps = struct smu8_power_state *smu8_ps;
cast_smu8_power_state(&prequest_ps->hardware); const struct smu8_power_state *smu8_current_ps;
const struct smu8_power_state *smu8_current_ps =
cast_const_smu8_power_state(&pcurrent_ps->hardware);
struct smu8_hwmgr *data = hwmgr->backend; struct smu8_hwmgr *data = hwmgr->backend;
struct PP_Clocks clocks = {0, 0, 0, 0}; struct PP_Clocks clocks = {0, 0, 0, 0};
bool force_high; bool force_high;
smu8_ps = cast_smu8_power_state(&prequest_ps->hardware);
smu8_current_ps = cast_const_smu8_power_state(&pcurrent_ps->hardware);
if (!smu8_ps || !smu8_current_ps)
return -EINVAL;
smu8_ps->need_dfs_bypass = true; smu8_ps->need_dfs_bypass = true;
data->battery_state = (PP_StateUILabel_Battery == prequest_ps->classification.ui_label); data->battery_state = (PP_StateUILabel_Battery == prequest_ps->classification.ui_label);

View file

@ -3259,8 +3259,7 @@ static int vega10_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
const struct pp_power_state *current_ps) const struct pp_power_state *current_ps)
{ {
struct amdgpu_device *adev = hwmgr->adev; struct amdgpu_device *adev = hwmgr->adev;
struct vega10_power_state *vega10_ps = struct vega10_power_state *vega10_ps;
cast_phw_vega10_power_state(&request_ps->hardware);
uint32_t sclk; uint32_t sclk;
uint32_t mclk; uint32_t mclk;
struct PP_Clocks minimum_clocks = {0}; struct PP_Clocks minimum_clocks = {0};
@ -3278,6 +3277,10 @@ static int vega10_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
uint32_t stable_pstate_sclk = 0, stable_pstate_mclk = 0; uint32_t stable_pstate_sclk = 0, stable_pstate_mclk = 0;
uint32_t latency; uint32_t latency;
vega10_ps = cast_phw_vega10_power_state(&request_ps->hardware);
if (!vega10_ps)
return -EINVAL;
data->battery_state = (PP_StateUILabel_Battery == data->battery_state = (PP_StateUILabel_Battery ==
request_ps->classification.ui_label); request_ps->classification.ui_label);
@ -3415,13 +3418,17 @@ static int vega10_find_dpm_states_clocks_in_dpm_table(struct pp_hwmgr *hwmgr, co
const struct vega10_power_state *vega10_ps = const struct vega10_power_state *vega10_ps =
cast_const_phw_vega10_power_state(states->pnew_state); cast_const_phw_vega10_power_state(states->pnew_state);
struct vega10_single_dpm_table *sclk_table = &(data->dpm_table.gfx_table); struct vega10_single_dpm_table *sclk_table = &(data->dpm_table.gfx_table);
uint32_t sclk = vega10_ps->performance_levels
[vega10_ps->performance_level_count - 1].gfx_clock;
struct vega10_single_dpm_table *mclk_table = &(data->dpm_table.mem_table); struct vega10_single_dpm_table *mclk_table = &(data->dpm_table.mem_table);
uint32_t mclk = vega10_ps->performance_levels uint32_t sclk, mclk;
[vega10_ps->performance_level_count - 1].mem_clock;
uint32_t i; uint32_t i;
if (vega10_ps == NULL)
return -EINVAL;
sclk = vega10_ps->performance_levels
[vega10_ps->performance_level_count - 1].gfx_clock;
mclk = vega10_ps->performance_levels
[vega10_ps->performance_level_count - 1].mem_clock;
for (i = 0; i < sclk_table->count; i++) { for (i = 0; i < sclk_table->count; i++) {
if (sclk == sclk_table->dpm_levels[i].value) if (sclk == sclk_table->dpm_levels[i].value)
break; break;
@ -3728,6 +3735,9 @@ static int vega10_generate_dpm_level_enable_mask(
cast_const_phw_vega10_power_state(states->pnew_state); cast_const_phw_vega10_power_state(states->pnew_state);
int i; int i;
if (vega10_ps == NULL)
return -EINVAL;
PP_ASSERT_WITH_CODE(!vega10_trim_dpm_states(hwmgr, vega10_ps), PP_ASSERT_WITH_CODE(!vega10_trim_dpm_states(hwmgr, vega10_ps),
"Attempt to Trim DPM States Failed!", "Attempt to Trim DPM States Failed!",
return -1); return -1);
@ -4995,6 +5005,8 @@ static int vega10_check_states_equal(struct pp_hwmgr *hwmgr,
vega10_psa = cast_const_phw_vega10_power_state(pstate1); vega10_psa = cast_const_phw_vega10_power_state(pstate1);
vega10_psb = cast_const_phw_vega10_power_state(pstate2); vega10_psb = cast_const_phw_vega10_power_state(pstate2);
if (vega10_psa == NULL || vega10_psb == NULL)
return -EINVAL;
/* If the two states don't even have the same number of performance levels /* If the two states don't even have the same number of performance levels
* they cannot be the same state. * they cannot be the same state.
@ -5128,6 +5140,8 @@ static int vega10_set_sclk_od(struct pp_hwmgr *hwmgr, uint32_t value)
return -EINVAL; return -EINVAL;
vega10_ps = cast_phw_vega10_power_state(&ps->hardware); vega10_ps = cast_phw_vega10_power_state(&ps->hardware);
if (vega10_ps == NULL)
return -EINVAL;
vega10_ps->performance_levels vega10_ps->performance_levels
[vega10_ps->performance_level_count - 1].gfx_clock = [vega10_ps->performance_level_count - 1].gfx_clock =
@ -5179,6 +5193,8 @@ static int vega10_set_mclk_od(struct pp_hwmgr *hwmgr, uint32_t value)
return -EINVAL; return -EINVAL;
vega10_ps = cast_phw_vega10_power_state(&ps->hardware); vega10_ps = cast_phw_vega10_power_state(&ps->hardware);
if (vega10_ps == NULL)
return -EINVAL;
vega10_ps->performance_levels vega10_ps->performance_levels
[vega10_ps->performance_level_count - 1].mem_clock = [vega10_ps->performance_level_count - 1].mem_clock =
@ -5420,6 +5436,9 @@ static void vega10_odn_update_power_state(struct pp_hwmgr *hwmgr)
return; return;
vega10_ps = cast_phw_vega10_power_state(&ps->hardware); vega10_ps = cast_phw_vega10_power_state(&ps->hardware);
if (vega10_ps == NULL)
return;
max_level = vega10_ps->performance_level_count - 1; max_level = vega10_ps->performance_level_count - 1;
if (vega10_ps->performance_levels[max_level].gfx_clock != if (vega10_ps->performance_levels[max_level].gfx_clock !=
@ -5442,6 +5461,9 @@ static void vega10_odn_update_power_state(struct pp_hwmgr *hwmgr)
ps = (struct pp_power_state *)((unsigned long)(hwmgr->ps) + hwmgr->ps_size * (hwmgr->num_ps - 1)); ps = (struct pp_power_state *)((unsigned long)(hwmgr->ps) + hwmgr->ps_size * (hwmgr->num_ps - 1));
vega10_ps = cast_phw_vega10_power_state(&ps->hardware); vega10_ps = cast_phw_vega10_power_state(&ps->hardware);
if (vega10_ps == NULL)
return;
max_level = vega10_ps->performance_level_count - 1; max_level = vega10_ps->performance_level_count - 1;
if (vega10_ps->performance_levels[max_level].gfx_clock != if (vega10_ps->performance_levels[max_level].gfx_clock !=
@ -5632,6 +5654,8 @@ static int vega10_get_performance_level(struct pp_hwmgr *hwmgr, const struct pp_
return -EINVAL; return -EINVAL;
vega10_ps = cast_const_phw_vega10_power_state(state); vega10_ps = cast_const_phw_vega10_power_state(state);
if (vega10_ps == NULL)
return -EINVAL;
i = index > vega10_ps->performance_level_count - 1 ? i = index > vega10_ps->performance_level_count - 1 ?
vega10_ps->performance_level_count - 1 : index; vega10_ps->performance_level_count - 1 : index;

View file

@ -1846,7 +1846,7 @@ static int smu_adjust_power_state_dynamic(struct smu_context *smu,
{ {
int ret = 0; int ret = 0;
int index = 0; int index = 0;
long workload; long workload[1];
struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm); struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);
if (!skip_display_settings) { if (!skip_display_settings) {
@ -1886,10 +1886,10 @@ static int smu_adjust_power_state_dynamic(struct smu_context *smu,
smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM) { smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM) {
index = fls(smu->workload_mask); index = fls(smu->workload_mask);
index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0; index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0;
workload = smu->workload_setting[index]; workload[0] = smu->workload_setting[index];
if (smu->power_profile_mode != workload) if (smu->power_profile_mode != workload[0])
smu_bump_power_profile_mode(smu, &workload, 0); smu_bump_power_profile_mode(smu, workload, 0);
} }
return ret; return ret;
@ -1939,7 +1939,7 @@ static int smu_switch_power_profile(void *handle,
{ {
struct smu_context *smu = handle; struct smu_context *smu = handle;
struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm); struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);
long workload; long workload[1];
uint32_t index; uint32_t index;
if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled) if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled)
@ -1952,17 +1952,17 @@ static int smu_switch_power_profile(void *handle,
smu->workload_mask &= ~(1 << smu->workload_prority[type]); smu->workload_mask &= ~(1 << smu->workload_prority[type]);
index = fls(smu->workload_mask); index = fls(smu->workload_mask);
index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0; index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0;
workload = smu->workload_setting[index]; workload[0] = smu->workload_setting[index];
} else { } else {
smu->workload_mask |= (1 << smu->workload_prority[type]); smu->workload_mask |= (1 << smu->workload_prority[type]);
index = fls(smu->workload_mask); index = fls(smu->workload_mask);
index = index <= WORKLOAD_POLICY_MAX ? index - 1 : 0; index = index <= WORKLOAD_POLICY_MAX ? index - 1 : 0;
workload = smu->workload_setting[index]; workload[0] = smu->workload_setting[index];
} }
if (smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL && if (smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL &&
smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM) smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM)
smu_bump_power_profile_mode(smu, &workload, 0); smu_bump_power_profile_mode(smu, workload, 0);
return 0; return 0;
} }

View file

@ -4034,6 +4034,7 @@ static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr)
if (up_req->msg.req_type == DP_CONNECTION_STATUS_NOTIFY) { if (up_req->msg.req_type == DP_CONNECTION_STATUS_NOTIFY) {
const struct drm_dp_connection_status_notify *conn_stat = const struct drm_dp_connection_status_notify *conn_stat =
&up_req->msg.u.conn_stat; &up_req->msg.u.conn_stat;
bool handle_csn;
drm_dbg_kms(mgr->dev, "Got CSN: pn: %d ldps:%d ddps: %d mcs: %d ip: %d pdt: %d\n", drm_dbg_kms(mgr->dev, "Got CSN: pn: %d ldps:%d ddps: %d mcs: %d ip: %d pdt: %d\n",
conn_stat->port_number, conn_stat->port_number,
@ -4042,6 +4043,16 @@ static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr)
conn_stat->message_capability_status, conn_stat->message_capability_status,
conn_stat->input_port, conn_stat->input_port,
conn_stat->peer_device_type); conn_stat->peer_device_type);
mutex_lock(&mgr->probe_lock);
handle_csn = mgr->mst_primary->link_address_sent;
mutex_unlock(&mgr->probe_lock);
if (!handle_csn) {
drm_dbg_kms(mgr->dev, "Got CSN before finish topology probing. Skip it.");
kfree(up_req);
goto out;
}
} else if (up_req->msg.req_type == DP_RESOURCE_STATUS_NOTIFY) { } else if (up_req->msg.req_type == DP_RESOURCE_STATUS_NOTIFY) {
const struct drm_dp_resource_status_notify *res_stat = const struct drm_dp_resource_status_notify *res_stat =
&up_req->msg.u.resource_stat; &up_req->msg.u.resource_stat;

View file

@ -879,6 +879,11 @@ int drm_client_modeset_probe(struct drm_client_dev *client, unsigned int width,
kfree(modeset->mode); kfree(modeset->mode);
modeset->mode = drm_mode_duplicate(dev, mode); modeset->mode = drm_mode_duplicate(dev, mode);
if (!modeset->mode) {
ret = -ENOMEM;
break;
}
drm_connector_get(connector); drm_connector_get(connector);
modeset->connectors[modeset->num_connectors++] = connector; modeset->connectors[modeset->num_connectors++] = connector;
modeset->x = offset->x; modeset->x = offset->x;

View file

@ -325,6 +325,41 @@ out:
return i915_error_to_vmf_fault(err); return i915_error_to_vmf_fault(err);
} }
static void set_address_limits(struct vm_area_struct *area,
struct i915_vma *vma,
unsigned long obj_offset,
unsigned long *start_vaddr,
unsigned long *end_vaddr)
{
unsigned long vm_start, vm_end, vma_size; /* user's memory parameters */
long start, end; /* memory boundaries */
/*
* Let's move into the ">> PAGE_SHIFT"
* domain to be sure not to lose bits
*/
vm_start = area->vm_start >> PAGE_SHIFT;
vm_end = area->vm_end >> PAGE_SHIFT;
vma_size = vma->size >> PAGE_SHIFT;
/*
* Calculate the memory boundaries by considering the offset
* provided by the user during memory mapping and the offset
* provided for the partial mapping.
*/
start = vm_start;
start -= obj_offset;
start += vma->gtt_view.partial.offset;
end = start + vma_size;
start = max_t(long, start, vm_start);
end = min_t(long, end, vm_end);
/* Let's move back into the "<< PAGE_SHIFT" domain */
*start_vaddr = (unsigned long)start << PAGE_SHIFT;
*end_vaddr = (unsigned long)end << PAGE_SHIFT;
}
static vm_fault_t vm_fault_gtt(struct vm_fault *vmf) static vm_fault_t vm_fault_gtt(struct vm_fault *vmf)
{ {
#define MIN_CHUNK_PAGES (SZ_1M >> PAGE_SHIFT) #define MIN_CHUNK_PAGES (SZ_1M >> PAGE_SHIFT)
@ -337,14 +372,18 @@ static vm_fault_t vm_fault_gtt(struct vm_fault *vmf)
struct i915_ggtt *ggtt = to_gt(i915)->ggtt; struct i915_ggtt *ggtt = to_gt(i915)->ggtt;
bool write = area->vm_flags & VM_WRITE; bool write = area->vm_flags & VM_WRITE;
struct i915_gem_ww_ctx ww; struct i915_gem_ww_ctx ww;
unsigned long obj_offset;
unsigned long start, end; /* memory boundaries */
intel_wakeref_t wakeref; intel_wakeref_t wakeref;
struct i915_vma *vma; struct i915_vma *vma;
pgoff_t page_offset; pgoff_t page_offset;
unsigned long pfn;
int srcu; int srcu;
int ret; int ret;
/* We don't use vmf->pgoff since that has the fake offset */ obj_offset = area->vm_pgoff - drm_vma_node_start(&mmo->vma_node);
page_offset = (vmf->address - area->vm_start) >> PAGE_SHIFT; page_offset = (vmf->address - area->vm_start) >> PAGE_SHIFT;
page_offset += obj_offset;
trace_i915_gem_object_fault(obj, page_offset, true, write); trace_i915_gem_object_fault(obj, page_offset, true, write);
@ -437,12 +476,14 @@ retry:
if (ret) if (ret)
goto err_unpin; goto err_unpin;
set_address_limits(area, vma, obj_offset, &start, &end);
pfn = (ggtt->gmadr.start + i915_ggtt_offset(vma)) >> PAGE_SHIFT;
pfn += (start - area->vm_start) >> PAGE_SHIFT;
pfn += obj_offset - vma->gtt_view.partial.offset;
/* Finally, remap it using the new GTT offset */ /* Finally, remap it using the new GTT offset */
ret = remap_io_mapping(area, ret = remap_io_mapping(area, start, pfn, end - start, &ggtt->iomap);
area->vm_start + (vma->gtt_view.partial.offset << PAGE_SHIFT),
(ggtt->gmadr.start + i915_ggtt_offset(vma)) >> PAGE_SHIFT,
min_t(u64, vma->size, area->vm_end - area->vm_start),
&ggtt->iomap);
if (ret) if (ret)
goto err_fence; goto err_fence;
@ -655,6 +696,41 @@ remap_io_mapping(pmap_t pm, vm_prot_t mapprot,
return 0; return 0;
} }
static void set_address_limits(struct vm_map_entry *entry,
struct i915_vma *vma,
unsigned long obj_offset,
unsigned long *start_vaddr,
unsigned long *end_vaddr)
{
unsigned long vm_start, vm_end, vma_size; /* user's memory parameters */
long start, end; /* memory boundaries */
/*
* Let's move into the ">> PAGE_SHIFT"
* domain to be sure not to lose bits
*/
vm_start = entry->start >> PAGE_SHIFT;
vm_end = entry->end >> PAGE_SHIFT;
vma_size = vma->size >> PAGE_SHIFT;
/*
* Calculate the memory boundaries by considering the offset
* provided by the user during memory mapping and the offset
* provided for the partial mapping.
*/
start = vm_start;
start -= obj_offset;
start += vma->gtt_view.partial.offset;
end = start + vma_size;
start = max_t(long, start, vm_start);
end = min_t(long, end, vm_end);
/* Let's move back into the "<< PAGE_SHIFT" domain */
*start_vaddr = (unsigned long)start << PAGE_SHIFT;
*end_vaddr = (unsigned long)end << PAGE_SHIFT;
}
static int static int
vm_fault_gtt(struct i915_mmap_offset *mmo, struct uvm_faultinfo *ufi, vm_fault_gtt(struct i915_mmap_offset *mmo, struct uvm_faultinfo *ufi,
vaddr_t vaddr, vm_prot_t access_type) vaddr_t vaddr, vm_prot_t access_type)
@ -668,13 +744,16 @@ vm_fault_gtt(struct i915_mmap_offset *mmo, struct uvm_faultinfo *ufi,
struct i915_ggtt *ggtt = to_gt(i915)->ggtt; struct i915_ggtt *ggtt = to_gt(i915)->ggtt;
int write = !!(access_type & PROT_WRITE); int write = !!(access_type & PROT_WRITE);
struct i915_gem_ww_ctx ww; struct i915_gem_ww_ctx ww;
unsigned long obj_offset;
unsigned long start, end; /* memory boundaries */
intel_wakeref_t wakeref; intel_wakeref_t wakeref;
struct i915_vma *vma; struct i915_vma *vma;
pgoff_t page_offset; pgoff_t page_offset;
unsigned long pfn;
int srcu; int srcu;
int ret; int ret;
/* We don't use vmf->pgoff since that has the fake offset */ obj_offset = entry->offset - drm_vma_node_start(&mmo->vma_node);
page_offset = (vaddr - entry->start) >> PAGE_SHIFT; page_offset = (vaddr - entry->start) >> PAGE_SHIFT;
trace_i915_gem_object_fault(obj, page_offset, true, write); trace_i915_gem_object_fault(obj, page_offset, true, write);
@ -768,11 +847,15 @@ retry:
if (ret) if (ret)
goto err_unpin; goto err_unpin;
set_address_limits(entry, vma, obj_offset, &start, &end);
pfn = (ggtt->gmadr.start + i915_ggtt_offset(vma)) >> PAGE_SHIFT;
pfn += (start - entry->start) >> PAGE_SHIFT;
pfn += obj_offset - vma->gtt_view.partial.offset;
/* Finally, remap it using the new GTT offset */ /* Finally, remap it using the new GTT offset */
ret = remap_io_mapping(ufi->orig_map->pmap, entry->protection, ret = remap_io_mapping(ufi->orig_map->pmap, entry->protection,
entry->start + (vma->gtt_view.partial.offset << PAGE_SHIFT), start, pfn, end - start);
(ggtt->gmadr.start + i915_ggtt_offset(vma)) >> PAGE_SHIFT,
min_t(u64, vma->size, entry->end - entry->start));
if (ret) if (ret)
goto err_fence; goto err_fence;
@ -1507,6 +1590,8 @@ int i915_gem_fb_mmap(struct drm_i915_gem_object *obj, struct vm_area_struct *vma
mmo = mmap_offset_attach(obj, mmap_type, NULL); mmo = mmap_offset_attach(obj, mmap_type, NULL);
if (IS_ERR(mmo)) if (IS_ERR(mmo))
return PTR_ERR(mmo); return PTR_ERR(mmo);
vma->vm_pgoff += drm_vma_node_start(&mmo->vma_node);
} }
/* /*

View file

@ -439,7 +439,7 @@ typedef struct _StateArray{
//how many states we have //how many states we have
UCHAR ucNumEntries; UCHAR ucNumEntries;
ATOM_PPLIB_STATE_V2 states[] __counted_by(ucNumEntries); ATOM_PPLIB_STATE_V2 states[] /* __counted_by(ucNumEntries) */;
}StateArray; }StateArray;

View file

@ -1,4 +1,4 @@
/* $OpenBSD: if_qwz_pci.c,v 1.1 2024/08/14 14:40:46 patrick Exp $ */ /* $OpenBSD: if_qwz_pci.c,v 1.3 2024/08/16 00:26:54 patrick Exp $ */
/* /*
* Copyright 2023 Stefan Sperling <stsp@openbsd.org> * Copyright 2023 Stefan Sperling <stsp@openbsd.org>
@ -116,11 +116,12 @@
#define ATH12K_PCI_WINDOW_VALUE_MASK GENMASK(24, 19) #define ATH12K_PCI_WINDOW_VALUE_MASK GENMASK(24, 19)
#define ATH12K_PCI_WINDOW_START 0x80000 #define ATH12K_PCI_WINDOW_START 0x80000
#define ATH12K_PCI_WINDOW_RANGE_MASK GENMASK(18, 0) #define ATH12K_PCI_WINDOW_RANGE_MASK GENMASK(18, 0)
#define ATH12K_PCI_WINDOW_STATIC_MASK GENMASK(31, 6)
/* BAR0 + 4k is always accessible, and no need to force wakeup. */ /* BAR0 + 4k is always accessible, and no need to force wakeup. */
#define ATH12K_PCI_ACCESS_ALWAYS_OFF 0xFE0 /* 4K - 32 = 0xFE0 */ #define ATH12K_PCI_ACCESS_ALWAYS_OFF 0xFE0 /* 4K - 32 = 0xFE0 */
#define TCSR_SOC_HW_VERSION 0x0224 #define TCSR_SOC_HW_VERSION 0x1b00000
#define TCSR_SOC_HW_VERSION_MAJOR_MASK GENMASK(11, 8) #define TCSR_SOC_HW_VERSION_MAJOR_MASK GENMASK(11, 8)
#define TCSR_SOC_HW_VERSION_MINOR_MASK GENMASK(7, 0) #define TCSR_SOC_HW_VERSION_MINOR_MASK GENMASK(7, 0)
@ -145,7 +146,7 @@
#define PCIE_PCIE_PARF_LTSSM 0x1e081b0 #define PCIE_PCIE_PARF_LTSSM 0x1e081b0
#define PARM_LTSSM_VALUE 0x111 #define PARM_LTSSM_VALUE 0x111
#define GCC_GCC_PCIE_HOT_RST 0x1e402bc #define GCC_GCC_PCIE_HOT_RST 0x1e38338
#define GCC_GCC_PCIE_HOT_RST_VAL 0x10 #define GCC_GCC_PCIE_HOT_RST_VAL 0x10
#define PCIE_PCIE_INT_ALL_CLEAR 0x1e08228 #define PCIE_PCIE_INT_ALL_CLEAR 0x1e08228
@ -170,6 +171,9 @@
#define WLAON_QFPROM_PWR_CTRL_REG 0x01f8031c #define WLAON_QFPROM_PWR_CTRL_REG 0x01f8031c
#define QFPROM_PWR_CTRL_VDD4BLOW_MASK 0x4 #define QFPROM_PWR_CTRL_VDD4BLOW_MASK 0x4
#define PCI_MHIREGLEN_REG 0x1e0e100
#define PCI_MHI_REGION_END 0x1e0effc
/* /*
* mhi.h * mhi.h
*/ */
@ -374,11 +378,9 @@ struct qwz_pci_softc {
struct qwz_dmamem *cmd_ctxt; struct qwz_dmamem *cmd_ctxt;
struct qwz_pci_xfer_ring xfer_rings[4]; struct qwz_pci_xfer_ring xfer_rings[2];
#define QWZ_PCI_XFER_RING_LOOPBACK_OUTBOUND 0 #define QWZ_PCI_XFER_RING_IPCR_OUTBOUND 0
#define QWZ_PCI_XFER_RING_LOOPBACK_INBOUND 1 #define QWZ_PCI_XFER_RING_IPCR_INBOUND 1
#define QWZ_PCI_XFER_RING_IPCR_OUTBOUND 2
#define QWZ_PCI_XFER_RING_IPCR_INBOUND 3
struct qwz_pci_event_ring event_rings[QWZ_NUM_EVENT_CTX]; struct qwz_pci_event_ring event_rings[QWZ_NUM_EVENT_CTX];
struct qwz_pci_cmd_ring cmd_ring; struct qwz_pci_cmd_ring cmd_ring;
}; };
@ -482,28 +484,14 @@ struct qwz_pci_ops {
}; };
static const struct qwz_pci_ops qwz_pci_ops_qca6390 = { static const struct qwz_pci_ops qwz_pci_ops_wcn7850 = {
.wakeup = qwz_pci_bus_wake_up, .wakeup = qwz_pci_bus_wake_up,
.release = qwz_pci_bus_release, .release = qwz_pci_bus_release,
#if notyet
.get_msi_irq = qwz_pci_get_msi_irq,
#endif
.window_write32 = qwz_pci_window_write32, .window_write32 = qwz_pci_window_write32,
.window_read32 = qwz_pci_window_read32, .window_read32 = qwz_pci_window_read32,
.alloc_xfer_rings = qwz_pci_alloc_xfer_rings_qca6390, .alloc_xfer_rings = qwz_pci_alloc_xfer_rings_qca6390,
}; };
static const struct qwz_pci_ops qwz_pci_ops_qcn9074 = {
.wakeup = NULL,
.release = NULL,
#if notyet
.get_msi_irq = qwz_pci_get_msi_irq,
#endif
.window_write32 = qwz_pci_window_write32,
.window_read32 = qwz_pci_window_read32,
.alloc_xfer_rings = qwz_pci_alloc_xfer_rings_qcn9074,
};
const struct cfattach qwz_pci_ca = { const struct cfattach qwz_pci_ca = {
sizeof(struct qwz_pci_softc), sizeof(struct qwz_pci_softc),
qwz_pci_match, qwz_pci_match,
@ -512,16 +500,8 @@ const struct cfattach qwz_pci_ca = {
qwz_activate qwz_activate
}; };
/* XXX pcidev */
#define PCI_PRODUCT_QUALCOMM_QCA6390 0x1101
#define PCI_PRODUCT_QUALCOMM_QCN9074 0x1104
static const struct pci_matchid qwz_pci_devices[] = { static const struct pci_matchid qwz_pci_devices[] = {
#if notyet { PCI_VENDOR_QUALCOMM, PCI_PRODUCT_QUALCOMM_WCN7850 }
{ PCI_VENDOR_QUALCOMM, PCI_PRODUCT_QUALCOMM_QCA6390 },
{ PCI_VENDOR_QUALCOMM, PCI_PRODUCT_QUALCOMM_QCN9074 },
#endif
{ PCI_VENDOR_QUALCOMM, PCI_PRODUCT_QUALCOMM_QCNFA765 }
}; };
int int
@ -535,8 +515,8 @@ qwz_pci_init_qmi_ce_config(struct qwz_softc *sc)
{ {
struct qwz_qmi_ce_cfg *cfg = &sc->qmi_ce_cfg; struct qwz_qmi_ce_cfg *cfg = &sc->qmi_ce_cfg;
qwz_ce_get_shadow_config(sc, &cfg->shadow_reg_v2, qwz_ce_get_shadow_config(sc, &cfg->shadow_reg_v3,
&cfg->shadow_reg_v2_len); &cfg->shadow_reg_v3_len);
} }
const struct qwz_msi_config qwz_msi_config_one_msi = { const struct qwz_msi_config qwz_msi_config_one_msi = {
@ -551,17 +531,6 @@ const struct qwz_msi_config qwz_msi_config_one_msi = {
}; };
const struct qwz_msi_config qwz_msi_config[] = { const struct qwz_msi_config qwz_msi_config[] = {
{
.total_vectors = 32,
.total_users = 4,
.users = (struct qwz_msi_user[]) {
{ .name = "MHI", .num_vectors = 3, .base_vector = 0 },
{ .name = "CE", .num_vectors = 10, .base_vector = 3 },
{ .name = "WAKE", .num_vectors = 1, .base_vector = 13 },
{ .name = "DP", .num_vectors = 18, .base_vector = 14 },
},
.hw_rev = ATH12K_HW_QCA6390_HW20,
},
{ {
.total_vectors = 16, .total_vectors = 16,
.total_users = 3, .total_users = 3,
@ -570,38 +539,7 @@ const struct qwz_msi_config qwz_msi_config[] = {
{ .name = "CE", .num_vectors = 5, .base_vector = 3 }, { .name = "CE", .num_vectors = 5, .base_vector = 3 },
{ .name = "DP", .num_vectors = 8, .base_vector = 8 }, { .name = "DP", .num_vectors = 8, .base_vector = 8 },
}, },
.hw_rev = ATH12K_HW_QCN9074_HW10, .hw_rev = ATH12K_HW_WCN7850_HW20,
},
{
.total_vectors = 32,
.total_users = 4,
.users = (struct qwz_msi_user[]) {
{ .name = "MHI", .num_vectors = 3, .base_vector = 0 },
{ .name = "CE", .num_vectors = 10, .base_vector = 3 },
{ .name = "WAKE", .num_vectors = 1, .base_vector = 13 },
{ .name = "DP", .num_vectors = 18, .base_vector = 14 },
},
.hw_rev = ATH12K_HW_WCN6855_HW20,
},
{
.total_vectors = 32,
.total_users = 4,
.users = (struct qwz_msi_user[]) {
{ .name = "MHI", .num_vectors = 3, .base_vector = 0 },
{ .name = "CE", .num_vectors = 10, .base_vector = 3 },
{ .name = "WAKE", .num_vectors = 1, .base_vector = 13 },
{ .name = "DP", .num_vectors = 18, .base_vector = 14 },
},
.hw_rev = ATH12K_HW_WCN6855_HW21,
},
{
.total_vectors = 28,
.total_users = 2,
.users = (struct qwz_msi_user[]) {
{ .name = "CE", .num_vectors = 10, .base_vector = 0 },
{ .name = "DP", .num_vectors = 18, .base_vector = 10 },
},
.hw_rev = ATH12K_HW_WCN6750_HW10,
}, },
}; };
@ -745,7 +683,6 @@ qwz_pci_attach(struct device *parent, struct device *self, void *aux)
struct ieee80211com *ic = &sc->sc_ic; struct ieee80211com *ic = &sc->sc_ic;
struct ifnet *ifp = &ic->ic_if; struct ifnet *ifp = &ic->ic_if;
uint32_t soc_hw_version_major, soc_hw_version_minor; uint32_t soc_hw_version_major, soc_hw_version_minor;
const struct qwz_pci_ops *pci_ops;
struct pci_attach_args *pa = aux; struct pci_attach_args *pa = aux;
pci_intr_handle_t ih; pci_intr_handle_t ih;
pcireg_t memtype, reg; pcireg_t memtype, reg;
@ -885,54 +822,22 @@ qwz_pci_attach(struct device *parent, struct device *self, void *aux)
pci_set_powerstate(pa->pa_pc, pa->pa_tag, PCI_PMCSR_STATE_D0); pci_set_powerstate(pa->pa_pc, pa->pa_tag, PCI_PMCSR_STATE_D0);
switch (PCI_PRODUCT(pa->pa_id)) { switch (PCI_PRODUCT(pa->pa_id)) {
case PCI_PRODUCT_QUALCOMM_QCA6390: case PCI_PRODUCT_QUALCOMM_WCN7850:
qwz_pci_read_hw_version(sc, &soc_hw_version_major, sc->static_window_map = 0;
&soc_hw_version_minor); psc->sc_pci_ops = &qwz_pci_ops_wcn7850;
switch (soc_hw_version_major) {
case 2:
sc->sc_hw_rev = ATH12K_HW_QCA6390_HW20;
break;
default:
printf(": unsupported QCA6390 SOC version: %d %d\n",
soc_hw_version_major, soc_hw_version_minor);
return;
}
pci_ops = &qwz_pci_ops_qca6390;
psc->max_chan = QWZ_MHI_CONFIG_QCA6390_MAX_CHANNELS;
break;
case PCI_PRODUCT_QUALCOMM_QCN9074:
pci_ops = &qwz_pci_ops_qcn9074;
sc->sc_hw_rev = ATH12K_HW_QCN9074_HW10;
psc->max_chan = QWZ_MHI_CONFIG_QCA9074_MAX_CHANNELS;
break;
case PCI_PRODUCT_QUALCOMM_QCNFA765:
sc->id.bdf_search = ATH12K_BDF_SEARCH_BUS_AND_BOARD; sc->id.bdf_search = ATH12K_BDF_SEARCH_BUS_AND_BOARD;
qwz_pci_read_hw_version(sc, &soc_hw_version_major, qwz_pci_read_hw_version(sc, &soc_hw_version_major,
&soc_hw_version_minor); &soc_hw_version_minor);
switch (soc_hw_version_major) { switch (soc_hw_version_major) {
case 2: case 2:
switch (soc_hw_version_minor) { sc->sc_hw_rev = ATH12K_HW_WCN7850_HW20;
case 0x00:
case 0x01:
sc->sc_hw_rev = ATH12K_HW_WCN6855_HW20;
break;
case 0x10:
case 0x11:
sc->sc_hw_rev = ATH12K_HW_WCN6855_HW21;
break;
default:
goto unsupported_wcn6855_soc;
}
break; break;
default: default:
unsupported_wcn6855_soc: printf(": unknown hardware version found for WCN785: "
printf(": unsupported WCN6855 SOC version: %d %d\n", "%d\n", soc_hw_version_major);
soc_hw_version_major, soc_hw_version_minor);
return; return;
} }
pci_ops = &qwz_pci_ops_qca6390;
psc->max_chan = QWZ_MHI_CONFIG_QCA6390_MAX_CHANNELS; psc->max_chan = QWZ_MHI_CONFIG_QCA6390_MAX_CHANNELS;
break; break;
default: default:
@ -940,9 +845,6 @@ unsupported_wcn6855_soc:
return; return;
} }
/* register PCI ops */
psc->sc_pci_ops = pci_ops;
error = qwz_pcic_init_msi_config(sc); error = qwz_pcic_init_msi_config(sc);
if (error) if (error)
goto err_pci_free_region; goto err_pci_free_region;
@ -1020,8 +922,6 @@ unsupported_wcn6855_soc:
if (sc->sc_nswq == NULL) if (sc->sc_nswq == NULL)
goto err_ce_free; goto err_ce_free;
qwz_pci_init_qmi_ce_config(sc);
error = qwz_pcic_config_irq(sc, pa); error = qwz_pcic_config_irq(sc, pa);
if (error) { if (error) {
printf("%s: failed to config irq: %d\n", printf("%s: failed to config irq: %d\n",
@ -1296,18 +1196,6 @@ qwz_pci_alloc_xfer_rings_qca6390(struct qwz_pci_softc *psc)
struct qwz_softc *sc = &psc->sc_sc; struct qwz_softc *sc = &psc->sc_sc;
int ret; int ret;
ret = qwz_pci_alloc_xfer_ring(sc,
&psc->xfer_rings[QWZ_PCI_XFER_RING_LOOPBACK_OUTBOUND],
0, MHI_CHAN_TYPE_OUTBOUND, 0, 32);
if (ret)
goto fail;
ret = qwz_pci_alloc_xfer_ring(sc,
&psc->xfer_rings[QWZ_PCI_XFER_RING_LOOPBACK_INBOUND],
1, MHI_CHAN_TYPE_INBOUND, 0, 32);
if (ret)
goto fail;
ret = qwz_pci_alloc_xfer_ring(sc, ret = qwz_pci_alloc_xfer_ring(sc,
&psc->xfer_rings[QWZ_PCI_XFER_RING_IPCR_OUTBOUND], &psc->xfer_rings[QWZ_PCI_XFER_RING_IPCR_OUTBOUND],
20, MHI_CHAN_TYPE_OUTBOUND, 1, 64); 20, MHI_CHAN_TYPE_OUTBOUND, 1, 64);
@ -1332,18 +1220,6 @@ qwz_pci_alloc_xfer_rings_qcn9074(struct qwz_pci_softc *psc)
struct qwz_softc *sc = &psc->sc_sc; struct qwz_softc *sc = &psc->sc_sc;
int ret; int ret;
ret = qwz_pci_alloc_xfer_ring(sc,
&psc->xfer_rings[QWZ_PCI_XFER_RING_LOOPBACK_OUTBOUND],
0, MHI_CHAN_TYPE_OUTBOUND, 1, 32);
if (ret)
goto fail;
ret = qwz_pci_alloc_xfer_ring(sc,
&psc->xfer_rings[QWZ_PCI_XFER_RING_LOOPBACK_INBOUND],
1, MHI_CHAN_TYPE_INBOUND, 1, 32);
if (ret)
goto fail;
ret = qwz_pci_alloc_xfer_ring(sc, ret = qwz_pci_alloc_xfer_ring(sc,
&psc->xfer_rings[QWZ_PCI_XFER_RING_IPCR_OUTBOUND], &psc->xfer_rings[QWZ_PCI_XFER_RING_IPCR_OUTBOUND],
20, MHI_CHAN_TYPE_OUTBOUND, 1, 32); 20, MHI_CHAN_TYPE_OUTBOUND, 1, 32);
@ -1602,11 +1478,13 @@ qwz_pcic_ext_irq_config(struct qwz_softc *sc, struct pci_attach_args *pa)
struct qwz_pci_softc *psc = (struct qwz_pci_softc *)sc; struct qwz_pci_softc *psc = (struct qwz_pci_softc *)sc;
int i, ret, num_vectors = 0; int i, ret, num_vectors = 0;
uint32_t msi_data_start = 0; uint32_t msi_data_start = 0;
uint32_t base_vector = 0; uint32_t base_idx, base_vector = 0;
if (!test_bit(ATH12K_FLAG_MULTI_MSI_VECTORS, sc->sc_flags)) if (!test_bit(ATH12K_FLAG_MULTI_MSI_VECTORS, sc->sc_flags))
return 0; return 0;
base_idx = ATH12K_PCI_IRQ_CE0_OFFSET + CE_COUNT_MAX;
ret = qwz_pcic_get_user_msi_vector(sc, "DP", &num_vectors, ret = qwz_pcic_get_user_msi_vector(sc, "DP", &num_vectors,
&msi_data_start, &base_vector); &msi_data_start, &base_vector);
if (ret < 0) if (ret < 0)
@ -1635,7 +1513,7 @@ qwz_pcic_ext_irq_config(struct qwz_softc *sc, struct pci_attach_args *pa)
} }
irq_grp->num_irq = num_irq; irq_grp->num_irq = num_irq;
irq_grp->irqs[0] = ATH12K_PCI_IRQ_DP_OFFSET + i; irq_grp->irqs[0] = base_idx + i;
if (num_irq) { if (num_irq) {
int irq_idx = irq_grp->irqs[0]; int irq_idx = irq_grp->irqs[0];
@ -1805,13 +1683,13 @@ qwz_pci_bus_release(struct qwz_softc *sc)
uint32_t uint32_t
qwz_pci_get_window_start(struct qwz_softc *sc, uint32_t offset) qwz_pci_get_window_start(struct qwz_softc *sc, uint32_t offset)
{ {
if (!sc->hw_params.static_window_map) if (!sc->static_window_map)
return ATH12K_PCI_WINDOW_START; return ATH12K_PCI_WINDOW_START;
if ((offset ^ HAL_SEQ_WCSS_UMAC_OFFSET) < ATH12K_PCI_WINDOW_RANGE_MASK) if ((offset ^ HAL_SEQ_WCSS_UMAC_OFFSET) < ATH12K_PCI_WINDOW_RANGE_MASK)
/* if offset lies within DP register range, use 3rd window */ /* if offset lies within DP register range, use 3rd window */
return 3 * ATH12K_PCI_WINDOW_START; return 3 * ATH12K_PCI_WINDOW_START;
else if ((offset ^ HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(sc)) < else if ((offset ^ HAL_SEQ_WCSS_UMAC_CE0_SRC_REG) <
ATH12K_PCI_WINDOW_RANGE_MASK) ATH12K_PCI_WINDOW_RANGE_MASK)
/* if offset lies within CE register range, use 2nd window */ /* if offset lies within CE register range, use 2nd window */
return 2 * ATH12K_PCI_WINDOW_START; return 2 * ATH12K_PCI_WINDOW_START;
@ -1829,6 +1707,12 @@ qwz_pci_select_window(struct qwz_softc *sc, uint32_t offset)
lockdep_assert_held(&ab_pci->window_lock); lockdep_assert_held(&ab_pci->window_lock);
#endif #endif
/*
* Preserve the static window configuration and reset only
* dynamic window.
*/
window |= psc->register_window & ATH12K_PCI_WINDOW_STATIC_MASK;
if (window != psc->register_window) { if (window != psc->register_window) {
qwz_pci_write(sc, ATH12K_PCI_WINDOW_REG_ADDRESS, qwz_pci_write(sc, ATH12K_PCI_WINDOW_REG_ADDRESS,
ATH12K_PCI_WINDOW_ENABLE_BIT | window); ATH12K_PCI_WINDOW_ENABLE_BIT | window);
@ -1837,6 +1721,12 @@ qwz_pci_select_window(struct qwz_softc *sc, uint32_t offset)
} }
} }
static inline bool
qwz_pci_is_offset_within_mhi_region(uint32_t offset)
{
return (offset >= PCI_MHIREGLEN_REG && offset <= PCI_MHI_REGION_END);
}
void void
qwz_pci_window_write32(struct qwz_softc *sc, uint32_t offset, uint32_t value) qwz_pci_window_write32(struct qwz_softc *sc, uint32_t offset, uint32_t value)
{ {
@ -1849,8 +1739,15 @@ qwz_pci_window_write32(struct qwz_softc *sc, uint32_t offset, uint32_t value)
spin_lock_bh(&ab_pci->window_lock); spin_lock_bh(&ab_pci->window_lock);
#endif #endif
qwz_pci_select_window(sc, offset); qwz_pci_select_window(sc, offset);
qwz_pci_write(sc, window_start +
(offset & ATH12K_PCI_WINDOW_RANGE_MASK), value); if (qwz_pci_is_offset_within_mhi_region(offset)) {
offset = offset - PCI_MHIREGLEN_REG;
qwz_pci_write(sc, offset & ATH12K_PCI_WINDOW_RANGE_MASK,
value);
} else {
qwz_pci_write(sc, window_start +
(offset & ATH12K_PCI_WINDOW_RANGE_MASK), value);
}
#if notyet #if notyet
spin_unlock_bh(&ab_pci->window_lock); spin_unlock_bh(&ab_pci->window_lock);
#endif #endif
@ -1872,8 +1769,15 @@ qwz_pci_window_read32(struct qwz_softc *sc, uint32_t offset)
spin_lock_bh(&ab_pci->window_lock); spin_lock_bh(&ab_pci->window_lock);
#endif #endif
qwz_pci_select_window(sc, offset); qwz_pci_select_window(sc, offset);
val = qwz_pci_read(sc, window_start +
(offset & ATH12K_PCI_WINDOW_RANGE_MASK)); if (qwz_pci_is_offset_within_mhi_region(offset)) {
offset = offset - PCI_MHIREGLEN_REG;
val = qwz_pci_read(sc,
offset & ATH12K_PCI_WINDOW_RANGE_MASK);
} else {
val = qwz_pci_read(sc, window_start +
(offset & ATH12K_PCI_WINDOW_RANGE_MASK));
}
#if notyet #if notyet
spin_unlock_bh(&ab_pci->window_lock); spin_unlock_bh(&ab_pci->window_lock);
#endif #endif
@ -2120,7 +2024,7 @@ qwz_pci_msi_config(struct qwz_softc *sc, bool enable)
else else
val &= ~PCI_MSI_MC_MSIE; val &= ~PCI_MSI_MC_MSIE;
pci_conf_write(psc->sc_pc, psc->sc_tag, psc->sc_msi_off + PCI_MSI_MC, pci_conf_write(psc->sc_pc, psc->sc_tag, psc->sc_msi_off + PCI_MSI_MC,
val); val);
} }
@ -2189,7 +2093,7 @@ qwz_pci_power_up(struct qwz_softc *sc)
if (error) if (error)
return error; return error;
if (sc->hw_params.static_window_map) if (sc->static_window_map)
qwz_pci_select_static_window(sc); qwz_pci_select_static_window(sc);
return 0; return 0;

View file

@ -1,4 +1,4 @@
$OpenBSD: pcidevs,v 1.2083 2024/08/10 11:00:14 jsg Exp $ $OpenBSD: pcidevs,v 1.2084 2024/08/15 11:25:37 patrick Exp $
/* $NetBSD: pcidevs,v 1.30 1997/06/24 06:20:24 thorpej Exp $ */ /* $NetBSD: pcidevs,v 1.30 1997/06/24 06:20:24 thorpej Exp $ */
/* /*
@ -8645,6 +8645,7 @@ product QLOGIC ISP8432 0x8432 ISP8432
product QUALCOMM SC8280XP_PCIE 0x010e SC8280XP PCIe product QUALCOMM SC8280XP_PCIE 0x010e SC8280XP PCIe
product QUALCOMM X1E80100_PCIE 0x0111 X1E80100 PCIe product QUALCOMM X1E80100_PCIE 0x0111 X1E80100 PCIe
product QUALCOMM QCNFA765 0x1103 QCNFA765 product QUALCOMM QCNFA765 0x1103 QCNFA765
product QUALCOMM WCN7850 0x1107 WCN7850
/* Quancom products */ /* Quancom products */
product QUANCOM PWDOG1 0x0010 PWDOG1 product QUANCOM PWDOG1 0x0010 PWDOG1

View file

@ -2,7 +2,7 @@
* THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT. * THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT.
* *
* generated from: * generated from:
* OpenBSD: pcidevs,v 1.2083 2024/08/10 11:00:14 jsg Exp * OpenBSD: pcidevs,v 1.2084 2024/08/15 11:25:37 patrick Exp
*/ */
/* $NetBSD: pcidevs,v 1.30 1997/06/24 06:20:24 thorpej Exp $ */ /* $NetBSD: pcidevs,v 1.30 1997/06/24 06:20:24 thorpej Exp $ */
@ -8650,6 +8650,7 @@
#define PCI_PRODUCT_QUALCOMM_SC8280XP_PCIE 0x010e /* SC8280XP PCIe */ #define PCI_PRODUCT_QUALCOMM_SC8280XP_PCIE 0x010e /* SC8280XP PCIe */
#define PCI_PRODUCT_QUALCOMM_X1E80100_PCIE 0x0111 /* X1E80100 PCIe */ #define PCI_PRODUCT_QUALCOMM_X1E80100_PCIE 0x0111 /* X1E80100 PCIe */
#define PCI_PRODUCT_QUALCOMM_QCNFA765 0x1103 /* QCNFA765 */ #define PCI_PRODUCT_QUALCOMM_QCNFA765 0x1103 /* QCNFA765 */
#define PCI_PRODUCT_QUALCOMM_WCN7850 0x1107 /* WCN7850 */
/* Quancom products */ /* Quancom products */
#define PCI_PRODUCT_QUANCOM_PWDOG1 0x0010 /* PWDOG1 */ #define PCI_PRODUCT_QUANCOM_PWDOG1 0x0010 /* PWDOG1 */

View file

@ -2,7 +2,7 @@
* THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT. * THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT.
* *
* generated from: * generated from:
* OpenBSD: pcidevs,v 1.2083 2024/08/10 11:00:14 jsg Exp * OpenBSD: pcidevs,v 1.2084 2024/08/15 11:25:37 patrick Exp
*/ */
/* $NetBSD: pcidevs,v 1.30 1997/06/24 06:20:24 thorpej Exp $ */ /* $NetBSD: pcidevs,v 1.30 1997/06/24 06:20:24 thorpej Exp $ */
@ -31207,6 +31207,10 @@ static const struct pci_known_product pci_known_products[] = {
PCI_VENDOR_QUALCOMM, PCI_PRODUCT_QUALCOMM_QCNFA765, PCI_VENDOR_QUALCOMM, PCI_PRODUCT_QUALCOMM_QCNFA765,
"QCNFA765", "QCNFA765",
}, },
{
PCI_VENDOR_QUALCOMM, PCI_PRODUCT_QUALCOMM_WCN7850,
"WCN7850",
},
{ {
PCI_VENDOR_QUANCOM, PCI_PRODUCT_QUANCOM_PWDOG1, PCI_VENDOR_QUANCOM, PCI_PRODUCT_QUANCOM_PWDOG1,
"PWDOG1", "PWDOG1",

View file

@ -1,4 +1,4 @@
/* $OpenBSD: xhci.c,v 1.132 2024/08/06 17:30:04 kettenis Exp $ */ /* $OpenBSD: xhci.c,v 1.133 2024/08/15 17:17:05 kettenis Exp $ */
/* /*
* Copyright (c) 2014-2015 Martin Pieuchot * Copyright (c) 2014-2015 Martin Pieuchot
@ -415,6 +415,7 @@ xhci_config(struct xhci_softc *sc)
{ {
uint64_t paddr; uint64_t paddr;
uint32_t hcr; uint32_t hcr;
int i;
/* Make sure to program a number of device slots we can handle. */ /* Make sure to program a number of device slots we can handle. */
if (sc->sc_noslot > USB_MAX_DEVICES) if (sc->sc_noslot > USB_MAX_DEVICES)
@ -457,6 +458,27 @@ xhci_config(struct xhci_softc *sc)
DPRINTF(("%s: ERDP=%#x%#x\n", DEVNAME(sc), DPRINTF(("%s: ERDP=%#x%#x\n", DEVNAME(sc),
XRREAD4(sc, XHCI_ERDP_HI(0)), XRREAD4(sc, XHCI_ERDP_LO(0)))); XRREAD4(sc, XHCI_ERDP_HI(0)), XRREAD4(sc, XHCI_ERDP_LO(0))));
/*
* If we successfully saved the state during suspend, restore
* it here. Otherwise some Intel controllers don't function
* correctly after resume.
*/
if (sc->sc_saved_state) {
XOWRITE4(sc, XHCI_USBCMD, XHCI_CMD_CRS); /* Restore state */
hcr = XOREAD4(sc, XHCI_USBSTS);
for (i = 0; i < 100; i++) {
usb_delay_ms(&sc->sc_bus, 1);
hcr = XOREAD4(sc, XHCI_USBSTS) & XHCI_STS_RSS;
if (!hcr)
break;
}
if (hcr)
printf("%s: restore state timeout\n", DEVNAME(sc));
sc->sc_saved_state = 0;
}
/* Enable interrupts. */ /* Enable interrupts. */
hcr = XRREAD4(sc, XHCI_IMAN(0)); hcr = XRREAD4(sc, XHCI_IMAN(0));
XRWRITE4(sc, XHCI_IMAN(0), hcr | XHCI_IMAN_INTR_ENA); XRWRITE4(sc, XHCI_IMAN(0), hcr | XHCI_IMAN_INTR_ENA);
@ -603,10 +625,6 @@ xhci_suspend(struct xhci_softc *sc)
* unless they have seen a save state command. This in turn * unless they have seen a save state command. This in turn
* will prevent the SoC from reaching its lowest idle state. * will prevent the SoC from reaching its lowest idle state.
* So save the state here. * So save the state here.
*
* Note that we don't restore this saved state anywhere.
* Instead we reset the controller and reinitialize it from
* scratch when we resume.
*/ */
XOWRITE4(sc, XHCI_USBCMD, XHCI_CMD_CSS); /* Save state */ XOWRITE4(sc, XHCI_USBCMD, XHCI_CMD_CSS); /* Save state */
@ -624,6 +642,8 @@ xhci_suspend(struct xhci_softc *sc)
return; return;
} }
sc->sc_saved_state = 1;
/* Disable interrupts. */ /* Disable interrupts. */
XRWRITE4(sc, XHCI_IMOD(0), 0); XRWRITE4(sc, XHCI_IMOD(0), 0);
XRWRITE4(sc, XHCI_IMAN(0), 0); XRWRITE4(sc, XHCI_IMAN(0), 0);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: xhcivar.h,v 1.14 2022/12/12 19:18:25 kettenis Exp $ */ /* $OpenBSD: xhcivar.h,v 1.15 2024/08/15 17:17:05 kettenis Exp $ */
/* /*
* Copyright (c) 2014 Martin Pieuchot * Copyright (c) 2014 Martin Pieuchot
@ -89,6 +89,7 @@ struct xhci_softc {
bus_size_t sc_size; bus_size_t sc_size;
int sc_dead; int sc_dead;
int sc_saved_state;
bus_size_t sc_oper_off; /* Operational Register space */ bus_size_t sc_oper_off; /* Operational Register space */
bus_size_t sc_runt_off; /* Runtime */ bus_size_t sc_runt_off; /* Runtime */

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bpf.c,v 1.224 2024/08/12 17:02:58 mvs Exp $ */ /* $OpenBSD: bpf.c,v 1.225 2024/08/15 12:20:20 dlg Exp $ */
/* $NetBSD: bpf.c,v 1.33 1997/02/21 23:59:35 thorpej Exp $ */ /* $NetBSD: bpf.c,v 1.33 1997/02/21 23:59:35 thorpej Exp $ */
/* /*
@ -760,7 +760,8 @@ bpf_get_wtimeout(struct bpf_d *d, struct timeval *tv)
/* /*
* FIONREAD Check for read packet available. * FIONREAD Check for read packet available.
* BIOCGBLEN Get buffer len [for read()]. * BIOCGBLEN Get buffer len [for read()].
* BIOCSETF Set ethernet read filter. * BIOCSETF Set read filter.
* BIOCSETFNR Set read filter without resetting descriptor.
* BIOCFLUSH Flush read packet buffer. * BIOCFLUSH Flush read packet buffer.
* BIOCPROMISC Put interface into promiscuous mode. * BIOCPROMISC Put interface into promiscuous mode.
* BIOCGDLTLIST Get supported link layer types. * BIOCGDLTLIST Get supported link layer types.
@ -867,17 +868,12 @@ bpfioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
break; break;
/* /*
* Set link layer read filter. * Set link layer read/write filter.
*/ */
case BIOCSETF: case BIOCSETF:
error = bpf_setf(d, (struct bpf_program *)addr, 0); case BIOCSETFNR:
break;
/*
* Set link layer write filter.
*/
case BIOCSETWF: case BIOCSETWF:
error = bpf_setf(d, (struct bpf_program *)addr, 1); error = bpf_setf(d, (struct bpf_program *)addr, cmd);
break; break;
/* /*
@ -1122,7 +1118,7 @@ bpfioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
* free it and replace it. Returns EINVAL for bogus requests. * free it and replace it. Returns EINVAL for bogus requests.
*/ */
int int
bpf_setf(struct bpf_d *d, struct bpf_program *fp, int wf) bpf_setf(struct bpf_d *d, struct bpf_program *fp, u_long cmd)
{ {
struct bpf_program_smr *bps, *old_bps; struct bpf_program_smr *bps, *old_bps;
struct bpf_insn *fcode; struct bpf_insn *fcode;
@ -1157,7 +1153,7 @@ bpf_setf(struct bpf_d *d, struct bpf_program *fp, int wf)
bps->bps_bf.bf_insns = fcode; bps->bps_bf.bf_insns = fcode;
} }
if (wf == 0) { if (cmd != BIOCSETWF) {
old_bps = SMR_PTR_GET_LOCKED(&d->bd_rfilter); old_bps = SMR_PTR_GET_LOCKED(&d->bd_rfilter);
SMR_PTR_SET_LOCKED(&d->bd_rfilter, bps); SMR_PTR_SET_LOCKED(&d->bd_rfilter, bps);
} else { } else {
@ -1165,9 +1161,12 @@ bpf_setf(struct bpf_d *d, struct bpf_program *fp, int wf)
SMR_PTR_SET_LOCKED(&d->bd_wfilter, bps); SMR_PTR_SET_LOCKED(&d->bd_wfilter, bps);
} }
mtx_enter(&d->bd_mtx); if (cmd == BIOCSETF) {
bpf_resetd(d); mtx_enter(&d->bd_mtx);
mtx_leave(&d->bd_mtx); bpf_resetd(d);
mtx_leave(&d->bd_mtx);
}
if (old_bps != NULL) if (old_bps != NULL)
smr_call(&old_bps->bps_smr, bpf_prog_smr, old_bps); smr_call(&old_bps->bps_smr, bpf_prog_smr, old_bps);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bpf.h,v 1.72 2024/01/26 21:14:08 jan Exp $ */ /* $OpenBSD: bpf.h,v 1.73 2024/08/15 12:20:20 dlg Exp $ */
/* $NetBSD: bpf.h,v 1.15 1996/12/13 07:57:33 mikel Exp $ */ /* $NetBSD: bpf.h,v 1.15 1996/12/13 07:57:33 mikel Exp $ */
/* /*
@ -122,6 +122,7 @@ struct bpf_version {
#define BIOCSWTIMEOUT _IOW('B',126, struct timeval) #define BIOCSWTIMEOUT _IOW('B',126, struct timeval)
#define BIOCGWTIMEOUT _IOR('B',126, struct timeval) #define BIOCGWTIMEOUT _IOR('B',126, struct timeval)
#define BIOCDWTIMEOUT _IO('B',126) #define BIOCDWTIMEOUT _IO('B',126)
#define BIOCSETFNR _IOW('B',127, struct bpf_program)
/* /*
* Direction filters for BIOCSDIRFILT/BIOCGDIRFILT * Direction filters for BIOCSDIRFILT/BIOCGDIRFILT

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bpfdesc.h,v 1.48 2023/03/09 05:56:58 dlg Exp $ */ /* $OpenBSD: bpfdesc.h,v 1.49 2024/08/15 12:20:20 dlg Exp $ */
/* $NetBSD: bpfdesc.h,v 1.11 1995/09/27 18:30:42 thorpej Exp $ */ /* $NetBSD: bpfdesc.h,v 1.11 1995/09/27 18:30:42 thorpej Exp $ */
/* /*
@ -123,6 +123,6 @@ struct bpf_if {
struct ifnet *bif_ifp; /* corresponding interface */ struct ifnet *bif_ifp; /* corresponding interface */
}; };
int bpf_setf(struct bpf_d *, struct bpf_program *, int); int bpf_setf(struct bpf_d *, struct bpf_program *, u_long);
#endif /* _KERNEL */ #endif /* _KERNEL */
#endif /* _NET_BPFDESC_H_ */ #endif /* _NET_BPFDESC_H_ */

View file

@ -1,4 +1,4 @@
/* $OpenBSD: packet.c,v 1.315 2024/05/31 08:49:35 djm Exp $ */ /* $OpenBSD: packet.c,v 1.316 2024/08/15 00:51:51 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -2617,6 +2617,11 @@ sshpkt_put_ec(struct ssh *ssh, const EC_POINT *v, const EC_GROUP *g)
return sshbuf_put_ec(ssh->state->outgoing_packet, v, g); return sshbuf_put_ec(ssh->state->outgoing_packet, v, g);
} }
int
sshpkt_put_ec_pkey(struct ssh *ssh, EVP_PKEY *pkey)
{
return sshbuf_put_ec_pkey(ssh->state->outgoing_packet, pkey);
}
int int
sshpkt_put_bignum2(struct ssh *ssh, const BIGNUM *v) sshpkt_put_bignum2(struct ssh *ssh, const BIGNUM *v)

View file

@ -1,4 +1,4 @@
/* $OpenBSD: packet.h,v 1.98 2024/05/17 06:42:04 jsg Exp $ */ /* $OpenBSD: packet.h,v 1.99 2024/08/15 00:51:51 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -25,10 +25,12 @@
#include <openssl/bn.h> #include <openssl/bn.h>
#include <openssl/ec.h> #include <openssl/ec.h>
#include <openssl/ecdsa.h> #include <openssl/ecdsa.h>
#include <openssl/evp.h>
#else /* OPENSSL */ #else /* OPENSSL */
#define BIGNUM void #define BIGNUM void
#define EC_GROUP void #define EC_GROUP void
#define EC_POINT void #define EC_POINT void
#define EVP_PKEY void
#endif /* WITH_OPENSSL */ #endif /* WITH_OPENSSL */
struct kex; struct kex;
@ -185,6 +187,7 @@ int sshpkt_put_string(struct ssh *ssh, const void *v, size_t len);
int sshpkt_put_cstring(struct ssh *ssh, const void *v); int sshpkt_put_cstring(struct ssh *ssh, const void *v);
int sshpkt_put_stringb(struct ssh *ssh, const struct sshbuf *v); int sshpkt_put_stringb(struct ssh *ssh, const struct sshbuf *v);
int sshpkt_put_ec(struct ssh *ssh, const EC_POINT *v, const EC_GROUP *g); int sshpkt_put_ec(struct ssh *ssh, const EC_POINT *v, const EC_GROUP *g);
int sshpkt_put_ec_pkey(struct ssh *ssh, EVP_PKEY *pkey);
int sshpkt_put_bignum2(struct ssh *ssh, const BIGNUM *v); int sshpkt_put_bignum2(struct ssh *ssh, const BIGNUM *v);
int sshpkt_get(struct ssh *ssh, void *valp, size_t len); int sshpkt_get(struct ssh *ssh, void *valp, size_t len);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-ecdsa-sk.c,v 1.18 2023/03/08 04:43:12 guenther Exp $ */ /* $OpenBSD: ssh-ecdsa-sk.c,v 1.19 2024/08/15 00:51:51 djm Exp $ */
/* /*
* Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2010 Damien Miller. All rights reserved. * Copyright (c) 2010 Damien Miller. All rights reserved.
@ -219,11 +219,13 @@ ssh_ecdsa_sk_verify(const struct sshkey *key,
struct sshkey_sig_details **detailsp) struct sshkey_sig_details **detailsp)
{ {
ECDSA_SIG *esig = NULL; ECDSA_SIG *esig = NULL;
EVP_MD_CTX *md_ctx = NULL;
BIGNUM *sig_r = NULL, *sig_s = NULL; BIGNUM *sig_r = NULL, *sig_s = NULL;
u_char sig_flags; u_char sig_flags;
u_char msghash[32], apphash[32], sighash[32]; u_char msghash[32], apphash[32];
u_int sig_counter; u_int sig_counter;
int is_webauthn = 0, ret = SSH_ERR_INTERNAL_ERROR; u_char *sigb = NULL, *cp;
int is_webauthn = 0, ret = SSH_ERR_INTERNAL_ERROR, len = 0;
struct sshbuf *b = NULL, *sigbuf = NULL, *original_signed = NULL; struct sshbuf *b = NULL, *sigbuf = NULL, *original_signed = NULL;
struct sshbuf *webauthn_wrapper = NULL, *webauthn_exts = NULL; struct sshbuf *webauthn_wrapper = NULL, *webauthn_exts = NULL;
char *ktype = NULL, *webauthn_origin = NULL; char *ktype = NULL, *webauthn_origin = NULL;
@ -234,7 +236,7 @@ ssh_ecdsa_sk_verify(const struct sshkey *key,
if (detailsp != NULL) if (detailsp != NULL)
*detailsp = NULL; *detailsp = NULL;
if (key == NULL || key->ecdsa == NULL || if (key == NULL || key->pkey == NULL ||
sshkey_type_plain(key->type) != KEY_ECDSA_SK || sshkey_type_plain(key->type) != KEY_ECDSA_SK ||
sig == NULL || siglen == 0) sig == NULL || siglen == 0)
return SSH_ERR_INVALID_ARGUMENT; return SSH_ERR_INVALID_ARGUMENT;
@ -345,21 +347,43 @@ ssh_ecdsa_sk_verify(const struct sshkey *key,
(ret = sshbuf_putb(original_signed, webauthn_exts)) != 0 || (ret = sshbuf_putb(original_signed, webauthn_exts)) != 0 ||
(ret = sshbuf_put(original_signed, msghash, sizeof(msghash))) != 0) (ret = sshbuf_put(original_signed, msghash, sizeof(msghash))) != 0)
goto out; goto out;
/* Signature is over H(original_signed) */
if ((ret = ssh_digest_buffer(SSH_DIGEST_SHA256, original_signed,
sighash, sizeof(sighash))) != 0)
goto out;
details->sk_counter = sig_counter; details->sk_counter = sig_counter;
details->sk_flags = sig_flags; details->sk_flags = sig_flags;
#ifdef DEBUG_SK #ifdef DEBUG_SK
fprintf(stderr, "%s: signed buf:\n", __func__); fprintf(stderr, "%s: signed buf:\n", __func__);
sshbuf_dump(original_signed, stderr); sshbuf_dump(original_signed, stderr);
fprintf(stderr, "%s: signed hash:\n", __func__);
sshbuf_dump_data(sighash, sizeof(sighash), stderr);
#endif #endif
if ((md_ctx = EVP_MD_CTX_new()) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
if ((len = i2d_ECDSA_SIG(esig, NULL)) <= 0) {
len = 0;
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
if ((sigb = calloc(1, len)) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
cp = sigb; /* ASN1_item_i2d increments the pointer past the object */
if (i2d_ECDSA_SIG(esig, &cp) != len) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
#ifdef DEBUG_SK
fprintf(stderr, "%s: signed hash:\n", __func__);
sshbuf_dump_data(sigb, len, stderr);
#endif
/* Verify it */ /* Verify it */
switch (ECDSA_do_verify(sighash, sizeof(sighash), esig, key->ecdsa)) { if (EVP_DigestVerifyInit(md_ctx, NULL, EVP_sha256(), NULL,
key->pkey) != 1) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
switch (EVP_DigestVerify(md_ctx, sigb, len,
sshbuf_ptr(original_signed), sshbuf_len(original_signed))) {
case 1: case 1:
ret = 0; ret = 0;
break; break;
@ -379,7 +403,6 @@ ssh_ecdsa_sk_verify(const struct sshkey *key,
explicit_bzero(&sig_flags, sizeof(sig_flags)); explicit_bzero(&sig_flags, sizeof(sig_flags));
explicit_bzero(&sig_counter, sizeof(sig_counter)); explicit_bzero(&sig_counter, sizeof(sig_counter));
explicit_bzero(msghash, sizeof(msghash)); explicit_bzero(msghash, sizeof(msghash));
explicit_bzero(sighash, sizeof(msghash));
explicit_bzero(apphash, sizeof(apphash)); explicit_bzero(apphash, sizeof(apphash));
sshkey_sig_details_free(details); sshkey_sig_details_free(details);
sshbuf_free(webauthn_wrapper); sshbuf_free(webauthn_wrapper);
@ -392,6 +415,8 @@ ssh_ecdsa_sk_verify(const struct sshkey *key,
BN_clear_free(sig_r); BN_clear_free(sig_r);
BN_clear_free(sig_s); BN_clear_free(sig_s);
free(ktype); free(ktype);
freezero(sigb, len);
EVP_MD_CTX_free(md_ctx);
return ret; return ret;
} }

View file

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-ecdsa.c,v 1.26 2023/03/08 04:43:12 guenther Exp $ */ /* $OpenBSD: ssh-ecdsa.c,v 1.27 2024/08/15 00:51:51 djm Exp $ */
/* /*
* Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2010 Damien Miller. All rights reserved. * Copyright (c) 2010 Damien Miller. All rights reserved.
@ -39,6 +39,59 @@
#define SSHKEY_INTERNAL #define SSHKEY_INTERNAL
#include "sshkey.h" #include "sshkey.h"
int
sshkey_ecdsa_fixup_group(EVP_PKEY *k)
{
int nids[] = {
NID_X9_62_prime256v1,
NID_secp384r1,
NID_secp521r1,
-1
};
int nid = -1;
u_int i;
const EC_GROUP *g;
EC_KEY *ec = NULL;
EC_GROUP *eg = NULL;
if ((ec = EVP_PKEY_get1_EC_KEY(k)) == NULL ||
(g = EC_KEY_get0_group(ec)) == NULL)
goto out;
/*
* The group may be stored in a ASN.1 encoded private key in one of two
* ways: as a "named group", which is reconstituted by ASN.1 object ID
* or explicit group parameters encoded into the key blob. Only the
* "named group" case sets the group NID for us, but we can figure
* it out for the other case by comparing against all the groups that
* are supported.
*/
if ((nid = EC_GROUP_get_curve_name(g)) > 0)
goto out;
nid = -1;
for (i = 0; nids[i] != -1; i++) {
if ((eg = EC_GROUP_new_by_curve_name(nids[i])) == NULL)
goto out;
if (EC_GROUP_cmp(g, eg, NULL) == 0)
break;
EC_GROUP_free(eg);
eg = NULL;
}
if (nids[i] == -1)
goto out;
/* Use the group with the NID attached */
EC_GROUP_set_asn1_flag(eg, OPENSSL_EC_NAMED_CURVE);
if (EC_KEY_set_group(ec, eg) != 1 ||
EVP_PKEY_set1_EC_KEY(k, ec) != 1)
goto out;
/* success */
nid = nids[i];
out:
EC_KEY_free(ec);
EC_GROUP_free(eg);
return nid;
}
static u_int static u_int
ssh_ecdsa_size(const struct sshkey *key) ssh_ecdsa_size(const struct sshkey *key)
{ {
@ -57,30 +110,16 @@ ssh_ecdsa_size(const struct sshkey *key)
static void static void
ssh_ecdsa_cleanup(struct sshkey *k) ssh_ecdsa_cleanup(struct sshkey *k)
{ {
EC_KEY_free(k->ecdsa); EVP_PKEY_free(k->pkey);
k->ecdsa = NULL; k->pkey = NULL;
} }
static int static int
ssh_ecdsa_equal(const struct sshkey *a, const struct sshkey *b) ssh_ecdsa_equal(const struct sshkey *a, const struct sshkey *b)
{ {
const EC_GROUP *grp_a, *grp_b; if (a->pkey == NULL || b->pkey == NULL)
const EC_POINT *pub_a, *pub_b;
if (a->ecdsa == NULL || b->ecdsa == NULL)
return 0; return 0;
if ((grp_a = EC_KEY_get0_group(a->ecdsa)) == NULL || return EVP_PKEY_cmp(a->pkey, b->pkey) == 1;
(grp_b = EC_KEY_get0_group(b->ecdsa)) == NULL)
return 0;
if ((pub_a = EC_KEY_get0_public_key(a->ecdsa)) == NULL ||
(pub_b = EC_KEY_get0_public_key(b->ecdsa)) == NULL)
return 0;
if (EC_GROUP_cmp(grp_a, grp_b, NULL) != 0)
return 0;
if (EC_POINT_cmp(grp_a, pub_a, pub_b, NULL) != 0)
return 0;
return 1;
} }
static int static int
@ -89,11 +128,11 @@ ssh_ecdsa_serialize_public(const struct sshkey *key, struct sshbuf *b,
{ {
int r; int r;
if (key->ecdsa == NULL) if (key->pkey == NULL)
return SSH_ERR_INVALID_ARGUMENT; return SSH_ERR_INVALID_ARGUMENT;
if ((r = sshbuf_put_cstring(b, if ((r = sshbuf_put_cstring(b,
sshkey_curve_nid_to_name(key->ecdsa_nid))) != 0 || sshkey_curve_nid_to_name(key->ecdsa_nid))) != 0 ||
(r = sshbuf_put_eckey(b, key->ecdsa)) != 0) (r = sshbuf_put_ec_pkey(b, key->pkey)) != 0)
return r; return r;
return 0; return 0;
@ -110,7 +149,7 @@ ssh_ecdsa_serialize_private(const struct sshkey *key, struct sshbuf *b,
return r; return r;
} }
if ((r = sshbuf_put_bignum2(b, if ((r = sshbuf_put_bignum2(b,
EC_KEY_get0_private_key(key->ecdsa))) != 0) EC_KEY_get0_private_key(EVP_PKEY_get0_EC_KEY(key->pkey)))) != 0)
return r; return r;
return 0; return 0;
} }
@ -118,31 +157,64 @@ ssh_ecdsa_serialize_private(const struct sshkey *key, struct sshbuf *b,
static int static int
ssh_ecdsa_generate(struct sshkey *k, int bits) ssh_ecdsa_generate(struct sshkey *k, int bits)
{ {
EC_KEY *private; EVP_PKEY *res = NULL;
EVP_PKEY_CTX *ctx = NULL;
int ret = SSH_ERR_INTERNAL_ERROR;
if ((k->ecdsa_nid = sshkey_ecdsa_bits_to_nid(bits)) == -1) if ((k->ecdsa_nid = sshkey_ecdsa_bits_to_nid(bits)) == -1)
return SSH_ERR_KEY_LENGTH; return SSH_ERR_KEY_LENGTH;
if ((private = EC_KEY_new_by_curve_name(k->ecdsa_nid)) == NULL)
if ((ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL)) == NULL)
return SSH_ERR_ALLOC_FAIL; return SSH_ERR_ALLOC_FAIL;
if (EC_KEY_generate_key(private) != 1) {
EC_KEY_free(private); if (EVP_PKEY_keygen_init(ctx) <= 0 ||
return SSH_ERR_LIBCRYPTO_ERROR; EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, k->ecdsa_nid) <= 0 ||
EVP_PKEY_keygen(ctx, &res) <= 0) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
} }
EC_KEY_set_asn1_flag(private, OPENSSL_EC_NAMED_CURVE); /* success */
k->ecdsa = private; k->pkey = res;
return 0; res = NULL;
ret = 0;
out:
EVP_PKEY_free(res);
EVP_PKEY_CTX_free(ctx);
return ret;
} }
static int static int
ssh_ecdsa_copy_public(const struct sshkey *from, struct sshkey *to) ssh_ecdsa_copy_public(const struct sshkey *from, struct sshkey *to)
{ {
const EC_KEY *ec_from;
EC_KEY *ec_to = NULL;
int ret = SSH_ERR_INTERNAL_ERROR;
ec_from = EVP_PKEY_get0_EC_KEY(from->pkey);
if (ec_from == NULL)
return SSH_ERR_LIBCRYPTO_ERROR;
to->ecdsa_nid = from->ecdsa_nid; to->ecdsa_nid = from->ecdsa_nid;
if ((to->ecdsa = EC_KEY_new_by_curve_name(from->ecdsa_nid)) == NULL) if ((ec_to = EC_KEY_new_by_curve_name(from->ecdsa_nid)) == NULL)
return SSH_ERR_ALLOC_FAIL; return SSH_ERR_ALLOC_FAIL;
if (EC_KEY_set_public_key(to->ecdsa, if (EC_KEY_set_public_key(ec_to,
EC_KEY_get0_public_key(from->ecdsa)) != 1) EC_KEY_get0_public_key(ec_from)) != 1) {
return SSH_ERR_LIBCRYPTO_ERROR; /* caller will free k->ecdsa */ ret = SSH_ERR_LIBCRYPTO_ERROR;
return 0; goto out;
}
EVP_PKEY_free(to->pkey);
if ((to->pkey = EVP_PKEY_new()) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
if (EVP_PKEY_set1_EC_KEY(to->pkey, ec_to) != 1) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
ret = 0;
out:
EC_KEY_free(ec_to);
return ret;
} }
static int static int
@ -151,6 +223,8 @@ ssh_ecdsa_deserialize_public(const char *ktype, struct sshbuf *b,
{ {
int r; int r;
char *curve = NULL; char *curve = NULL;
EVP_PKEY *pkey = NULL;
EC_KEY *ec = NULL;
if ((key->ecdsa_nid = sshkey_ecdsa_nid_from_name(ktype)) == -1) if ((key->ecdsa_nid = sshkey_ecdsa_nid_from_name(ktype)) == -1)
return SSH_ERR_INVALID_ARGUMENT; return SSH_ERR_INVALID_ARGUMENT;
@ -160,31 +234,39 @@ ssh_ecdsa_deserialize_public(const char *ktype, struct sshbuf *b,
r = SSH_ERR_EC_CURVE_MISMATCH; r = SSH_ERR_EC_CURVE_MISMATCH;
goto out; goto out;
} }
EC_KEY_free(key->ecdsa); if ((ec = EC_KEY_new_by_curve_name(key->ecdsa_nid)) == NULL) {
key->ecdsa = NULL;
if ((key->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid)) == NULL) {
r = SSH_ERR_LIBCRYPTO_ERROR; r = SSH_ERR_LIBCRYPTO_ERROR;
goto out; goto out;
} }
if ((r = sshbuf_get_eckey(b, key->ecdsa)) != 0) if ((r = sshbuf_get_eckey(b, ec)) != 0)
goto out; goto out;
if (sshkey_ec_validate_public(EC_KEY_get0_group(key->ecdsa), if (sshkey_ec_validate_public(EC_KEY_get0_group(ec),
EC_KEY_get0_public_key(key->ecdsa)) != 0) { EC_KEY_get0_public_key(ec)) != 0) {
r = SSH_ERR_KEY_INVALID_EC_VALUE; r = SSH_ERR_KEY_INVALID_EC_VALUE;
goto out; goto out;
} }
if ((pkey = EVP_PKEY_new()) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
if (EVP_PKEY_set1_EC_KEY(pkey, ec) != 1) {
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
EVP_PKEY_free(key->pkey);
key->pkey = pkey;
pkey = NULL;
/* success */ /* success */
r = 0; r = 0;
#ifdef DEBUG_PK #ifdef DEBUG_PK
sshkey_dump_ec_point(EC_KEY_get0_group(key->ecdsa), sshkey_dump_ec_point(
EC_KEY_get0_public_key(key->ecdsa)); EC_KEY_get0_group(EVP_PKEY_get0_EC_KEY(key->pkey)),
EC_KEY_get0_public_key(EVP_PKEY_get0_EC_KEY(key->pkey)));
#endif #endif
out: out:
EC_KEY_free(ec);
EVP_PKEY_free(pkey);
free(curve); free(curve);
if (r != 0) {
EC_KEY_free(key->ecdsa);
key->ecdsa = NULL;
}
return r; return r;
} }
@ -194,6 +276,7 @@ ssh_ecdsa_deserialize_private(const char *ktype, struct sshbuf *b,
{ {
int r; int r;
BIGNUM *exponent = NULL; BIGNUM *exponent = NULL;
EC_KEY *ec = NULL;
if (!sshkey_is_cert(key)) { if (!sshkey_is_cert(key)) {
if ((r = ssh_ecdsa_deserialize_public(ktype, b, key)) != 0) if ((r = ssh_ecdsa_deserialize_public(ktype, b, key)) != 0)
@ -201,16 +284,25 @@ ssh_ecdsa_deserialize_private(const char *ktype, struct sshbuf *b,
} }
if ((r = sshbuf_get_bignum2(b, &exponent)) != 0) if ((r = sshbuf_get_bignum2(b, &exponent)) != 0)
goto out; goto out;
if (EC_KEY_set_private_key(key->ecdsa, exponent) != 1) { if ((ec = EVP_PKEY_get1_EC_KEY(key->pkey)) == NULL) {
r = SSH_ERR_LIBCRYPTO_ERROR; r = SSH_ERR_LIBCRYPTO_ERROR;
goto out; goto out;
} }
if ((r = sshkey_ec_validate_private(key->ecdsa)) != 0) if (EC_KEY_set_private_key(ec, exponent) != 1) {
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out; goto out;
}
if ((r = sshkey_ec_validate_private(ec)) != 0)
goto out;
if (EVP_PKEY_set1_EC_KEY(key->pkey, ec) != 1) {
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
/* success */ /* success */
r = 0; r = 0;
out: out:
BN_clear_free(exponent); BN_clear_free(exponent);
EC_KEY_free(ec);
return r; return r;
} }
@ -221,34 +313,35 @@ ssh_ecdsa_sign(struct sshkey *key,
const char *alg, const char *sk_provider, const char *sk_pin, u_int compat) const char *alg, const char *sk_provider, const char *sk_pin, u_int compat)
{ {
ECDSA_SIG *esig = NULL; ECDSA_SIG *esig = NULL;
unsigned char *sigb = NULL;
const unsigned char *psig;
const BIGNUM *sig_r, *sig_s; const BIGNUM *sig_r, *sig_s;
int hash_alg; int hash_alg;
u_char digest[SSH_DIGEST_MAX_LENGTH]; size_t slen = 0;
size_t len, hlen;
struct sshbuf *b = NULL, *bb = NULL; struct sshbuf *b = NULL, *bb = NULL;
int ret = SSH_ERR_INTERNAL_ERROR; int len = 0, ret = SSH_ERR_INTERNAL_ERROR;
if (lenp != NULL) if (lenp != NULL)
*lenp = 0; *lenp = 0;
if (sigp != NULL) if (sigp != NULL)
*sigp = NULL; *sigp = NULL;
if (key == NULL || key->ecdsa == NULL || if (key == NULL || key->pkey == NULL ||
sshkey_type_plain(key->type) != KEY_ECDSA) sshkey_type_plain(key->type) != KEY_ECDSA)
return SSH_ERR_INVALID_ARGUMENT; return SSH_ERR_INVALID_ARGUMENT;
if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1 || if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1)
(hlen = ssh_digest_bytes(hash_alg)) == 0)
return SSH_ERR_INTERNAL_ERROR; return SSH_ERR_INTERNAL_ERROR;
if ((ret = ssh_digest_memory(hash_alg, data, dlen,
digest, sizeof(digest))) != 0) if ((ret = sshkey_pkey_digest_sign(key->pkey, hash_alg, &sigb, &slen,
data, dlen)) != 0)
goto out; goto out;
if ((esig = ECDSA_do_sign(digest, hlen, key->ecdsa)) == NULL) { psig = sigb;
if ((esig = d2i_ECDSA_SIG(NULL, &psig, slen)) == NULL) {
ret = SSH_ERR_LIBCRYPTO_ERROR; ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out; goto out;
} }
if ((bb = sshbuf_new()) == NULL || (b = sshbuf_new()) == NULL) { if ((bb = sshbuf_new()) == NULL || (b = sshbuf_new()) == NULL) {
ret = SSH_ERR_ALLOC_FAIL; ret = SSH_ERR_ALLOC_FAIL;
goto out; goto out;
@ -272,7 +365,7 @@ ssh_ecdsa_sign(struct sshkey *key,
*lenp = len; *lenp = len;
ret = 0; ret = 0;
out: out:
explicit_bzero(digest, sizeof(digest)); freezero(sigb, slen);
sshbuf_free(b); sshbuf_free(b);
sshbuf_free(bb); sshbuf_free(bb);
ECDSA_SIG_free(esig); ECDSA_SIG_free(esig);
@ -287,20 +380,18 @@ ssh_ecdsa_verify(const struct sshkey *key,
{ {
ECDSA_SIG *esig = NULL; ECDSA_SIG *esig = NULL;
BIGNUM *sig_r = NULL, *sig_s = NULL; BIGNUM *sig_r = NULL, *sig_s = NULL;
int hash_alg; int hash_alg, len = 0;
u_char digest[SSH_DIGEST_MAX_LENGTH];
size_t hlen;
int ret = SSH_ERR_INTERNAL_ERROR; int ret = SSH_ERR_INTERNAL_ERROR;
struct sshbuf *b = NULL, *sigbuf = NULL; struct sshbuf *b = NULL, *sigbuf = NULL;
char *ktype = NULL; char *ktype = NULL;
unsigned char *sigb = NULL, *cp;
if (key == NULL || key->ecdsa == NULL || if (key == NULL || key->pkey == NULL ||
sshkey_type_plain(key->type) != KEY_ECDSA || sshkey_type_plain(key->type) != KEY_ECDSA ||
sig == NULL || siglen == 0) sig == NULL || siglen == 0)
return SSH_ERR_INVALID_ARGUMENT; return SSH_ERR_INVALID_ARGUMENT;
if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1 || if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1)
(hlen = ssh_digest_bytes(hash_alg)) == 0)
return SSH_ERR_INTERNAL_ERROR; return SSH_ERR_INTERNAL_ERROR;
/* fetch signature */ /* fetch signature */
@ -326,6 +417,11 @@ ssh_ecdsa_verify(const struct sshkey *key,
ret = SSH_ERR_INVALID_FORMAT; ret = SSH_ERR_INVALID_FORMAT;
goto out; goto out;
} }
if (sshbuf_len(sigbuf) != 0) {
ret = SSH_ERR_UNEXPECTED_TRAILING_DATA;
goto out;
}
if ((esig = ECDSA_SIG_new()) == NULL) { if ((esig = ECDSA_SIG_new()) == NULL) {
ret = SSH_ERR_ALLOC_FAIL; ret = SSH_ERR_ALLOC_FAIL;
goto out; goto out;
@ -336,28 +432,26 @@ ssh_ecdsa_verify(const struct sshkey *key,
} }
sig_r = sig_s = NULL; /* transferred */ sig_r = sig_s = NULL; /* transferred */
if (sshbuf_len(sigbuf) != 0) { if ((len = i2d_ECDSA_SIG(esig, NULL)) <= 0) {
ret = SSH_ERR_UNEXPECTED_TRAILING_DATA; len = 0;
goto out;
}
if ((ret = ssh_digest_memory(hash_alg, data, dlen,
digest, sizeof(digest))) != 0)
goto out;
switch (ECDSA_do_verify(digest, hlen, esig, key->ecdsa)) {
case 1:
ret = 0;
break;
case 0:
ret = SSH_ERR_SIGNATURE_INVALID;
goto out;
default:
ret = SSH_ERR_LIBCRYPTO_ERROR; ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out; goto out;
} }
if ((sigb = calloc(1, len)) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
cp = sigb; /* ASN1_item_i2d increments the pointer past the object */
if (i2d_ECDSA_SIG(esig, &cp) != len) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
if ((ret = sshkey_pkey_digest_verify(key->pkey, hash_alg,
data, dlen, sigb, len)) != 0)
goto out;
/* success */
out: out:
explicit_bzero(digest, sizeof(digest)); freezero(sigb, len);
sshbuf_free(sigbuf); sshbuf_free(sigbuf);
sshbuf_free(b); sshbuf_free(b);
ECDSA_SIG_free(esig); ECDSA_SIG_free(esig);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-keygen.c,v 1.472 2024/01/11 01:45:36 djm Exp $ */ /* $OpenBSD: ssh-keygen.c,v 1.473 2024/08/15 00:51:51 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -362,7 +362,8 @@ do_convert_to_pkcs8(struct sshkey *k)
{ {
switch (sshkey_type_plain(k->type)) { switch (sshkey_type_plain(k->type)) {
case KEY_RSA: case KEY_RSA:
if (!PEM_write_RSA_PUBKEY(stdout, k->rsa)) if (!PEM_write_RSA_PUBKEY(stdout,
EVP_PKEY_get0_RSA(k->pkey)))
fatal("PEM_write_RSA_PUBKEY failed"); fatal("PEM_write_RSA_PUBKEY failed");
break; break;
#ifdef WITH_DSA #ifdef WITH_DSA
@ -372,7 +373,8 @@ do_convert_to_pkcs8(struct sshkey *k)
break; break;
#endif #endif
case KEY_ECDSA: case KEY_ECDSA:
if (!PEM_write_EC_PUBKEY(stdout, k->ecdsa)) if (!PEM_write_EC_PUBKEY(stdout,
EVP_PKEY_get0_EC_KEY(k->pkey)))
fatal("PEM_write_EC_PUBKEY failed"); fatal("PEM_write_EC_PUBKEY failed");
break; break;
default: default:
@ -386,7 +388,8 @@ do_convert_to_pem(struct sshkey *k)
{ {
switch (sshkey_type_plain(k->type)) { switch (sshkey_type_plain(k->type)) {
case KEY_RSA: case KEY_RSA:
if (!PEM_write_RSAPublicKey(stdout, k->rsa)) if (!PEM_write_RSAPublicKey(stdout,
EVP_PKEY_get0_RSA(k->pkey)))
fatal("PEM_write_RSAPublicKey failed"); fatal("PEM_write_RSAPublicKey failed");
break; break;
#ifdef WITH_DSA #ifdef WITH_DSA
@ -396,7 +399,8 @@ do_convert_to_pem(struct sshkey *k)
break; break;
#endif #endif
case KEY_ECDSA: case KEY_ECDSA:
if (!PEM_write_EC_PUBKEY(stdout, k->ecdsa)) if (!PEM_write_EC_PUBKEY(stdout,
EVP_PKEY_get0_EC_KEY(k->pkey)))
fatal("PEM_write_EC_PUBKEY failed"); fatal("PEM_write_EC_PUBKEY failed");
break; break;
default: default:
@ -473,6 +477,8 @@ do_convert_private_ssh2(struct sshbuf *b)
#endif #endif
BIGNUM *rsa_n = NULL, *rsa_e = NULL, *rsa_d = NULL; BIGNUM *rsa_n = NULL, *rsa_e = NULL, *rsa_d = NULL;
BIGNUM *rsa_p = NULL, *rsa_q = NULL, *rsa_iqmp = NULL; BIGNUM *rsa_p = NULL, *rsa_q = NULL, *rsa_iqmp = NULL;
BIGNUM *rsa_dmp1 = NULL, *rsa_dmq1 = NULL;
RSA *rsa = NULL;
if ((r = sshbuf_get_u32(b, &magic)) != 0) if ((r = sshbuf_get_u32(b, &magic)) != 0)
fatal_fr(r, "parse magic"); fatal_fr(r, "parse magic");
@ -567,15 +573,25 @@ do_convert_private_ssh2(struct sshbuf *b)
buffer_get_bignum_bits(b, rsa_iqmp); buffer_get_bignum_bits(b, rsa_iqmp);
buffer_get_bignum_bits(b, rsa_q); buffer_get_bignum_bits(b, rsa_q);
buffer_get_bignum_bits(b, rsa_p); buffer_get_bignum_bits(b, rsa_p);
if (!RSA_set0_key(key->rsa, rsa_n, rsa_e, rsa_d)) if ((r = ssh_rsa_complete_crt_parameters(rsa_d, rsa_p, rsa_q,
rsa_iqmp, &rsa_dmp1, &rsa_dmq1)) != 0)
fatal_fr(r, "generate RSA CRT parameters");
if ((key->pkey = EVP_PKEY_new()) == NULL)
fatal_f("EVP_PKEY_new failed");
if ((rsa = RSA_new()) == NULL)
fatal_f("RSA_new failed");
if (!RSA_set0_key(rsa, rsa_n, rsa_e, rsa_d))
fatal_f("RSA_set0_key failed"); fatal_f("RSA_set0_key failed");
rsa_n = rsa_e = rsa_d = NULL; /* transferred */ rsa_n = rsa_e = rsa_d = NULL; /* transferred */
if (!RSA_set0_factors(key->rsa, rsa_p, rsa_q)) if (!RSA_set0_factors(rsa, rsa_p, rsa_q))
fatal_f("RSA_set0_factors failed"); fatal_f("RSA_set0_factors failed");
rsa_p = rsa_q = NULL; /* transferred */ rsa_p = rsa_q = NULL; /* transferred */
if ((r = ssh_rsa_complete_crt_parameters(key, rsa_iqmp)) != 0) if (RSA_set0_crt_params(rsa, rsa_dmp1, rsa_dmq1, rsa_iqmp) != 1)
fatal_fr(r, "generate RSA parameters"); fatal_f("RSA_set0_crt_params failed");
BN_clear_free(rsa_iqmp); rsa_dmp1 = rsa_dmq1 = rsa_iqmp = NULL;
if (EVP_PKEY_set1_RSA(key->pkey, rsa) != 1)
fatal_f("EVP_PKEY_set1_RSA failed");
RSA_free(rsa);
alg = "rsa-sha2-256"; alg = "rsa-sha2-256";
break; break;
} }
@ -695,7 +711,8 @@ do_convert_from_pkcs8(struct sshkey **k, int *private)
if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) if ((*k = sshkey_new(KEY_UNSPEC)) == NULL)
fatal("sshkey_new failed"); fatal("sshkey_new failed");
(*k)->type = KEY_RSA; (*k)->type = KEY_RSA;
(*k)->rsa = EVP_PKEY_get1_RSA(pubkey); (*k)->pkey = pubkey;
pubkey = NULL;
break; break;
#ifdef WITH_DSA #ifdef WITH_DSA
case EVP_PKEY_DSA: case EVP_PKEY_DSA:
@ -708,9 +725,11 @@ do_convert_from_pkcs8(struct sshkey **k, int *private)
case EVP_PKEY_EC: case EVP_PKEY_EC:
if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) if ((*k = sshkey_new(KEY_UNSPEC)) == NULL)
fatal("sshkey_new failed"); fatal("sshkey_new failed");
if (((*k)->ecdsa_nid = sshkey_ecdsa_fixup_group(pubkey)) == -1)
fatal("sshkey_ecdsa_fixup_group failed");
(*k)->type = KEY_ECDSA; (*k)->type = KEY_ECDSA;
(*k)->ecdsa = EVP_PKEY_get1_EC_KEY(pubkey); (*k)->pkey = pubkey;
(*k)->ecdsa_nid = sshkey_ecdsa_key_to_nid((*k)->ecdsa); pubkey = NULL;
break; break;
default: default:
fatal_f("unsupported pubkey type %d", fatal_f("unsupported pubkey type %d",
@ -731,8 +750,12 @@ do_convert_from_pem(struct sshkey **k, int *private)
if ((rsa = PEM_read_RSAPublicKey(fp, NULL, NULL, NULL)) != NULL) { if ((rsa = PEM_read_RSAPublicKey(fp, NULL, NULL, NULL)) != NULL) {
if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) if ((*k = sshkey_new(KEY_UNSPEC)) == NULL)
fatal("sshkey_new failed"); fatal("sshkey_new failed");
if (((*k)->pkey = EVP_PKEY_new()) == NULL)
fatal("EVP_PKEY_new failed");
(*k)->type = KEY_RSA; (*k)->type = KEY_RSA;
(*k)->rsa = rsa; if (EVP_PKEY_set1_RSA((*k)->pkey, rsa) != 1)
fatal("EVP_PKEY_set1_RSA failed");
RSA_free(rsa);
fclose(fp); fclose(fp);
return; return;
} }
@ -779,12 +802,14 @@ do_convert_from(struct passwd *pw)
break; break;
#endif #endif
case KEY_ECDSA: case KEY_ECDSA:
ok = PEM_write_ECPrivateKey(stdout, k->ecdsa, NULL, ok = PEM_write_ECPrivateKey(stdout,
NULL, 0, NULL, NULL); EVP_PKEY_get0_EC_KEY(k->pkey), NULL, NULL, 0,
NULL, NULL);
break; break;
case KEY_RSA: case KEY_RSA:
ok = PEM_write_RSAPrivateKey(stdout, k->rsa, NULL, ok = PEM_write_RSAPrivateKey(stdout,
NULL, 0, NULL, NULL); EVP_PKEY_get0_RSA(k->pkey), NULL, NULL, 0,
NULL, NULL);
break; break;
default: default:
fatal_f("unsupported key type %s", sshkey_type(k)); fatal_f("unsupported key type %s", sshkey_type(k));

View file

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-pkcs11-client.c,v 1.19 2023/12/18 14:46:56 djm Exp $ */ /* $OpenBSD: ssh-pkcs11-client.c,v 1.20 2024/08/15 00:51:51 djm Exp $ */
/* /*
* Copyright (c) 2010 Markus Friedl. All rights reserved. * Copyright (c) 2010 Markus Friedl. All rights reserved.
* Copyright (c) 2014 Pedro Martelletto. All rights reserved. * Copyright (c) 2014 Pedro Martelletto. All rights reserved.
@ -247,14 +247,17 @@ rsa_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, int padding)
debug3_f("signing with PKCS11 provider %s", helper->path); debug3_f("signing with PKCS11 provider %s", helper->path);
if (padding != RSA_PKCS1_PADDING) if (padding != RSA_PKCS1_PADDING)
goto fail; goto fail;
key = sshkey_new(KEY_UNSPEC); if ((key = sshkey_new(KEY_UNSPEC)) == NULL) {
if (key == NULL) {
error_f("sshkey_new failed"); error_f("sshkey_new failed");
goto fail; goto fail;
} }
if ((key->pkey = EVP_PKEY_new()) == NULL ||
EVP_PKEY_set1_RSA(key->pkey, rsa) != 1) {
error_f("pkey setup failed");
goto fail;
}
key->type = KEY_RSA; key->type = KEY_RSA;
RSA_up_ref(rsa);
key->rsa = rsa;
if ((r = sshkey_to_blob(key, &blob, &blen)) != 0) { if ((r = sshkey_to_blob(key, &blob, &blen)) != 0) {
error_fr(r, "encode key"); error_fr(r, "encode key");
goto fail; goto fail;
@ -321,21 +324,22 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv,
if ((helper = helper_by_ec(ec)) == NULL || helper->fd == -1) if ((helper = helper_by_ec(ec)) == NULL || helper->fd == -1)
fatal_f("no helper for PKCS11 key"); fatal_f("no helper for PKCS11 key");
debug3_f("signing with PKCS11 provider %s", helper->path); debug3_f("signing with PKCS11 provider %s", helper->path);
nid = sshkey_ecdsa_key_to_nid(ec);
if (nid < 0) {
error_f("couldn't get curve nid");
goto fail;
}
key = sshkey_new(KEY_UNSPEC); if ((key = sshkey_new(KEY_UNSPEC)) == NULL) {
if (key == NULL) {
error_f("sshkey_new failed"); error_f("sshkey_new failed");
goto fail; goto fail;
} }
key->ecdsa = ec; if ((key->pkey = EVP_PKEY_new()) == NULL ||
EVP_PKEY_set1_EC_KEY(key->pkey, ec) != 1) {
error("pkey setup failed");
goto fail;
}
if ((nid = sshkey_ecdsa_pkey_to_nid(key->pkey)) < 0) {
error("couldn't get curve nid");
goto fail;
}
key->ecdsa_nid = nid; key->ecdsa_nid = nid;
key->type = KEY_ECDSA; key->type = KEY_ECDSA;
EC_KEY_up_ref(ec);
if ((r = sshkey_to_blob(key, &blob, &blen)) != 0) { if ((r = sshkey_to_blob(key, &blob, &blen)) != 0) {
error_fr(r, "encode key"); error_fr(r, "encode key");
@ -389,15 +393,30 @@ ecdsa_do_finish(EC_KEY *ec)
static void static void
wrap_key(struct helper *helper, struct sshkey *k) wrap_key(struct helper *helper, struct sshkey *k)
{ {
RSA *rsa = NULL;
EC_KEY *ecdsa = NULL;
debug3_f("wrap %s for provider %s", sshkey_type(k), helper->path); debug3_f("wrap %s for provider %s", sshkey_type(k), helper->path);
if (k->type == KEY_RSA) { if (k->type == KEY_RSA) {
RSA_set_method(k->rsa, helper->rsa_meth); if ((rsa = EVP_PKEY_get1_RSA(k->pkey)) == NULL)
fatal_f("no RSA key");
if (RSA_set_method(rsa, helper->rsa_meth) != 1)
fatal_f("RSA_set_method failed");
if (helper->nrsa++ >= INT_MAX) if (helper->nrsa++ >= INT_MAX)
fatal_f("RSA refcount error"); fatal_f("RSA refcount error");
if (EVP_PKEY_set1_RSA(k->pkey, rsa) != 1)
fatal_f("EVP_PKEY_set1_RSA failed");
RSA_free(rsa);
} else if (k->type == KEY_ECDSA) { } else if (k->type == KEY_ECDSA) {
EC_KEY_set_method(k->ecdsa, helper->ec_meth); if ((ecdsa = EVP_PKEY_get1_EC_KEY(k->pkey)) == NULL)
fatal_f("no ECDSA key");
if (EC_KEY_set_method(ecdsa, helper->ec_meth) != 1)
fatal_f("EC_KEY_set_method failed");
if (helper->nec++ >= INT_MAX) if (helper->nec++ >= INT_MAX)
fatal_f("EC refcount error"); fatal_f("EC refcount error");
if (EVP_PKEY_set1_EC_KEY(k->pkey, ecdsa) != 1)
fatal_f("EVP_PKEY_set1_EC_KEY failed");
EC_KEY_free(ecdsa);
} else } else
fatal_f("unknown key type"); fatal_f("unknown key type");
k->flags |= SSHKEY_FLAG_EXT; k->flags |= SSHKEY_FLAG_EXT;
@ -416,6 +435,8 @@ pkcs11_make_cert(const struct sshkey *priv,
struct helper *helper = NULL; struct helper *helper = NULL;
struct sshkey *ret; struct sshkey *ret;
int r; int r;
RSA *rsa_priv = NULL, *rsa_cert = NULL;
EC_KEY *ec_priv = NULL, *ec_cert = NULL;
debug3_f("private key type %s cert type %s", sshkey_type(priv), debug3_f("private key type %s cert type %s", sshkey_type(priv),
sshkey_type(certpub)); sshkey_type(certpub));
@ -428,23 +449,41 @@ pkcs11_make_cert(const struct sshkey *priv,
} }
*certprivp = NULL; *certprivp = NULL;
if (priv->type == KEY_RSA) { if (priv->type == KEY_RSA) {
if ((helper = helper_by_rsa(priv->rsa)) == NULL || if ((rsa_priv = EVP_PKEY_get1_RSA(priv->pkey)) == NULL)
fatal_f("no RSA pkey");
if ((helper = helper_by_rsa(rsa_priv)) == NULL ||
helper->fd == -1) helper->fd == -1)
fatal_f("no helper for PKCS11 RSA key"); fatal_f("no helper for PKCS11 RSA key");
if ((r = sshkey_from_private(priv, &ret)) != 0) if ((r = sshkey_from_private(priv, &ret)) != 0)
fatal_fr(r, "copy key"); fatal_fr(r, "copy key");
RSA_set_method(ret->rsa, helper->rsa_meth); if ((rsa_cert = EVP_PKEY_get1_RSA(ret->pkey)) == NULL)
fatal_f("no RSA cert pkey");
if (RSA_set_method(rsa_cert, helper->rsa_meth) != 1)
fatal_f("RSA_set_method failed");
if (helper->nrsa++ >= INT_MAX) if (helper->nrsa++ >= INT_MAX)
fatal_f("RSA refcount error"); fatal_f("RSA refcount error");
if (EVP_PKEY_set1_RSA(ret->pkey, rsa_cert) != 1)
fatal_f("EVP_PKEY_set1_RSA failed");
RSA_free(rsa_priv);
RSA_free(rsa_cert);
} else if (priv->type == KEY_ECDSA) { } else if (priv->type == KEY_ECDSA) {
if ((helper = helper_by_ec(priv->ecdsa)) == NULL || if ((ec_priv = EVP_PKEY_get1_EC_KEY(priv->pkey)) == NULL)
fatal_f("no EC pkey");
if ((helper = helper_by_ec(ec_priv)) == NULL ||
helper->fd == -1) helper->fd == -1)
fatal_f("no helper for PKCS11 EC key"); fatal_f("no helper for PKCS11 EC key");
if ((r = sshkey_from_private(priv, &ret)) != 0) if ((r = sshkey_from_private(priv, &ret)) != 0)
fatal_fr(r, "copy key"); fatal_fr(r, "copy key");
EC_KEY_set_method(ret->ecdsa, helper->ec_meth); if ((ec_cert = EVP_PKEY_get1_EC_KEY(ret->pkey)) == NULL)
fatal_f("no EC cert pkey");
if (EC_KEY_set_method(ec_cert, helper->ec_meth) != 1)
fatal_f("EC_KEY_set_method failed");
if (helper->nec++ >= INT_MAX) if (helper->nec++ >= INT_MAX)
fatal_f("EC refcount error"); fatal_f("EC refcount error");
if (EVP_PKEY_set1_EC_KEY(ret->pkey, ec_cert) != 1)
fatal_f("EVP_PKEY_set1_EC_KEY failed");
EC_KEY_free(ec_priv);
EC_KEY_free(ec_cert);
} else } else
fatal_f("unknown key type %s", sshkey_type(priv)); fatal_f("unknown key type %s", sshkey_type(priv));

View file

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-pkcs11-helper.c,v 1.26 2021/11/18 03:31:44 djm Exp $ */ /* $OpenBSD: ssh-pkcs11-helper.c,v 1.27 2024/08/15 00:51:51 djm Exp $ */
/* /*
* Copyright (c) 2010 Markus Friedl. All rights reserved. * Copyright (c) 2010 Markus Friedl. All rights reserved.
* *
@ -36,6 +36,8 @@
#include "ssherr.h" #include "ssherr.h"
#ifdef WITH_OPENSSL #ifdef WITH_OPENSSL
#include <openssl/ec.h>
#include <openssl/rsa.h>
/* borrows code from sftp-server and ssh-agent */ /* borrows code from sftp-server and ssh-agent */
@ -176,10 +178,13 @@ static void
process_sign(void) process_sign(void)
{ {
u_char *blob, *data, *signature = NULL; u_char *blob, *data, *signature = NULL;
size_t blen, dlen, slen = 0; size_t blen, dlen;
int r, ok = -1; u_int slen = 0;
struct sshkey *key, *found; int len, r, ok = -1;
struct sshkey *key = NULL, *found;
struct sshbuf *msg; struct sshbuf *msg;
RSA *rsa = NULL;
EC_KEY *ecdsa = NULL;
/* XXX support SHA2 signature flags */ /* XXX support SHA2 signature flags */
if ((r = sshbuf_get_string(iqueue, &blob, &blen)) != 0 || if ((r = sshbuf_get_string(iqueue, &blob, &blen)) != 0 ||
@ -189,39 +194,43 @@ process_sign(void)
if ((r = sshkey_from_blob(blob, blen, &key)) != 0) if ((r = sshkey_from_blob(blob, blen, &key)) != 0)
fatal_fr(r, "decode key"); fatal_fr(r, "decode key");
else { if ((found = lookup_key(key)) == NULL)
if ((found = lookup_key(key)) != NULL) { goto reply;
#ifdef WITH_OPENSSL
int ret;
if (key->type == KEY_RSA) { /* XXX use pkey API properly for signing */
slen = RSA_size(key->rsa); switch (key->type) {
signature = xmalloc(slen); case KEY_RSA:
ret = RSA_private_encrypt(dlen, data, signature, if ((rsa = EVP_PKEY_get1_RSA(found->pkey)) == NULL)
found->rsa, RSA_PKCS1_PADDING); fatal_f("no RSA in pkey");
if (ret != -1) { if ((len = RSA_size(rsa)) < 0)
slen = ret; fatal_f("bad RSA length");
ok = 0; signature = xmalloc(len);
} if ((len = RSA_private_encrypt(dlen, data, signature,
} else if (key->type == KEY_ECDSA) { rsa, RSA_PKCS1_PADDING)) < 0) {
u_int xslen = ECDSA_size(key->ecdsa); error_f("RSA_private_encrypt failed");
goto reply;
signature = xmalloc(xslen);
/* "The parameter type is ignored." */
ret = ECDSA_sign(-1, data, dlen, signature,
&xslen, found->ecdsa);
if (ret != 0)
ok = 0;
else
error_f("ECDSA_sign returned %d", ret);
slen = xslen;
} else
error_f("don't know how to sign with key "
"type %d", (int)key->type);
#endif /* WITH_OPENSSL */
} }
sshkey_free(key); slen = (u_int)len;
break;
case KEY_ECDSA:
if ((ecdsa = EVP_PKEY_get1_EC_KEY(found->pkey)) == NULL)
fatal_f("no ECDSA in pkey");
if ((len = ECDSA_size(ecdsa)) < 0)
fatal_f("bad ECDSA length");
slen = (u_int)len;
signature = xmalloc(slen);
/* "The parameter type is ignored." */
if (!ECDSA_sign(-1, data, dlen, signature, &slen, ecdsa)) {
error_f("ECDSA_sign failed");
goto reply;
}
break;
default:
fatal_f("unsupported key type %d", key->type);
} }
/* success */
ok = 0;
reply:
if ((msg = sshbuf_new()) == NULL) if ((msg = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed"); fatal_f("sshbuf_new failed");
if (ok == 0) { if (ok == 0) {
@ -232,6 +241,9 @@ process_sign(void)
if ((r = sshbuf_put_u8(msg, SSH2_AGENT_FAILURE)) != 0) if ((r = sshbuf_put_u8(msg, SSH2_AGENT_FAILURE)) != 0)
fatal_fr(r, "compose failure response"); fatal_fr(r, "compose failure response");
} }
sshkey_free(key);
RSA_free(rsa);
EC_KEY_free(ecdsa);
free(data); free(data);
free(blob); free(blob);
free(signature); free(signature);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-pkcs11.c,v 1.62 2024/04/02 12:22:38 deraadt Exp $ */ /* $OpenBSD: ssh-pkcs11.c,v 1.63 2024/08/15 00:51:51 djm Exp $ */
/* /*
* Copyright (c) 2010 Markus Friedl. All rights reserved. * Copyright (c) 2010 Markus Friedl. All rights reserved.
* Copyright (c) 2014 Pedro Martelletto. All rights reserved. * Copyright (c) 2014 Pedro Martelletto. All rights reserved.
@ -493,8 +493,10 @@ pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx,
memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len);
} }
RSA_set_method(rsa, rsa_method); if (RSA_set_method(rsa, rsa_method) != 1)
RSA_set_ex_data(rsa, rsa_idx, k11); fatal_f("RSA_set_method failed");
if (RSA_set_ex_data(rsa, rsa_idx, k11) != 1)
fatal_f("RSA_set_ex_data failed");
return (0); return (0);
} }
@ -605,8 +607,10 @@ pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx,
k11->keyid = xmalloc(k11->keyid_len); k11->keyid = xmalloc(k11->keyid_len);
memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len);
} }
EC_KEY_set_method(ec, ec_key_method); if (EC_KEY_set_method(ec, ec_key_method) != 1)
EC_KEY_set_ex_data(ec, ec_key_idx, k11); fatal_f("EC_KEY_set_method failed");
if (EC_KEY_set_ex_data(ec, ec_key_idx, k11) != 1)
fatal_f("EC_KEY_set_ex_data failed");
return (0); return (0);
} }
@ -791,11 +795,14 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx,
goto fail; goto fail;
} }
key->ecdsa = ec; EVP_PKEY_free(key->pkey);
if ((key->pkey = EVP_PKEY_new()) == NULL)
fatal("EVP_PKEY_new failed");
if (EVP_PKEY_set1_EC_KEY(key->pkey, ec) != 1)
fatal("EVP_PKEY_set1_EC_KEY failed");
key->ecdsa_nid = nid; key->ecdsa_nid = nid;
key->type = KEY_ECDSA; key->type = KEY_ECDSA;
key->flags |= SSHKEY_FLAG_EXT; key->flags |= SSHKEY_FLAG_EXT;
ec = NULL; /* now owned by key */
fail: fail:
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
@ -886,10 +893,13 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx,
goto fail; goto fail;
} }
key->rsa = rsa; EVP_PKEY_free(key->pkey);
if ((key->pkey = EVP_PKEY_new()) == NULL)
fatal("EVP_PKEY_new failed");
if (EVP_PKEY_set1_RSA(key->pkey, rsa) != 1)
fatal("EVP_PKEY_set1_RSA failed");
key->type = KEY_RSA; key->type = KEY_RSA;
key->flags |= SSHKEY_FLAG_EXT; key->flags |= SSHKEY_FLAG_EXT;
rsa = NULL; /* now owned by key */
fail: fail:
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
@ -997,10 +1007,13 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx,
goto out; goto out;
} }
key->rsa = rsa; EVP_PKEY_free(key->pkey);
if ((key->pkey = EVP_PKEY_new()) == NULL)
fatal("EVP_PKEY_new failed");
if (EVP_PKEY_set1_RSA(key->pkey, rsa) != 1)
fatal("EVP_PKEY_set1_RSA failed");
key->type = KEY_RSA; key->type = KEY_RSA;
key->flags |= SSHKEY_FLAG_EXT; key->flags |= SSHKEY_FLAG_EXT;
rsa = NULL; /* now owned by key */
} else if (EVP_PKEY_base_id(evp) == EVP_PKEY_EC) { } else if (EVP_PKEY_base_id(evp) == EVP_PKEY_EC) {
if (EVP_PKEY_get0_EC_KEY(evp) == NULL) { if (EVP_PKEY_get0_EC_KEY(evp) == NULL) {
error("invalid x509; no ec key"); error("invalid x509; no ec key");
@ -1026,11 +1039,14 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx,
goto out; goto out;
} }
key->ecdsa = ec; EVP_PKEY_free(key->pkey);
if ((key->pkey = EVP_PKEY_new()) == NULL)
fatal("EVP_PKEY_new failed");
if (EVP_PKEY_set1_EC_KEY(key->pkey, ec) != 1)
fatal("EVP_PKEY_set1_EC_KEY failed");
key->ecdsa_nid = nid; key->ecdsa_nid = nid;
key->type = KEY_ECDSA; key->type = KEY_ECDSA;
key->flags |= SSHKEY_FLAG_EXT; key->flags |= SSHKEY_FLAG_EXT;
ec = NULL; /* now owned by key */
} else { } else {
error("unknown certificate key type"); error("unknown certificate key type");
goto out; goto out;

View file

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-rsa.c,v 1.79 2023/03/05 05:34:09 dtucker Exp $ */ /* $OpenBSD: ssh-rsa.c,v 1.80 2024/08/15 00:51:51 djm Exp $ */
/* /*
* Copyright (c) 2000, 2003 Markus Friedl <markus@openbsd.org> * Copyright (c) 2000, 2003 Markus Friedl <markus@openbsd.org>
* *
@ -29,23 +29,18 @@
#include "digest.h" #include "digest.h"
#include "log.h" #include "log.h"
static int openssh_RSA_verify(int, u_char *, size_t, u_char *, size_t, RSA *);
static u_int static u_int
ssh_rsa_size(const struct sshkey *key) ssh_rsa_size(const struct sshkey *k)
{ {
const BIGNUM *rsa_n; if (k->pkey == NULL)
if (key->rsa == NULL)
return 0; return 0;
RSA_get0_key(key->rsa, &rsa_n, NULL, NULL); return EVP_PKEY_bits(k->pkey);
return BN_num_bits(rsa_n);
} }
static int static int
ssh_rsa_alloc(struct sshkey *k) ssh_rsa_alloc(struct sshkey *k)
{ {
if ((k->rsa = RSA_new()) == NULL) if ((k->pkey = EVP_PKEY_new()) == NULL)
return SSH_ERR_ALLOC_FAIL; return SSH_ERR_ALLOC_FAIL;
return 0; return 0;
} }
@ -53,29 +48,16 @@ ssh_rsa_alloc(struct sshkey *k)
static void static void
ssh_rsa_cleanup(struct sshkey *k) ssh_rsa_cleanup(struct sshkey *k)
{ {
RSA_free(k->rsa); EVP_PKEY_free(k->pkey);
k->rsa = NULL; k->pkey = NULL;
} }
static int static int
ssh_rsa_equal(const struct sshkey *a, const struct sshkey *b) ssh_rsa_equal(const struct sshkey *a, const struct sshkey *b)
{ {
const BIGNUM *rsa_e_a, *rsa_n_a; if (a->pkey == NULL || b->pkey == NULL)
const BIGNUM *rsa_e_b, *rsa_n_b;
if (a->rsa == NULL || b->rsa == NULL)
return 0; return 0;
RSA_get0_key(a->rsa, &rsa_n_a, &rsa_e_a, NULL); return EVP_PKEY_cmp(a->pkey, b->pkey) == 1;
RSA_get0_key(b->rsa, &rsa_n_b, &rsa_e_b, NULL);
if (rsa_e_a == NULL || rsa_e_b == NULL)
return 0;
if (rsa_n_a == NULL || rsa_n_b == NULL)
return 0;
if (BN_cmp(rsa_e_a, rsa_e_b) != 0)
return 0;
if (BN_cmp(rsa_n_a, rsa_n_b) != 0)
return 0;
return 1;
} }
static int static int
@ -84,10 +66,14 @@ ssh_rsa_serialize_public(const struct sshkey *key, struct sshbuf *b,
{ {
int r; int r;
const BIGNUM *rsa_n, *rsa_e; const BIGNUM *rsa_n, *rsa_e;
const RSA *rsa;
if (key->rsa == NULL) if (key->pkey == NULL)
return SSH_ERR_INVALID_ARGUMENT; return SSH_ERR_INVALID_ARGUMENT;
RSA_get0_key(key->rsa, &rsa_n, &rsa_e, NULL); if ((rsa = EVP_PKEY_get0_RSA(key->pkey)) == NULL)
return SSH_ERR_LIBCRYPTO_ERROR;
RSA_get0_key(rsa, &rsa_n, &rsa_e, NULL);
if ((r = sshbuf_put_bignum2(b, rsa_e)) != 0 || if ((r = sshbuf_put_bignum2(b, rsa_e)) != 0 ||
(r = sshbuf_put_bignum2(b, rsa_n)) != 0) (r = sshbuf_put_bignum2(b, rsa_n)) != 0)
return r; return r;
@ -101,10 +87,13 @@ ssh_rsa_serialize_private(const struct sshkey *key, struct sshbuf *b,
{ {
int r; int r;
const BIGNUM *rsa_n, *rsa_e, *rsa_d, *rsa_iqmp, *rsa_p, *rsa_q; const BIGNUM *rsa_n, *rsa_e, *rsa_d, *rsa_iqmp, *rsa_p, *rsa_q;
const RSA *rsa;
RSA_get0_key(key->rsa, &rsa_n, &rsa_e, &rsa_d); if ((rsa = EVP_PKEY_get0_RSA(key->pkey)) == NULL)
RSA_get0_factors(key->rsa, &rsa_p, &rsa_q); return SSH_ERR_LIBCRYPTO_ERROR;
RSA_get0_crt_params(key->rsa, NULL, NULL, &rsa_iqmp); RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d);
RSA_get0_factors(rsa, &rsa_p, &rsa_q);
RSA_get0_crt_params(rsa, NULL, NULL, &rsa_iqmp);
if (!sshkey_is_cert(key)) { if (!sshkey_is_cert(key)) {
/* Note: can't reuse ssh_rsa_serialize_public: e, n vs. n, e */ /* Note: can't reuse ssh_rsa_serialize_public: e, n vs. n, e */
@ -124,28 +113,36 @@ ssh_rsa_serialize_private(const struct sshkey *key, struct sshbuf *b,
static int static int
ssh_rsa_generate(struct sshkey *k, int bits) ssh_rsa_generate(struct sshkey *k, int bits)
{ {
RSA *private = NULL; EVP_PKEY_CTX *ctx = NULL;
BIGNUM *f4 = NULL; EVP_PKEY *res = NULL;
int ret = SSH_ERR_INTERNAL_ERROR; int ret = SSH_ERR_INTERNAL_ERROR;
if (bits < SSH_RSA_MINIMUM_MODULUS_SIZE || if (bits < SSH_RSA_MINIMUM_MODULUS_SIZE ||
bits > SSHBUF_MAX_BIGNUM * 8) bits > SSHBUF_MAX_BIGNUM * 8)
return SSH_ERR_KEY_LENGTH; return SSH_ERR_KEY_LENGTH;
if ((private = RSA_new()) == NULL || (f4 = BN_new()) == NULL) {
if ((ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL)) == NULL) {
ret = SSH_ERR_ALLOC_FAIL; ret = SSH_ERR_ALLOC_FAIL;
goto out; goto out;
} }
if (!BN_set_word(f4, RSA_F4) || if (EVP_PKEY_keygen_init(ctx) <= 0) {
!RSA_generate_key_ex(private, bits, f4, NULL)) {
ret = SSH_ERR_LIBCRYPTO_ERROR; ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out; goto out;
} }
k->rsa = private; if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) <= 0) {
private = NULL; ret = SSH_ERR_KEY_LENGTH;
goto out;
}
if (EVP_PKEY_keygen(ctx, &res) <= 0 || res == NULL) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
/* success */
k->pkey = res;
ret = 0; ret = 0;
out: out:
RSA_free(private); EVP_PKEY_CTX_free(ctx);
BN_free(f4);
return ret; return ret;
} }
@ -155,21 +152,33 @@ ssh_rsa_copy_public(const struct sshkey *from, struct sshkey *to)
const BIGNUM *rsa_n, *rsa_e; const BIGNUM *rsa_n, *rsa_e;
BIGNUM *rsa_n_dup = NULL, *rsa_e_dup = NULL; BIGNUM *rsa_n_dup = NULL, *rsa_e_dup = NULL;
int r = SSH_ERR_INTERNAL_ERROR; int r = SSH_ERR_INTERNAL_ERROR;
const RSA *rsa_from;
RSA *rsa_to = NULL;
RSA_get0_key(from->rsa, &rsa_n, &rsa_e, NULL); if ((rsa_from = EVP_PKEY_get0_RSA(from->pkey)) == NULL ||
(rsa_to = RSA_new()) == NULL)
return SSH_ERR_LIBCRYPTO_ERROR;
RSA_get0_key(rsa_from, &rsa_n, &rsa_e, NULL);
if ((rsa_n_dup = BN_dup(rsa_n)) == NULL || if ((rsa_n_dup = BN_dup(rsa_n)) == NULL ||
(rsa_e_dup = BN_dup(rsa_e)) == NULL) { (rsa_e_dup = BN_dup(rsa_e)) == NULL) {
r = SSH_ERR_ALLOC_FAIL; r = SSH_ERR_ALLOC_FAIL;
goto out; goto out;
} }
if (!RSA_set0_key(to->rsa, rsa_n_dup, rsa_e_dup, NULL)) { if (!RSA_set0_key(rsa_to, rsa_n_dup, rsa_e_dup, NULL)) {
r = SSH_ERR_LIBCRYPTO_ERROR; r = SSH_ERR_LIBCRYPTO_ERROR;
goto out; goto out;
} }
rsa_n_dup = rsa_e_dup = NULL; /* transferred */ rsa_n_dup = rsa_e_dup = NULL; /* transferred */
if (EVP_PKEY_set1_RSA(to->pkey, rsa_to) != 1) {
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
/* success */ /* success */
r = 0; r = 0;
out: out:
RSA_free(rsa_to);
BN_clear_free(rsa_n_dup); BN_clear_free(rsa_n_dup);
BN_clear_free(rsa_e_dup); BN_clear_free(rsa_e_dup);
return r; return r;
@ -181,25 +190,34 @@ ssh_rsa_deserialize_public(const char *ktype, struct sshbuf *b,
{ {
int ret = SSH_ERR_INTERNAL_ERROR; int ret = SSH_ERR_INTERNAL_ERROR;
BIGNUM *rsa_n = NULL, *rsa_e = NULL; BIGNUM *rsa_n = NULL, *rsa_e = NULL;
RSA *rsa = NULL;
if ((rsa = RSA_new()) == NULL)
return SSH_ERR_LIBCRYPTO_ERROR;
if (sshbuf_get_bignum2(b, &rsa_e) != 0 || if (sshbuf_get_bignum2(b, &rsa_e) != 0 ||
sshbuf_get_bignum2(b, &rsa_n) != 0) { sshbuf_get_bignum2(b, &rsa_n) != 0) {
ret = SSH_ERR_INVALID_FORMAT; ret = SSH_ERR_INVALID_FORMAT;
goto out; goto out;
} }
if (!RSA_set0_key(key->rsa, rsa_n, rsa_e, NULL)) { if (!RSA_set0_key(rsa, rsa_n, rsa_e, NULL)) {
ret = SSH_ERR_LIBCRYPTO_ERROR; ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out; goto out;
} }
rsa_n = rsa_e = NULL; /* transferred */ rsa_n = rsa_e = NULL; /* transferred */
if (EVP_PKEY_set1_RSA(key->pkey, rsa) != 1) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
if ((ret = sshkey_check_rsa_length(key, 0)) != 0) if ((ret = sshkey_check_rsa_length(key, 0)) != 0)
goto out; goto out;
#ifdef DEBUG_PK #ifdef DEBUG_PK
RSA_print_fp(stderr, key->rsa, 8); RSA_print_fp(stderr, rsa, 8);
#endif #endif
/* success */ /* success */
ret = 0; ret = 0;
out: out:
RSA_free(rsa);
BN_clear_free(rsa_n); BN_clear_free(rsa_n);
BN_clear_free(rsa_e); BN_clear_free(rsa_e);
return ret; return ret;
@ -212,13 +230,25 @@ ssh_rsa_deserialize_private(const char *ktype, struct sshbuf *b,
int r; int r;
BIGNUM *rsa_n = NULL, *rsa_e = NULL, *rsa_d = NULL; BIGNUM *rsa_n = NULL, *rsa_e = NULL, *rsa_d = NULL;
BIGNUM *rsa_iqmp = NULL, *rsa_p = NULL, *rsa_q = NULL; BIGNUM *rsa_iqmp = NULL, *rsa_p = NULL, *rsa_q = NULL;
BIGNUM *rsa_dmp1 = NULL, *rsa_dmq1 = NULL;
RSA *rsa = NULL;
/* Note: can't reuse ssh_rsa_deserialize_public: e, n vs. n, e */ if (sshkey_is_cert(key)) {
if (!sshkey_is_cert(key)) { /* sshkey_private_deserialize already has pubkey from cert */
if ((rsa = EVP_PKEY_get1_RSA(key->pkey)) == NULL) {
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
} else {
if ((rsa = RSA_new()) == NULL) {
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
/* Note: can't reuse ssh_rsa_deserialize_public: e,n vs. n,e */
if ((r = sshbuf_get_bignum2(b, &rsa_n)) != 0 || if ((r = sshbuf_get_bignum2(b, &rsa_n)) != 0 ||
(r = sshbuf_get_bignum2(b, &rsa_e)) != 0) (r = sshbuf_get_bignum2(b, &rsa_e)) != 0)
goto out; goto out;
if (!RSA_set0_key(key->rsa, rsa_n, rsa_e, NULL)) { if (!RSA_set0_key(rsa, rsa_n, rsa_e, NULL)) {
r = SSH_ERR_LIBCRYPTO_ERROR; r = SSH_ERR_LIBCRYPTO_ERROR;
goto out; goto out;
} }
@ -229,33 +259,46 @@ ssh_rsa_deserialize_private(const char *ktype, struct sshbuf *b,
(r = sshbuf_get_bignum2(b, &rsa_p)) != 0 || (r = sshbuf_get_bignum2(b, &rsa_p)) != 0 ||
(r = sshbuf_get_bignum2(b, &rsa_q)) != 0) (r = sshbuf_get_bignum2(b, &rsa_q)) != 0)
goto out; goto out;
if (!RSA_set0_key(key->rsa, NULL, NULL, rsa_d)) { if ((r = ssh_rsa_complete_crt_parameters(rsa_d, rsa_p, rsa_q,
rsa_iqmp, &rsa_dmp1, &rsa_dmq1)) != 0)
goto out;
if (!RSA_set0_key(rsa, NULL, NULL, rsa_d)) {
r = SSH_ERR_LIBCRYPTO_ERROR; r = SSH_ERR_LIBCRYPTO_ERROR;
goto out; goto out;
} }
rsa_d = NULL; /* transferred */ rsa_d = NULL; /* transferred */
if (!RSA_set0_factors(key->rsa, rsa_p, rsa_q)) { if (!RSA_set0_factors(rsa, rsa_p, rsa_q)) {
r = SSH_ERR_LIBCRYPTO_ERROR; r = SSH_ERR_LIBCRYPTO_ERROR;
goto out; goto out;
} }
rsa_p = rsa_q = NULL; /* transferred */ rsa_p = rsa_q = NULL; /* transferred */
if ((r = sshkey_check_rsa_length(key, 0)) != 0) if (!RSA_set0_crt_params(rsa, rsa_dmp1, rsa_dmq1, rsa_iqmp)) {
goto out;
if ((r = ssh_rsa_complete_crt_parameters(key, rsa_iqmp)) != 0)
goto out;
if (RSA_blinding_on(key->rsa, NULL) != 1) {
r = SSH_ERR_LIBCRYPTO_ERROR; r = SSH_ERR_LIBCRYPTO_ERROR;
goto out; goto out;
} }
rsa_dmp1 = rsa_dmq1 = rsa_iqmp = NULL;
if (RSA_blinding_on(rsa, NULL) != 1) {
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
if (EVP_PKEY_set1_RSA(key->pkey, rsa) != 1) {
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
if ((r = sshkey_check_rsa_length(key, 0)) != 0)
goto out;
/* success */ /* success */
r = 0; r = 0;
out: out:
RSA_free(rsa);
BN_clear_free(rsa_n); BN_clear_free(rsa_n);
BN_clear_free(rsa_e); BN_clear_free(rsa_e);
BN_clear_free(rsa_d); BN_clear_free(rsa_d);
BN_clear_free(rsa_p); BN_clear_free(rsa_p);
BN_clear_free(rsa_q); BN_clear_free(rsa_q);
BN_clear_free(rsa_iqmp); BN_clear_free(rsa_iqmp);
BN_clear_free(rsa_dmp1);
BN_clear_free(rsa_dmq1);
return r; return r;
} }
@ -310,45 +353,23 @@ rsa_hash_id_from_keyname(const char *alg)
return -1; return -1;
} }
static int
rsa_hash_alg_nid(int type)
{
switch (type) {
case SSH_DIGEST_SHA1:
return NID_sha1;
case SSH_DIGEST_SHA256:
return NID_sha256;
case SSH_DIGEST_SHA512:
return NID_sha512;
default:
return -1;
}
}
int int
ssh_rsa_complete_crt_parameters(struct sshkey *key, const BIGNUM *iqmp) ssh_rsa_complete_crt_parameters(const BIGNUM *rsa_d, const BIGNUM *rsa_p,
const BIGNUM *rsa_q, const BIGNUM *rsa_iqmp, BIGNUM **rsa_dmp1,
BIGNUM **rsa_dmq1)
{ {
const BIGNUM *rsa_p, *rsa_q, *rsa_d;
BIGNUM *aux = NULL, *d_consttime = NULL; BIGNUM *aux = NULL, *d_consttime = NULL;
BIGNUM *rsa_dmq1 = NULL, *rsa_dmp1 = NULL, *rsa_iqmp = NULL;
BN_CTX *ctx = NULL; BN_CTX *ctx = NULL;
int r; int r;
if (key == NULL || key->rsa == NULL || *rsa_dmq1 = *rsa_dmp1 = NULL;
sshkey_type_plain(key->type) != KEY_RSA)
return SSH_ERR_INVALID_ARGUMENT;
RSA_get0_key(key->rsa, NULL, NULL, &rsa_d);
RSA_get0_factors(key->rsa, &rsa_p, &rsa_q);
if ((ctx = BN_CTX_new()) == NULL) if ((ctx = BN_CTX_new()) == NULL)
return SSH_ERR_ALLOC_FAIL; return SSH_ERR_ALLOC_FAIL;
if ((aux = BN_new()) == NULL || if ((aux = BN_new()) == NULL ||
(rsa_dmq1 = BN_new()) == NULL || (*rsa_dmq1 = BN_new()) == NULL ||
(rsa_dmp1 = BN_new()) == NULL) (*rsa_dmp1 = BN_new()) == NULL)
return SSH_ERR_ALLOC_FAIL; return SSH_ERR_ALLOC_FAIL;
if ((d_consttime = BN_dup(rsa_d)) == NULL || if ((d_consttime = BN_dup(rsa_d)) == NULL) {
(rsa_iqmp = BN_dup(iqmp)) == NULL) {
r = SSH_ERR_ALLOC_FAIL; r = SSH_ERR_ALLOC_FAIL;
goto out; goto out;
} }
@ -356,25 +377,17 @@ ssh_rsa_complete_crt_parameters(struct sshkey *key, const BIGNUM *iqmp)
BN_set_flags(d_consttime, BN_FLG_CONSTTIME); BN_set_flags(d_consttime, BN_FLG_CONSTTIME);
if ((BN_sub(aux, rsa_q, BN_value_one()) == 0) || if ((BN_sub(aux, rsa_q, BN_value_one()) == 0) ||
(BN_mod(rsa_dmq1, d_consttime, aux, ctx) == 0) || (BN_mod(*rsa_dmq1, d_consttime, aux, ctx) == 0) ||
(BN_sub(aux, rsa_p, BN_value_one()) == 0) || (BN_sub(aux, rsa_p, BN_value_one()) == 0) ||
(BN_mod(rsa_dmp1, d_consttime, aux, ctx) == 0)) { (BN_mod(*rsa_dmp1, d_consttime, aux, ctx) == 0)) {
r = SSH_ERR_LIBCRYPTO_ERROR; r = SSH_ERR_LIBCRYPTO_ERROR;
goto out; goto out;
} }
if (!RSA_set0_crt_params(key->rsa, rsa_dmp1, rsa_dmq1, rsa_iqmp)) {
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
rsa_dmp1 = rsa_dmq1 = rsa_iqmp = NULL; /* transferred */
/* success */ /* success */
r = 0; r = 0;
out: out:
BN_clear_free(aux); BN_clear_free(aux);
BN_clear_free(d_consttime); BN_clear_free(d_consttime);
BN_clear_free(rsa_dmp1);
BN_clear_free(rsa_dmq1);
BN_clear_free(rsa_iqmp);
BN_CTX_free(ctx); BN_CTX_free(ctx);
return r; return r;
} }
@ -386,11 +399,10 @@ ssh_rsa_sign(struct sshkey *key,
const u_char *data, size_t datalen, const u_char *data, size_t datalen,
const char *alg, const char *sk_provider, const char *sk_pin, u_int compat) const char *alg, const char *sk_provider, const char *sk_pin, u_int compat)
{ {
const BIGNUM *rsa_n; u_char *sig = NULL;
u_char digest[SSH_DIGEST_MAX_LENGTH], *sig = NULL; size_t diff, len = 0;
size_t slen = 0; int slen = 0;
u_int hlen, len; int hash_alg, ret = SSH_ERR_INTERNAL_ERROR;
int nid, hash_alg, ret = SSH_ERR_INTERNAL_ERROR;
struct sshbuf *b = NULL; struct sshbuf *b = NULL;
if (lenp != NULL) if (lenp != NULL)
@ -402,41 +414,28 @@ ssh_rsa_sign(struct sshkey *key,
hash_alg = SSH_DIGEST_SHA1; hash_alg = SSH_DIGEST_SHA1;
else else
hash_alg = rsa_hash_id_from_keyname(alg); hash_alg = rsa_hash_id_from_keyname(alg);
if (key == NULL || key->rsa == NULL || hash_alg == -1 ||
if (key == NULL || key->pkey == NULL || hash_alg == -1 ||
sshkey_type_plain(key->type) != KEY_RSA) sshkey_type_plain(key->type) != KEY_RSA)
return SSH_ERR_INVALID_ARGUMENT; return SSH_ERR_INVALID_ARGUMENT;
RSA_get0_key(key->rsa, &rsa_n, NULL, NULL); slen = EVP_PKEY_size(key->pkey);
if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
return SSH_ERR_KEY_LENGTH;
slen = RSA_size(key->rsa);
if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM) if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM)
return SSH_ERR_INVALID_ARGUMENT; return SSH_ERR_INVALID_ARGUMENT;
if (EVP_PKEY_bits(key->pkey) < SSH_RSA_MINIMUM_MODULUS_SIZE)
return SSH_ERR_KEY_LENGTH;
/* hash the data */ if ((ret = sshkey_pkey_digest_sign(key->pkey, hash_alg, &sig, &len,
nid = rsa_hash_alg_nid(hash_alg); data, datalen)) < 0)
if ((hlen = ssh_digest_bytes(hash_alg)) == 0)
return SSH_ERR_INTERNAL_ERROR;
if ((ret = ssh_digest_memory(hash_alg, data, datalen,
digest, sizeof(digest))) != 0)
goto out; goto out;
if (len < (size_t)slen) {
if ((sig = malloc(slen)) == NULL) { diff = slen - len;
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
if (RSA_sign(nid, digest, hlen, sig, &len, key->rsa) != 1) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
if (len < slen) {
size_t diff = slen - len;
memmove(sig + diff, sig, len); memmove(sig + diff, sig, len);
explicit_bzero(sig, diff); explicit_bzero(sig, diff);
} else if (len > slen) { } else if (len > (size_t)slen) {
ret = SSH_ERR_INTERNAL_ERROR; ret = SSH_ERR_INTERNAL_ERROR;
goto out; goto out;
} }
/* encode signature */ /* encode signature */
if ((b = sshbuf_new()) == NULL) { if ((b = sshbuf_new()) == NULL) {
ret = SSH_ERR_ALLOC_FAIL; ret = SSH_ERR_ALLOC_FAIL;
@ -457,7 +456,6 @@ ssh_rsa_sign(struct sshkey *key,
*lenp = len; *lenp = len;
ret = 0; ret = 0;
out: out:
explicit_bzero(digest, sizeof(digest));
freezero(sig, slen); freezero(sig, slen);
sshbuf_free(b); sshbuf_free(b);
return ret; return ret;
@ -469,19 +467,17 @@ ssh_rsa_verify(const struct sshkey *key,
const u_char *data, size_t dlen, const char *alg, u_int compat, const u_char *data, size_t dlen, const char *alg, u_int compat,
struct sshkey_sig_details **detailsp) struct sshkey_sig_details **detailsp)
{ {
const BIGNUM *rsa_n;
char *sigtype = NULL; char *sigtype = NULL;
int hash_alg, want_alg, ret = SSH_ERR_INTERNAL_ERROR; int hash_alg, want_alg, ret = SSH_ERR_INTERNAL_ERROR;
size_t len = 0, diff, modlen, hlen; size_t len = 0, diff, modlen, rsasize;
struct sshbuf *b = NULL; struct sshbuf *b = NULL;
u_char digest[SSH_DIGEST_MAX_LENGTH], *osigblob, *sigblob = NULL; u_char digest[SSH_DIGEST_MAX_LENGTH], *osigblob, *sigblob = NULL;
if (key == NULL || key->rsa == NULL || if (key == NULL || key->pkey == NULL ||
sshkey_type_plain(key->type) != KEY_RSA || sshkey_type_plain(key->type) != KEY_RSA ||
sig == NULL || siglen == 0) sig == NULL || siglen == 0)
return SSH_ERR_INVALID_ARGUMENT; return SSH_ERR_INVALID_ARGUMENT;
RSA_get0_key(key->rsa, &rsa_n, NULL, NULL); if (EVP_PKEY_bits(key->pkey) < SSH_RSA_MINIMUM_MODULUS_SIZE)
if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
return SSH_ERR_KEY_LENGTH; return SSH_ERR_KEY_LENGTH;
if ((b = sshbuf_from(sig, siglen)) == NULL) if ((b = sshbuf_from(sig, siglen)) == NULL)
@ -517,7 +513,7 @@ ssh_rsa_verify(const struct sshkey *key,
goto out; goto out;
} }
/* RSA_verify expects a signature of RSA_size */ /* RSA_verify expects a signature of RSA_size */
modlen = RSA_size(key->rsa); modlen = EVP_PKEY_size(key->pkey);
if (len > modlen) { if (len > modlen) {
ret = SSH_ERR_KEY_BITS_MISMATCH; ret = SSH_ERR_KEY_BITS_MISMATCH;
goto out; goto out;
@ -533,16 +529,16 @@ ssh_rsa_verify(const struct sshkey *key,
explicit_bzero(sigblob, diff); explicit_bzero(sigblob, diff);
len = modlen; len = modlen;
} }
if ((hlen = ssh_digest_bytes(hash_alg)) == 0) {
ret = SSH_ERR_INTERNAL_ERROR; rsasize = EVP_PKEY_size(key->pkey);
if (rsasize <= 0 || rsasize > SSHBUF_MAX_BIGNUM ||
len == 0 || len > rsasize) {
ret = SSH_ERR_INVALID_ARGUMENT;
goto out; goto out;
} }
if ((ret = ssh_digest_memory(hash_alg, data, dlen, ret = sshkey_pkey_digest_verify(key->pkey, hash_alg, data, dlen,
digest, sizeof(digest))) != 0) sigblob, len);
goto out;
ret = openssh_RSA_verify(hash_alg, digest, hlen, sigblob, len,
key->rsa);
out: out:
freezero(sigblob, len); freezero(sigblob, len);
free(sigtype); free(sigtype);
@ -551,125 +547,6 @@ ssh_rsa_verify(const struct sshkey *key,
return ret; return ret;
} }
/*
* See:
* http://www.rsasecurity.com/rsalabs/pkcs/pkcs-1/
* ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.asn
*/
/*
* id-sha1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
* oiw(14) secsig(3) algorithms(2) 26 }
*/
static const u_char id_sha1[] = {
0x30, 0x21, /* type Sequence, length 0x21 (33) */
0x30, 0x09, /* type Sequence, length 0x09 */
0x06, 0x05, /* type OID, length 0x05 */
0x2b, 0x0e, 0x03, 0x02, 0x1a, /* id-sha1 OID */
0x05, 0x00, /* NULL */
0x04, 0x14 /* Octet string, length 0x14 (20), followed by sha1 hash */
};
/*
* See http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html
* id-sha256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840)
* organization(1) gov(101) csor(3) nistAlgorithm(4) hashAlgs(2)
* id-sha256(1) }
*/
static const u_char id_sha256[] = {
0x30, 0x31, /* type Sequence, length 0x31 (49) */
0x30, 0x0d, /* type Sequence, length 0x0d (13) */
0x06, 0x09, /* type OID, length 0x09 */
0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, /* id-sha256 */
0x05, 0x00, /* NULL */
0x04, 0x20 /* Octet string, length 0x20 (32), followed by sha256 hash */
};
/*
* See http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html
* id-sha512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840)
* organization(1) gov(101) csor(3) nistAlgorithm(4) hashAlgs(2)
* id-sha256(3) }
*/
static const u_char id_sha512[] = {
0x30, 0x51, /* type Sequence, length 0x51 (81) */
0x30, 0x0d, /* type Sequence, length 0x0d (13) */
0x06, 0x09, /* type OID, length 0x09 */
0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, /* id-sha512 */
0x05, 0x00, /* NULL */
0x04, 0x40 /* Octet string, length 0x40 (64), followed by sha512 hash */
};
static int
rsa_hash_alg_oid(int hash_alg, const u_char **oidp, size_t *oidlenp)
{
switch (hash_alg) {
case SSH_DIGEST_SHA1:
*oidp = id_sha1;
*oidlenp = sizeof(id_sha1);
break;
case SSH_DIGEST_SHA256:
*oidp = id_sha256;
*oidlenp = sizeof(id_sha256);
break;
case SSH_DIGEST_SHA512:
*oidp = id_sha512;
*oidlenp = sizeof(id_sha512);
break;
default:
return SSH_ERR_INVALID_ARGUMENT;
}
return 0;
}
static int
openssh_RSA_verify(int hash_alg, u_char *hash, size_t hashlen,
u_char *sigbuf, size_t siglen, RSA *rsa)
{
size_t rsasize = 0, oidlen = 0, hlen = 0;
int ret, len, oidmatch, hashmatch;
const u_char *oid = NULL;
u_char *decrypted = NULL;
if ((ret = rsa_hash_alg_oid(hash_alg, &oid, &oidlen)) != 0)
return ret;
ret = SSH_ERR_INTERNAL_ERROR;
hlen = ssh_digest_bytes(hash_alg);
if (hashlen != hlen) {
ret = SSH_ERR_INVALID_ARGUMENT;
goto done;
}
rsasize = RSA_size(rsa);
if (rsasize <= 0 || rsasize > SSHBUF_MAX_BIGNUM ||
siglen == 0 || siglen > rsasize) {
ret = SSH_ERR_INVALID_ARGUMENT;
goto done;
}
if ((decrypted = malloc(rsasize)) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
goto done;
}
if ((len = RSA_public_decrypt(siglen, sigbuf, decrypted, rsa,
RSA_PKCS1_PADDING)) < 0) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto done;
}
if (len < 0 || (size_t)len != hlen + oidlen) {
ret = SSH_ERR_INVALID_FORMAT;
goto done;
}
oidmatch = timingsafe_bcmp(decrypted, oid, oidlen) == 0;
hashmatch = timingsafe_bcmp(decrypted + oidlen, hash, hlen) == 0;
if (!oidmatch || !hashmatch) {
ret = SSH_ERR_SIGNATURE_INVALID;
goto done;
}
ret = 0;
done:
freezero(decrypted, rsasize);
return ret;
}
static const struct sshkey_impl_funcs sshkey_rsa_funcs = { static const struct sshkey_impl_funcs sshkey_rsa_funcs = {
/* .size = */ ssh_rsa_size, /* .size = */ ssh_rsa_size,
/* .alloc = */ ssh_rsa_alloc, /* .alloc = */ ssh_rsa_alloc,

View file

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-sk.c,v 1.40 2023/07/19 14:02:27 djm Exp $ */ /* $OpenBSD: ssh-sk.c,v 1.41 2024/08/15 00:51:51 djm Exp $ */
/* /*
* Copyright (c) 2019 Google LLC * Copyright (c) 2019 Google LLC
* *
@ -26,6 +26,7 @@
#ifdef WITH_OPENSSL #ifdef WITH_OPENSSL
#include <openssl/objects.h> #include <openssl/objects.h>
#include <openssl/ec.h> #include <openssl/ec.h>
#include <openssl/evp.h>
#endif /* WITH_OPENSSL */ #endif /* WITH_OPENSSL */
#include "log.h" #include "log.h"
@ -188,7 +189,9 @@ sshsk_ecdsa_assemble(struct sk_enroll_response *resp, struct sshkey **keyp)
{ {
struct sshkey *key = NULL; struct sshkey *key = NULL;
struct sshbuf *b = NULL; struct sshbuf *b = NULL;
EC_KEY *ecdsa = NULL;
EC_POINT *q = NULL; EC_POINT *q = NULL;
const EC_GROUP *g = NULL;
int r; int r;
*keyp = NULL; *keyp = NULL;
@ -198,8 +201,9 @@ sshsk_ecdsa_assemble(struct sk_enroll_response *resp, struct sshkey **keyp)
goto out; goto out;
} }
key->ecdsa_nid = NID_X9_62_prime256v1; key->ecdsa_nid = NID_X9_62_prime256v1;
if ((key->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid)) == NULL || if ((ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid)) == NULL ||
(q = EC_POINT_new(EC_KEY_get0_group(key->ecdsa))) == NULL || (g = EC_KEY_get0_group(ecdsa)) == NULL ||
(q = EC_POINT_new(g)) == NULL ||
(b = sshbuf_new()) == NULL) { (b = sshbuf_new()) == NULL) {
error_f("allocation failed"); error_f("allocation failed");
r = SSH_ERR_ALLOC_FAIL; r = SSH_ERR_ALLOC_FAIL;
@ -210,30 +214,41 @@ sshsk_ecdsa_assemble(struct sk_enroll_response *resp, struct sshkey **keyp)
error_fr(r, "sshbuf_put_string"); error_fr(r, "sshbuf_put_string");
goto out; goto out;
} }
if ((r = sshbuf_get_ec(b, q, EC_KEY_get0_group(key->ecdsa))) != 0) { if ((r = sshbuf_get_ec(b, q, g)) != 0) {
error_fr(r, "parse"); error_fr(r, "parse");
r = SSH_ERR_INVALID_FORMAT; r = SSH_ERR_INVALID_FORMAT;
goto out; goto out;
} }
if (sshkey_ec_validate_public(EC_KEY_get0_group(key->ecdsa), q) != 0) { if (sshkey_ec_validate_public(g, q) != 0) {
error("Authenticator returned invalid ECDSA key"); error("Authenticator returned invalid ECDSA key");
r = SSH_ERR_KEY_INVALID_EC_VALUE; r = SSH_ERR_KEY_INVALID_EC_VALUE;
goto out; goto out;
} }
if (EC_KEY_set_public_key(key->ecdsa, q) != 1) { if (EC_KEY_set_public_key(ecdsa, q) != 1) {
/* XXX assume it is a allocation error */ /* XXX assume it is a allocation error */
error_f("allocation failed"); error_f("allocation failed");
r = SSH_ERR_ALLOC_FAIL; r = SSH_ERR_ALLOC_FAIL;
goto out; goto out;
} }
if ((key->pkey = EVP_PKEY_new()) == NULL) {
error_f("allocation failed");
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
if (EVP_PKEY_set1_EC_KEY(key->pkey, ecdsa) != 1) {
error_f("Assigning EC_KEY failed");
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
/* success */ /* success */
*keyp = key; *keyp = key;
key = NULL; /* transferred */ key = NULL; /* transferred */
r = 0; r = 0;
out: out:
EC_POINT_free(q);
sshkey_free(key); sshkey_free(key);
sshbuf_free(b); sshbuf_free(b);
EC_KEY_free(ecdsa);
EC_POINT_free(q);
return r; return r;
} }
#endif /* WITH_OPENSSL */ #endif /* WITH_OPENSSL */

View file

@ -1,4 +1,4 @@
/* $OpenBSD: sshbuf-getput-crypto.c,v 1.11 2024/02/01 02:37:33 djm Exp $ */ /* $OpenBSD: sshbuf-getput-crypto.c,v 1.12 2024/08/15 00:51:51 djm Exp $ */
/* /*
* Copyright (c) 2011 Damien Miller * Copyright (c) 2011 Damien Miller
* *
@ -169,3 +169,12 @@ sshbuf_put_eckey(struct sshbuf *buf, const EC_KEY *v)
EC_KEY_get0_group(v)); EC_KEY_get0_group(v));
} }
int
sshbuf_put_ec_pkey(struct sshbuf *buf, EVP_PKEY *pkey)
{
const EC_KEY *ec;
if ((ec = EVP_PKEY_get0_EC_KEY(pkey)) == NULL)
return SSH_ERR_LIBCRYPTO_ERROR;
return sshbuf_put_eckey(buf, ec);
}

View file

@ -1,4 +1,4 @@
/* $OpenBSD: sshbuf.h,v 1.28 2022/12/02 04:40:27 djm Exp $ */ /* $OpenBSD: sshbuf.h,v 1.29 2024/08/15 00:51:51 djm Exp $ */
/* /*
* Copyright (c) 2011 Damien Miller * Copyright (c) 2011 Damien Miller
* *
@ -26,11 +26,13 @@
#include <openssl/bn.h> #include <openssl/bn.h>
#include <openssl/ec.h> #include <openssl/ec.h>
#include <openssl/ecdsa.h> #include <openssl/ecdsa.h>
#include <openssl/evp.h>
#else /* OPENSSL */ #else /* OPENSSL */
#define BIGNUM void #define BIGNUM void
#define EC_KEY void #define EC_KEY void
#define EC_GROUP void #define EC_GROUP void
#define EC_POINT void #define EC_POINT void
#define EVP_PKEY void
#endif /* WITH_OPENSSL */ #endif /* WITH_OPENSSL */
#define SSHBUF_SIZE_MAX 0x8000000 /* Hard maximum size */ #define SSHBUF_SIZE_MAX 0x8000000 /* Hard maximum size */
@ -226,6 +228,7 @@ int sshbuf_get_ec(struct sshbuf *buf, EC_POINT *v, const EC_GROUP *g);
int sshbuf_get_eckey(struct sshbuf *buf, EC_KEY *v); int sshbuf_get_eckey(struct sshbuf *buf, EC_KEY *v);
int sshbuf_put_ec(struct sshbuf *buf, const EC_POINT *v, const EC_GROUP *g); int sshbuf_put_ec(struct sshbuf *buf, const EC_POINT *v, const EC_GROUP *g);
int sshbuf_put_eckey(struct sshbuf *buf, const EC_KEY *v); int sshbuf_put_eckey(struct sshbuf *buf, const EC_KEY *v);
int sshbuf_put_ec_pkey(struct sshbuf *buf, EVP_PKEY *pkey);
/* Dump the contents of the buffer in a human-readable format */ /* Dump the contents of the buffer in a human-readable format */
void sshbuf_dump(const struct sshbuf *buf, FILE *f); void sshbuf_dump(const struct sshbuf *buf, FILE *f);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: sshkey.c,v 1.142 2024/01/11 01:45:36 djm Exp $ */ /* $OpenBSD: sshkey.c,v 1.143 2024/08/15 00:51:51 djm Exp $ */
/* /*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
* Copyright (c) 2008 Alexander von Gernler. All rights reserved. * Copyright (c) 2008 Alexander von Gernler. All rights reserved.
@ -460,6 +460,98 @@ sshkey_type_certified(int type)
} }
#ifdef WITH_OPENSSL #ifdef WITH_OPENSSL
static const EVP_MD *
ssh_digest_to_md(int hash_alg)
{
switch (hash_alg) {
case SSH_DIGEST_SHA1:
return EVP_sha1();
case SSH_DIGEST_SHA256:
return EVP_sha256();
case SSH_DIGEST_SHA384:
return EVP_sha384();
case SSH_DIGEST_SHA512:
return EVP_sha512();
}
return NULL;
}
int
sshkey_pkey_digest_sign(EVP_PKEY *pkey, int hash_alg, u_char **sigp,
size_t *lenp, const u_char *data, size_t datalen)
{
EVP_MD_CTX *ctx = NULL;
u_char *sig = NULL;
int ret;
size_t slen;
const EVP_MD *evpmd;
*sigp = NULL;
*lenp = 0;
slen = EVP_PKEY_size(pkey);
if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM ||
(evpmd = ssh_digest_to_md(hash_alg)) == NULL)
return SSH_ERR_INVALID_ARGUMENT;
if ((sig = malloc(slen)) == NULL)
return SSH_ERR_ALLOC_FAIL;
if ((ctx = EVP_MD_CTX_new()) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
if (EVP_DigestSignInit(ctx, NULL, evpmd, NULL, pkey) != 1 ||
EVP_DigestSign(ctx, sig, &slen, data, datalen) != 1) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
*sigp = sig;
*lenp = slen;
/* Now owned by the caller */
sig = NULL;
ret = 0;
out:
EVP_MD_CTX_free(ctx);
free(sig);
return ret;
}
int
sshkey_pkey_digest_verify(EVP_PKEY *pkey, int hash_alg, const u_char *data,
size_t datalen, u_char *sigbuf, size_t siglen)
{
EVP_MD_CTX *ctx = NULL;
int ret = SSH_ERR_INTERNAL_ERROR;
const EVP_MD *evpmd;
if ((evpmd = ssh_digest_to_md(hash_alg)) == NULL)
return SSH_ERR_INVALID_ARGUMENT;
if ((ctx = EVP_MD_CTX_new()) == NULL)
return SSH_ERR_ALLOC_FAIL;
if (EVP_DigestVerifyInit(ctx, NULL, evpmd, NULL, pkey) != 1) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
switch (EVP_DigestVerify(ctx, sigbuf, siglen, data, datalen)) {
case 1:
ret = 0;
break;
case 0:
ret = SSH_ERR_SIGNATURE_INVALID;
break;
default:
ret = SSH_ERR_LIBCRYPTO_ERROR;
break;
}
out:
EVP_MD_CTX_free(ctx);
return ret;
}
/* XXX: these are really begging for a table-driven approach */ /* XXX: these are really begging for a table-driven approach */
int int
sshkey_curve_name_to_nid(const char *name) sshkey_curve_name_to_nid(const char *name)
@ -1302,14 +1394,12 @@ int
sshkey_check_rsa_length(const struct sshkey *k, int min_size) sshkey_check_rsa_length(const struct sshkey *k, int min_size)
{ {
#ifdef WITH_OPENSSL #ifdef WITH_OPENSSL
const BIGNUM *rsa_n;
int nbits; int nbits;
if (k == NULL || k->rsa == NULL || if (k == NULL || k->pkey == NULL ||
(k->type != KEY_RSA && k->type != KEY_RSA_CERT)) (k->type != KEY_RSA && k->type != KEY_RSA_CERT))
return 0; return 0;
RSA_get0_key(k->rsa, &rsa_n, NULL, NULL); nbits = EVP_PKEY_bits(k->pkey);
nbits = BN_num_bits(rsa_n);
if (nbits < SSH_RSA_MINIMUM_MODULUS_SIZE || if (nbits < SSH_RSA_MINIMUM_MODULUS_SIZE ||
(min_size > 0 && nbits < min_size)) (min_size > 0 && nbits < min_size))
return SSH_ERR_KEY_LENGTH; return SSH_ERR_KEY_LENGTH;
@ -1319,45 +1409,22 @@ sshkey_check_rsa_length(const struct sshkey *k, int min_size)
#ifdef WITH_OPENSSL #ifdef WITH_OPENSSL
int int
sshkey_ecdsa_key_to_nid(EC_KEY *k) sshkey_ecdsa_key_to_nid(const EC_KEY *k)
{ {
EC_GROUP *eg; const EC_GROUP *g;
int nids[] = {
NID_X9_62_prime256v1,
NID_secp384r1,
NID_secp521r1,
-1
};
int nid; int nid;
u_int i;
const EC_GROUP *g = EC_KEY_get0_group(k);
/* if (k == NULL || (g = EC_KEY_get0_group(k)) == NULL)
* The group may be stored in a ASN.1 encoded private key in one of two return -1;
* ways: as a "named group", which is reconstituted by ASN.1 object ID if ((nid = EC_GROUP_get_curve_name(g)) <= 0)
* or explicit group parameters encoded into the key blob. Only the return -1;
* "named group" case sets the group NID for us, but we can figure return nid;
* it out for the other case by comparing against all the groups that }
* are supported.
*/ int
if ((nid = EC_GROUP_get_curve_name(g)) > 0) sshkey_ecdsa_pkey_to_nid(EVP_PKEY *pkey)
return nid; {
for (i = 0; nids[i] != -1; i++) { return sshkey_ecdsa_key_to_nid(EVP_PKEY_get0_EC_KEY(pkey));
if ((eg = EC_GROUP_new_by_curve_name(nids[i])) == NULL)
return -1;
if (EC_GROUP_cmp(g, eg, NULL) == 0)
break;
EC_GROUP_free(eg);
}
if (nids[i] != -1) {
/* Use the group with the NID attached */
EC_GROUP_set_asn1_flag(eg, OPENSSL_EC_NAMED_CURVE);
if (EC_KEY_set_group(k, eg) != 1) {
EC_GROUP_free(eg);
return -1;
}
}
return nids[i];
} }
#endif /* WITH_OPENSSL */ #endif /* WITH_OPENSSL */
@ -3193,10 +3260,6 @@ sshkey_private_to_blob_pem_pkcs8(struct sshkey *key, struct sshbuf *buf,
r = SSH_ERR_ALLOC_FAIL; r = SSH_ERR_ALLOC_FAIL;
goto out; goto out;
} }
if (format == SSHKEY_PRIVATE_PKCS8 && (pkey = EVP_PKEY_new()) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
if ((r = sshkey_unshield_private(key)) != 0) if ((r = sshkey_unshield_private(key)) != 0)
goto out; goto out;
@ -3207,24 +3270,34 @@ sshkey_private_to_blob_pem_pkcs8(struct sshkey *key, struct sshbuf *buf,
success = PEM_write_bio_DSAPrivateKey(bio, key->dsa, success = PEM_write_bio_DSAPrivateKey(bio, key->dsa,
cipher, passphrase, len, NULL, NULL); cipher, passphrase, len, NULL, NULL);
} else { } else {
if ((pkey = EVP_PKEY_new()) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
success = EVP_PKEY_set1_DSA(pkey, key->dsa); success = EVP_PKEY_set1_DSA(pkey, key->dsa);
} }
break; break;
#endif #endif
case KEY_ECDSA: case KEY_ECDSA:
if (format == SSHKEY_PRIVATE_PEM) { if (format == SSHKEY_PRIVATE_PEM) {
success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa, success = PEM_write_bio_ECPrivateKey(bio,
EVP_PKEY_get0_EC_KEY(key->pkey),
cipher, passphrase, len, NULL, NULL); cipher, passphrase, len, NULL, NULL);
} else { } else {
success = EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa); pkey = key->pkey;
EVP_PKEY_up_ref(key->pkey);
success = 1;
} }
break; break;
case KEY_RSA: case KEY_RSA:
if (format == SSHKEY_PRIVATE_PEM) { if (format == SSHKEY_PRIVATE_PEM) {
success = PEM_write_bio_RSAPrivateKey(bio, key->rsa, success = PEM_write_bio_RSAPrivateKey(bio,
EVP_PKEY_get0_RSA(key->pkey),
cipher, passphrase, len, NULL, NULL); cipher, passphrase, len, NULL, NULL);
} else { } else {
success = EVP_PKEY_set1_RSA(pkey, key->rsa); pkey = key->pkey;
EVP_PKEY_up_ref(key->pkey);
success = 1;
} }
break; break;
default: default:
@ -3373,6 +3446,8 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
struct sshkey *prv = NULL; struct sshkey *prv = NULL;
BIO *bio = NULL; BIO *bio = NULL;
int r; int r;
RSA *rsa = NULL;
EC_KEY *ecdsa = NULL;
if (keyp != NULL) if (keyp != NULL)
*keyp = NULL; *keyp = NULL;
@ -3406,15 +3481,21 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
r = SSH_ERR_ALLOC_FAIL; r = SSH_ERR_ALLOC_FAIL;
goto out; goto out;
} }
prv->rsa = EVP_PKEY_get1_RSA(pk); if ((rsa = EVP_PKEY_get1_RSA(pk)) == NULL) {
prv->type = KEY_RSA;
#ifdef DEBUG_PK
RSA_print_fp(stderr, prv->rsa, 8);
#endif
if (RSA_blinding_on(prv->rsa, NULL) != 1) {
r = SSH_ERR_LIBCRYPTO_ERROR; r = SSH_ERR_LIBCRYPTO_ERROR;
goto out; goto out;
} }
prv->type = KEY_RSA;
#ifdef DEBUG_PK
RSA_print_fp(stderr, rsa, 8);
#endif
if (RSA_blinding_on(rsa, NULL) != 1 ||
EVP_PKEY_set1_RSA(pk, rsa) != 1) {
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
EVP_PKEY_up_ref(pk);
prv->pkey = pk;
if ((r = sshkey_check_rsa_length(prv, 0)) != 0) if ((r = sshkey_check_rsa_length(prv, 0)) != 0)
goto out; goto out;
#ifdef WITH_DSA #ifdef WITH_DSA
@ -3436,20 +3517,24 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
r = SSH_ERR_ALLOC_FAIL; r = SSH_ERR_ALLOC_FAIL;
goto out; goto out;
} }
prv->ecdsa = EVP_PKEY_get1_EC_KEY(pk); if ((prv->ecdsa_nid = sshkey_ecdsa_fixup_group(pk)) == -1 ||
(ecdsa = EVP_PKEY_get1_EC_KEY(pk)) == NULL) {
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
prv->type = KEY_ECDSA; prv->type = KEY_ECDSA;
prv->ecdsa_nid = sshkey_ecdsa_key_to_nid(prv->ecdsa); if (sshkey_curve_nid_to_name(prv->ecdsa_nid) == NULL ||
if (prv->ecdsa_nid == -1 || sshkey_ec_validate_public(EC_KEY_get0_group(ecdsa),
sshkey_curve_nid_to_name(prv->ecdsa_nid) == NULL || EC_KEY_get0_public_key(ecdsa)) != 0 ||
sshkey_ec_validate_public(EC_KEY_get0_group(prv->ecdsa), sshkey_ec_validate_private(ecdsa) != 0) {
EC_KEY_get0_public_key(prv->ecdsa)) != 0 ||
sshkey_ec_validate_private(prv->ecdsa) != 0) {
r = SSH_ERR_INVALID_FORMAT; r = SSH_ERR_INVALID_FORMAT;
goto out; goto out;
} }
EVP_PKEY_up_ref(pk);
prv->pkey = pk;
#ifdef DEBUG_PK #ifdef DEBUG_PK
if (prv != NULL && prv->ecdsa != NULL) if (prv != NULL && prv->pkey != NULL)
sshkey_dump_ec_key(prv->ecdsa); sshkey_dump_ec_key(EVP_PKEY_get0_EC_KEY(prv->pkey));
#endif #endif
} else if (EVP_PKEY_base_id(pk) == EVP_PKEY_ED25519 && } else if (EVP_PKEY_base_id(pk) == EVP_PKEY_ED25519 &&
(type == KEY_UNSPEC || type == KEY_ED25519)) { (type == KEY_UNSPEC || type == KEY_ED25519)) {
@ -3498,6 +3583,8 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
out: out:
BIO_free(bio); BIO_free(bio);
EVP_PKEY_free(pk); EVP_PKEY_free(pk);
RSA_free(rsa);
EC_KEY_free(ecdsa);
sshkey_free(prv); sshkey_free(prv);
return r; return r;
} }

View file

@ -1,4 +1,4 @@
/* $OpenBSD: sshkey.h,v 1.63 2024/05/17 06:42:04 jsg Exp $ */ /* $OpenBSD: sshkey.h,v 1.64 2024/08/15 00:51:51 djm Exp $ */
/* /*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@ -33,6 +33,7 @@
#include <openssl/dsa.h> #include <openssl/dsa.h>
#include <openssl/ec.h> #include <openssl/ec.h>
#include <openssl/ecdsa.h> #include <openssl/ecdsa.h>
#include <openssl/evp.h>
#define SSH_OPENSSL_VERSION OpenSSL_version(OPENSSL_VERSION) #define SSH_OPENSSL_VERSION OpenSSL_version(OPENSSL_VERSION)
#else /* OPENSSL */ #else /* OPENSSL */
#define BIGNUM void #define BIGNUM void
@ -41,6 +42,7 @@
#define EC_KEY void #define EC_KEY void
#define EC_GROUP void #define EC_GROUP void
#define EC_POINT void #define EC_POINT void
#define EVP_PKEY void
#define SSH_OPENSSL_VERSION "without OpenSSL" #define SSH_OPENSSL_VERSION "without OpenSSL"
#endif /* WITH_OPENSSL */ #endif /* WITH_OPENSSL */
@ -119,13 +121,12 @@ struct sshkey_cert {
struct sshkey { struct sshkey {
int type; int type;
int flags; int flags;
/* KEY_RSA */
RSA *rsa;
/* KEY_DSA */ /* KEY_DSA */
DSA *dsa; DSA *dsa;
/* KEY_ECDSA and KEY_ECDSA_SK */ /* KEY_ECDSA and KEY_ECDSA_SK */
int ecdsa_nid; /* NID of curve */ int ecdsa_nid; /* NID of curve */
EC_KEY *ecdsa; /* libcrypto-backed keys */
EVP_PKEY *pkey;
/* KEY_ED25519 and KEY_ED25519_SK */ /* KEY_ED25519 and KEY_ED25519_SK */
u_char *ed25519_sk; u_char *ed25519_sk;
u_char *ed25519_pk; u_char *ed25519_pk;
@ -252,7 +253,8 @@ int sshkey_curve_name_to_nid(const char *);
const char * sshkey_curve_nid_to_name(int); const char * sshkey_curve_nid_to_name(int);
u_int sshkey_curve_nid_to_bits(int); u_int sshkey_curve_nid_to_bits(int);
int sshkey_ecdsa_bits_to_nid(int); int sshkey_ecdsa_bits_to_nid(int);
int sshkey_ecdsa_key_to_nid(EC_KEY *); int sshkey_ecdsa_key_to_nid(const EC_KEY *);
int sshkey_ecdsa_pkey_to_nid(EVP_PKEY *);
int sshkey_ec_nid_to_hash_alg(int nid); int sshkey_ec_nid_to_hash_alg(int nid);
int sshkey_ec_validate_public(const EC_GROUP *, const EC_POINT *); int sshkey_ec_validate_public(const EC_GROUP *, const EC_POINT *);
int sshkey_ec_validate_private(const EC_KEY *); int sshkey_ec_validate_private(const EC_KEY *);
@ -281,6 +283,12 @@ int sshkey_check_sigtype(const u_char *, size_t, const char *);
const char *sshkey_sigalg_by_name(const char *); const char *sshkey_sigalg_by_name(const char *);
int sshkey_get_sigtype(const u_char *, size_t, char **); int sshkey_get_sigtype(const u_char *, size_t, char **);
/* Signing and verification backend for libcrypto-backed keys */
int sshkey_pkey_digest_sign(EVP_PKEY*, int, u_char **,
size_t *, const u_char *, size_t);
int sshkey_pkey_digest_verify(EVP_PKEY *, int, const u_char *,
size_t, u_char *, size_t);
/* for debug */ /* for debug */
void sshkey_dump_ec_point(const EC_GROUP *, const EC_POINT *); void sshkey_dump_ec_point(const EC_GROUP *, const EC_POINT *);
void sshkey_dump_ec_key(const EC_KEY *); void sshkey_dump_ec_key(const EC_KEY *);
@ -304,7 +312,8 @@ int sshkey_parse_pubkey_from_private_fileblob_type(struct sshbuf *blob,
int sshkey_check_rsa_length(const struct sshkey *, int); int sshkey_check_rsa_length(const struct sshkey *, int);
/* XXX should be internal, but used by ssh-keygen */ /* XXX should be internal, but used by ssh-keygen */
int ssh_rsa_complete_crt_parameters(struct sshkey *, const BIGNUM *); int ssh_rsa_complete_crt_parameters(const BIGNUM *, const BIGNUM *,
const BIGNUM *, const BIGNUM *, BIGNUM **, BIGNUM **);
/* stateful keys (e.g. XMSS) */ /* stateful keys (e.g. XMSS) */
int sshkey_set_filename(struct sshkey *, const char *); int sshkey_set_filename(struct sshkey *, const char *);
@ -315,6 +324,10 @@ int sshkey_private_serialize_maxsign(struct sshkey *key,
void sshkey_sig_details_free(struct sshkey_sig_details *); void sshkey_sig_details_free(struct sshkey_sig_details *);
#ifdef WITH_OPENSSL
int sshkey_ecdsa_fixup_group(EVP_PKEY *k); /* ssh-ecdsa.c */
#endif
#ifdef SSHKEY_INTERNAL #ifdef SSHKEY_INTERNAL
int sshkey_sk_fields_equal(const struct sshkey *a, const struct sshkey *b); int sshkey_sk_fields_equal(const struct sshkey *a, const struct sshkey *b);
void sshkey_sk_cleanup(struct sshkey *k); void sshkey_sk_cleanup(struct sshkey *k);
@ -335,6 +348,7 @@ int check_rsa_length(const RSA *rsa); /* XXX remove */
#undef EC_KEY #undef EC_KEY
#undef EC_GROUP #undef EC_GROUP
#undef EC_POINT #undef EC_POINT
#undef EVP_PKEY
#endif /* WITH_OPENSSL */ #endif /* WITH_OPENSSL */
#endif /* SSHKEY_H */ #endif /* SSHKEY_H */

View file

@ -1,4 +1,4 @@
.\" $OpenBSD: bgplgd.8,v 1.8 2024/01/26 18:11:49 job Exp $ .\" $OpenBSD: bgplgd.8,v 1.9 2024/08/15 09:13:13 claudio Exp $
.\" .\"
.\" Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org> .\" Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
.\" .\"
@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\" .\"
.Dd $Mdocdate: January 26 2024 $ .Dd $Mdocdate: August 15 2024 $
.Dt BGPLGD 8 .Dt BGPLGD 8
.Os .Os
.Sh NAME .Sh NAME
@ -148,6 +148,8 @@ Show only prefixes that match the specified ASPA Validation State.
Show only selected routes. Show only selected routes.
.It Cm error Ns = Ns 1 .It Cm error Ns = Ns 1
Show only prefixes which are marked invalid and were treated as withdrawn. Show only prefixes which are marked invalid and were treated as withdrawn.
.It Cm filtered Ns = Ns 1
Show only prefixes which are marked filtered by the input filter.
.It Cm invalid Ns = Ns 1 .It Cm invalid Ns = Ns 1
Show only prefixes which are not eligible. Show only prefixes which are not eligible.
.It Cm leaked Ns = Ns 1 .It Cm leaked Ns = Ns 1

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bgplgd.h,v 1.3 2023/03/13 17:31:28 claudio Exp $ */ /* $OpenBSD: bgplgd.h,v 1.4 2024/08/15 09:13:13 claudio Exp $ */
/* /*
* Copyright (c) 2020 Claudio Jeker <claudio@openbsd.org> * Copyright (c) 2020 Claudio Jeker <claudio@openbsd.org>
* *
@ -32,7 +32,8 @@
#define QS_AVS 15 #define QS_AVS 15
#define QS_INVALID 16 #define QS_INVALID 16
#define QS_LEAKED 17 #define QS_LEAKED 17
#define QS_MAX 18 #define QS_FILTERED 18
#define QS_MAX 19
/* too add: empty-as, in, out, peer-as, source-as, transit-as */ /* too add: empty-as, in, out, peer-as, source-as, transit-as */
@ -44,7 +45,7 @@
(1 << QS_AF) | (1 << QS_RIB) | (1 << QS_OVS) | \ (1 << QS_AF) | (1 << QS_RIB) | (1 << QS_OVS) | \
(1 << QS_BEST) | (1 << QS_ALL) | (1 << QS_SHORTER) | \ (1 << QS_BEST) | (1 << QS_ALL) | (1 << QS_SHORTER) | \
(1 << QS_ERROR) | (1 << QS_AVS) | (1 << QS_INVALID) | \ (1 << QS_ERROR) | (1 << QS_AVS) | (1 << QS_INVALID) | \
(1 << QS_LEAKED)) (1 << QS_LEAKED) | (1 << QS_FILTERED))
struct cmd; struct cmd;
struct lg_ctx { struct lg_ctx {

View file

@ -1,4 +1,4 @@
/* $OpenBSD: qs.c,v 1.5 2023/05/09 14:35:45 claudio Exp $ */ /* $OpenBSD: qs.c,v 1.6 2024/08/15 09:13:13 claudio Exp $ */
/* /*
* Copyright (c) 2020 Claudio Jeker <claudio@openbsd.org> * Copyright (c) 2020 Claudio Jeker <claudio@openbsd.org>
* *
@ -57,6 +57,7 @@ const struct qs {
{ QS_AVS, "avs", AVS }, { QS_AVS, "avs", AVS },
{ QS_INVALID, "invalid", ONE }, { QS_INVALID, "invalid", ONE },
{ QS_LEAKED, "leaked", ONE }, { QS_LEAKED, "leaked", ONE },
{ QS_FILTERED, "filtered", ONE },
{ 0, NULL } { 0, NULL }
}; };
@ -382,13 +383,16 @@ qs_argv(char **argv, size_t argc, size_t len, struct lg_ctx *ctx, int barenbr)
if (argc < len) if (argc < len)
argv[argc++] = ctx->qs_args[QS_AVS].string; argv[argc++] = ctx->qs_args[QS_AVS].string;
} }
/* BEST, ERROR, INVALID and LEAKED are exclusive */ /* BEST, ERROR, FILTERED, INVALID and LEAKED are exclusive */
if (ctx->qs_args[QS_BEST].one) { if (ctx->qs_args[QS_BEST].one) {
if (argc < len) if (argc < len)
argv[argc++] = "best"; argv[argc++] = "best";
} else if (ctx->qs_args[QS_ERROR].one) { } else if (ctx->qs_args[QS_ERROR].one) {
if (argc < len) if (argc < len)
argv[argc++] = "error"; argv[argc++] = "error";
} else if (ctx->qs_args[QS_FILTERED].one) {
if (argc < len)
argv[argc++] = "filtered";
} else if (ctx->qs_args[QS_INVALID].one) { } else if (ctx->qs_args[QS_INVALID].one) {
if (argc < len) if (argc < len)
argv[argc++] = "disqualified"; argv[argc++] = "disqualified";

View file

@ -1,4 +1,4 @@
/* $OpenBSD: parse.y,v 1.26 2024/07/14 16:09:23 yasuoka Exp $ */ /* $OpenBSD: parse.y,v 1.27 2024/08/15 07:24:28 yasuoka Exp $ */
/* /*
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org> * Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
@ -451,7 +451,8 @@ authopts : authopts '\n' authopt
| authopt | authopt
; ;
authopt : AUTHENTICATE_BY STRING { authopt : /* empty */
| AUTHENTICATE_BY STRING {
struct radiusd_module_ref *modref; struct radiusd_module_ref *modref;
if (authen.auth != NULL) { if (authen.auth != NULL) {

View file

@ -1,4 +1,4 @@
/* $OpenBSD: main.c,v 1.262 2024/07/12 09:27:32 claudio Exp $ */ /* $OpenBSD: main.c,v 1.263 2024/08/15 09:22:12 claudio Exp $ */
/* /*
* Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org> * Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
@ -1285,14 +1285,14 @@ main(int argc, char *argv[])
while (entity_queue > 0 && !killme) { while (entity_queue > 0 && !killme) {
int polltim; int polltim;
polltim = repo_check_timeout(INFTIM);
for (i = 0; i < NPFD; i++) { for (i = 0; i < NPFD; i++) {
pfd[i].events = POLLIN; pfd[i].events = POLLIN;
if (queues[i]->queued) if (queues[i]->queued)
pfd[i].events |= POLLOUT; pfd[i].events |= POLLOUT;
} }
polltim = repo_check_timeout(INFTIM);
if (poll(pfd, NPFD, polltim) == -1) { if (poll(pfd, NPFD, polltim) == -1) {
if (errno == EINTR) if (errno == EINTR)
continue; continue;

View file

@ -1,4 +1,4 @@
/* $OpenBSD: repo.c,v 1.61 2024/07/12 09:27:32 claudio Exp $ */ /* $OpenBSD: repo.c,v 1.62 2024/08/15 11:30:43 job Exp $ */
/* /*
* Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org> * Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
@ -1376,12 +1376,15 @@ repo_abort(struct repo *rp)
/* reset the alarm */ /* reset the alarm */
rp->alarm = getmonotime() + repo_timeout; rp->alarm = getmonotime() + repo_timeout;
if (rp->rsync) if (rp->rsync) {
warnx("%s: synchronisation timeout", rp->repouri);
rsync_abort(rp->rsync->id); rsync_abort(rp->rsync->id);
else if (rp->rrdp) } else if (rp->rrdp) {
warnx("%s: synchronisation timeout", rp->notifyuri);
rrdp_abort(rp->rrdp->id); rrdp_abort(rp->rrdp->id);
else }
repo_fail(rp);
repo_fail(rp);
} }
int int
@ -1412,11 +1415,9 @@ repo_check_timeout(int timeout)
/* Look up in repository table. (Lookup should actually fail here) */ /* Look up in repository table. (Lookup should actually fail here) */
SLIST_FOREACH(rp, &repos, entry) { SLIST_FOREACH(rp, &repos, entry) {
if (repo_state(rp) == REPO_LOADING) { if (repo_state(rp) == REPO_LOADING) {
if (rp->alarm <= now) { if (rp->alarm <= now)
warnx("%s: synchronisation timeout",
rp->repouri);
repo_abort(rp); repo_abort(rp);
} else { else {
diff = rp->alarm - now; diff = rp->alarm - now;
diff *= 1000; diff *= 1000;
if (timeout == INFTIM || diff < timeout) if (timeout == INFTIM || diff < timeout)