sync with OpenBSD -current

This commit is contained in:
purplerain 2025-01-24 19:21:17 +00:00
parent 614315d09f
commit 05d10b89c5
Signed by: purplerain
GPG key ID: F42C07F07E2E35B7
10 changed files with 389 additions and 316 deletions

View file

@ -1,4 +1,4 @@
# $OpenBSD: Makefile.inc,v 1.35 2024/12/06 11:57:17 jsing Exp $
# $OpenBSD: Makefile.inc,v 1.36 2025/01/24 13:35:04 jsing Exp $
# amd64-specific libcrypto build rules
@ -40,7 +40,7 @@ SRCS += word_clz.S
# md5
CFLAGS+= -DMD5_ASM
SSLASM+= md5 md5-x86_64
SRCS+= md5_amd64_generic.S
# modes
CFLAGS+= -DGHASH_ASM
SSLASM+= modes ghash-x86_64

View file

@ -30,7 +30,7 @@ $X="esi";
0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9, # R3
);
&md5_block("md5_block_asm_data_order");
&md5_block("md5_block_data_order");
&asm_finish();
sub Np

View file

@ -1,265 +0,0 @@
#!/usr/bin/perl -w
#
# MD5 optimized for AMD64.
#
# Author: Marc Bevand <bevand_m (at) epita.fr>
# Licence: I hereby disclaim the copyright on this code and place it
# in the public domain.
#
use strict;
my $code;
# round1_step() does:
# dst = x + ((dst + F(x,y,z) + X[k] + T_i) <<< s)
# %r10d = X[k_next]
# %r11d = z' (copy of z for the next step)
# Each round1_step() takes about 5.3 clocks (9 instructions, 1.7 IPC)
sub round1_step
{
my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_;
$code .= " mov 0*4(%rsi), %r10d /* (NEXT STEP) X[0] */\n" if ($pos == -1);
$code .= " mov %edx, %r11d /* (NEXT STEP) z' = %edx */\n" if ($pos == -1);
$code .= <<EOF;
xor $y, %r11d /* y ^ ... */
lea $T_i($dst,%r10d),$dst /* Const + dst + ... */
and $x, %r11d /* x & ... */
xor $z, %r11d /* z ^ ... */
mov $k_next*4(%rsi),%r10d /* (NEXT STEP) X[$k_next] */
add %r11d, $dst /* dst += ... */
rol \$$s, $dst /* dst <<< s */
mov $y, %r11d /* (NEXT STEP) z' = $y */
add $x, $dst /* dst += x */
EOF
}
# round2_step() does:
# dst = x + ((dst + G(x,y,z) + X[k] + T_i) <<< s)
# %r10d = X[k_next]
# %r11d = z' (copy of z for the next step)
# %r12d = z' (copy of z for the next step)
# Each round2_step() takes about 5.4 clocks (11 instructions, 2.0 IPC)
sub round2_step
{
my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_;
$code .= " mov 1*4(%rsi), %r10d /* (NEXT STEP) X[1] */\n" if ($pos == -1);
$code .= " mov %edx, %r11d /* (NEXT STEP) z' = %edx */\n" if ($pos == -1);
$code .= " mov %edx, %r12d /* (NEXT STEP) z' = %edx */\n" if ($pos == -1);
$code .= <<EOF;
not %r11d /* not z */
lea $T_i($dst,%r10d),$dst /* Const + dst + ... */
and $x, %r12d /* x & z */
and $y, %r11d /* y & (not z) */
mov $k_next*4(%rsi),%r10d /* (NEXT STEP) X[$k_next] */
or %r11d, %r12d /* (y & (not z)) | (x & z) */
mov $y, %r11d /* (NEXT STEP) z' = $y */
add %r12d, $dst /* dst += ... */
mov $y, %r12d /* (NEXT STEP) z' = $y */
rol \$$s, $dst /* dst <<< s */
add $x, $dst /* dst += x */
EOF
}
# round3_step() does:
# dst = x + ((dst + H(x,y,z) + X[k] + T_i) <<< s)
# %r10d = X[k_next]
# %r11d = y' (copy of y for the next step)
# Each round3_step() takes about 4.2 clocks (8 instructions, 1.9 IPC)
sub round3_step
{
my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_;
$code .= " mov 5*4(%rsi), %r10d /* (NEXT STEP) X[5] */\n" if ($pos == -1);
$code .= " mov %ecx, %r11d /* (NEXT STEP) y' = %ecx */\n" if ($pos == -1);
$code .= <<EOF;
lea $T_i($dst,%r10d),$dst /* Const + dst + ... */
mov $k_next*4(%rsi),%r10d /* (NEXT STEP) X[$k_next] */
xor $z, %r11d /* z ^ ... */
xor $x, %r11d /* x ^ ... */
add %r11d, $dst /* dst += ... */
rol \$$s, $dst /* dst <<< s */
mov $x, %r11d /* (NEXT STEP) y' = $x */
add $x, $dst /* dst += x */
EOF
}
# round4_step() does:
# dst = x + ((dst + I(x,y,z) + X[k] + T_i) <<< s)
# %r10d = X[k_next]
# %r11d = not z' (copy of not z for the next step)
# Each round4_step() takes about 5.2 clocks (9 instructions, 1.7 IPC)
sub round4_step
{
my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_;
$code .= " mov 0*4(%rsi), %r10d /* (NEXT STEP) X[0] */\n" if ($pos == -1);
$code .= " mov \$0xffffffff, %r11d\n" if ($pos == -1);
$code .= " xor %edx, %r11d /* (NEXT STEP) not z' = not %edx*/\n"
if ($pos == -1);
$code .= <<EOF;
lea $T_i($dst,%r10d),$dst /* Const + dst + ... */
or $x, %r11d /* x | ... */
xor $y, %r11d /* y ^ ... */
add %r11d, $dst /* dst += ... */
mov $k_next*4(%rsi),%r10d /* (NEXT STEP) X[$k_next] */
mov \$0xffffffff, %r11d
rol \$$s, $dst /* dst <<< s */
xor $y, %r11d /* (NEXT STEP) not z' = not $y */
add $x, $dst /* dst += x */
EOF
}
my $flavour = shift;
my $output = shift;
if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
$0 =~ m/(.*[\/\\])[^\/\\]+$/; my $dir=$1; my $xlate;
( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
die "can't locate x86_64-xlate.pl";
no warnings qw(uninitialized);
open OUT,"| \"$^X\" $xlate $flavour $output";
*STDOUT=*OUT;
$code .= <<EOF;
.text
.align 16
.globl md5_block_asm_data_order
.type md5_block_asm_data_order,\@function,3
md5_block_asm_data_order:
_CET_ENDBR
push %rbp
push %rbx
push %r12
push %r14
push %r15
.Lprologue:
# rdi = arg #1 (ctx, MD5_CTX pointer)
# rsi = arg #2 (ptr, data pointer)
# rdx = arg #3 (nbr, number of 16-word blocks to process)
mov %rdi, %rbp # rbp = ctx
shl \$6, %rdx # rdx = nbr in bytes
lea (%rsi,%rdx), %rdi # rdi = end
mov 0*4(%rbp), %eax # eax = ctx->A
mov 1*4(%rbp), %ebx # ebx = ctx->B
mov 2*4(%rbp), %ecx # ecx = ctx->C
mov 3*4(%rbp), %edx # edx = ctx->D
# end is 'rdi'
# ptr is 'rsi'
# A is 'eax'
# B is 'ebx'
# C is 'ecx'
# D is 'edx'
cmp %rdi, %rsi # cmp end with ptr
je .Lend # jmp if ptr == end
# BEGIN of loop over 16-word blocks
.Lloop: # save old values of A, B, C, D
mov %eax, %r8d
mov %ebx, %r9d
mov %ecx, %r14d
mov %edx, %r15d
EOF
round1_step(-1,'%eax','%ebx','%ecx','%edx', '1','0xd76aa478', '7');
round1_step( 0,'%edx','%eax','%ebx','%ecx', '2','0xe8c7b756','12');
round1_step( 0,'%ecx','%edx','%eax','%ebx', '3','0x242070db','17');
round1_step( 0,'%ebx','%ecx','%edx','%eax', '4','0xc1bdceee','22');
round1_step( 0,'%eax','%ebx','%ecx','%edx', '5','0xf57c0faf', '7');
round1_step( 0,'%edx','%eax','%ebx','%ecx', '6','0x4787c62a','12');
round1_step( 0,'%ecx','%edx','%eax','%ebx', '7','0xa8304613','17');
round1_step( 0,'%ebx','%ecx','%edx','%eax', '8','0xfd469501','22');
round1_step( 0,'%eax','%ebx','%ecx','%edx', '9','0x698098d8', '7');
round1_step( 0,'%edx','%eax','%ebx','%ecx','10','0x8b44f7af','12');
round1_step( 0,'%ecx','%edx','%eax','%ebx','11','0xffff5bb1','17');
round1_step( 0,'%ebx','%ecx','%edx','%eax','12','0x895cd7be','22');
round1_step( 0,'%eax','%ebx','%ecx','%edx','13','0x6b901122', '7');
round1_step( 0,'%edx','%eax','%ebx','%ecx','14','0xfd987193','12');
round1_step( 0,'%ecx','%edx','%eax','%ebx','15','0xa679438e','17');
round1_step( 1,'%ebx','%ecx','%edx','%eax', '0','0x49b40821','22');
round2_step(-1,'%eax','%ebx','%ecx','%edx', '6','0xf61e2562', '5');
round2_step( 0,'%edx','%eax','%ebx','%ecx','11','0xc040b340', '9');
round2_step( 0,'%ecx','%edx','%eax','%ebx', '0','0x265e5a51','14');
round2_step( 0,'%ebx','%ecx','%edx','%eax', '5','0xe9b6c7aa','20');
round2_step( 0,'%eax','%ebx','%ecx','%edx','10','0xd62f105d', '5');
round2_step( 0,'%edx','%eax','%ebx','%ecx','15', '0x2441453', '9');
round2_step( 0,'%ecx','%edx','%eax','%ebx', '4','0xd8a1e681','14');
round2_step( 0,'%ebx','%ecx','%edx','%eax', '9','0xe7d3fbc8','20');
round2_step( 0,'%eax','%ebx','%ecx','%edx','14','0x21e1cde6', '5');
round2_step( 0,'%edx','%eax','%ebx','%ecx', '3','0xc33707d6', '9');
round2_step( 0,'%ecx','%edx','%eax','%ebx', '8','0xf4d50d87','14');
round2_step( 0,'%ebx','%ecx','%edx','%eax','13','0x455a14ed','20');
round2_step( 0,'%eax','%ebx','%ecx','%edx', '2','0xa9e3e905', '5');
round2_step( 0,'%edx','%eax','%ebx','%ecx', '7','0xfcefa3f8', '9');
round2_step( 0,'%ecx','%edx','%eax','%ebx','12','0x676f02d9','14');
round2_step( 1,'%ebx','%ecx','%edx','%eax', '0','0x8d2a4c8a','20');
round3_step(-1,'%eax','%ebx','%ecx','%edx', '8','0xfffa3942', '4');
round3_step( 0,'%edx','%eax','%ebx','%ecx','11','0x8771f681','11');
round3_step( 0,'%ecx','%edx','%eax','%ebx','14','0x6d9d6122','16');
round3_step( 0,'%ebx','%ecx','%edx','%eax', '1','0xfde5380c','23');
round3_step( 0,'%eax','%ebx','%ecx','%edx', '4','0xa4beea44', '4');
round3_step( 0,'%edx','%eax','%ebx','%ecx', '7','0x4bdecfa9','11');
round3_step( 0,'%ecx','%edx','%eax','%ebx','10','0xf6bb4b60','16');
round3_step( 0,'%ebx','%ecx','%edx','%eax','13','0xbebfbc70','23');
round3_step( 0,'%eax','%ebx','%ecx','%edx', '0','0x289b7ec6', '4');
round3_step( 0,'%edx','%eax','%ebx','%ecx', '3','0xeaa127fa','11');
round3_step( 0,'%ecx','%edx','%eax','%ebx', '6','0xd4ef3085','16');
round3_step( 0,'%ebx','%ecx','%edx','%eax', '9', '0x4881d05','23');
round3_step( 0,'%eax','%ebx','%ecx','%edx','12','0xd9d4d039', '4');
round3_step( 0,'%edx','%eax','%ebx','%ecx','15','0xe6db99e5','11');
round3_step( 0,'%ecx','%edx','%eax','%ebx', '2','0x1fa27cf8','16');
round3_step( 1,'%ebx','%ecx','%edx','%eax', '0','0xc4ac5665','23');
round4_step(-1,'%eax','%ebx','%ecx','%edx', '7','0xf4292244', '6');
round4_step( 0,'%edx','%eax','%ebx','%ecx','14','0x432aff97','10');
round4_step( 0,'%ecx','%edx','%eax','%ebx', '5','0xab9423a7','15');
round4_step( 0,'%ebx','%ecx','%edx','%eax','12','0xfc93a039','21');
round4_step( 0,'%eax','%ebx','%ecx','%edx', '3','0x655b59c3', '6');
round4_step( 0,'%edx','%eax','%ebx','%ecx','10','0x8f0ccc92','10');
round4_step( 0,'%ecx','%edx','%eax','%ebx', '1','0xffeff47d','15');
round4_step( 0,'%ebx','%ecx','%edx','%eax', '8','0x85845dd1','21');
round4_step( 0,'%eax','%ebx','%ecx','%edx','15','0x6fa87e4f', '6');
round4_step( 0,'%edx','%eax','%ebx','%ecx', '6','0xfe2ce6e0','10');
round4_step( 0,'%ecx','%edx','%eax','%ebx','13','0xa3014314','15');
round4_step( 0,'%ebx','%ecx','%edx','%eax', '4','0x4e0811a1','21');
round4_step( 0,'%eax','%ebx','%ecx','%edx','11','0xf7537e82', '6');
round4_step( 0,'%edx','%eax','%ebx','%ecx', '2','0xbd3af235','10');
round4_step( 0,'%ecx','%edx','%eax','%ebx', '9','0x2ad7d2bb','15');
round4_step( 1,'%ebx','%ecx','%edx','%eax', '0','0xeb86d391','21');
$code .= <<EOF;
# add old values of A, B, C, D
add %r8d, %eax
add %r9d, %ebx
add %r14d, %ecx
add %r15d, %edx
# loop control
add \$64, %rsi # ptr += 64
cmp %rdi, %rsi # cmp end with ptr
jb .Lloop # jmp if ptr < end
# END of loop over 16-word blocks
.Lend:
mov %eax, 0*4(%rbp) # ctx->A = A
mov %ebx, 1*4(%rbp) # ctx->B = B
mov %ecx, 2*4(%rbp) # ctx->C = C
mov %edx, 3*4(%rbp) # ctx->D = D
mov (%rsp),%r15
mov 8(%rsp),%r14
mov 16(%rsp),%r12
mov 24(%rsp),%rbx
mov 32(%rsp),%rbp
add \$40,%rsp
.Lepilogue:
ret
.size md5_block_asm_data_order,.-md5_block_asm_data_order
EOF
print $code;
close STDOUT;

View file

@ -1,4 +1,4 @@
/* $OpenBSD: md5.c,v 1.24 2025/01/19 07:51:41 jsing Exp $ */
/* $OpenBSD: md5.c,v 1.25 2025/01/24 13:35:04 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -71,8 +71,7 @@
CTASSERT(sizeof(MD5_LONG) == sizeof(uint32_t));
#ifdef MD5_ASM
void md5_block_asm_data_order(MD5_CTX *c, const void *p, size_t num);
#define md5_block_data_order md5_block_asm_data_order
void md5_block_data_order(MD5_CTX *c, const void *p, size_t num);
#endif
#ifndef MD5_ASM

View file

@ -0,0 +1,237 @@
/* $OpenBSD: md5_amd64_generic.S,v 1.1 2025/01/24 13:35:04 jsing Exp $ */
/*
* Copyright (c) 2025 Joel Sing <jsing@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef __CET__
#include <cet.h>
#else
#define _CET_ENDBR
#endif
#define ctx %rdi
#define in %rsi
#define num %rdx
#define end %rbp
#define A %eax
#define B %ebx
#define C %ecx
#define D %edx
#define AA %r8d
#define BB %r9d
#define CC %r10d
#define DD %r11d
#define tmp0 %r12d
#define tmp1 %r13d
/*
* Compute MD5 round 1 as:
*
* a = b + rol(a + F(b, c, d) + x + t, s)
* F(x, y, z) = (x & y) | (~x & z)
* = ((y ^ z) & x) ^ z
*/
#define md5_round1(a, b, c, d, x, t, s) \
addl (x*4)(in), a; \
movl c, tmp0; \
xorl d, tmp0; \
andl b, tmp0; \
xorl d, tmp0; \
leal t(tmp0, a), a; \
roll $s, a; \
addl b, a;
/*
* Compute MD5 round 2 as:
*
* a = b + rol(a + G(b, c, d) + x + t, s)
* G(x, y, z) = (x & z) | (y & ~z)
*/
#define md5_round2(a, b, c, d, x, t, s) \
addl (x*4)(in), a; \
movl d, tmp0; \
xorl $-1, tmp0; \
andl c, tmp0; \
addl tmp0, a; \
movl d, tmp1; \
andl b, tmp1; \
leal t(tmp1, a), a; \
roll $s, a; \
addl b, a;
/*
* Compute MD5 round 3 as:
*
* a = b + rol(a + H(b, c, d) + x + t, s)
* H(x, y, z) = x ^ y ^ z;
*/
#define md5_round3(a, b, c, d, x, t, s) \
addl (x*4)(in), a; \
movl d, tmp0; \
xorl c, tmp0; \
xorl b, tmp0; \
leal t(tmp0, a), a; \
roll $s, a; \
addl b, a;
/*
* Compute MD5 round 4 as:
*
* a = b + rol(a + I(b, c, d) + x + t, s)
* I(x, y, z) = y ^ (x | ~z)
*/
#define md5_round4(a, b, c, d, x, t, s) \
addl (x*4)(in), a; \
movl d, tmp0; \
xorl $-1, tmp0; \
orl b, tmp0; \
xorl c, tmp0; \
leal t(tmp0, a), a; \
roll $s, a; \
addl b, a;
.text
/*
* void md5_block_data_order(MD5_CTX *ctx, const void *in, size_t num);
*
* Standard x86-64 ABI: rdi = ctx, rsi = in, rdx = num
*/
.align 16
.globl md5_block_data_order
.type md5_block_data_order,@function
md5_block_data_order:
_CET_ENDBR
/* Save callee save registers. */
pushq %rbx
pushq %rbp
pushq %r12
pushq %r13
/* Compute end of message. */
shlq $6, num
leaq (in, num, 1), end
/* Load current hash state from context. */
movl (0*4)(ctx), AA
movl (1*4)(ctx), BB
movl (2*4)(ctx), CC
movl (3*4)(ctx), DD
jmp .Lblock_loop
.align 16
.Lblock_loop:
movl AA, A
movl BB, B
movl CC, C
movl DD, D
md5_round1(A, B, C, D, 0, 0xd76aa478L, 7);
md5_round1(D, A, B, C, 1, 0xe8c7b756L, 12);
md5_round1(C, D, A, B, 2, 0x242070dbL, 17);
md5_round1(B, C, D, A, 3, 0xc1bdceeeL, 22);
md5_round1(A, B, C, D, 4, 0xf57c0fafL, 7);
md5_round1(D, A, B, C, 5, 0x4787c62aL, 12);
md5_round1(C, D, A, B, 6, 0xa8304613L, 17);
md5_round1(B, C, D, A, 7, 0xfd469501L, 22);
md5_round1(A, B, C, D, 8, 0x698098d8L, 7);
md5_round1(D, A, B, C, 9, 0x8b44f7afL, 12);
md5_round1(C, D, A, B, 10, 0xffff5bb1L, 17);
md5_round1(B, C, D, A, 11, 0x895cd7beL, 22);
md5_round1(A, B, C, D, 12, 0x6b901122L, 7);
md5_round1(D, A, B, C, 13, 0xfd987193L, 12);
md5_round1(C, D, A, B, 14, 0xa679438eL, 17);
md5_round1(B, C, D, A, 15, 0x49b40821L, 22);
md5_round2(A, B, C, D, 1, 0xf61e2562L, 5);
md5_round2(D, A, B, C, 6, 0xc040b340L, 9);
md5_round2(C, D, A, B, 11, 0x265e5a51L, 14);
md5_round2(B, C, D, A, 0, 0xe9b6c7aaL, 20);
md5_round2(A, B, C, D, 5, 0xd62f105dL, 5);
md5_round2(D, A, B, C, 10, 0x02441453L, 9);
md5_round2(C, D, A, B, 15, 0xd8a1e681L, 14);
md5_round2(B, C, D, A, 4, 0xe7d3fbc8L, 20);
md5_round2(A, B, C, D, 9, 0x21e1cde6L, 5);
md5_round2(D, A, B, C, 14, 0xc33707d6L, 9);
md5_round2(C, D, A, B, 3, 0xf4d50d87L, 14);
md5_round2(B, C, D, A, 8, 0x455a14edL, 20);
md5_round2(A, B, C, D, 13, 0xa9e3e905L, 5);
md5_round2(D, A, B, C, 2, 0xfcefa3f8L, 9);
md5_round2(C, D, A, B, 7, 0x676f02d9L, 14);
md5_round2(B, C, D, A, 12, 0x8d2a4c8aL, 20);
md5_round3(A, B, C, D, 5, 0xfffa3942L, 4);
md5_round3(D, A, B, C, 8, 0x8771f681L, 11);
md5_round3(C, D, A, B, 11, 0x6d9d6122L, 16);
md5_round3(B, C, D, A, 14, 0xfde5380cL, 23);
md5_round3(A, B, C, D, 1, 0xa4beea44L, 4);
md5_round3(D, A, B, C, 4, 0x4bdecfa9L, 11);
md5_round3(C, D, A, B, 7, 0xf6bb4b60L, 16);
md5_round3(B, C, D, A, 10, 0xbebfbc70L, 23);
md5_round3(A, B, C, D, 13, 0x289b7ec6L, 4);
md5_round3(D, A, B, C, 0, 0xeaa127faL, 11);
md5_round3(C, D, A, B, 3, 0xd4ef3085L, 16);
md5_round3(B, C, D, A, 6, 0x04881d05L, 23);
md5_round3(A, B, C, D, 9, 0xd9d4d039L, 4);
md5_round3(D, A, B, C, 12, 0xe6db99e5L, 11);
md5_round3(C, D, A, B, 15, 0x1fa27cf8L, 16);
md5_round3(B, C, D, A, 2, 0xc4ac5665L, 23);
md5_round4(A, B, C, D, 0, 0xf4292244L, 6);
md5_round4(D, A, B, C, 7, 0x432aff97L, 10);
md5_round4(C, D, A, B, 14, 0xab9423a7L, 15);
md5_round4(B, C, D, A, 5, 0xfc93a039L, 21);
md5_round4(A, B, C, D, 12, 0x655b59c3L, 6);
md5_round4(D, A, B, C, 3, 0x8f0ccc92L, 10);
md5_round4(C, D, A, B, 10, 0xffeff47dL, 15);
md5_round4(B, C, D, A, 1, 0x85845dd1L, 21);
md5_round4(A, B, C, D, 8, 0x6fa87e4fL, 6);
md5_round4(D, A, B, C, 15, 0xfe2ce6e0L, 10);
md5_round4(C, D, A, B, 6, 0xa3014314L, 15);
md5_round4(B, C, D, A, 13, 0x4e0811a1L, 21);
md5_round4(A, B, C, D, 4, 0xf7537e82L, 6);
md5_round4(D, A, B, C, 11, 0xbd3af235L, 10);
md5_round4(C, D, A, B, 2, 0x2ad7d2bbL, 15);
md5_round4(B, C, D, A, 9, 0xeb86d391L, 21);
/* Add intermediate state to hash state. */
addl A, AA
addl B, BB
addl C, CC
addl D, DD
addq $64, in
cmpq end, in
jb .Lblock_loop
/* Store new hash state to context. */
movl AA, (0*4)(ctx)
movl BB, (1*4)(ctx)
movl CC, (2*4)(ctx)
movl DD, (3*4)(ctx)
/* Restore callee save registers. */
popq %r13
popq %r12
popq %rbp
popq %rbx
ret

View file

@ -1,4 +1,4 @@
/* $OpenBSD: ectest.c,v 1.34 2025/01/22 15:38:25 tb Exp $ */
/* $OpenBSD: ectest.c,v 1.35 2025/01/24 11:49:13 tb Exp $ */
/*
* Originally written by Bodo Moeller for the OpenSSL project.
*/
@ -117,8 +117,6 @@ group_order_tests(EC_GROUP *group, BN_CTX *ctx)
ABORT;
fprintf(stdout, ".");
fflush(stdout);
if (!EC_GROUP_precompute_mult(group, ctx))
ABORT;
if (!EC_POINT_mul(group, Q, order, NULL, NULL, ctx))
ABORT;
if (!EC_POINT_is_at_infinity(group, Q))

View file

@ -1,4 +1,4 @@
/* $OpenBSD: if_vmx.c,v 1.89 2024/09/01 03:08:59 jsg Exp $ */
/* $OpenBSD: if_vmx.c,v 1.90 2025/01/24 10:29:43 yasuoka Exp $ */
/*
* Copyright (c) 2013 Tsubai Masanari
@ -1621,10 +1621,8 @@ vmxnet3_start(struct ifqueue *ifq)
for (;;) {
int hdrlen;
if (free <= NTXSEGS) {
ifq_set_oactive(ifq);
if (free <= NTXSEGS)
break;
}
m = ifq_dequeue(ifq);
if (m == NULL)
@ -1672,6 +1670,11 @@ vmxnet3_start(struct ifqueue *ifq)
bus_dmamap_sync(sc->sc_dmat, map, 0,
map->dm_mapsize, BUS_DMASYNC_PREWRITE);
free -= map->dm_nsegs;
/* set oactive here since txintr may be triggered in parallel */
if (free <= NTXSEGS)
ifq_set_oactive(ifq);
gen = rgen ^ VMX_TX_GEN;
sop = &ring->txd[prod];
for (i = 0; i < map->dm_nsegs; i++) {
@ -1699,7 +1702,6 @@ vmxnet3_start(struct ifqueue *ifq)
BUS_DMASYNC_PREWRITE|BUS_DMASYNC_POSTWRITE);
sop->tx_word2 ^= VMX_TX_GEN;
free -= i;
post = 1;
}

View file

@ -1,4 +1,4 @@
/* $OpenBSD: if.c,v 1.723 2025/01/21 17:40:57 mvs Exp $ */
/* $OpenBSD: if.c,v 1.724 2025/01/24 09:19:07 mvs Exp $ */
/* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */
/*
@ -235,6 +235,7 @@ LIST_HEAD(, if_clone) if_cloners =
int if_cloners_count; /* [I] number of clonable interfaces */
struct rwlock if_cloners_lock = RWLOCK_INITIALIZER("clonelk");
struct rwlock if_tmplist_lock = RWLOCK_INITIALIZER("iftmplk");
/* hooks should only be added, deleted, and run from a process context */
struct mutex if_hooks_mtx = MUTEX_INITIALIZER(IPL_NONE);
@ -2506,9 +2507,7 @@ ifioctl_get(u_long cmd, caddr_t data)
error = if_clone_list((struct if_clonereq *)data);
return (error);
case SIOCGIFGMEMB:
NET_LOCK_SHARED();
error = if_getgroupmembers(data);
NET_UNLOCK_SHARED();
return (error);
case SIOCGIFGATTR:
NET_LOCK_SHARED();
@ -2516,9 +2515,7 @@ ifioctl_get(u_long cmd, caddr_t data)
NET_UNLOCK_SHARED();
return (error);
case SIOCGIFGLIST:
NET_LOCK_SHARED();
error = if_getgrouplist(data);
NET_UNLOCK_SHARED();
return (error);
}
@ -2596,9 +2593,7 @@ ifioctl_get(u_long cmd, caddr_t data)
break;
case SIOCGIFGROUP:
NET_LOCK_SHARED();
error = if_getgroup(data, ifp);
NET_UNLOCK_SHARED();
break;
case SIOCGIFLLPRIO:
@ -2871,6 +2866,19 @@ if_detached_ioctl(struct ifnet *ifp, u_long a, caddr_t b)
return ENODEV;
}
static inline void
ifgroup_icref(struct ifg_group *ifg)
{
refcnt_take(&ifg->ifg_tmprefcnt);
}
static inline void
ifgroup_icrele(struct ifg_group *ifg)
{
if (refcnt_rele(&ifg->ifg_tmprefcnt) != 0)
free(ifg, M_IFGROUP, sizeof(*ifg));
}
/*
* Create interface group without members
*/
@ -2886,6 +2894,7 @@ if_creategroup(const char *groupname)
ifg->ifg_refcnt = 1;
ifg->ifg_carp_demoted = 0;
TAILQ_INIT(&ifg->ifg_members);
refcnt_init(&ifg->ifg_tmprefcnt);
#if NPF > 0
pfi_attach_ifgroup(ifg);
#endif
@ -2986,7 +2995,7 @@ if_delgroup(struct ifnet *ifp, const char *groupname)
#if NPF > 0
pfi_detach_ifgroup(ifgl->ifgl_group);
#endif
free(ifgl->ifgl_group, M_IFGROUP, sizeof(*ifgl->ifgl_group));
ifgroup_icrele(ifgl->ifgl_group);
}
free(ifgl, M_IFGROUP, sizeof(*ifgl));
@ -3001,33 +3010,57 @@ if_delgroup(struct ifnet *ifp, const char *groupname)
int
if_getgroup(caddr_t data, struct ifnet *ifp)
{
int len, error;
TAILQ_HEAD(, ifg_group) ifg_tmplist =
TAILQ_HEAD_INITIALIZER(ifg_tmplist);
struct ifg_list *ifgl;
struct ifg_req ifgrq, *ifgp;
struct ifgroupreq *ifgr = (struct ifgroupreq *)data;
struct ifg_group *ifg;
int len, error = 0;
if (ifgr->ifgr_len == 0) {
NET_LOCK_SHARED();
TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next)
ifgr->ifgr_len += sizeof(struct ifg_req);
NET_UNLOCK_SHARED();
return (0);
}
len = ifgr->ifgr_len;
ifgp = ifgr->ifgr_groups;
rw_enter_write(&if_tmplist_lock);
NET_LOCK_SHARED();
TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next) {
if (len < sizeof(ifgrq))
return (EINVAL);
ifgroup_icref(ifgl->ifgl_group);
TAILQ_INSERT_TAIL(&ifg_tmplist, ifgl->ifgl_group, ifg_tmplist);
}
NET_UNLOCK_SHARED();
TAILQ_FOREACH(ifg, &ifg_tmplist, ifg_tmplist) {
if (len < sizeof(ifgrq)) {
error = EINVAL;
break;
}
bzero(&ifgrq, sizeof ifgrq);
strlcpy(ifgrq.ifgrq_group, ifgl->ifgl_group->ifg_group,
strlcpy(ifgrq.ifgrq_group, ifg->ifg_group,
sizeof(ifgrq.ifgrq_group));
if ((error = copyout((caddr_t)&ifgrq, (caddr_t)ifgp,
sizeof(struct ifg_req))))
return (error);
break;
len -= sizeof(ifgrq);
ifgp++;
}
return (0);
while ((ifg = TAILQ_FIRST(&ifg_tmplist))){
TAILQ_REMOVE(&ifg_tmplist, ifg, ifg_tmplist);
ifgroup_icrele(ifg);
}
rw_exit_write(&if_tmplist_lock);
return (error);
}
/*
@ -3036,40 +3069,69 @@ if_getgroup(caddr_t data, struct ifnet *ifp)
int
if_getgroupmembers(caddr_t data)
{
TAILQ_HEAD(, ifnet) if_tmplist =
TAILQ_HEAD_INITIALIZER(if_tmplist);
struct ifnet *ifp;
struct ifgroupreq *ifgr = (struct ifgroupreq *)data;
struct ifg_group *ifg;
struct ifg_member *ifgm;
struct ifg_req ifgrq, *ifgp;
int len, error;
int len, error = 0;
rw_enter_write(&if_tmplist_lock);
NET_LOCK_SHARED();
TAILQ_FOREACH(ifg, &ifg_head, ifg_next)
if (!strcmp(ifg->ifg_group, ifgr->ifgr_name))
break;
if (ifg == NULL)
return (ENOENT);
if (ifg == NULL) {
error = ENOENT;
goto unlock;
}
if (ifgr->ifgr_len == 0) {
TAILQ_FOREACH(ifgm, &ifg->ifg_members, ifgm_next)
ifgr->ifgr_len += sizeof(ifgrq);
return (0);
goto unlock;
}
TAILQ_FOREACH (ifgm, &ifg->ifg_members, ifgm_next) {
if_ref(ifgm->ifgm_ifp);
TAILQ_INSERT_TAIL(&if_tmplist, ifgm->ifgm_ifp, if_tmplist);
}
NET_UNLOCK_SHARED();
len = ifgr->ifgr_len;
ifgp = ifgr->ifgr_groups;
TAILQ_FOREACH(ifgm, &ifg->ifg_members, ifgm_next) {
if (len < sizeof(ifgrq))
return (EINVAL);
TAILQ_FOREACH (ifp, &if_tmplist, if_tmplist) {
if (len < sizeof(ifgrq)) {
error = EINVAL;
break;
}
bzero(&ifgrq, sizeof ifgrq);
strlcpy(ifgrq.ifgrq_member, ifgm->ifgm_ifp->if_xname,
strlcpy(ifgrq.ifgrq_member, ifp->if_xname,
sizeof(ifgrq.ifgrq_member));
if ((error = copyout((caddr_t)&ifgrq, (caddr_t)ifgp,
sizeof(struct ifg_req))))
return (error);
break;
len -= sizeof(ifgrq);
ifgp++;
}
return (0);
while ((ifp = TAILQ_FIRST(&if_tmplist))) {
TAILQ_REMOVE(&if_tmplist, ifp, if_tmplist);
if_put(ifp);
}
rw_exit_write(&if_tmplist_lock);
return (error);
unlock:
NET_UNLOCK_SHARED();
rw_exit_write(&if_tmplist_lock);
return (error);
}
int
@ -3122,33 +3184,56 @@ if_setgroupattribs(caddr_t data)
int
if_getgrouplist(caddr_t data)
{
TAILQ_HEAD(, ifg_group) ifg_tmplist =
TAILQ_HEAD_INITIALIZER(ifg_tmplist);
struct ifgroupreq *ifgr = (struct ifgroupreq *)data;
struct ifg_group *ifg;
struct ifg_req ifgrq, *ifgp;
int len, error;
int len, error = 0;
if (ifgr->ifgr_len == 0) {
NET_LOCK_SHARED();
TAILQ_FOREACH(ifg, &ifg_head, ifg_next)
ifgr->ifgr_len += sizeof(ifgrq);
NET_LOCK_SHARED();
return (0);
}
len = ifgr->ifgr_len;
ifgp = ifgr->ifgr_groups;
rw_enter_write(&if_tmplist_lock);
NET_LOCK_SHARED();
TAILQ_FOREACH(ifg, &ifg_head, ifg_next) {
if (len < sizeof(ifgrq))
return (EINVAL);
ifgroup_icref(ifg);
TAILQ_INSERT_TAIL(&ifg_tmplist, ifg, ifg_tmplist);
}
NET_UNLOCK_SHARED();
TAILQ_FOREACH(ifg, &ifg_tmplist, ifg_tmplist) {
if (len < sizeof(ifgrq)) {
error = EINVAL;
break;
}
bzero(&ifgrq, sizeof ifgrq);
strlcpy(ifgrq.ifgrq_group, ifg->ifg_group,
sizeof(ifgrq.ifgrq_group));
if ((error = copyout((caddr_t)&ifgrq, (caddr_t)ifgp,
sizeof(struct ifg_req))))
return (error);
break;
len -= sizeof(ifgrq);
ifgp++;
}
return (0);
while ((ifg = TAILQ_FIRST(&ifg_tmplist))){
TAILQ_REMOVE(&ifg_tmplist, ifg, ifg_tmplist);
ifgroup_icrele(ifg);
}
rw_exit_write(&if_tmplist_lock);
return (error);
}
void

View file

@ -1,4 +1,4 @@
/* $OpenBSD: if_var.h,v 1.134 2025/01/21 17:40:57 mvs Exp $ */
/* $OpenBSD: if_var.h,v 1.135 2025/01/24 09:19:07 mvs Exp $ */
/* $NetBSD: if.h,v 1.23 1996/05/07 02:40:27 thorpej Exp $ */
/*
@ -79,6 +79,7 @@
* c only used in ioctl or routing socket contexts (kernel lock)
* K kernel lock
* N net lock
* T if_tmplist_lock
*
* For SRP related structures that allow lock-free reads, the write lock
* is indicated below.
@ -138,6 +139,7 @@ struct ifnet { /* and the entries */
void *if_softc; /* [I] lower-level data for this if */
struct refcnt if_refcnt;
TAILQ_ENTRY(ifnet) if_list; /* [NK] all struct ifnets are chained */
TAILQ_ENTRY(ifnet) if_tmplist; /* [T] temporary list */
TAILQ_HEAD(, ifaddr) if_addrlist; /* [N] list of addresses per if */
TAILQ_HEAD(, ifmaddr) if_maddrlist; /* [N] list of multicast records */
TAILQ_HEAD(, ifg_list) if_groups; /* [N] list of groups per if */
@ -273,6 +275,9 @@ struct ifg_group {
int ifg_carp_demoted; /* [K] carp demotion counter */
TAILQ_HEAD(, ifg_member) ifg_members; /* [N] list of members per group */
TAILQ_ENTRY(ifg_group) ifg_next; /* [N] all groups are chained */
struct refcnt ifg_tmprefcnt;
TAILQ_ENTRY(ifg_group) ifg_tmplist; /* [T] temporary list */
};
struct ifg_member {

View file

@ -1,4 +1,4 @@
/* $OpenBSD: rtsock.c,v 1.377 2025/01/09 18:20:29 bluhm Exp $ */
/* $OpenBSD: rtsock.c,v 1.378 2025/01/24 09:16:55 mvs Exp $ */
/* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */
/*
@ -2136,11 +2136,17 @@ sysctl_ifnames(struct walkarg *w)
int
sysctl_source(int af, u_int tableid, struct walkarg *w)
{
union {
struct sockaddr_in in;
#ifdef INET6
struct sockaddr_in6 in6;
#endif
} buf;
struct sockaddr *sa;
int size, error = 0;
sa = rtable_getsource(tableid, af);
if (sa) {
NET_LOCK_SHARED();
if ((sa = rtable_getsource(tableid, af)) != NULL) {
switch (sa->sa_family) {
case AF_INET:
size = sizeof(struct sockaddr_in);
@ -2151,11 +2157,19 @@ sysctl_source(int af, u_int tableid, struct walkarg *w)
break;
#endif
default:
return (0);
sa = NULL;
break;
}
}
if (sa != NULL)
memcpy(&buf, sa, size);
NET_UNLOCK_SHARED();
if (sa != NULL) {
w->w_needed += size;
if (w->w_where && w->w_needed <= w->w_given) {
if ((error = copyout(sa, w->w_where, size)))
if ((error = copyout(&buf, w->w_where, size)))
return (error);
w->w_where += size;
}
@ -2236,7 +2250,6 @@ sysctl_rtable(int *name, u_int namelen, void *where, size_t *given, void *new,
tableid = w.w_arg;
if (!rtable_exists(tableid))
return (ENOENT);
NET_LOCK_SHARED();
for (i = 1; i <= AF_MAX; i++) {
if (af != 0 && af != i)
continue;
@ -2247,7 +2260,6 @@ sysctl_rtable(int *name, u_int namelen, void *where, size_t *given, void *new,
if (error)
break;
}
NET_UNLOCK_SHARED();
break;
}
free(w.w_tmem, M_RTABLE, w.w_tmemsize);