Merge ^/head r292951 through r293015.

This commit is contained in:
Dimitry Andric 2015-12-31 22:55:02 +00:00
commit 8c49098554
99 changed files with 11042 additions and 1875 deletions

View File

@ -4,7 +4,7 @@
The compilation of software known as FreeBSD is distributed under the
following terms:
Copyright (c) 1992-2015 The FreeBSD Project. All rights reserved.
Copyright (c) 1992-2016 The FreeBSD Project. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions

File diff suppressed because it is too large Load Diff

View File

@ -43,12 +43,15 @@ struct arglist {
/*
* expandarg() flags
*/
#define EXP_FULL 0x1 /* perform word splitting & file globbing */
#define EXP_SPLIT 0x1 /* perform word splitting */
#define EXP_TILDE 0x2 /* do normal tilde expansion */
#define EXP_VARTILDE 0x4 /* expand tildes in an assignment */
#define EXP_CASE 0x10 /* keeps quotes around for CASE pattern */
#define EXP_SPLIT_LIT 0x20 /* IFS split literal text ${v+-a b c} */
#define EXP_LIT_QUOTED 0x40 /* for EXP_SPLIT_LIT, start off quoted */
#define EXP_GLOB 0x80 /* perform file globbing */
#define EXP_FULL (EXP_SPLIT | EXP_GLOB)
void emptyarglist(struct arglist *);

View File

@ -7720,12 +7720,26 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
refers to is in a different object. We can't tell for
sure yet, because something later might force the
symbol local. */
if (r_type != R_ARM_ABS32
&& r_type != R_ARM_REL32
&& r_type != R_ARM_ABS32_NOI
&& r_type != R_ARM_REL32_NOI
&& r_type != R_ARM_ABS12)
h->needs_plt = 1;
switch (r_type)
{
case R_ARM_ABS12:
case R_ARM_ABS32:
case R_ARM_ABS32_NOI:
case R_ARM_REL32:
case R_ARM_REL32_NOI:
case R_ARM_MOVW_ABS_NC:
case R_ARM_MOVT_ABS:
case R_ARM_MOVW_PREL_NC:
case R_ARM_MOVT_PREL:
case R_ARM_THM_MOVW_ABS_NC:
case R_ARM_THM_MOVT_ABS:
case R_ARM_THM_MOVW_PREL_NC:
case R_ARM_THM_MOVT_PREL:
break;
default:
h->needs_plt = 1;
break;
}
/* If we create a PLT entry, this relocation will reference
it, even if it's an ABS32 relocation. */

View File

@ -59,14 +59,18 @@ MDXFileChunk(const char *filename, char *buf, off_t ofs, off_t len)
f = open(filename, O_RDONLY);
if (f < 0)
return 0;
if (fstat(f, &stbuf) < 0)
return 0;
if (fstat(f, &stbuf) < 0) {
i = -1;
goto error;
}
if (ofs > stbuf.st_size)
ofs = stbuf.st_size;
if ((len == 0) || (len > stbuf.st_size - ofs))
len = stbuf.st_size - ofs;
if (lseek(f, ofs, SEEK_SET) < 0)
return 0;
if (lseek(f, ofs, SEEK_SET) < 0) {
i = -1;
goto error;
}
n = len;
i = 0;
while (n > 0) {
@ -79,6 +83,7 @@ MDXFileChunk(const char *filename, char *buf, off_t ofs, off_t len)
MDXUpdate(&ctx, buffer, i);
n -= i;
}
error:
e = errno;
close(f);
errno = e;

View File

@ -44,6 +44,12 @@ SRCS+= bcmp.c bcopy.c bzero.c ffs.c memccpy.c memchr.c memcmp.c memcpy.c \
.if ${MACHINE_CPUARCH} == "arm"
.PATH: ${LIBC_SRC}/arm/gen
# Do not generate movt/movw, because the relocation fixup for them does not
# translate to the -Bsymbolic -pie format required by self_reloc() in loader(8).
# Also, the fpu is not available in a standalone environment.
CFLAGS.clang+= -mllvm -arm-use-movt=0
CFLAGS.clang+= -mfpu=none
# Compiler support functions
.PATH: ${LIBSTAND_SRC}/../../contrib/compiler-rt/lib/builtins/
# __clzsi2 and ctzsi2 for various builtin functions

View File

@ -424,6 +424,8 @@ MAN= aac.4 \
rndtest.4 \
route.4 \
rp.4 \
rtwn.4 \
rtwnfw.4 \
rue.4 \
rum.4 \
run.4 \

165
share/man/man4/rtwn.4 Normal file
View File

@ -0,0 +1,165 @@
.\" $OpenBSD: rtwn.4,v 1.2 2015/07/09 11:28:53 stsp Exp $
.\"
.\" Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
.\" Copyright (c) 2015 Stefan Sperling <stsp@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.
.\"
.\" $FreeBSD$
.\"
.Dd October 28, 2015
.Dt RTWN 4
.Os
.Sh NAME
.Nm rtwn
.Nd Realtek RTL8188CE PCIe IEEE 802.11b/g/n wireless network device
.Sh SYNOPSIS
To compile this driver into the kernel,
place the following lines in your
kernel configuration file:
.Bd -ragged -offset indent
.Cd "device rtwn"
.Cd "device rtwnfw"
.Cd "device wlan"
.Cd "device firmware"
.Ed
.Pp
Alternatively, to load the driver as a
module at boot time, place the following line in
.Xr loader.conf 5 :
.Bd -literal -offset indent
if_rtwn_load="YES"
.Ed
.Pp
After you have read the license in
.Pa /usr/share/doc/legal/realtek.LICENSE
you will want to add the following lines to
.Xr loader.conf 5 :
.Bd -literal -offset indent
legal.realtek.license_ack=1
rtwn-rtl8192cfwU_load="YES"
rtwn-rtl8192cfwU_B_load="YES"
.Ed
.Sh DESCRIPTION
The
.Nm
driver supports PCIe wireless network devices based on the Realtek
RTL8188CE chipset.
.Pp
The RTL8188CE is a highly integrated 802.11n adapter that combines a MAC,
a 1T1R capable baseband and an RF in a single chip.
It operates in the 2GHz spectrum only.
.Pp
These are the modes the
.Nm
driver can operate in:
.Bl -tag -width "IBSS-masterXX"
.It BSS mode
Also known as
.Em infrastructure
mode, this is used when associating with an access point, through
which all traffic passes.
This mode is the default.
.It monitor mode
In this mode the driver is able to receive packets without
associating with an access point.
This disables the internal receive filter and enables the card to
capture packets from networks which it wouldn't normally have access to,
or to scan for access points.
.El
.Pp
The
.Nm
driver can be configured to use
Wired Equivalent Privacy (WEP) or
Wi-Fi Protected Access (WPA-PSK and WPA2-PSK).
WPA is the current encryption standard for wireless networks.
It is strongly recommended that WEP
not be used as the sole mechanism
to secure wireless communication,
due to serious weaknesses in it.
.Pp
The
.Nm
driver can be configured at runtime with
.Xr ifconfig 8 .
.Sh FILES
The driver needs at least version 1.0 of the following firmware files,
which are loaded when an interface is brought up:
.Pp
.Bl -tag -width Ds -offset indent -compact
.It Pa /boot/kernel/rtwn-rtl8192cfwU.ko
.It Pa /boot/kernel/rtwn-rtl8192cfwU_B.ko
.El
.Sh EXAMPLES
Join an existing BSS network (i.e., connect to an access point):
.Bd -literal -offset indent
ifconfig wlan create wlandev rtwn0 inet 192.168.0.20 \e
netmask 0xffffff00
.Ed
.Pp
Join a specific BSS network with network name
.Dq Li my_net :
.Pp
.Dl "ifconfig wlan create wlandev rtwn0 ssid my_net up"
.Pp
Join a specific BSS network with 64-bit WEP encryption:
.Bd -literal -offset indent
ifconfig wlan create wlandev rtwn0 ssid my_net \e
wepmode on wepkey 0x1234567890 weptxkey 1 up
.Ed
.Sh DIAGNOSTICS
.Bl -diag
.It "could not read firmware %s"
For some reason, the driver was unable to read the microcode file from the
filesystem.
The file might be missing or corrupted.
.It "device timeout"
A frame dispatched to the hardware for transmission did not complete in time.
The driver will reset the hardware.
This should not happen.
.El
.Sh SEE ALSO
.Xr pci 4 ,
.Xr rtwnfw 4 ,
.Xr wlan 4 ,
.Xr wlan_ccmp 4 ,
.Xr wlan_tkip 4 ,
.Xr wlan_wep 4 ,
.Xr ifconfig 8 ,
.Xr wpa_supplicant 8
.Sh HISTORY
The
.Nm
driver first appeared in
.Ox 5.8 .
.Sh AUTHORS
The
.Nm
driver was written by
.An -nosplit
.An Stefan Sperling Aq Mt stsp@openbsd.org
and ported by
.An Kevin Lo Aq Mt kevlo@freebsd.org .
It was based on the
.Xr urtwn 4
driver written by
.An Damien Bergamini Aq Mt damien.bergamini@free.fr .
.Sh CAVEATS
The
.Nm
driver does not support any of the 802.11n capabilities offered by the
adapters.
Additional work is required in
.Xr ieee80211 9
before those features can be supported.

74
share/man/man4/rtwnfw.4 Normal file
View File

@ -0,0 +1,74 @@
.\" Copyright (c) 2015 Kevin Lo
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. The name of the author may not be used to endorse or promote products
.\" derived from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $FreeBSD$
.\"
.Dd October 28, 2015
.Dt RTWNFW 4
.Os
.Sh NAME
.Nm rtwnfw
.Nd "Firmware Module for Realtek Wireless driver"
.Sh SYNOPSIS
To compile this module into the kernel,
place the following line in your
kernel configuration file:
.Bd -ragged -offset indent
.Cd "device rtwnfw"
.Ed
.Pp
This will include three firmware images inside the kernel.
If you want to pick only the firmware image for your network adapter choose one
of the following:
.Bd -ragged -offset indent
.Cd "device rtwn-rtl8192cfwU"
.Cd "device rtwn-rtl8192cfwU_B"
.Ed
.Pp
Alternatively, to load the driver as a
module at boot time, place the following line in
.Xr loader.conf 5 :
.Bd -literal -offset indent
rtwn-rtl8192cfwU_load="YES"
rtwn-rtl8192cfwU_B_load="YES"
.Ed
.Sh DESCRIPTION
This module provides access to firmware sets for the
Realtek RTL8188CE chip based PCIe adapters.
It may be
statically linked into the kernel, or loaded as a module.
.Pp
For the loaded firmware to be enabled for use the license at
.Pa /usr/share/doc/legal/realtek.LICENSE
must be agreed to by adding the following line to
.Xr loader.conf 5 :
.Pp
.Dl "legal.realtek.license_ack=1"
.Sh FILES
.Bl -tag -width ".Pa /usr/share/doc/legal/realtek.LICENSE" -compact
.It Pa /usr/share/doc/legal/realtek.LICENSE
.Nm
firmware license
.El
.Sh SEE ALSO
.Xr rtwn 4 ,
.Xr firmware 9

View File

@ -37,9 +37,12 @@ __FBSDID("$FreeBSD$");
#include <sys/sysctl.h>
#include <sys/systm.h>
#include <machine/atomic.h>
#include <machine/cpu.h>
#include <machine/cpufunc.h>
static int ident_lock;
char machine[] = "arm64";
SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0,
@ -56,6 +59,7 @@ SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0,
* Aff0 - CPU number in Aff1 cluster
*/
uint64_t __cpu_affinity[MAXCPU];
static u_int cpu_aff_levels;
struct cpu_desc {
u_int cpu_impl;
@ -64,9 +68,32 @@ struct cpu_desc {
u_int cpu_revision;
const char *cpu_impl_name;
const char *cpu_part_name;
uint64_t mpidr;
uint64_t id_aa64afr0;
uint64_t id_aa64afr1;
uint64_t id_aa64dfr0;
uint64_t id_aa64dfr1;
uint64_t id_aa64isar0;
uint64_t id_aa64isar1;
uint64_t id_aa64mmfr0;
uint64_t id_aa64mmfr1;
uint64_t id_aa64pfr0;
uint64_t id_aa64pfr1;
};
struct cpu_desc cpu_desc[MAXCPU];
static u_int cpu_print_regs;
#define PRINT_ID_AA64_AFR0 0x00000001
#define PRINT_ID_AA64_AFR1 0x00000002
#define PRINT_ID_AA64_DFR0 0x00000004
#define PRINT_ID_AA64_DFR1 0x00000008
#define PRINT_ID_AA64_ISAR0 0x00000010
#define PRINT_ID_AA64_ISAR1 0x00000020
#define PRINT_ID_AA64_MMFR0 0x00000040
#define PRINT_ID_AA64_MMFR1 0x00000080
#define PRINT_ID_AA64_PFR0 0x00000100
#define PRINT_ID_AA64_PFR1 0x00000200
struct cpu_parts {
u_int part_id;
@ -124,7 +151,398 @@ const struct cpu_implementers cpu_implementers[] = {
CPU_IMPLEMENTER_NONE,
};
void identify_cpu(void);
void
print_cpu_features(u_int cpu)
{
int printed;
printf("CPU%3d: %s %s r%dp%d", cpu, cpu_desc[cpu].cpu_impl_name,
cpu_desc[cpu].cpu_part_name, cpu_desc[cpu].cpu_variant,
cpu_desc[cpu].cpu_revision);
printf(" affinity:");
switch(cpu_aff_levels) {
default:
case 4:
printf(" %2d", CPU_AFF3(cpu_desc[cpu].mpidr));
/* FALLTHROUGH */
case 3:
printf(" %2d", CPU_AFF2(cpu_desc[cpu].mpidr));
/* FALLTHROUGH */
case 2:
printf(" %2d", CPU_AFF1(cpu_desc[cpu].mpidr));
/* FALLTHROUGH */
case 1:
case 0: /* On UP this will be zero */
printf(" %2d", CPU_AFF0(cpu_desc[cpu].mpidr));
break;
}
printf("\n");
if (cpu != 0 && cpu_print_regs == 0)
return;
#define SEP_STR ((printed++) == 0) ? "" : ","
/* AArch64 Instruction Set Attribute Register 0 */
if (cpu == 0 || (cpu_print_regs & PRINT_ID_AA64_ISAR0) != 0) {
printed = 0;
printf(" Instruction Set Attributes 0 = <");
switch (ID_AA64ISAR0_AES(cpu_desc[cpu].id_aa64isar0)) {
case ID_AA64ISAR0_AES_NONE:
break;
case ID_AA64ISAR0_AES_BASE:
printf("%sAES", SEP_STR);
break;
case ID_AA64ISAR0_AES_PMULL:
printf("%sAES+PMULL", SEP_STR);
break;
default:
printf("%sUnknown AES", SEP_STR);
break;
}
switch (ID_AA64ISAR0_SHA1(cpu_desc[cpu].id_aa64isar0)) {
case ID_AA64ISAR0_SHA1_NONE:
break;
case ID_AA64ISAR0_SHA1_BASE:
printf("%sSHA1", SEP_STR);
break;
default:
printf("%sUnknown SHA1", SEP_STR);
break;
}
switch (ID_AA64ISAR0_SHA2(cpu_desc[cpu].id_aa64isar0)) {
case ID_AA64ISAR0_SHA2_NONE:
break;
case ID_AA64ISAR0_SHA2_BASE:
printf("%sSHA2", SEP_STR);
break;
default:
printf("%sUnknown SHA2", SEP_STR);
break;
}
switch (ID_AA64ISAR0_CRC32(cpu_desc[cpu].id_aa64isar0)) {
case ID_AA64ISAR0_CRC32_NONE:
break;
case ID_AA64ISAR0_CRC32_BASE:
printf("%sCRC32", SEP_STR);
break;
default:
printf("%sUnknown CRC32", SEP_STR);
break;
}
if ((cpu_desc[cpu].id_aa64isar0 & ~ID_AA64ISAR0_MASK) != 0)
printf("%s%#lx", SEP_STR,
cpu_desc[cpu].id_aa64isar0 & ~ID_AA64ISAR0_MASK);
printf(">\n");
}
/* AArch64 Instruction Set Attribute Register 1 */
if (cpu == 0 || (cpu_print_regs & PRINT_ID_AA64_ISAR1) != 0) {
printf(" Instruction Set Attributes 1 = <%#lx>\n",
cpu_desc[cpu].id_aa64isar1);
}
/* AArch64 Processor Feature Register 0 */
if (cpu == 0 || (cpu_print_regs & PRINT_ID_AA64_PFR0) != 0) {
printed = 0;
printf(" Processor Features 0 = <");
switch (ID_AA64PFR0_GIC(cpu_desc[cpu].id_aa64pfr0)) {
case ID_AA64PFR0_GIC_CPUIF_NONE:
break;
case ID_AA64PFR0_GIC_CPUIF_EN:
printf("%sGIC", SEP_STR);
break;
default:
printf("%sUnknown GIC interface", SEP_STR);
break;
}
switch (ID_AA64PFR0_ADV_SIMD(cpu_desc[cpu].id_aa64pfr0)) {
case ID_AA64PFR0_ADV_SIMD_NONE:
break;
case ID_AA64PFR0_ADV_SIMD_IMPL:
printf("%sAdvSIMD", SEP_STR);
break;
default:
printf("%sUnknown AdvSIMD", SEP_STR);
break;
}
switch (ID_AA64PFR0_FP(cpu_desc[cpu].id_aa64pfr0)) {
case ID_AA64PFR0_FP_NONE:
break;
case ID_AA64PFR0_FP_IMPL:
printf("%sFloat", SEP_STR);
break;
default:
printf("%sUnknown Float", SEP_STR);
break;
}
switch (ID_AA64PFR0_EL3(cpu_desc[cpu].id_aa64pfr0)) {
case ID_AA64PFR0_EL3_NONE:
printf("%sNo EL3", SEP_STR);
break;
case ID_AA64PFR0_EL3_64:
printf("%sEL3", SEP_STR);
break;
case ID_AA64PFR0_EL3_64_32:
printf("%sEL3 32", SEP_STR);
break;
default:
printf("%sUnknown EL3", SEP_STR);
break;
}
switch (ID_AA64PFR0_EL2(cpu_desc[cpu].id_aa64pfr0)) {
case ID_AA64PFR0_EL2_NONE:
printf("%sNo EL2", SEP_STR);
break;
case ID_AA64PFR0_EL2_64:
printf("%sEL2", SEP_STR);
break;
case ID_AA64PFR0_EL2_64_32:
printf("%sEL2 32", SEP_STR);
break;
default:
printf("%sUnknown EL2", SEP_STR);
break;
}
switch (ID_AA64PFR0_EL1(cpu_desc[cpu].id_aa64pfr0)) {
case ID_AA64PFR0_EL1_64:
printf("%sEL1", SEP_STR);
break;
case ID_AA64PFR0_EL1_64_32:
printf("%sEL1 32", SEP_STR);
break;
default:
printf("%sUnknown EL1", SEP_STR);
break;
}
switch (ID_AA64PFR0_EL0(cpu_desc[cpu].id_aa64pfr0)) {
case ID_AA64PFR0_EL0_64:
printf("%sEL0", SEP_STR);
break;
case ID_AA64PFR0_EL0_64_32:
printf("%sEL0 32", SEP_STR);
break;
default:
printf("%sUnknown EL0", SEP_STR);
break;
}
if ((cpu_desc[cpu].id_aa64pfr0 & ~ID_AA64PFR0_MASK) != 0)
printf("%s%#lx", SEP_STR,
cpu_desc[cpu].id_aa64pfr0 & ~ID_AA64PFR0_MASK);
printf(">\n");
}
/* AArch64 Processor Feature Register 1 */
if (cpu == 0 || (cpu_print_regs & PRINT_ID_AA64_PFR1) != 0) {
printf(" Processor Features 1 = <%#lx>\n",
cpu_desc[cpu].id_aa64pfr1);
}
/* AArch64 Memory Model Feature Register 0 */
if (cpu == 0 || (cpu_print_regs & PRINT_ID_AA64_MMFR0) != 0) {
printed = 0;
printf(" Memory Model Features 0 = <");
switch (ID_AA64MMFR0_TGRAN4(cpu_desc[cpu].id_aa64mmfr0)) {
case ID_AA64MMFR0_TGRAN4_NONE:
break;
case ID_AA64MMFR0_TGRAN4_IMPL:
printf("%s4k Granule", SEP_STR);
break;
default:
printf("%sUnknown 4k Granule", SEP_STR);
break;
}
switch (ID_AA64MMFR0_TGRAN16(cpu_desc[cpu].id_aa64mmfr0)) {
case ID_AA64MMFR0_TGRAN16_NONE:
break;
case ID_AA64MMFR0_TGRAN16_IMPL:
printf("%s16k Granule", SEP_STR);
break;
default:
printf("%sUnknown 16k Granule", SEP_STR);
break;
}
switch (ID_AA64MMFR0_TGRAN64(cpu_desc[cpu].id_aa64mmfr0)) {
case ID_AA64MMFR0_TGRAN64_NONE:
break;
case ID_AA64MMFR0_TGRAN64_IMPL:
printf("%s64k Granule", SEP_STR);
break;
default:
printf("%sUnknown 64k Granule", SEP_STR);
break;
}
switch (ID_AA64MMFR0_BIGEND(cpu_desc[cpu].id_aa64mmfr0)) {
case ID_AA64MMFR0_BIGEND_FIXED:
break;
case ID_AA64MMFR0_BIGEND_MIXED:
printf("%sMixedEndian", SEP_STR);
break;
default:
printf("%sUnknown Endian switching", SEP_STR);
break;
}
switch (ID_AA64MMFR0_BIGEND_EL0(cpu_desc[cpu].id_aa64mmfr0)) {
case ID_AA64MMFR0_BIGEND_EL0_FIXED:
break;
case ID_AA64MMFR0_BIGEND_EL0_MIXED:
printf("%sEL0 MixEndian", SEP_STR);
break;
default:
printf("%sUnknown EL0 Endian switching", SEP_STR);
break;
}
switch (ID_AA64MMFR0_S_NS_MEM(cpu_desc[cpu].id_aa64mmfr0)) {
case ID_AA64MMFR0_S_NS_MEM_NONE:
break;
case ID_AA64MMFR0_S_NS_MEM_DISTINCT:
printf("%sS/NS Mem", SEP_STR);
break;
default:
printf("%sUnknown S/NS Mem", SEP_STR);
break;
}
switch (ID_AA64MMFR0_ASID_BITS(cpu_desc[cpu].id_aa64mmfr0)) {
case ID_AA64MMFR0_ASID_BITS_8:
printf("%s8bit ASID", SEP_STR);
break;
case ID_AA64MMFR0_ASID_BITS_16:
printf("%s16bit ASID", SEP_STR);
break;
default:
printf("%sUnknown ASID", SEP_STR);
break;
}
switch (ID_AA64MMFR0_PA_RANGE(cpu_desc[cpu].id_aa64mmfr0)) {
case ID_AA64MMFR0_PA_RANGE_4G:
printf("%s4GB PA", SEP_STR);
break;
case ID_AA64MMFR0_PA_RANGE_64G:
printf("%s64GB PA", SEP_STR);
break;
case ID_AA64MMFR0_PA_RANGE_1T:
printf("%s1TB PA", SEP_STR);
break;
case ID_AA64MMFR0_PA_RANGE_4T:
printf("%s4TB PA", SEP_STR);
break;
case ID_AA64MMFR0_PA_RANGE_16T:
printf("%s16TB PA", SEP_STR);
break;
case ID_AA64MMFR0_PA_RANGE_256T:
printf("%s256TB PA", SEP_STR);
break;
default:
printf("%sUnknown PA Range", SEP_STR);
break;
}
if ((cpu_desc[cpu].id_aa64mmfr0 & ~ID_AA64MMFR0_MASK) != 0)
printf("%s%#lx", SEP_STR,
cpu_desc[cpu].id_aa64mmfr0 & ~ID_AA64MMFR0_MASK);
printf(">\n");
}
/* AArch64 Memory Model Feature Register 1 */
if (cpu == 0 || (cpu_print_regs & PRINT_ID_AA64_MMFR1) != 0) {
printf(" Memory Model Features 1 = <%#lx>\n",
cpu_desc[cpu].id_aa64mmfr1);
}
/* AArch64 Debug Feature Register 0 */
if (cpu == 0 || (cpu_print_regs & PRINT_ID_AA64_DFR0) != 0) {
printed = 0;
printf(" Debug Features 0 = <");
printf("%s%lu CTX Breakpoints", SEP_STR,
ID_AA64DFR0_CTX_CMPS(cpu_desc[cpu].id_aa64dfr0));
printf("%s%lu Watchpoints", SEP_STR,
ID_AA64DFR0_WRPS(cpu_desc[cpu].id_aa64dfr0));
printf("%s%lu Breakpoints", SEP_STR,
ID_AA64DFR0_BRPS(cpu_desc[cpu].id_aa64dfr0));
switch (ID_AA64DFR0_PMU_VER(cpu_desc[cpu].id_aa64dfr0)) {
case ID_AA64DFR0_PMU_VER_NONE:
break;
case ID_AA64DFR0_PMU_VER_3:
printf("%sPMUv3", SEP_STR);
break;
case ID_AA64DFR0_PMU_VER_IMPL:
printf("%sImplementation defined PMU", SEP_STR);
break;
default:
printf("%sUnknown PMU", SEP_STR);
break;
}
switch (ID_AA64DFR0_TRACE_VER(cpu_desc[cpu].id_aa64dfr0)) {
case ID_AA64DFR0_TRACE_VER_NONE:
break;
case ID_AA64DFR0_TRACE_VER_IMPL:
printf("%sTrace", SEP_STR);
break;
default:
printf("%sUnknown Trace", SEP_STR);
break;
}
switch (ID_AA64DFR0_DEBUG_VER(cpu_desc[cpu].id_aa64dfr0)) {
case ID_AA64DFR0_DEBUG_VER_8:
printf("%sDebug v8", SEP_STR);
break;
default:
printf("%sUnknown Debug", SEP_STR);
break;
}
if (cpu_desc[cpu].id_aa64dfr0 & ~ID_AA64DFR0_MASK)
printf("%s%#lx", SEP_STR,
cpu_desc[cpu].id_aa64dfr0 & ~ID_AA64DFR0_MASK);
printf(">\n");
}
/* AArch64 Memory Model Feature Register 1 */
if (cpu == 0 || (cpu_print_regs & PRINT_ID_AA64_DFR1) != 0) {
printf(" Debug Features 1 = <%#lx>\n",
cpu_desc[cpu].id_aa64dfr1);
}
/* AArch64 Auxiliary Feature Register 0 */
if (cpu == 0 || (cpu_print_regs & PRINT_ID_AA64_AFR0) != 0) {
printf(" Auxiliary Features 0 = <%#lx>\n",
cpu_desc[cpu].id_aa64afr0);
}
/* AArch64 Auxiliary Feature Register 1 */
if (cpu == 0 || (cpu_print_regs & PRINT_ID_AA64_AFR1) != 0) {
printf(" Auxiliary Features 1 = <%#lx>\n",
cpu_desc[cpu].id_aa64afr1);
}
#undef SEP_STR
}
void
identify_cpu(void)
@ -133,7 +551,6 @@ identify_cpu(void)
u_int impl_id;
u_int part_id;
u_int cpu;
uint64_t mpidr;
size_t i;
const struct cpu_parts *cpu_partsp = NULL;
@ -171,19 +588,77 @@ identify_cpu(void)
cpu_desc[cpu].cpu_variant = CPU_VAR(midr);
/* Save affinity for current CPU */
mpidr = get_mpidr();
CPU_AFFINITY(cpu) = mpidr & CPU_AFF_MASK;
cpu_desc[cpu].mpidr = get_mpidr();
CPU_AFFINITY(cpu) = cpu_desc[cpu].mpidr & CPU_AFF_MASK;
/* Print details for boot CPU or if we want verbose output */
if (cpu == 0 || bootverbose) {
printf("CPU(%d): %s %s r%dp%d\n", cpu,
cpu_desc[cpu].cpu_impl_name,
cpu_desc[cpu].cpu_part_name,
cpu_desc[cpu].cpu_variant,
cpu_desc[cpu].cpu_revision);
cpu_desc[cpu].id_aa64dfr0 = READ_SPECIALREG(id_aa64dfr0_el1);
cpu_desc[cpu].id_aa64dfr1 = READ_SPECIALREG(id_aa64dfr1_el1);
cpu_desc[cpu].id_aa64isar0 = READ_SPECIALREG(id_aa64isar0_el1);
cpu_desc[cpu].id_aa64isar1 = READ_SPECIALREG(id_aa64isar1_el1);
cpu_desc[cpu].id_aa64mmfr0 = READ_SPECIALREG(id_aa64mmfr0_el1);
cpu_desc[cpu].id_aa64mmfr1 = READ_SPECIALREG(id_aa64mmfr1_el1);
cpu_desc[cpu].id_aa64pfr0 = READ_SPECIALREG(id_aa64pfr0_el1);
cpu_desc[cpu].id_aa64pfr1 = READ_SPECIALREG(id_aa64pfr1_el1);
if (cpu != 0) {
/*
* This code must run on one cpu at a time, but we are
* not scheduling on the current core so implement a
* simple spinlock.
*/
while (atomic_cmpset_acq_int(&ident_lock, 0, 1) == 0)
__asm __volatile("wfe" ::: "memory");
switch (cpu_aff_levels) {
case 0:
if (CPU_AFF0(cpu_desc[cpu].mpidr) !=
CPU_AFF0(cpu_desc[0].mpidr))
cpu_aff_levels = 1;
/* FALLTHROUGH */
case 1:
if (CPU_AFF1(cpu_desc[cpu].mpidr) !=
CPU_AFF1(cpu_desc[0].mpidr))
cpu_aff_levels = 2;
/* FALLTHROUGH */
case 2:
if (CPU_AFF2(cpu_desc[cpu].mpidr) !=
CPU_AFF2(cpu_desc[0].mpidr))
cpu_aff_levels = 3;
/* FALLTHROUGH */
case 3:
if (CPU_AFF3(cpu_desc[cpu].mpidr) !=
CPU_AFF3(cpu_desc[0].mpidr))
cpu_aff_levels = 4;
break;
}
if (cpu_desc[cpu].id_aa64afr0 != cpu_desc[0].id_aa64afr0)
cpu_print_regs |= PRINT_ID_AA64_AFR0;
if (cpu_desc[cpu].id_aa64afr1 != cpu_desc[0].id_aa64afr1)
cpu_print_regs |= PRINT_ID_AA64_AFR1;
if (cpu_desc[cpu].id_aa64dfr0 != cpu_desc[0].id_aa64dfr0)
cpu_print_regs |= PRINT_ID_AA64_DFR0;
if (cpu_desc[cpu].id_aa64dfr1 != cpu_desc[0].id_aa64dfr1)
cpu_print_regs |= PRINT_ID_AA64_DFR1;
if (cpu_desc[cpu].id_aa64isar0 != cpu_desc[0].id_aa64isar0)
cpu_print_regs |= PRINT_ID_AA64_ISAR0;
if (cpu_desc[cpu].id_aa64isar1 != cpu_desc[0].id_aa64isar1)
cpu_print_regs |= PRINT_ID_AA64_ISAR1;
if (cpu_desc[cpu].id_aa64mmfr0 != cpu_desc[0].id_aa64mmfr0)
cpu_print_regs |= PRINT_ID_AA64_MMFR0;
if (cpu_desc[cpu].id_aa64mmfr1 != cpu_desc[0].id_aa64mmfr1)
cpu_print_regs |= PRINT_ID_AA64_MMFR1;
if (cpu_desc[cpu].id_aa64pfr0 != cpu_desc[0].id_aa64pfr0)
cpu_print_regs |= PRINT_ID_AA64_PFR0;
if (cpu_desc[cpu].id_aa64pfr1 != cpu_desc[0].id_aa64pfr1)
cpu_print_regs |= PRINT_ID_AA64_PFR1;
/* Wake up the other CPUs */
atomic_store_rel_int(&ident_lock, 0);
__asm __volatile("sev" ::: "memory");
}
if (bootverbose)
printf("CPU%u affinity: %u.%u.%u.%u\n", 0, CPU_AFF0(mpidr),
CPU_AFF1(mpidr), CPU_AFF2(mpidr), CPU_AFF3(mpidr));
}

View File

@ -175,7 +175,7 @@ arm64_cpu_attach(device_t dev)
static void
release_aps(void *dummy __unused)
{
int i;
int cpu, i;
/* Setup the IPI handler */
for (i = 0; i < COUNT_IPI; i++)
@ -188,8 +188,14 @@ release_aps(void *dummy __unused)
printf("Release APs\n");
for (i = 0; i < 2000; i++) {
if (smp_started)
if (smp_started) {
for (cpu = 0; cpu <= mp_maxid; cpu++) {
if (CPU_ABSENT(cpu))
continue;
print_cpu_features(cpu);
}
return;
}
DELAY(1000);
}

View File

@ -121,19 +121,147 @@
/* ICC_SRE_EL2 */
#define ICC_SRE_EL2_EN (1U << 3)
/* ID_AA64DFR0_EL1 */
#define ID_AA64DFR0_MASK 0xf0f0ffff
#define ID_AA64DFR0_DEBUG_VER_SHIFT 0
#define ID_AA64DFR0_DEBUG_VER_MASK (0xf << ID_AA64DFR0_DEBUG_VER_SHIFT)
#define ID_AA64DFR0_DEBUG_VER(x) ((x) & ID_AA64DFR0_DEBUG_VER_MASK)
#define ID_AA64DFR0_DEBUG_VER_8 (0x6 << ID_AA64DFR0_DEBUG_VER_SHIFT)
#define ID_AA64DFR0_TRACE_VER_SHIFT 4
#define ID_AA64DFR0_TRACE_VER_MASK (0xf << ID_AA64DFR0_TRACE_VER_SHIFT)
#define ID_AA64DFR0_TRACE_VER(x) ((x) & ID_AA64DFR0_TRACE_VER_MASK)
#define ID_AA64DFR0_TRACE_VER_NONE (0x0 << ID_AA64DFR0_TRACE_VER_SHIFT)
#define ID_AA64DFR0_TRACE_VER_IMPL (0x1 << ID_AA64DFR0_TRACE_VER_SHIFT)
#define ID_AA64DFR0_PMU_VER_SHIFT 8
#define ID_AA64DFR0_PMU_VER_MASK (0xf << ID_AA64DFR0_PMU_VER_SHIFT)
#define ID_AA64DFR0_PMU_VER(x) ((x) & ID_AA64DFR0_PMU_VER_MASK)
#define ID_AA64DFR0_PMU_VER_NONE (0x0 << ID_AA64DFR0_PMU_VER_SHIFT)
#define ID_AA64DFR0_PMU_VER_3 (0x1 << ID_AA64DFR0_PMU_VER_SHIFT)
#define ID_AA64DFR0_PMU_VER_IMPL (0xf << ID_AA64DFR0_PMU_VER_SHIFT)
#define ID_AA64DFR0_BRPS_SHIFT 12
#define ID_AA64DFR0_BRPS_MASK (0xf << ID_AA64DFR0_BRPS_SHIFT)
#define ID_AA64DFR0_BRPS(x) \
((((x) >> ID_AA64DFR0_BRPS_SHIFT) & 0xf) + 1)
#define ID_AA64DFR0_WRPS_SHIFT 20
#define ID_AA64DFR0_WRPS_MASK (0xf << ID_AA64DFR0_WRPS_SHIFT)
#define ID_AA64DFR0_WRPS(x) \
((((x) >> ID_AA64DFR0_WRPS_SHIFT) & 0xf) + 1)
#define ID_AA64DFR0_CTX_CMPS_SHIFT 28
#define ID_AA64DFR0_CTX_CMPS_MASK (0xf << ID_AA64DFR0_CTX_CMPS_SHIFT)
#define ID_AA64DFR0_CTX_CMPS(x) \
((((x) >> ID_AA64DFR0_CTX_CMPS_SHIFT) & 0xf) + 1)
/* ID_AA64ISAR0_EL1 */
#define ID_AA64ISAR0_MASK 0x000ffff0
#define ID_AA64ISAR0_AES_SHIFT 4
#define ID_AA64ISAR0_AES_MASK (0xf << ID_AA64ISAR0_AES_SHIFT)
#define ID_AA64ISAR0_AES(x) ((x) & ID_AA64ISAR0_AES_MASK)
#define ID_AA64ISAR0_AES_NONE (0x0 << ID_AA64ISAR0_AES_SHIFT)
#define ID_AA64ISAR0_AES_BASE (0x1 << ID_AA64ISAR0_AES_SHIFT)
#define ID_AA64ISAR0_AES_PMULL (0x2 << ID_AA64ISAR0_AES_SHIFT)
#define ID_AA64ISAR0_SHA1_SHIFT 8
#define ID_AA64ISAR0_SHA1_MASK (0xf << ID_AA64ISAR0_SHA1_SHIFT)
#define ID_AA64ISAR0_SHA1(x) ((x) & ID_AA64ISAR0_SHA1_MASK)
#define ID_AA64ISAR0_SHA1_NONE (0x0 << ID_AA64ISAR0_SHA1_SHIFT)
#define ID_AA64ISAR0_SHA1_BASE (0x1 << ID_AA64ISAR0_SHA1_SHIFT)
#define ID_AA64ISAR0_SHA2_SHIFT 12
#define ID_AA64ISAR0_SHA2_MASK (0xf << ID_AA64ISAR0_SHA2_SHIFT)
#define ID_AA64ISAR0_SHA2(x) ((x) & ID_AA64ISAR0_SHA2_MASK)
#define ID_AA64ISAR0_SHA2_NONE (0x0 << ID_AA64ISAR0_SHA2_SHIFT)
#define ID_AA64ISAR0_SHA2_BASE (0x1 << ID_AA64ISAR0_SHA2_SHIFT)
#define ID_AA64ISAR0_CRC32_SHIFT 16
#define ID_AA64ISAR0_CRC32_MASK (0xf << ID_AA64ISAR0_CRC32_SHIFT)
#define ID_AA64ISAR0_CRC32(x) ((x) & ID_AA64ISAR0_CRC32_MASK)
#define ID_AA64ISAR0_CRC32_NONE (0x0 << ID_AA64ISAR0_CRC32_SHIFT)
#define ID_AA64ISAR0_CRC32_BASE (0x1 << ID_AA64ISAR0_CRC32_SHIFT)
/* ID_AA64MMFR0_EL1 */
#define ID_AA64MMFR0_MASK 0xffffffff
#define ID_AA64MMFR0_PA_RANGE_SHIFT 0
#define ID_AA64MMFR0_PA_RANGE_MASK (0xf << ID_AA64MMFR0_PA_RANGE_SHIFT)
#define ID_AA64MMFR0_PA_RANGE(x) ((x) & ID_AA64MMFR0_PA_RANGE_MASK)
#define ID_AA64MMFR0_PA_RANGE_4G (0x0 << ID_AA64MMFR0_PA_RANGE_SHIFT)
#define ID_AA64MMFR0_PA_RANGE_64G (0x1 << ID_AA64MMFR0_PA_RANGE_SHIFT)
#define ID_AA64MMFR0_PA_RANGE_1T (0x2 << ID_AA64MMFR0_PA_RANGE_SHIFT)
#define ID_AA64MMFR0_PA_RANGE_4T (0x3 << ID_AA64MMFR0_PA_RANGE_SHIFT)
#define ID_AA64MMFR0_PA_RANGE_16T (0x4 << ID_AA64MMFR0_PA_RANGE_SHIFT)
#define ID_AA64MMFR0_PA_RANGE_256T (0x5 << ID_AA64MMFR0_PA_RANGE_SHIFT)
#define ID_AA64MMFR0_ASID_BITS_SHIFT 4
#define ID_AA64MMFR0_ASID_BITS_MASK (0xf << ID_AA64MMFR0_ASID_BITS_SHIFT)
#define ID_AA64MMFR0_ASID_BITS(x) ((x) & ID_AA64MMFR0_ASID_BITS_MASK)
#define ID_AA64MMFR0_ASID_BITS_8 (0x0 << ID_AA64MMFR0_ASID_BITS_SHIFT)
#define ID_AA64MMFR0_ASID_BITS_16 (0x2 << ID_AA64MMFR0_ASID_BITS_SHIFT)
#define ID_AA64MMFR0_BIGEND_SHIFT 8
#define ID_AA64MMFR0_BIGEND_MASK (0xf << ID_AA64MMFR0_BIGEND_SHIFT)
#define ID_AA64MMFR0_BIGEND(x) ((x) & ID_AA64MMFR0_BIGEND_MASK)
#define ID_AA64MMFR0_BIGEND_FIXED (0x0 << ID_AA64MMFR0_BIGEND_SHIFT)
#define ID_AA64MMFR0_BIGEND_MIXED (0x1 << ID_AA64MMFR0_BIGEND_SHIFT)
#define ID_AA64MMFR0_S_NS_MEM_SHIFT 12
#define ID_AA64MMFR0_S_NS_MEM_MASK (0xf << ID_AA64MMFR0_S_NS_MEM_SHIFT)
#define ID_AA64MMFR0_S_NS_MEM(x) ((x) & ID_AA64MMFR0_S_NS_MEM_MASK)
#define ID_AA64MMFR0_S_NS_MEM_NONE (0x0 << ID_AA64MMFR0_S_NS_MEM_SHIFT)
#define ID_AA64MMFR0_S_NS_MEM_DISTINCT (0x1 << ID_AA64MMFR0_S_NS_MEM_SHIFT)
#define ID_AA64MMFR0_BIGEND_EL0_SHIFT 16
#define ID_AA64MMFR0_BIGEND_EL0_MASK (0xf << ID_AA64MMFR0_BIGEND_EL0_SHIFT)
#define ID_AA64MMFR0_BIGEND_EL0(x) ((x) & ID_AA64MMFR0_BIGEND_EL0_MASK)
#define ID_AA64MMFR0_BIGEND_EL0_FIXED (0x0 << ID_AA64MMFR0_BIGEND_EL0_SHIFT)
#define ID_AA64MMFR0_BIGEND_EL0_MIXED (0x1 << ID_AA64MMFR0_BIGEND_EL0_SHIFT)
#define ID_AA64MMFR0_TGRAN16_SHIFT 20
#define ID_AA64MMFR0_TGRAN16_MASK (0xf << ID_AA64MMFR0_TGRAN16_SHIFT)
#define ID_AA64MMFR0_TGRAN16(x) ((x) & ID_AA64MMFR0_TGRAN16_MASK)
#define ID_AA64MMFR0_TGRAN16_NONE (0x0 << ID_AA64MMFR0_TGRAN16_SHIFT)
#define ID_AA64MMFR0_TGRAN16_IMPL (0x1 << ID_AA64MMFR0_TGRAN16_SHIFT)
#define ID_AA64MMFR0_TGRAN64_SHIFT 24
#define ID_AA64MMFR0_TGRAN64_MASK (0xf << ID_AA64MMFR0_TGRAN64_SHIFT)
#define ID_AA64MMFR0_TGRAN64(x) ((x) & ID_AA64MMFR0_TGRAN64_MASK)
#define ID_AA64MMFR0_TGRAN64_IMPL (0x0 << ID_AA64MMFR0_TGRAN64_SHIFT)
#define ID_AA64MMFR0_TGRAN64_NONE (0xf << ID_AA64MMFR0_TGRAN64_SHIFT)
#define ID_AA64MMFR0_TGRAN4_SHIFT 28
#define ID_AA64MMFR0_TGRAN4_MASK (0xf << ID_AA64MMFR0_TGRAN4_SHIFT)
#define ID_AA64MMFR0_TGRAN4(x) ((x) & ID_AA64MMFR0_TGRAN4_MASK)
#define ID_AA64MMFR0_TGRAN4_IMPL (0x0 << ID_AA64MMFR0_TGRAN4_SHIFT)
#define ID_AA64MMFR0_TGRAN4_NONE (0xf << ID_AA64MMFR0_TGRAN4_SHIFT)
/* ID_AA64PFR0_EL1 */
#define ID_AA64PFR0_EL0_MASK (0xf << 0)
#define ID_AA64PFR0_EL1_MASK (0xf << 4)
#define ID_AA64PFR0_EL2_MASK (0xf << 8)
#define ID_AA64PFR0_EL3_MASK (0xf << 12)
#define ID_AA64PFR0_FP_MASK (0xf << 16)
#define ID_AA64PFR0_FP_IMPL (0x0 << 16) /* Floating-point implemented */
#define ID_AA64PFR0_FP_NONE (0xf << 16) /* Floating-point not implemented */
#define ID_AA64PFR0_ADV_SIMD_MASK (0xf << 20)
#define ID_AA64PFR0_GIC_SHIFT (24)
#define ID_AA64PFR0_GIC_BITS (0x4) /* Number of bits in GIC field */
#define ID_AA64PFR0_GIC_MASK (0xf << ID_AA64PFR0_GIC_SHIFT)
#define ID_AA64PFR0_GIC_CPUIF_EN (0x1 << ID_AA64PFR0_GIC_SHIFT)
#define ID_AA64PFR0_MASK 0x0fffffff
#define ID_AA64PFR0_EL0_SHIFT 0
#define ID_AA64PFR0_EL0_MASK (0xf << ID_AA64PFR0_EL0_SHIFT)
#define ID_AA64PFR0_EL0(x) ((x) & ID_AA64PFR0_EL0_MASK)
#define ID_AA64PFR0_EL0_64 (1 << ID_AA64PFR0_EL0_SHIFT)
#define ID_AA64PFR0_EL0_64_32 (2 << ID_AA64PFR0_EL0_SHIFT)
#define ID_AA64PFR0_EL1_SHIFT 4
#define ID_AA64PFR0_EL1_MASK (0xf << ID_AA64PFR0_EL1_SHIFT)
#define ID_AA64PFR0_EL1(x) ((x) & ID_AA64PFR0_EL1_MASK)
#define ID_AA64PFR0_EL1_64 (1 << ID_AA64PFR0_EL1_SHIFT)
#define ID_AA64PFR0_EL1_64_32 (2 << ID_AA64PFR0_EL1_SHIFT)
#define ID_AA64PFR0_EL2_SHIFT 8
#define ID_AA64PFR0_EL2_MASK (0xf << ID_AA64PFR0_EL2_SHIFT)
#define ID_AA64PFR0_EL2(x) ((x) & ID_AA64PFR0_EL2_MASK)
#define ID_AA64PFR0_EL2_NONE (0 << ID_AA64PFR0_EL2_SHIFT)
#define ID_AA64PFR0_EL2_64 (1 << ID_AA64PFR0_EL2_SHIFT)
#define ID_AA64PFR0_EL2_64_32 (2 << ID_AA64PFR0_EL2_SHIFT)
#define ID_AA64PFR0_EL3_SHIFT 12
#define ID_AA64PFR0_EL3_MASK (0xf << ID_AA64PFR0_EL3_SHIFT)
#define ID_AA64PFR0_EL3(x) ((x) & ID_AA64PFR0_EL3_MASK)
#define ID_AA64PFR0_EL3_NONE (0 << ID_AA64PFR0_EL3_SHIFT)
#define ID_AA64PFR0_EL3_64 (1 << ID_AA64PFR0_EL3_SHIFT)
#define ID_AA64PFR0_EL3_64_32 (2 << ID_AA64PFR0_EL3_SHIFT)
#define ID_AA64PFR0_FP_SHIFT 16
#define ID_AA64PFR0_FP_MASK (0xf << ID_AA64PFR0_FP_SHIFT)
#define ID_AA64PFR0_FP(x) ((x) & ID_AA64PFR0_FP_MASK)
#define ID_AA64PFR0_FP_IMPL (0x0 << ID_AA64PFR0_FP_SHIFT)
#define ID_AA64PFR0_FP_NONE (0xf << ID_AA64PFR0_FP_SHIFT)
#define ID_AA64PFR0_ADV_SIMD_SHIFT 20
#define ID_AA64PFR0_ADV_SIMD_MASK (0xf << ID_AA64PFR0_ADV_SIMD_SHIFT)
#define ID_AA64PFR0_ADV_SIMD(x) ((x) & ID_AA64PFR0_ADV_SIMD_MASK)
#define ID_AA64PFR0_ADV_SIMD_IMPL (0x0 << ID_AA64PFR0_ADV_SIMD_SHIFT)
#define ID_AA64PFR0_ADV_SIMD_NONE (0xf << ID_AA64PFR0_ADV_SIMD_SHIFT)
#define ID_AA64PFR0_GIC_BITS 0x4 /* Number of bits in GIC field */
#define ID_AA64PFR0_GIC_SHIFT 24
#define ID_AA64PFR0_GIC_MASK (0xf << ID_AA64PFR0_GIC_SHIFT)
#define ID_AA64PFR0_GIC(x) ((x) & ID_AA64PFR0_GIC_MASK)
#define ID_AA64PFR0_GIC_CPUIF_NONE (0x0 << ID_AA64PFR0_GIC_SHIFT)
#define ID_AA64PFR0_GIC_CPUIF_EN (0x1 << ID_AA64PFR0_GIC_SHIFT)
/* MAIR_EL1 - Memory Attribute Indirection Register */
#define MAIR_ATTR_MASK(idx) (0xff << ((n)* 8))

View File

@ -145,6 +145,7 @@ void cpu_halt(void) __dead2;
void cpu_reset(void) __dead2;
void fork_trampoline(void);
void identify_cpu(void);
void print_cpu_features(u_int);
void swi_vm(void *v);
#define CPU_AFFINITY(cpu) __cpu_affinity[(cpu)]

View File

@ -90,6 +90,7 @@ ram_blacklist_type="ram_blacklist" # Required for the kernel to find
#password="" # Prevent changes to boot options
#bootlock_password="" # Prevent booting (see check-password.4th(8))
#geom_eli_passphrase_prompt="NO" # Prompt for geli(8) passphrase to mount root
bootenv_autolist="YES" # Auto populate the list of ZFS Boot Environments
#beastie_disable="NO" # Turn the beastie boot menu on and off
#kernels="kernel kernel.old" # Kernels to display in the boot menu
#loader_logo="orbbw" # Desired logo: orbbw, orb, fbsdbw, beastiebw, beastie, none

View File

@ -351,4 +351,68 @@ also menu-namespace also menu-command-helpers
2 goto_menu
;
\
\ Set boot environment defaults
\
: init_bootenv ( -- )
s" set menu_caption[1]=${bemenu_current}${vfs.root.mountfrom}" evaluate
s" set ansi_caption[1]=${beansi_current}${vfs.root.mountfrom}" evaluate
s" set menu_caption[2]=${bemenu_bootfs}${zfs_be_active}" evaluate
s" set ansi_caption[2]=${beansi_bootfs}${zfs_be_active}" evaluate
s" set menu_caption[3]=${bemenu_page}${zfs_be_currpage}${bemenu_pageof}${zfs_be_pages}" evaluate
s" set ansi_caption[3]=${beansi_page}${zfs_be_currpage}${bemenu_pageof}${zfs_be_pages}" evaluate
;
\
\ Redraw the entire screen. A long BE name can corrupt the menu
\
: be_draw_screen
clear \ Clear the screen (in screen.4th)
print_version \ print version string (bottom-right; see version.4th)
draw-beastie \ Draw FreeBSD logo at right (in beastie.4th)
draw-brand \ Draw brand.4th logo at top (in brand.4th)
menu-init \ Initialize menu and draw bounding box (in menu.4th)
;
\
\ Select a boot environment
\
: set_bootenv ( N -- N TRUE )
dup s" set vfs.root.mountfrom=${bootenv_root[E]}" 38 +c! evaluate
s" set currdev=${vfs.root.mountfrom}:" evaluate
s" unload" evaluate
free-module-options
s" /boot/defaults/loader.conf" read-conf
s" /boot/loader.conf" read-conf
s" /boot/loader.conf.local" read-conf
init_bootenv
be_draw_screen
menu-redraw
TRUE
;
\
\ Switch to the next page of boot environments
\
: set_be_page ( N -- N TRUE )
s" zfs_be_currpage" getenv dup -1 = if
drop s" 1"
else
0 s>d 2swap
>number ( ud caddr/u -- ud' caddr'/u' ) \ convert string to numbers
2drop \ drop the string
1 um/mod ( ud u1 -- u2 u3 ) \ convert double ud' to single u3' and remainder u2
swap drop ( ud2 u3 -- u3 ) \ drop the remainder u2
1+ \ increment the page number
s>d <# #s #> \ convert back to a string
then
s" zfs_be_currpage" setenv
s" reloadbe" evaluate
3 goto_menu
;
only forth definitions

View File

@ -68,6 +68,13 @@ set mainmenu_command[6]="2 goto_menu"
set mainmenu_keycode[6]=111
set mainansi_caption[6]="Configure Boot ^[1mO^[mptions..."
s" currdev" getenv dup 0> [if] drop 4 s" zfs:" compare 0= [if]
set mainmenu_caption[7]="Select Boot [E]nvironment..."
set mainmenu_command[7]="3 goto_menu"
set mainmenu_keycode[7]=101
set mainansi_caption[7]="Select Boot ^[1mE^[37mnvironment..."
[then] [else] drop [then]
\
\ BOOT OPTIONS MENU
\
@ -119,6 +126,37 @@ set optionsmenu_keycode[6]=118
set optionsansi_caption[6]="^[1mV^[merbose..... ^[34;1mOff^[m"
set optionstoggled_ansi[6]="^[1mV^[merbose..... ^[32;7mOn^[m"
\
\ BOOT ENVIRONMENT MENU
\
set menuset_name3="bootenv"
set bemenu_current="Active: "
set beansi_current="^[1m${bemenu_current}^[m"
set bemenu_bootfs="bootfs: "
set beansi_bootfs="^[1m${bemenu_bootfs}^[m"
set bemenu_page="[P]age: "
set beansi_page="^[1mP^[mage: "
set bemenu_pageof=" of "
set beansi_pageof="${bemenu_pageof}"
set zfs_be_currpage=1
set bootenvmenu_init="init_bootenv"
set bootenvmenu_command[1]="be_draw_screen 1 goto_menu"
set bootenvmenu_keycode[1]=8
set bootenvmenu_command[2]="set_bootenv"
set bootenvmenu_keycode[2]=97
set bootenv_root[2]="${zfs_be_active}"
set bootenvmenu_command[3]="set_be_page"
set bootenvmenu_keycode[3]=112
set bootenvmenu_options=4
set bootenvmenu_optionstext="Boot Environments:"
\ Enable automatic booting (add ``autoboot_delay=N'' to loader.conf(5) to
\ customize the timeout; default is 10-seconds)
\
@ -128,6 +166,21 @@ set menu_timeout_command="boot"
\
try-include /boot/menu.rc.local
\ Initialize boot environment variables
\
s" reloadbe" sfind ( xt|0 bool ) [if]
s" bootenv_autolist" getenv dup -1 = [if]
drop s" execute" evaluate \ Use evaluate to avoid passing
\ reloadbe an optional parameter
[else]
s" YES" compare-insensitive 0= [if]
s" execute" evaluate
[then]
[then]
[else]
drop ( xt=0 )
[then]
\ Display the main menu (see `menu.4th')
set menuset_initial=1
menuset-loadinitial

View File

@ -684,7 +684,7 @@ only forth also support-functions also file-processing definitions
s" loader_conf_files" getenv conf_files string=
;
: set_nextboot_conf \ XXX maybe do as set_conf_files ?
: set_nextboot_conf
value_buffer strget unquote nextboot_conf_file string=
;
@ -852,7 +852,6 @@ only forth also support-functions definitions
\ Interface to loading conf files
: load_conf ( addr len -- )
\ ." ----- Trying conf " 2dup type cr \ debugging
0 to end_of_file?
reset_line_reading
O_RDONLY fopen fd !
@ -931,6 +930,30 @@ only forth definitions also support-functions
repeat
;
: free-one-module { addr -- addr }
addr module.name strfree
addr module.loadname strfree
addr module.type strfree
addr module.args strfree
addr module.beforeload strfree
addr module.afterload strfree
addr module.loaderror strfree
addr
;
: free-module-options
module_options @
begin
?dup
while
free-one-module
dup module.next @
swap free-memory
repeat
0 module_options !
0 last_module_option !
;
only forth also support-functions definitions
\ Variables used for processing multiple conf files
@ -944,7 +967,6 @@ string current_file_name_ref \ used to print the file name
\ loader_conf_files processing support functions
: get_conf_files ( -- addr len ) \ put addr/len on stack, reset var
\ ." -- starting on <" conf_files strtype ." >" cr \ debugging
conf_files strget 0 0 conf_files strset
;
@ -971,7 +993,6 @@ string current_file_name_ref \ used to print the file name
pos char+ to pos
repeat
addr len pos addr r@ + pos r> -
\ 2dup ." get_file_name has " type cr \ debugging
;
: get_next_file ( addr len ptr -- addr len ptr' addr' len' | 0 )
@ -1022,7 +1043,7 @@ string current_file_name_ref \ used to print the file name
;
: get_nextboot_conf_file ( -- addr len )
nextboot_conf_file strget strdup
nextboot_conf_file strget
;
: rewrite_nextboot_file ( -- )

View File

@ -69,6 +69,7 @@ static int isa_inb(int port);
static void isa_outb(int port, int value);
void exit(int code);
#ifdef LOADER_ZFS_SUPPORT
static void init_zfs_bootenv(char *currdev);
static void i386_zfs_probe(void);
#endif
@ -294,12 +295,40 @@ extract_currdev(void)
new_currdev.d_unit = 0;
}
#ifdef LOADER_ZFS_SUPPORT
init_zfs_bootenv(zfs_fmtdev(&new_currdev));
#endif
env_setenv("currdev", EV_VOLATILE, i386_fmtdev(&new_currdev),
i386_setcurrdev, env_nounset);
env_setenv("loaddev", EV_VOLATILE, i386_fmtdev(&new_currdev), env_noset,
env_nounset);
}
#ifdef LOADER_ZFS_SUPPORT
static void
init_zfs_bootenv(char *currdev)
{
char *beroot;
/* Remove the trailing : */
currdev[strlen(currdev) - 1] = '\0';
setenv("zfs_be_active", currdev, 1);
/* Do not overwrite if already set */
setenv("vfs.root.mountfrom", currdev, 0);
/* Forward past zfs: */
currdev = strchr(currdev, ':');
currdev++;
/* Remove the last element (current bootenv) */
beroot = strrchr(currdev, '/');
beroot[0] = '\0';
beroot = currdev;
setenv("zfs_be_root", beroot, 1);
}
#endif
COMMAND_SET(reboot, "reboot", "reboot the system", command_reboot);
static int
@ -353,6 +382,34 @@ command_lszfs(int argc, char *argv[])
command_errmsg = strerror(err);
return (CMD_ERROR);
}
return (CMD_OK);
}
COMMAND_SET(reloadbe, "reloadbe", "refresh the list of ZFS Boot Environments",
command_reloadbe);
static int
command_reloadbe(int argc, char *argv[])
{
int err;
if (argc > 2) {
command_errmsg = "wrong number of arguments";
return (CMD_ERROR);
}
if (argc == 2) {
err = zfs_bootenv(argv[1]);
} else {
err = zfs_bootenv(getenv("zfs_be_root"));
}
if (err != 0) {
command_errmsg = strerror(err);
return (CMD_ERROR);
}
return (CMD_OK);
}
#endif

View File

@ -62,6 +62,9 @@ int zfs_parsedev(struct zfs_devdesc *dev, const char *devspec,
char *zfs_fmtdev(void *vdev);
int zfs_probe_dev(const char *devname, uint64_t *pool_guid);
int zfs_list(const char *name);
int zfs_bootenv(const char *name);
int zfs_belist_add(const char *name);
int zfs_set_env(void);
extern struct devsw zfs_dev;
extern struct fs_ops zfs_fsops;

View File

@ -48,6 +48,10 @@ __FBSDID("$FreeBSD$");
#include "zfsimpl.c"
/* Define the range of indexes to be populated with ZFS Boot Environments */
#define ZFS_BE_FIRST 4
#define ZFS_BE_LAST 8
static int zfs_open(const char *path, struct open_file *f);
static int zfs_write(struct open_file *f, void *buf, size_t size, size_t *resid);
static int zfs_close(struct open_file *f);
@ -80,6 +84,16 @@ struct file {
zap_leaf_phys_t *f_zap_leaf; /* zap leaf buffer */
};
static int zfs_env_index;
static int zfs_env_count;
SLIST_HEAD(zfs_be_list, zfs_be_entry) zfs_be_head = SLIST_HEAD_INITIALIZER(zfs_be_head);
struct zfs_be_list *zfs_be_headp;
struct zfs_be_entry {
const char *name;
SLIST_ENTRY(zfs_be_entry) entries;
} *zfs_be, *zfs_be_tmp;
/*
* Open a file.
*/
@ -691,6 +705,156 @@ zfs_list(const char *name)
rv = zfs_lookup_dataset(spa, dsname, &objid);
if (rv != 0)
return (rv);
rv = zfs_list_dataset(spa, objid);
return (zfs_list_dataset(spa, objid));
}
int
zfs_bootenv(const char *name)
{
static char poolname[ZFS_MAXNAMELEN], *dsname;
char becount[4];
uint64_t objid;
spa_t *spa;
int len, rv, pages, perpage, currpage;
if (strcmp(name, getenv("zfs_be_root")) != 0) {
if (setenv("zfs_be_root", name, 1) != 0)
return (ENOMEM);
}
SLIST_INIT(&zfs_be_head);
zfs_env_count = 0;
len = strlen(name);
dsname = strchr(name, '/');
if (dsname != NULL) {
len = dsname - name;
dsname++;
} else
dsname = "";
memcpy(poolname, name, len);
poolname[len] = '\0';
spa = spa_find_by_name(poolname);
if (!spa)
return (ENXIO);
rv = zfs_lookup_dataset(spa, dsname, &objid);
if (rv != 0)
return (rv);
rv = zfs_callback_dataset(spa, objid, zfs_belist_add);
/* Calculate and store the number of pages of BEs */
perpage = (ZFS_BE_LAST - ZFS_BE_FIRST + 1);
pages = (zfs_env_count / perpage) + ((zfs_env_count % perpage) > 0 ? 1 : 0);
snprintf(becount, 4, "%d", pages);
if (setenv("zfs_be_pages", becount, 1) != 0)
return (ENOMEM);
/* Roll over the page counter if it has exceeded the maximum */
currpage = strtol(getenv("zfs_be_currpage"), NULL, 10);
if (currpage > pages) {
if (setenv("zfs_be_currpage", "1", 1) != 0)
return (ENOMEM);
}
/* Populate the menu environment variables */
zfs_set_env();
/* Clean up the SLIST of ZFS BEs */
while (!SLIST_EMPTY(&zfs_be_head)) {
zfs_be = SLIST_FIRST(&zfs_be_head);
SLIST_REMOVE_HEAD(&zfs_be_head, entries);
free(zfs_be);
}
return (rv);
}
int
zfs_belist_add(const char *name)
{
/* Add the boot environment to the head of the SLIST */
zfs_be = malloc(sizeof(struct zfs_be_entry));
zfs_be->name = name;
SLIST_INSERT_HEAD(&zfs_be_head, zfs_be, entries);
zfs_env_count++;
return (0);
}
int
zfs_set_env(void)
{
char envname[32], envval[256];
char *beroot, *pagenum;
int rv, page, ctr;
beroot = getenv("zfs_be_root");
if (beroot == NULL) {
return (1);
}
pagenum = getenv("zfs_be_currpage");
if (pagenum != NULL) {
page = strtol(pagenum, NULL, 10);
} else {
page = 1;
}
ctr = 1;
rv = 0;
zfs_env_index = ZFS_BE_FIRST;
SLIST_FOREACH_SAFE(zfs_be, &zfs_be_head, entries, zfs_be_tmp) {
/* Skip to the requested page number */
if (ctr <= ((ZFS_BE_LAST - ZFS_BE_FIRST + 1) * (page - 1))) {
ctr++;
continue;
}
snprintf(envname, sizeof(envname), "bootenvmenu_caption[%d]", zfs_env_index);
snprintf(envval, sizeof(envval), "%s", zfs_be->name);
rv = setenv(envname, envval, 1);
if (rv != 0) {
break;
}
snprintf(envname, sizeof(envname), "bootenvansi_caption[%d]", zfs_env_index);
rv = setenv(envname, envval, 1);
if (rv != 0){
break;
}
snprintf(envname, sizeof(envname), "bootenvmenu_command[%d]", zfs_env_index);
rv = setenv(envname, "set_bootenv", 1);
if (rv != 0){
break;
}
snprintf(envname, sizeof(envname), "bootenv_root[%d]", zfs_env_index);
snprintf(envval, sizeof(envval), "zfs:%s/%s", beroot, zfs_be->name);
rv = setenv(envname, envval, 1);
if (rv != 0){
break;
}
zfs_env_index++;
if (zfs_env_index > ZFS_BE_LAST) {
break;
}
}
for (; zfs_env_index <= ZFS_BE_LAST; zfs_env_index++) {
snprintf(envname, sizeof(envname), "bootenvmenu_caption[%d]", zfs_env_index);
(void)unsetenv(envname);
snprintf(envname, sizeof(envname), "bootenvansi_caption[%d]", zfs_env_index);
(void)unsetenv(envname);
snprintf(envname, sizeof(envname), "bootenvmenu_command[%d]", zfs_env_index);
(void)unsetenv(envname);
snprintf(envname, sizeof(envname), "bootenv_root[%d]", zfs_env_index);
(void)unsetenv(envname);
}
return (rv);
}

View File

@ -1473,7 +1473,7 @@ zap_lookup(const spa_t *spa, const dnode_phys_t *dnode, const char *name, uint64
* the directory contents.
*/
static int
mzap_list(const dnode_phys_t *dnode)
mzap_list(const dnode_phys_t *dnode, int (*callback)(const char *))
{
const mzap_phys_t *mz;
const mzap_ent_phys_t *mze;
@ -1492,7 +1492,7 @@ mzap_list(const dnode_phys_t *dnode)
mze = &mz->mz_chunk[i];
if (mze->mze_name[0])
//printf("%-32s 0x%jx\n", mze->mze_name, (uintmax_t)mze->mze_value);
printf("%s\n", mze->mze_name);
callback(mze->mze_name);
}
return (0);
@ -1503,7 +1503,7 @@ mzap_list(const dnode_phys_t *dnode)
* the directory header.
*/
static int
fzap_list(const spa_t *spa, const dnode_phys_t *dnode)
fzap_list(const spa_t *spa, const dnode_phys_t *dnode, int (*callback)(const char *))
{
int bsize = dnode->dn_datablkszsec << SPA_MINBLOCKSHIFT;
zap_phys_t zh = *(zap_phys_t *) zap_scratch;
@ -1566,13 +1566,21 @@ fzap_list(const spa_t *spa, const dnode_phys_t *dnode)
value = fzap_leaf_value(&zl, zc);
//printf("%s 0x%jx\n", name, (uintmax_t)value);
printf("%s\n", name);
callback((const char *)name);
}
}
return (0);
}
static int zfs_printf(const char *name)
{
printf("%s\n", name);
return (0);
}
/*
* List a zap directory.
*/
@ -1587,9 +1595,9 @@ zap_list(const spa_t *spa, const dnode_phys_t *dnode)
zap_type = *(uint64_t *) zap_scratch;
if (zap_type == ZBT_MICRO)
return mzap_list(dnode);
return mzap_list(dnode, zfs_printf);
else
return fzap_list(spa, dnode);
return fzap_list(spa, dnode, zfs_printf);
}
static int
@ -1858,6 +1866,48 @@ zfs_list_dataset(const spa_t *spa, uint64_t objnum/*, int pos, char *entry*/)
return (zap_list(spa, &child_dir_zap) != 0);
}
int
zfs_callback_dataset(const spa_t *spa, uint64_t objnum, int (*callback)(const char *name))
{
uint64_t dir_obj, child_dir_zapobj, zap_type;
dnode_phys_t child_dir_zap, dir, dataset;
dsl_dataset_phys_t *ds;
dsl_dir_phys_t *dd;
int err;
err = objset_get_dnode(spa, &spa->spa_mos, objnum, &dataset);
if (err != 0) {
printf("ZFS: can't find dataset %ju\n", (uintmax_t)objnum);
return (err);
}
ds = (dsl_dataset_phys_t *) &dataset.dn_bonus;
dir_obj = ds->ds_dir_obj;
err = objset_get_dnode(spa, &spa->spa_mos, dir_obj, &dir);
if (err != 0) {
printf("ZFS: can't find dirobj %ju\n", (uintmax_t)dir_obj);
return (err);
}
dd = (dsl_dir_phys_t *)&dir.dn_bonus;
child_dir_zapobj = dd->dd_child_dir_zapobj;
err = objset_get_dnode(spa, &spa->spa_mos, child_dir_zapobj, &child_dir_zap);
if (err != 0) {
printf("ZFS: can't find child zap %ju\n", (uintmax_t)dir_obj);
return (err);
}
err = dnode_read(spa, &child_dir_zap, 0, zap_scratch, child_dir_zap.dn_datablkszsec * 512);
if (err != 0)
return (err);
zap_type = *(uint64_t *) zap_scratch;
if (zap_type == ZBT_MICRO)
return mzap_list(&child_dir_zap, callback);
else
return fzap_list(spa, &child_dir_zap, callback);
}
#endif
/*

View File

@ -41,6 +41,8 @@ struct inode;
struct module;
extern struct cdevsw linuxcdevsw;
extern const struct kobj_type linux_cdev_ktype;
extern const struct kobj_type linux_cdev_static_ktype;
struct linux_cdev {
struct kobject kobj;
@ -50,40 +52,11 @@ struct linux_cdev {
const struct file_operations *ops;
};
static inline void
cdev_release(struct kobject *kobj)
{
struct linux_cdev *cdev;
cdev = container_of(kobj, struct linux_cdev, kobj);
if (cdev->cdev)
destroy_dev(cdev->cdev);
kfree(cdev);
}
static inline void
cdev_static_release(struct kobject *kobj)
{
struct linux_cdev *cdev;
cdev = container_of(kobj, struct linux_cdev, kobj);
if (cdev->cdev)
destroy_dev(cdev->cdev);
}
static struct kobj_type cdev_ktype = {
.release = cdev_release,
};
static struct kobj_type cdev_static_ktype = {
.release = cdev_static_release,
};
static inline void
cdev_init(struct linux_cdev *cdev, const struct file_operations *ops)
{
kobject_init(&cdev->kobj, &cdev_static_ktype);
kobject_init(&cdev->kobj, &linux_cdev_static_ktype);
cdev->ops = ops;
}
@ -94,7 +67,7 @@ cdev_alloc(void)
cdev = kzalloc(sizeof(struct linux_cdev), M_WAITOK);
if (cdev)
kobject_init(&cdev->kobj, &cdev_ktype);
kobject_init(&cdev->kobj, &linux_cdev_ktype);
return (cdev);
}
@ -114,6 +87,7 @@ cdev_add(struct linux_cdev *cdev, dev_t dev, unsigned count)
cdev->dev = dev;
cdev->cdev->si_drv1 = cdev;
kobject_get(cdev->kobj.parent);
return (0);
}

View File

@ -73,8 +73,10 @@ struct device {
unsigned int msix_max;
};
extern struct device linux_rootdev;
extern struct kobject class_root;
extern struct device linux_root_device;
extern struct kobject linux_class_root;
extern const struct kobj_type linux_dev_ktype;
extern const struct kobj_type linux_class_ktype;
struct class_attribute {
struct attribute attr;
@ -170,62 +172,14 @@ put_device(struct device *dev)
kobject_put(&dev->kobj);
}
static inline ssize_t
class_show(struct kobject *kobj, struct attribute *attr, char *buf)
{
struct class_attribute *dattr;
ssize_t error;
dattr = container_of(attr, struct class_attribute, attr);
error = -EIO;
if (dattr->show)
error = dattr->show(container_of(kobj, struct class, kobj),
dattr, buf);
return (error);
}
static inline ssize_t
class_store(struct kobject *kobj, struct attribute *attr, const char *buf,
size_t count)
{
struct class_attribute *dattr;
ssize_t error;
dattr = container_of(attr, struct class_attribute, attr);
error = -EIO;
if (dattr->store)
error = dattr->store(container_of(kobj, struct class, kobj),
dattr, buf, count);
return (error);
}
static inline void
class_release(struct kobject *kobj)
{
struct class *class;
class = container_of(kobj, struct class, kobj);
if (class->class_release)
class->class_release(class);
}
static struct sysfs_ops class_sysfs = {
.show = class_show,
.store = class_store,
};
static struct kobj_type class_ktype = {
.release = class_release,
.sysfs_ops = &class_sysfs
};
static inline int
class_register(struct class *class)
{
class->bsdclass = devclass_create(class->name);
kobject_init(&class->kobj, &class_ktype);
kobject_init(&class->kobj, &linux_class_ktype);
kobject_set_name(&class->kobj, class->name);
kobject_add(&class->kobj, &class_root, class->name);
kobject_add(&class->kobj, &linux_class_root, class->name);
return (0);
}
@ -237,54 +191,6 @@ class_unregister(struct class *class)
kobject_put(&class->kobj);
}
static inline void
device_release(struct kobject *kobj)
{
struct device *dev;
dev = container_of(kobj, struct device, kobj);
/* This is the precedence defined by linux. */
if (dev->release)
dev->release(dev);
else if (dev->class && dev->class->dev_release)
dev->class->dev_release(dev);
}
static inline ssize_t
dev_show(struct kobject *kobj, struct attribute *attr, char *buf)
{
struct device_attribute *dattr;
ssize_t error;
dattr = container_of(attr, struct device_attribute, attr);
error = -EIO;
if (dattr->show)
error = dattr->show(container_of(kobj, struct device, kobj),
dattr, buf);
return (error);
}
static inline ssize_t
dev_store(struct kobject *kobj, struct attribute *attr, const char *buf,
size_t count)
{
struct device_attribute *dattr;
ssize_t error;
dattr = container_of(attr, struct device_attribute, attr);
error = -EIO;
if (dattr->store)
error = dattr->store(container_of(kobj, struct device, kobj),
dattr, buf, count);
return (error);
}
static struct sysfs_ops dev_sysfs = { .show = dev_show, .store = dev_store, };
static struct kobj_type dev_ktype = {
.release = device_release,
.sysfs_ops = &dev_sysfs
};
/*
* Devices are registered and created for exporting to sysfs. create
* implies register and register assumes the device fields have been
@ -311,7 +217,7 @@ device_register(struct device *dev)
device_set_softc(bsddev, dev);
}
dev->bsddev = bsddev;
kobject_init(&dev->kobj, &dev_ktype);
kobject_init(&dev->kobj, &linux_dev_ktype);
kobject_add(&dev->kobj, &dev->class->kobj, dev_name(dev));
return (0);
@ -346,7 +252,7 @@ device_destroy(struct class *class, dev_t devt)
}
static inline void
class_kfree(struct class *class)
linux_class_kfree(struct class *class)
{
kfree(class);
@ -361,7 +267,7 @@ class_create(struct module *owner, const char *name)
class = kzalloc(sizeof(*class), M_WAITOK);
class->owner = owner;
class->name= name;
class->class_release = class_kfree;
class->class_release = linux_class_kfree;
error = class_register(class);
if (error) {
kfree(class);
@ -414,7 +320,8 @@ class_remove_file(struct class *class, const struct class_attribute *attr)
sysfs_remove_file(&class->kobj, &attr->attr);
}
static inline int dev_to_node(struct device *dev)
static inline int
dev_to_node(struct device *dev)
{
return -1;
}

View File

@ -101,10 +101,11 @@ fd_install(unsigned int fd, struct linux_file *filp)
if (fget_unlocked(curthread->td_proc->p_fd, fd,
cap_rights_init(&rights), &file, NULL) != 0) {
file = NULL;
filp->_file = NULL;
} else {
filp->_file = file;
finit(file, filp->f_mode, DTYPE_DEV, filp, &linuxfileops);
}
filp->_file = file;
finit(file, filp->f_mode, DTYPE_DEV, filp, &linuxfileops);
/* drop the extra reference */
fput(filp);

View File

@ -46,13 +46,13 @@ struct kobj_type {
struct attribute **default_attrs;
};
extern struct kobj_type kfree_type;
extern const struct kobj_type linux_kfree_type;
struct kobject {
struct kobject *parent;
char *name;
struct kref kref;
struct kobj_type *ktype;
const struct kobj_type *ktype;
struct list_head entry;
struct sysctl_oid *oidp;
};
@ -74,7 +74,7 @@ struct kobj_attribute {
};
static inline void
kobject_init(struct kobject *kobj, struct kobj_type *ktype)
kobject_init(struct kobject *kobj, const struct kobj_type *ktype)
{
kref_init(&kobj->kref);
@ -83,15 +83,14 @@ kobject_init(struct kobject *kobj, struct kobj_type *ktype)
kobj->oidp = NULL;
}
static inline void kobject_put(struct kobject *kobj);
void kobject_release(struct kref *kref);
void linux_kobject_release(struct kref *kref);
static inline void
kobject_put(struct kobject *kobj)
{
if (kobj)
kref_put(&kobj->kref, kobject_release);
kref_put(&kobj->kref, linux_kobject_release);
}
static inline struct kobject *
@ -115,7 +114,7 @@ kobject_create(void)
kobj = kzalloc(sizeof(*kobj), GFP_KERNEL);
if (kobj == NULL)
return (NULL);
kobject_init(kobj, &kfree_type);
kobject_init(kobj, &linux_kfree_type);
return (kobj);
}
@ -135,7 +134,6 @@ kobject_create_and_add(const char *name, struct kobject *parent)
return (NULL);
}
static inline char *
kobject_name(const struct kobject *kobj)
{
@ -144,7 +142,7 @@ kobject_name(const struct kobject *kobj)
}
int kobject_set_name(struct kobject *kobj, const char *fmt, ...);
int kobject_init_and_add(struct kobject *kobj, struct kobj_type *ktype,
int kobject_init_and_add(struct kobject *kobj, const struct kobj_type *ktype,
struct kobject *parent, const char *fmt, ...);
#endif /* _LINUX_KOBJECT_H_ */

View File

@ -46,13 +46,13 @@ struct miscdevice {
umode_t mode;
};
extern struct class miscclass;
extern struct class linux_class_misc;
static inline int
misc_register(struct miscdevice *misc)
{
misc->this_device = device_create(&miscclass, &linux_rootdev, 0, misc,
misc->name);
misc->this_device = device_create(&linux_class_misc,
&linux_root_device, 0, misc, misc->name);
misc->cdev = cdev_alloc();
if (misc->cdev == NULL)
return -ENOMEM;
@ -67,7 +67,7 @@ misc_register(struct miscdevice *misc)
static inline int
misc_deregister(struct miscdevice *misc)
{
device_destroy(&miscclass, misc->this_device->devt);
device_destroy(&linux_class_misc, misc->this_device->devt);
cdev_del(misc->cdev);
return (0);

View File

@ -77,9 +77,9 @@ MALLOC_DEFINE(M_KMALLOC, "linux", "Linux kmalloc compat");
#undef cdev
#define RB_ROOT(head) (head)->rbh_root
struct kobject class_root;
struct device linux_rootdev;
struct class miscclass;
struct kobject linux_class_root;
struct device linux_root_device;
struct class linux_class_misc;
struct list_head pci_drivers;
struct list_head pci_devices;
struct net init_net;
@ -151,13 +151,13 @@ kobject_set_name(struct kobject *kobj, const char *fmt, ...)
return (error);
}
static inline int
static int
kobject_add_complete(struct kobject *kobj, struct kobject *parent)
{
struct kobj_type *t;
const struct kobj_type *t;
int error;
kobj->parent = kobject_get(parent);
kobj->parent = parent;
error = sysfs_create_dir(kobj);
if (error == 0 && kobj->ktype && kobj->ktype->default_attrs) {
struct attribute **attr;
@ -191,16 +191,13 @@ kobject_add(struct kobject *kobj, struct kobject *parent, const char *fmt, ...)
}
void
kobject_release(struct kref *kref)
linux_kobject_release(struct kref *kref)
{
struct kobject *kobj;
char *name;
kobj = container_of(kref, struct kobject, kref);
sysfs_remove_dir(kobj);
if (kobj->parent)
kobject_put(kobj->parent);
kobj->parent = NULL;
name = kobj->name;
if (kobj->ktype && kobj->ktype->release)
kobj->ktype->release(kobj);
@ -208,28 +205,131 @@ kobject_release(struct kref *kref)
}
static void
kobject_kfree(struct kobject *kobj)
linux_kobject_kfree(struct kobject *kobj)
{
kfree(kobj);
}
static void
kobject_kfree_name(struct kobject *kobj)
linux_kobject_kfree_name(struct kobject *kobj)
{
if (kobj) {
kfree(kobj->name);
}
}
struct kobj_type kfree_type = { .release = kobject_kfree };
const struct kobj_type linux_kfree_type = {
.release = linux_kobject_kfree
};
static void
dev_release(struct device *dev)
linux_device_release(struct device *dev)
{
pr_debug("dev_release: %s\n", dev_name(dev));
pr_debug("linux_device_release: %s\n", dev_name(dev));
kfree(dev);
}
static ssize_t
linux_class_show(struct kobject *kobj, struct attribute *attr, char *buf)
{
struct class_attribute *dattr;
ssize_t error;
dattr = container_of(attr, struct class_attribute, attr);
error = -EIO;
if (dattr->show)
error = dattr->show(container_of(kobj, struct class, kobj),
dattr, buf);
return (error);
}
static ssize_t
linux_class_store(struct kobject *kobj, struct attribute *attr, const char *buf,
size_t count)
{
struct class_attribute *dattr;
ssize_t error;
dattr = container_of(attr, struct class_attribute, attr);
error = -EIO;
if (dattr->store)
error = dattr->store(container_of(kobj, struct class, kobj),
dattr, buf, count);
return (error);
}
static void
linux_class_release(struct kobject *kobj)
{
struct class *class;
class = container_of(kobj, struct class, kobj);
if (class->class_release)
class->class_release(class);
}
static const struct sysfs_ops linux_class_sysfs = {
.show = linux_class_show,
.store = linux_class_store,
};
const struct kobj_type linux_class_ktype = {
.release = linux_class_release,
.sysfs_ops = &linux_class_sysfs
};
static void
linux_dev_release(struct kobject *kobj)
{
struct device *dev;
dev = container_of(kobj, struct device, kobj);
/* This is the precedence defined by linux. */
if (dev->release)
dev->release(dev);
else if (dev->class && dev->class->dev_release)
dev->class->dev_release(dev);
}
static ssize_t
linux_dev_show(struct kobject *kobj, struct attribute *attr, char *buf)
{
struct device_attribute *dattr;
ssize_t error;
dattr = container_of(attr, struct device_attribute, attr);
error = -EIO;
if (dattr->show)
error = dattr->show(container_of(kobj, struct device, kobj),
dattr, buf);
return (error);
}
static ssize_t
linux_dev_store(struct kobject *kobj, struct attribute *attr, const char *buf,
size_t count)
{
struct device_attribute *dattr;
ssize_t error;
dattr = container_of(attr, struct device_attribute, attr);
error = -EIO;
if (dattr->store)
error = dattr->store(container_of(kobj, struct device, kobj),
dattr, buf, count);
return (error);
}
static const struct sysfs_ops linux_dev_sysfs = {
.show = linux_dev_show,
.store = linux_dev_store,
};
const struct kobj_type linux_dev_ktype = {
.release = linux_dev_release,
.sysfs_ops = &linux_dev_sysfs
};
struct device *
device_create(struct class *class, struct device *parent, dev_t devt,
void *drvdata, const char *fmt, ...)
@ -242,7 +342,7 @@ device_create(struct class *class, struct device *parent, dev_t devt,
dev->class = class;
dev->devt = devt;
dev->driver_data = drvdata;
dev->release = dev_release;
dev->release = linux_device_release;
va_start(args, fmt);
kobject_set_name_vargs(&dev->kobj, fmt, args);
va_end(args);
@ -252,7 +352,7 @@ device_create(struct class *class, struct device *parent, dev_t devt,
}
int
kobject_init_and_add(struct kobject *kobj, struct kobj_type *ktype,
kobject_init_and_add(struct kobject *kobj, const struct kobj_type *ktype,
struct kobject *parent, const char *fmt, ...)
{
va_list args;
@ -1001,6 +1101,41 @@ destroy_workqueue(struct workqueue_struct *wq)
kfree(wq);
}
static void
linux_cdev_release(struct kobject *kobj)
{
struct linux_cdev *cdev;
struct kobject *parent;
cdev = container_of(kobj, struct linux_cdev, kobj);
parent = kobj->parent;
if (cdev->cdev)
destroy_dev(cdev->cdev);
kfree(cdev);
kobject_put(parent);
}
static void
linux_cdev_static_release(struct kobject *kobj)
{
struct linux_cdev *cdev;
struct kobject *parent;
cdev = container_of(kobj, struct linux_cdev, kobj);
parent = kobj->parent;
if (cdev->cdev)
destroy_dev(cdev->cdev);
kobject_put(parent);
}
const struct kobj_type linux_cdev_ktype = {
.release = linux_cdev_release,
};
const struct kobj_type linux_cdev_static_ktype = {
.release = linux_cdev_static_release,
};
static void
linux_compat_init(void *arg)
{
@ -1009,18 +1144,18 @@ linux_compat_init(void *arg)
rootoid = SYSCTL_ADD_ROOT_NODE(NULL,
OID_AUTO, "sys", CTLFLAG_RD|CTLFLAG_MPSAFE, NULL, "sys");
kobject_init(&class_root, &class_ktype);
kobject_set_name(&class_root, "class");
class_root.oidp = SYSCTL_ADD_NODE(NULL, SYSCTL_CHILDREN(rootoid),
kobject_init(&linux_class_root, &linux_class_ktype);
kobject_set_name(&linux_class_root, "class");
linux_class_root.oidp = SYSCTL_ADD_NODE(NULL, SYSCTL_CHILDREN(rootoid),
OID_AUTO, "class", CTLFLAG_RD|CTLFLAG_MPSAFE, NULL, "class");
kobject_init(&linux_rootdev.kobj, &dev_ktype);
kobject_set_name(&linux_rootdev.kobj, "device");
linux_rootdev.kobj.oidp = SYSCTL_ADD_NODE(NULL,
kobject_init(&linux_root_device.kobj, &linux_dev_ktype);
kobject_set_name(&linux_root_device.kobj, "device");
linux_root_device.kobj.oidp = SYSCTL_ADD_NODE(NULL,
SYSCTL_CHILDREN(rootoid), OID_AUTO, "device", CTLFLAG_RD, NULL,
"device");
linux_rootdev.bsddev = root_bus;
miscclass.name = "misc";
class_register(&miscclass);
linux_root_device.bsddev = root_bus;
linux_class_misc.name = "misc";
class_register(&linux_class_misc);
INIT_LIST_HEAD(&pci_drivers);
INIT_LIST_HEAD(&pci_devices);
spin_lock_init(&pci_lock);
@ -1033,9 +1168,9 @@ SYSINIT(linux_compat, SI_SUB_DRIVERS, SI_ORDER_SECOND, linux_compat_init, NULL);
static void
linux_compat_uninit(void *arg)
{
kobject_kfree_name(&class_root);
kobject_kfree_name(&linux_rootdev.kobj);
kobject_kfree_name(&miscclass.kobj);
linux_kobject_kfree_name(&linux_class_root);
linux_kobject_kfree_name(&linux_root_device.kobj);
linux_kobject_kfree_name(&linux_class_misc.kobj);
}
SYSUNINIT(linux_compat, SI_SUB_DRIVERS, SI_ORDER_SECOND, linux_compat_uninit, NULL);

View File

@ -119,16 +119,16 @@ linux_pci_attach(device_t dev)
pdrv = linux_pci_find(dev, &id);
pdev = device_get_softc(dev);
pdev->dev.parent = &linux_rootdev;
pdev->dev.parent = &linux_root_device;
pdev->dev.bsddev = dev;
INIT_LIST_HEAD(&pdev->dev.irqents);
pdev->device = id->device;
pdev->vendor = id->vendor;
pdev->dev.dma_mask = &pdev->dma_mask;
pdev->pdrv = pdrv;
kobject_init(&pdev->dev.kobj, &dev_ktype);
kobject_init(&pdev->dev.kobj, &linux_dev_ktype);
kobject_set_name(&pdev->dev.kobj, device_get_nameunit(dev));
kobject_add(&pdev->dev.kobj, &linux_rootdev.kobj,
kobject_add(&pdev->dev.kobj, &linux_root_device.kobj,
kobject_name(&pdev->dev.kobj));
rle = _pci_get_rle(pdev, SYS_RES_IRQ, 0);
if (rle)

View File

@ -97,7 +97,10 @@ then
fi
touch version
v=`cat version` u=${USER:-root} d=`pwd` h=${HOSTNAME:-`hostname`}
v=`cat version`
u=${USER:-root}
d=`pwd`
h=${HOSTNAME:-`hostname`}
if [ -n "$SOURCE_DATE_EPOCH" ]; then
if ! t=`date -r $SOURCE_DATE_EPOCH 2>/dev/null`; then
echo "Invalid SOURCE_DATE_EPOCH" >&2

View File

@ -0,0 +1,39 @@
Copyright (c) 2010, Realtek Semiconductor Corporation
All rights reserved.
Redistribution. Redistribution and use in binary form, without
modification, are permitted provided that the following conditions are
met:
* Redistributions must reproduce the above copyright notice and the
following disclaimer in the documentation and/or other materials
provided with the distribution.
* Neither the name of Realtek Semiconductor Corporation nor the names of its
suppliers may be used to endorse or promote products derived from this
software without specific prior written permission.
* No reverse engineering, decompilation, or disassembly of this software
is permitted.
Limited patent license. Realtek Semiconductor Corporation grants a world-wide,
royalty-free, non-exclusive license under patents it now or hereafter
owns or controls to make, have made, use, import, offer to sell and
sell ("Utilize") this software, but solely to the extent that any
such patent is necessary to Utilize the software alone, or in
combination with an operating system licensed under an approved Open
Source license as listed by the Open Source Initiative at
http://opensource.org/licenses. The patent license shall not apply to
any other combinations which include this software. No hardware per
se is licensed hereunder.
DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

View File

@ -0,0 +1,333 @@
begin 444 rtwn-rtl8192cfwU.fw.uu
MP8@"`$@````%$!!3PCD!`(%C`0`````````````````"0[H`````````````
M`````````E!$````````````````````````````````````````````````
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
-29"77>`D_Y*O(@"'%P``
`
end

View File

@ -0,0 +1,366 @@
begin 444 rtwn-rtl8192cfwU_B.fw.uu
MPH@"`%@``@`'%11$K#\!`,S,S,P````````````````"19L`````````````
M`````````EE4````````````````````````````````````````````````
M`````````````F2,```````"2[(```4$`P(``P8%!`,`!`8%!`(`!`@'!@0`
M!@H)"`8`"`H)"`0`"`H)"`(`"`H)"```"!(1$`@`$!H9&!``&"(A(!@`("(A
M(!``("(A(`@`("(A'`@`("(A%`@`("(@&`@`(#$P(!``,#$P&```,#$O$!``
M,#$L$!``,#$H$```,#$@$```,#$0$```,`0$!`4$!`0%!04&!@0$!`4%!08&
M!`0%!04%!@8$!`4%!04&!PH+#1`$!04&!@D,$0@("0D*#!`1!`0$!00$!0<'
M!P@*!`0$!`8*"PT%!0<'"`L-#P0$!`4'!PD)#`X0$@8'"0H,#A$3"0D)"0P.
M$1,````````````D)BH8&AT?(2<I*@```!\C*"HL``0`!``(`!``&``D`#``
M2`!@`)``P`#8`%``>`"@`,@!0`&0`>`",`$L`4`!X`+0`^@$L`9`!]```@`"
M``0`"``,`!(`&``D`#``2`!@`&P`*``\`%``9`"@`,@`\`$8`&0`H`#P`6@!
M]`)8`R`#Z`("`@("`@,#!`0%!P(#!`H,#A`2!0<'"`L2)#P!`0$!`0(#!`4&
M!P@!`@,$!08'"`4&!P@)"@L,(!X<&!`8````````````````NP$,Y8(I]8+E
M@SKU@^`B4`;I)8+XYB*[_@;I)8+XXB+E@BGU@N6#.O6#Y),BNP$&B8**@_`B
M4`+W(KO^`?,B^+L!#>6"*?6"Y8,Z]8/H\")0!NDE@LCV(KO^!>DE@LCR(L7P
M^*/@*/#%\/CE@A6"<`(5@^`X\"*[`0J)@HJ#X/7PH^`B4`:'\`GG&2*[_@?C
M]?`)XQDBB8**@^23]?!T`9,BNP$0Y8(I]8+E@SKU@^#U\*/@(E`)Z26"^(;P
M".8BN_X*Z26"^.+U\`CB(N6#*O6#Z9/U\*/IDR*[`0J)@HJ#\.7PH_`B4`;W
M":?P&2*[_@;SY?`)\QDB^+L!$>6"*?6"Y8,Z]8/H\.7PH_`B4`GI)8+(]@BF
M\"*[_@GI)8+(\N7P"/(B[TO_[DK^[4G][$C\(N#\H^#]H^#^H^#_(J0E@O6"
MY?`U@_6#(N#[H^#ZH^#Y(OC@^Z.CX/DE\/#E@A6"<`(5@^#Z./`BZ_"CZO"C
MZ?`BT(/0@OCDDW`2=`&3<`VCHY/X=`&3]8*(@^1S=`*3:&#OHZ.C@-_0@]""
M^.23<!)T`9-P#:.CD_AT`9/U@HB#Y'-T`I.U\`9T`Y-H8.FCHZ.C@-B.9(]E
MK66L9*]C$DJ0KV6N9)`$@.!4#_VL!W01+/6"Y#3\]8/@1`'P=!$L]8+D-/SU
M@^!4^_"L!W06+/6"Y#3\]8/@1/KP=!4L]8+D-/SU@^!$'_"L!W0&+/6"Y#3\
M]8/@1`_PD`13Y/"0!%+PD`11=/_PD`10=/WP=!0L]8+D-/SU@^!4P$W]=!0O
M]8+D-/SU@^WP(A)+5>]D`6`(D`&Y=`'P@&[E)50#8`B0`;ET`O"`8.4C5`_3
ME`)`")`!N70$\(!/Y24PX@B0`;ET"/"`0N4E,.0(D`&Y=!#P@#60DE?@8`B0
M`;ET(/"`)Y"27.!@")`!N72`\(`9Y29@!Y`!N>3P@`Z0`;GD\)`!N'0$\'\!
M(I`!N'0$\'\`(@)%`P)%!GT!?PS3$*\!P\#0CV>-:.5G5`__Y2)4#V]@<N5G
M,.(PY2(@X@5_`1)*Y^4B,.,0Y6<@XPL22*3O8%,22P&`3N4B(.-)Y6<PXT2O
M:!)*L8`]Y2)4#_^_#`[E9R#C"1)(I.]@*A)+`>4B5`__OP0.Y6<@X@D21'SO
M8!022C/E(E0/_[\""1)+@N]@`Q)+,=#0DJ\B`D79`E%WY).C^.23HT`#]H`!
M\@C?](`IY).C^%0')`S(PS/$5`]$(,B#0`3T5H`!1O;?Y(`+`0($"!`@0("0
M2T3D?@&38+RC_U0_,.4)5!_^Y).C8`$.SU3`)>!@J$"XY).C^N23H_CDDZ/(
MQ8+(RL6#RO"CR,6"R,K%@\K?Z=[G@+[D_^4D8'7E(60!<&_E)!1@*R3]8"<D
M`B3[4`*`(9"25>`4\.!@!*/@8!20DE7@<`B0DF/@D))5\'\!@`)_`>]@.D,E
M$.20DH/PD))6X'7P`Z3_D))?X"^0DH3PY/O]?U1^`1)+EY`!5W0%\.4B5`_#
ME`10!WT!?P0210TBY2%D`7!GY21@8^4D9`)@!N4D9`5P)Y`&J^"0DE7PD`:J
MX)"28_"0DE7@<`>0DF/@_X`%D))5X/^0DE7O\)"25^!@`N3PY)"25O"0!5AT
M`_"0`5?D\)`!/'0"\%,E_5,E[^4D%"3]4`*``Q)'""+DD)(0\)`&J>"0DA#P
MX%3`<`E3)?Y3)?T22WN0DA#@,.850R4!D))DX&0"8`422LR`"!))\X`#4R7^
MD)(0X##G)T,E`N20DH/PD));X)"2A/#D^_U_5'X!$DN7D`%7=`7PD))E=`'P
M(E,E_2+O9`%P,'UX?P(2-G5]`G\#$C9UD`%7Y/"0`3QT`O`210GD_Q)8II`&
M!.!4?_"0!@K@5/CP(I`!-G1[\*-T`O!]>_\2-N9]`G\#$C;FD`8$X$2`\)`&
M"N!$!_`22W#E(2#@!>20DE?P(I"2*1)#BQ)+9)"2*1)#:Q(IV?4D%&`.%&`?
M%&`Q)`-P1'\!@#V0DBD20VN0``(20B#]Y/\22F6`*9"2*1)#:Y```A)"(/U_
M`1)*91^`%)"2*1)#:Y```A)"(/U_`A)*9>3_$D=T(N3U)?4D=2,,=2(,D))D
M\)"28O"0DF'PD))C!/"0DE7PY)"29?"0DE?PD))?=`7PY)"25O"0DEWPHW0#
M\)"26O"C=`7PD))9=!3PD))@=`7PY)"26/"0DE3PD))]\)"27/`B$DM5[V0!
M8`B0`;ET`?"`1Y"28N!@")`!N70"\(`YD))AX&`(D`&Y=`3P@"OE(U0/TY0$
M0`B0`;ET"/"`&N4F8`B0`;ET(/"`#I`!N>3PD`&X=`CP?P$BD`&X=`CP?P`B
MY)"2%O#E)&!)D))EX&`-Y/!3)?WE)50'<#B`,Y"25N`$\%,E[Y"2%N#_D)):
MX"__Y#/^D))6X-.?[F2`^'2`F$`-Y2&T`0NCX'`'X`3P(A)+>R+E)!0D_5`"
M@$>0DF3@8"P210GDD)*#\)"26>"0DH3PY/O]?UA^`1)+EY`!6W0%\)`&DG0!
M\)"28O"`$.4B5`_#E`10!WT!?P0210WD_Q)8IB+3$*\!P\#0CV.0!!W@8"20
M!2+@]69T__`2=F6_`0V0DGC@_WT!$E@*$D/GD`4BY6;P@`V0DGC@_WT!$E@*
M$D/GD`0?="#PT-"2KR*0`5_D\)`!/'0(\.20DH/PD))9X)"2A/#D^_U_7'X!
M$DN7D`%?=`7PD`:2=`+PD))A%/#E(E0/PY0,4`,210DBD`$W=`+PD`4B=/_P
M$G9E[W`&D`'(=/WP?0)_`Q(VYN4D8`5_`1)8IA)W&U,B\$,B`B+O)/Y@"P1P
M(I"28W0!\(`6[7`*D))@X)"28_"`!9"28^WPD))CX)"25?`B[V`/="$M]8+D
M-/SU@^!$$/`B="$M]8+D-/SU@^!4[_`BD`8$X%2_\.]@"N4AM`$%Y/\22:A3
M(O!#(@PBD`0=X'`4D))WX/_D_1)8"HYICVJ0!!]T(/`BD)*I[_`2=J:0DJG@
M8`60!2+D\%,B\$,B!"*0!@3@1$#PY2&T`05_`1))J%,B\$,B!"+E(S#F$N4C
M5`__D`$OX%2`3V2`\%,COR)3(O!#(@$22X422X93(O!#(@(B09)U`$&2J`!!
MDJH`09*B``"0!!O@5']D?W\!8`)_`"+DD))E\)"25O#U)2*0DEW@H^"0!5CP
M(GT!KR,"10U_`"(B(O"0DEG@D)*$\.3[_7]8?@'3$*\!P\#0D)*#X/NCX/5$
MY/5%$C6KT-"2KR+`X,#PP(/`@L#0==``P`#``<`"P`/`!,`%P`;`!W4.`%.1
MWY`!/.!5,/4TH^!5,?4UH^!5,O4VH^!5,_4WY30PX`:0`3QT`?#E-##A")`!
M/'0"\#$$Y30PXBR0`3QT!/#E)&`BD`:2X##@%)"2@^1QAY`!6W0%\)`&DG0!
M\(`'D))BY/!Q>^4T,.,\D`$\=`CPY21@,I`&DN`PX220DH/D\)"26>"0DH3P
MY/O]?UQ^`7&7D`%?=`7PD`:2=`+P@`>0DF'D\'%[Y30PY`B0`3QT$/"1]N4T
M,.4)D`$\="#P$E._Y34PX!:0`3UT`?"0`(/@]2.0`;OE(_!Q&7%[Y34PX@:0
M`3UT!/#E-3#D!I`!/700\.4V,.`&D`$^=`'PY38PX0:0`3YT`O#0!]`&T`70
M!-`#T`+0`=``T-#0@M"#T/#0X#+E7F0!<#OQN[\!!'\!\:^0`$;@1`3]?T:Q
M0I``1.!4^_U_1+%"D`!&X%3[_7]&L4)_`O'ZCV*0`<GE8O"T`0+QD2+PD`!%
MX%3^_7]%TQ"O`</`T(^"=8,`[?#QZM#0DJ\B[Q1@,!1@9B0"8`*A_I"2/W0"
M\)``2.!$#/U_2+%"D`!'X$0(_7]'L4*0`$7@1!#]?T6`<>20DC_PD)([$D-3
MD("%$BI_?X!^"!(OV9``1>!$[_U_1;%"D`!%X%3O_7]%L4*0`$;@1!#]?T:`
M.)"2/W0!\)"211)#4Y"`A1(J?W^`?@@2+]F0`$7@1"#]?T6Q0I``1>!$$/U_
M1;%"D`!&X$00_7]&L4(BD``"$D(@D))!\)```1)"("7@)>"0DD#P$BG9)>`E
MX)"21/"0!6#@D))/\)`%8>"0DE#PD`5BX)"24?"0!6/@D))2\**OY#.0DB7P
MPJ^0DD#@_Q)3;9"2)>`D_Y*OD))!X'`"X0:0DD#@<`+A!I"21.!P`N$&HJ_D
M,Y"2)?#"KY"24W0!\)"2)>`D_Y*OL3F0`$;@1`']?T:Q0I"2.>!@%9"211)#
M4Y"`A1(J?W^`?@@2+]F`!I`%(G1_\)``1>!4[_U_1;%"D`6'X&2`\)"23^"0
M!83PD))0X)`%A?"0DE'@D`6&\)"24N"0!8?PHJ_D,Y"2)?#"KY`!/.!$(/!]
M(.3_$C<`@"N0DD'@<"V0DE.Q.)``1N!4_OU_1K%"D`4BY/"BKS.0DB7PPJ]]
M(.3_$C:2D)(EX"3_DJ\BD`$\=/_PH_"C\)`!-/"C\*/PH_#]?U2Q0GW_?U6Q
M0GW_?U:Q0GW_?U>A0I`!,.3PH_"C\*/PD`$X\*/PH_"C\/U_4+%"Y/U_4;%"
MY/U_4K%"Y/U_4Z%"D`!)X)"2J_#@5`_P1/#]?TFQ0I"2J^!$L/U_2:%"D`'*
MY6'P[V`"\9$B?POQ^N]E86`0Y6&T`07D]6&``W5A`7\!(G\`(N20DGOPD`"`
MX$2`_7^`H4+@7_#3$*\!P\#0?Q#?_M#0DJ\BTQ"O`</`T)"2K._PTY0'4$3@
M_W0!J`<(@`+#,]C\]/^0`$823^>0DJS@_70!?@"H!0B`!<,SSC/.V/G_D`!$
MX/OD_N];J`4(@`;.HN<3SA/8^/^`3)"2K.`D^/#@_W0!J`<(@`+#,]C\]/^0
M`$/@7_`23^J0DJS@_70!?@"H!0B`!<,SSC/.V/G_D`!"X/OD_N];J`4(@`;.
MHN<3SA/8^/_0T)*O(I`"A._PH^[PHW0%\"+OCO`20[I0RP!`4/,`@%$>`0!1
M,@(`44H$````46?M5#]P!/[_@`1^`']`[RW_[CS^[W@&SL,3SA/8^7@&PS/.
M,\[8^8`F[51_<`3^_X`$?@!_@.\M_^X\_N]X!\[#$\X3V/EX!\,SSC/.V/G]
MK`:`2>UP!/[_@`1^`7\`[RWN/'T`_(`U[%0!37`$_O^`!'X"?P#O+>X\PQ-]
M`(`:[%0#37`$_O^`!'X$?P#O+>X\$Q-4/WT`)>`EX/RN!*\%(I`!Y'18\*-T
M`O`BY)"2%_"C\'6.`A)/U]&ED))\[_#1F9"2?N_PT>V0DG/N\*/O\.3U5?4A
M$G#6T9`22$(2,CW1A1)/.O$%T<#1B='5T811)Q)^=)"2&>79\,*OD`"`X$1`
M\!)/ZG7H`T.HA=*O,6R0DA?@9`'PY54PY`G"KU-5[]*OD77E53#F%L*O4U6_
MTJ\2:;R0DD/@_V`#M`$"46N0DD/@<`,2?M)1/Y`!O>4B\)"29."0`;SP@+60
MDJ/@5/[PY)"2I?"0DJ/@5'_PHW0*\"*0!C3@8"44<!M[`7H&>35_^7X!$G8#
MOP$)D`8UX%0/\(`$@`#!LN20!C3P(I"2.N##E!10!>`$\&$CD)(ZX&048`)A
M(Y"22>!P)9"23.!P'Y"22N!P&9"23>!P$Y"22^!P#9"23N!P!Y`$_>!4_O"0
MDDG@D`1$\)"22N"0!$7PD))+X)`$1O"CY/"0DDS@D`1(\)"23>"0!$GPD)).
MX)`$2O"CY/"0DC7@D`1,\)"2-N"0!$WPD)(WX)`$3O"0DCC@D`1/\.20DCKP
MD)(U!/#DH_"C\*/PD)))\*/PH_"C\*/PH_"0!6#@D)(:\)`%8>"0DAOPD`5B
MX)"2'/"0!6/@D)(=\)"24N#_D)(=X/[3GU`+D))2X,.>TY0!0!"0DD#@M`$"
M@`.0DD3@_W%M(I`%8."0DD_PD`5AX)"24/"0!6+@D))1\)`%8^"0DE+PPW3_
MG_Z0DE#@TYY`'N`O\*/@M/\/Y/"CX+3_`^3P(I"24H`#D))1X`3P(I"24.`O
M\"*0DD'@9`%@`H%TD`!&X$0!_7]&$DU"D))3X'`RD)(YX&`5D))%$D-3D("%
M$BI_?X!^"!(OV8`&D`4B='_PD))`X/]Q;9"24W0!$DTX@$"0DE/@9`%P.)"2
M1.#_<6WDD))3\)``1>!$`?U_11)-0I"2.>!@%9"2.Q)#4Y"`A1(J?W^`?@@2
M+]F`!9`%(N3PD`6'X&2`\)"23^"0!83PD))0X)`%A?"0DE'@D`6&\)"24N"0
M!8?P(M,0KP'#P-"0`<S@5`^0DAKPD)(:X/UP`J&]D)*HX/]T`7X`J`<(@`7#
M,\XSSMCY_^]=<`*AMI"2J.!U\`20`=`20U_@D)(;\'4=`74>DG4?&W4@`7L!
M>I)Y'+'"D)(<X/_$$Q,35`&0DJ@PX%G@=?`"D`"($D-?X)"2'?"0DJC@=?`"
MD`")$D-?X)"2'O"0DJC@=?`$D`'1$D-?X)"2'_"0DJC@=?`$D`'2$D-?X)"2
M(/"0DJC@=?`$D`'3$D-?X)"2(?"`,^!U\`20`=$20U_@D)(=\)"2J.!U\`20
M`=(20U_@D)(>\)"2J.!U\`20`=,20U_@D)(?\.]4?_][`7J2>1T27<F0DAK@
M_Y"2J.#^=`&H!@B``L,SV/ST7Y"2&O"0DJC@_W0!J`<(@`+#,]C\D`',\)"2
MJ.`$\.!4`_"!AI`!QN!$`O#0T)*O(M,0KP'#P-"+&HH;B1R0DH420XNK':H>
MJ1^0DH@20XNO(!4@[V`>D)*(Y'7P`1)#=!(IV?^0DH7D=?`!$D-T[Q)"38#;
MJQJJ&ZD<T-"2KR+3$*\!P\#0D)*+$D.+D)*JX)```1)"7W^O?@$2<QGO8$V0
MDHL20VN+'8H>B1]U(`)[`7H!>:"QPI"2CA)#:XL=BAZ)'Y"2BQ)#:Q(IV?_$
M5`_U('L!>@%YHK'"D`&O=/_PD)*JX`3PD`'+X&2`\-#0DJ\B(N3U82*0`61T
MH/`BD))^X)"2#_`BD`#SX'\`,.,"?P$BD``"X%3@?P%@`G\`(I`&-'3_\.2C
M\*/PH_`BD`#SX##B#9`%0700\)`%6O"CY/`B=3`?=3$!Y/4RD`$XY3#PH^4Q
M\*/E,O`BD))^X+0!#)``\N`PYP5^_7\S(G[]?R\B=2@SY/4I=2H']2N0`3#E
M*/"CY2GPH^4J\*/E*_`BD)(0X%3P1`/P5`]$@/![`'H`>5:0DHX20XL+>I)Y
M$,$1TQ"O`</`T)"2D1)#BY"2E.!4\$0&__#M5`_$5/#^[U0/3O"0DI$20VN0
MDHX20XM[`7J2>931$=#0DJ\BTQ"O`</`T._#E"!0#G2$+_6"Y#0$]8/M\(`I
M=*8O]8+D-)#U@^WPD))F[_`DIO6"Y#20]8/@D))G\'L!>I)Y9GT"\430T)*O
M(H^"CH.CHZ/D\"+D]5Y_8'X!@.W3$*\!P\#0D`0=X&`:D`4BX%208`>0`<;@
M1$#PD`''X##AY'\`@`)_`=#0DJ\BTQ"O`</`T)"2EN_PH^WPY*/PH_#E)&`$
MY/\1II"2EN`PX`F0DICD\*-T@/"0DI;@_\,3D/T0\)`$)>_PD)*7X&`?HZ/@
M_R0/]8+D-/SU@^!$@/!T$"_U@N0T_/6#X$2`\)"2F*/@__TD"/6"Y#3\]8/D
M\'0)+?6"Y#3\]8/@5/#P="$O]8+D-/SU@^!4]_"0DIC@_J/@_]#0DJ\B[V`+
MD))^X+0!$.3_@`F0DG[@M`$%?P$2=^4B$E?<OP$/D`()X/]]`1$*D`0?="#P
M(I`!`N!4`__@5`P3$U0__N]D`6`$[[0#$)"2$'0!\*-T-_"C=`'P@!KN9`%@
M!Z\&[F0#<$B0DA!T`?"C=#WPHW1`\)"2$.#^H^#_]8*.@^#]D)(2X/SM7&`,
MCX*.@^SPY)"2=?`BD))UX`3PX,.4"D`+Y/"0!!G@,.`"$<$BP.#`\,"#P(+`
MT'70`,``P`'``L`#P`3`!<`&P`>0`33@52CU+*/@52GU+:/@52KU+J/@52OU
M+^4L(.`"0=^0`31T`?"%T4V%TDZ%TT^%U%"%U5&%UE*%UU.%V53E5%1`PQ/_
MY5-4(&]P`D&<Y50PY0)!G.525#_U".5-5#_U">515!__Y0@EX"3$]8+D-(WU
M@^2/\!)"@>535!__Y0@EX"2`]8+D-(?U@^2/\!)"@>4)TY0$0`-U"01U\`KE
M")"$`!)#7W7P`N4)$D-?X/ZCX/_E4U0?+__D/OYU\`KE")"$`!)#7W7P`N4)
M$D-?[O"C[_#E5"#F(^535!__Y0@EX"3$]8+D-(SU@^2/\!)"@>5/,.<TKPBQ
M$H`NY5-4'__E""7@)$3U@N0TC?6#Y(_P$D*!Y4\PYQ'E3U1__>535!_U#:L)
MKPB1F^4D%"3]4`*`.I"29.!@*Y`!6^3PD`$\=`3P$DM5[V0!<"&0DH,22X>0
M`5MT!?"0!I)T`?"0DF+P@`D22U6_`0,22WOE+##A(9`!-'0"\(715H725X73
M6(7468756H766X777(7971)7(^4L,.,&D`$T=`CPY2PPY`F0`31T$/!#51#E
M+##E)I`!S^`PY1_@5-_PD`$T="#P=:@`=>@`$D]ED``#X%3[\!)/ZH#^Y2PP
MY@:0`31T0/#E+C#@%)"2?70!\)`!-O`21AZ199"2?>3PY2XPX0N0`39T`O!#
M54`1U^4N,.()D`$V=`3P$D::Y2XPXSB0`39T"/#E(60!<"SE)&`HD`%7Y/"0
M`3QT`O"0DH/D\)"26^"0DH3PY/O]?U1^`1)+EY`!5W0%\.4N,.0KD`$V=!#P
MY2&T`2#E)&`<D`%7Y/"0`3QT`O"0DF7D\%,E_>4E5`=P`Q)+>^4N,.4?D`$V
M="#PY2&T`13E)&`0D))DX&0"8`422LR``Q))\^4N,.8;D`$V=$#PY2&T`1#E
M)&`,4R7^Y254!W`#$DM[Y2\PX0F0`3=T`O`225?0!]`&T`70!-`#T`+0`=``
MT-#0@M"#T/#0X#*0DJ/@,.`NY2&T`2F0DJ+@!/#@M`H+D)*EX`3PY)"2HO"0
MDJ7@_Y"2I.#3GU`'L9'DD)*E\"*/"HT+Y0M4'Y"2$O!T`2_U@N0TB/6#X)"2
M$/"0!/W@D)(3M`$%=`/P@`-T`?"0DA/@_^O#GT`$KPJ`/)"2$.`E#?^C\*/@
MD$'6D_[OTYY`%'0!)0KU@N0TB/6#Y/"M"Z\*`E>`D)(1X/]T`24*]8+D-(CU
M@^_P(JT'=?`)[9"*2!)#7^#_D)(5\'1G+?6"Y#21]8/@5!^0DA3PTY]`!J/@
MD)(4\)"2%.#_)>`DGO6"Y#1!]8/DD_IT`9/[[R7@)&;U@N0T0?6#=`&3*__D
MDSK#$_[O$__M)>`DPO6"Y#2)]8/N\*/O\*\%D)(4X/T25X"0DA3@_R+D_P))
MJ)"2)1)#BQ(IV50!_Y"2H^!4_D_PX##@`K&1D)(E$D-K$BG9PQ,PX`J0``$2
M0B"0DJ3P(I"2(A)#B^\20Y1>$`%>!P)>-`->/05>1@9>DP=>3@E>5PQ>8`U>
M:0Y><AM>>QQ>&2U>(BY>A#!>*SL``%Z,D)(B$D-K`G-CD)(B$D-K`G-ID)(B
M$D-K`G.>D)(B$D-K`G/FD)(B$D-K`G0?D)(B$D-K`G0XD)(B$D-K`G+,D)(B
M$D-K@$:0DB(20VL"=("0DB(20VL"3?^0DB(20VL"?D&0DB(20VL"?6F0DB(2
M0VL"<Q&0DB(20VL"<OB0DB(20VNAEI`!QN!$`?`BD``$$D(@_U0?_N]4(,03
M5`?]KP:0DB7O\*/M\*,20XN0DB<20VN0``,20B!4\,14#Y"2*O"0``020B!4
M0,03$U0#D)(K\)"2)>#_=?`)D(I&$D-?K8*L@Y"2+.SPH^WP[W7P":0D1/ET
MBC7P^GL!HQ)#BY"2)Q)#:Y```Q)"(%0/_Y"2+A)#:^\20DV0DB<20VN0``(2
M0B#_D)(N$D-KD``![Q)"7Y"2)Q)#:Y```1)"(/^0DBS@_*/@_?6"C(/O\!(I
MV8V"C(.C\)"2*N#^D)(EX/\D@O6"Y#2)]8/N\)"2)N#^=?`)[Y"*2A)#7^[P
M=?`)[Y"*2Q)#7W0!\)"2*^#^=?`)[Y"*3!)#7^[PCP_O)>`DQO6"Y#2/KX+U
M$(\1Y0]U\`*D)`+Y=(DU\'42`?43B11U\`GE#Y"*1A)#7Z^"A8,5CQ;E#W7P
M":0D1/ETBC7P=1<!]1B)&72")0_U@N0TB?6#X!)#E&`B`&`W`6!,`F!A`V"*
M!&"?!6"T!F#:#&$'#6$T#F%A#P``897E#R7@),;U@N0TC_6#=/#PHW05@#SE
M#R7@),;U@N0TC_6#=/#PHW00@"?E#R7@),;U@N0TC_6#=/#PHW0%@!+E#R7@
M),;U@N0TC_6#=/#PH^3PY0\EX"0"]8+D-(GU@W0/\*-TC_`AE>4/)>`DQO6"
MY#2/]8-T#_"C=/6`)^4/)>`DQO6"Y#2/]8-T#_"C=/"`$N4/)>`DQO6"Y#2/
M]8/D\*-T#?#E#R7@)`+U@N0TB?6#Y/"C\"&5D`1'X*L2JA.I%!)"39`$1N"K
M$JH3J120``$20E^0!$7@A1&"A1"#\)`$1"&,D`1+X*L2JA.I%!)"39`$2N"K
M$JH3J120``$20E^0!$G@A1&"A1"#\)`$2(!8D`1/X*L2JA.I%!)"39`$3N"K
M$JH3J120``$20E^0!$W@A1&"A1"#\)`$3(`KD`13X*L2JA.I%!)"39`$4N"K
M$JH3J120``$20E^0!%'@A1&"A1"#\)`$4."%$8*%$(.C\*L2JA.I%,`#P`+`
M`1(IV?^K%ZH8J1D2*=E?T`'0`M`#$D)-JQ+E%"0!^>0U$_K``\`"P`$2*=G_
MJQ>J&*D9D``!$D(@7]`!T`+0`Q)"3841@H40@\"#P(+@_X46@H45@^#^[U[0
M@M"#\(41@H40@Z/`@\""X/^%%H*%%8.CX/[O7M""T(/PY0\EX"0"]8+D-(GU
M@^#^H^!.8$N0DC%T"_"0DC'@_\.4`%`"0=IT`7X`J`<(@`7#,\XSSMCY_^4/
M)>`D`O6"Y#2)]8/@7OZCX%].8`J0DC'@)!"C\(!HD)(QX!3P@+OE#R7@),;U
M@N0TC_6#X/ZCX$Y@1Y"2,70/\)"2,>#_PY0`0#QT`7X`J`<(@`7#,\XSSMCY
M_^4/)>`DQO6"Y#2/]8/@7OZCX%].8`B0DC'@H_"`#9"2,>`4\("_Y)"2,O#E
M#R7@),;U@N0TC_6#X/ZCX$Y@1N20DC'PD)(QX/_#E!!``F&3=`%^`*@'"(`%
MPS/.,\[8^?_E#R7@),;U@N0TC_6#X%[^H^!?3F`&D)(QX(!CD)(QX`3P@+_E
M#R7@)`+U@N0TB?6#X/ZCX$Y@1N20DC'PD)(QX/_#E`Q0/'0!?@"H!PB`!<,S
MSC/.V/G_Y0\EX"0"]8+D-(GU@^!>_J/@7TY@")"2,>`D$(`)D)(QX`3P@+_D
MD)(S\)"2,N#_=?`)Y0^0BD@20U_O\)"2,^#^=?`)Y0^0BDD20U_N\.4/PY0@
M4"QTA"4/]8+D-`3U@^#3GT`"@$=TA"4/]8+D-`3U@^##GE`(D)(SX*/P@#>`
M+72F)0_U@N0TD/6#X/^0DC+@_N_3GD`'D)(T[O"`%Y"2,^#^[\.>4`6C[O"`
M")"2,N"0DC3PD)(TX/VO#Q)7@)"2-.#_="8E#_6"Y#21]8/O\)"2,N#_TY03
M0`>0BD-T`_`B[].4"T`'D(I#=`+P(N_3E`-`!Y"*0W0!\"+DD(I#\"+3$*\!
MP\#0Y/W\[S#@`GV`[\,3D/T0\*X$KP70T)*O(L#@P/#`@\""P-!UT`#``,`!
MP`+``\`$P`7`!L`'4Y'OD`!1X/^0`%7@7_4]D`!2X/^0`%;@7_4^Y3TPY`:0
M`%5T$/#E/3#E!I``570@\.4],.8;D`!5=$#PD))"X%0#_[\#"Y"2/^!@!7\!
M$DU7Y3TPYQ60`%5T@/"0DD+@5`/_OP,%?P(235?E/C#@!I``5G0!\.4^,.$&
MD`!6=`+PY3XPX@:0`%9T!/#E/C#C!I``5G0(\-`'T`;0!=`$T`/0`M`!T`#0
MT-""T(/0\-#@,N_#E"!0.>\PX!?MQ%3P_>_#$_XDI/6"Y#0$]8/@5`^`$._#
M$_XDI/6"Y#0$]8/@5/#P=*0N]8+D-`3U@^!-\"*M!^W#E"!0$W2$+?6"Y#0$
M]8/@5'^0DBGP@!%TIBWU@N0TD/6#X%1_D)(I\)"2*>#Y5!^C\'7P">V0BD@2
M0U_@_Y"2+/#M)>`D`O6"Y#2)]8/@^Z/@D)(MR_"CZ_#M)>`DQO6"Y#2/]8/@
M^Z/@D)(OR_"CZ_"0DBK@_B7@)&;U@N0T0?6#Y)/Z=`&3^^TEX"3"]8+D-(GU
M@^KPH^OP[L.?0`+!^)"2*N#_=&<M]8+D-)'U@^_P[P20DBOPD)(LX/^0DBO@
M_M.?0`+A,N[#E!!`(>XD\/]T`7X`J`<(@`7#,\XSSMCY_Y"2+>!>_J/@7TYP
M)Y"2*^#_PY004%ET`7X`J`<(@`7#,\XSSMCY_Y"2+^!>_J/@7TY@/)"2*^"T
M$0V0DB[@,.<&D)(K=!?PD)(KX/]D$V`$[[02#9"2+>`PX`:0DBMT&/"0DBO@
MD)(J\)"2*?"`0I"2*^`$\,%6D)(LX/R0DBK@_VQP<71G+?6"Y#21]8/O\'7P
M">V0BDH20U_@M`$0Z2#F#)"2*N!$0)"2*?"``Z\!(I"2*N#_)>`DGO6"Y#1!
M]8/DD_IT`9/[[R7@)&;U@N0T0?6#=`&3*__DDSK#$_[O$__M)>`DPO6"Y#2)
M]8/N\*/O\(!FD)(JX-.<0%Z0DBS@_W1G+?6"Y#21]8/O\)"2*N_PD)(I\/RC
MX/\EX"2>]8+D-$'U@^23^G0!D_OO)>`D9O6"Y#1!]8-T`9,K_^23.L,3_N\3
M_^TEX"3"]8+D-(GU@^[PH^_PKP0B=`$M]8+D-(CU@^3PKP60DBG@1(#]$E>`
MD)(IX$2`_R*L!^S#E"!0$W2$+/6"Y#0$]8/@5'^0DBGP@!%TIBSU@N0TD/6#
MX%1_D)(I\)"2*>!4'_^0DBSP=?`)[)"*21)#7^"0DB[P=?`)[)"*2!)#7^#^
MD)(O\.PEX"3&]8+D-(_U@^#[H^"0DC#+\*/K\.PEX"0"]8+D-(GU@^#[H^"0
MDC++\*/K\._3GD`,D)(OX)"2+/"0DBGP[7`"(6J0DBWM\)"2*>`PY@Z0DBS@
MD)(I\)"2+>`4\)"2+>!P`B%JD)(LX/_3E`!0`B%JY)"2*_#O%)"2*O"0DB[@
M_9"2*N#_TYU`;^^4$$`A[R3P_W0!?@"H!PB`!<,SSC/.V/G_D)(RX%[^H^!?
M3G`GD)(JX/_#E!!0-W0!?@"H!PB`!<,SSC/.V/G_D)(PX%[^H^!?3F`:D)(J
MX)"2*?"0DBO@!/"0DBW@_Y"2*^!O8`B0DBK@%/"`@Y"2+>#_D)(KX,.?4`^0
MDBK@M04(D)(NX)"2*?"0DBG@_R7@))[U@N0T0?6#Y)/Z=`&3^^\EX"1F]8+D
M-$'U@W0!DRO_Y),ZPQ/^[Q/_["7@),+U@N0TB?6#[O"C[_"O!)"2*>#]$E>`
MD)(IX/\BY)"2&O"0DAK@_\.40$`#`G#5[[0@%)".Q>`$\)")`>#_D([%X+4'
M`N3PD)(:X/]U\`F0BDL20U_@9`%@`P)PS.\EX"2`]8+D-(?U@^#^H^#3E`#N
ME`!0`P)PS)"2&N"4($`)D([%X&`#`G#5D)(:X'7P"J0D`/ETA#7P=1(!]1.)
M%.#_)>`D@/6"Y#2']8/@_:/@D)(?S?"C[?#O)>`DQ/6"Y#2,]8/@_Z/@D)(A
MS_"C[_"0DAK@_\.4(%`3=(0O]8+D-`3U@^!4/Y"2&_"`%)"2&N`DIO6"Y#20
M]8/@5#^0DAOPD)(;X/Y4'Z/PD)(:X/]U\`F0BD@20U_@D)(D\'3F+_6"Y#20
M]8/@PY0%0`*A'I"2).#_D)(<X)]`$Y"2)."0DASP[E1`_I"2&_#O3O"0!/W@
M5`5D`7`KD)(<X/^004J3_I"2&N`D1/6"Y#2.]8/@PYY`!N^00-J`,I"2'."0
M0/:`*9"2'.#_D$%*D_Z0DAK@)$3U@N0TCO6#X,.>0`;OD$$2@`>0DAS@D$$N
MDY"2(_"0DB/@=?`&I"10^71`-?!U#__U$(D1D)(;X)!!\I/_TY"2(N"?D)(A
MX)0`0`V0DAK@_^3]$F?\`G!BD)(:X"7@),+U@N0TB?6#X/^CX)"2'<_PH^_P
MJP^J$*D1$BG9_WX`JQ*J$ZD4$D*7_:SP$BGRD)(=[H_P$D*!JP^J$*D1D``!
M$D(@_WX`JQ*J$ZD4D``"$D+"_:SP$BGRD)(=[H_P$D*!JP^J$*D1D``"$D(@
M_WX`JQ*J$ZD4D``$$D+"_:SP$BGRD)(=[H_P$D*!JP^J$*D1D``#$D(@_WX`
MJQ*J$ZD4D``&$D+"_:SP$BGRD)(=[H_P$D*!JP^J$*D1D``$$D(@_WX`JQ*J
M$ZD4D``($D+"_:SP$BGRD)(=[H_P$D*!JP^J$*D1D``%$D(@_WX`D)(?X/RC
MX/T2*?+3D)(>X)^0DAW@GD`,H^"?\)"2'>">\(`'Y)"2'?"C\)"2'>#\H^#]
MD)(:X/\EX"3"]8+D-(GU@^SPH^WPD)(;X"7@)&;U@N0T0?6#Y)/Z=`&3^]/M
MF^R:0`8299L"<#"0DAO@)>`DGO6"Y#1!]8/DD_YT`9/_PY"2'N"?D)(=X)Y`
M`P)P,)"2&N#_?0$29_P"<#"0DAK@_R3F]8+D-)#U@^#\9`5@`L']D(I#X/ZT
M`PN0DAS@PY090#V`+NZT`@N0DAS@PY010"Z`'Y"*0^#^M`$+D)(<X,.4"D`;
M@`SN<!&0DAS@PY0#0`V0CH1T`?"`!>20CH3PD)(:X/XDA/6"Y#2,]8/@D)(H
M\'1$+O6"Y#2.]8/@_L.4,%`*Y)"2*/!TYB_!IY".A.!D`6`"P9R0DAK@)(7U
M@N0TCO6#X&0*8%N0DAK@_^XD!?OD,_IT02_U@N0TB/6#X/_3F^ID@/AT@)A0
M.)"2&N#^[R0%^^0S^G1$+O6"Y#2.]8/@TYOJ9(#X=("84!:0DAK@)";U@N0T
MD?6#X/^0DAS@;V!6D)(:X"1$]8+D-([U@^#_TY1"0`B0DBAT!?"`$>_3E#F0
MDBA`!70#\(`#=`'PD)(:X/\D1/6"Y#2.]8/@_G1!+_6"Y#2(]8/N\)"2&N`D
MA?6"Y#2.@"^0DAK@_R3F]8+D-)#U@^3P=(4O]8+D-([U@^`$\(`4Y)"2*/"0
MDAK@).;U@N0TD/6#Y/"0DAS@_I"2&N#_)";U@N0TD?6#[O"0DBC@_G2$+_6"
MY#2,]8/N\'7P">^0BDP20U_@M`$1Y)"2*/!TYB_U@N0TD/6#Y/"0DBC@_0)P
M+>QD!F`#`G`PD)(=\*/PD$(3D_]^`)"2'^#\H^#]$BGRD)(F[O"C[_"0DAK@
M)(3U@N0TC/6#X)"2*/#DD)(E\)"2)>#_TY0$4$>K$JH3J11U\`+OI/6"A?"#
M$D+"_:SP[Y!"#I/_?@`2*?*0DAWNC_`20H&0DB;@_J/@_].0DA[@GY"2'>">
M4`B0DB7@!/"`KY"2)>##$_"0DBC@_[0!#9"2)>!P79"2*`3P@%OOM`,=D)(E
MX/]P")"2*'0#\(!([[0!")"2*'0!\(`\@#60DBC@9`5P,I"2)>#_<`B0DBAT
M!?"`#^^0DBBT`05T`_"``W0!\-.0DB+@E`.0DB'@E`!`!>20DBCPTY"2(N"4
M`Y"2(>"4`$`%Y)"2*/"0DBC@_9"2&N#_)(3U@N0TC/6#[?`295N0DAK@_R3F
M]8+D-)#U@^#3E`50#W3F+_6"Y#20]8/@!/"`#Y"2&N`DYO6"Y#20]8/D\*L2
MJA.I%.3U\!)"^JL2JA.I%)```N3U\!)#&9``!.3U\!)#&9``!N3U\!)#&9``
M".3U\!)#&9"2&N#_)>`D@/6"Y#2']8/D\*/P[R7@),3U@N0TC/6#Y/"C\.\E
MX"1$]8+D-(WU@^3PH_"0DAK@!/`":<$BD`1$=!'PHW3P\*-T#_"CY/"0DAKP
MD)(:X/_#E!!0%'2D+_6"Y#0$]8/D\)"2&N`$\(#BY)".Q?"0B0$$\.20DAKP
MD)(:X/_#E$!``D'+=?`*[Y"$`!)#7^3PH_!U\`KOD(0"$D-?Y/"C\'7P"N^0
MA`020U_D\*/P=?`*[Y"$!A)#7^3PH_!U\`KOD(0($D-?Y/"C\'0F+_6"Y#21
M]8-T$_!TA2_U@N0TCO6#Y/!TA"_U@N0TC/6#Y/#O)>`D@/6"Y#2']8/D\*/P
M[R7@),3U@N0TC/6#Y/"C\.\EX"3$]8+D-(WU@^3PH_#O)>`D1/6"Y#2-]8/D
M\*/P[R7@),;U@N0TCO6#Y/"C\.\EX"1&]8+D-(_U@^3PH_!TAB_U@N0TD/6#
MY/!T1B_U@N0TD/6#Y/!TYB_U@N0TD/6#Y/"00<23_G0!D_^008QT`9,O_^23
M/L,3_N\3_Y"2&N#])>`DPO6"Y#2)]8/N\*/O\'7P">V0BDL20U]T`?!U\`GM
MD(I*$D-?=`'P=((M]8+D-(GU@W0,\'7P">V0BD820U]T__"C\'7P">V0BD02
M0U_D\*-T#_!U\`GMD(I($D-?=!/P=?`)[9"*21)#7^3P[<.4(%`/=(0M]8+D
M-`3U@W03\(`-=*8M]8+D-)#U@W03\)"2&N`$\"$8(A(IV?_#E$!0%)```A)"
M(/YT1"_U@N0TCO6#[O`B[[1`"I```A)"()"*0O`BD``$$D(@_U0__N]4@,03
M$Q-4`?VO!@)>J!(IV9")`?`BD)*:[O"C[_#DH_"C\)"2FN#^H^#U@HZ#X&`L
MPY"2G>"4Z)"2G."4`T`*D`'&X$00\'\`(I"2G.1U\`$20H%_"GX`$C=4@,9_
M`2(2*=GU(2+3$*\!P\#0D)(E$BJ+`````)```1)"()"29/"0``,20B"0DE3P
M$D?<D))DX)`!YO#0T)*O(I```A)"(/\PX"42*=F0DEKPD``!$D(@D));\._#
M$U1_D))9\)```Q)"()"28/`BD)):=`/PD));=`7PD))9=!3PD))@=`7P(A(I
MV3#@&<,35'^0DE_PD``!$D(@_Y"27>3PH^_P@`^0DE]T!?"0DEWD\*-T`_"0
MDEW@H^"0!5CP(A(IV9"27/!@!^3]?P0210V0DES@D`'G\"*0`@G@_1(IV?ZO
M!>TND))V\)```1)"(/_M+Y"2=_"0``(20B#_[2^0DGCPD``#$D(@_^TOD))Y
M\)``!!)"(/^N!>TOD))Z\"+3$*\!P\#0D)(E$D.+D)(E$D-KD``!$D+"^N7P
M)`#_Y#K^D)(E$D-KD``![H_P$D,9$BG9_V`LM5X6D)(E$D-KD``!$D+"96!P
M!.5?9?!@(Y"2)1)#:Y```1)"PO^N\)'X@!"0DB420VL2*=EE7F`#$E?3T-"2
MKR*0DBCN\*/O\'5>`8Y?]6#D_7\+L3SD_7\"L3P23[OD_Q)/K^3U8I`!R>5B
M\)"2*.#\H^#][/N-1.3U17T!?V!^`0(UJ],0KP'#P-"0DBOM\)"2*N_PTY0'
M4$^CX'`:D)(JX/]T`:@'"(`"PS/8_/3_D`!'X%_P@!>0DBK@_W0!J`<(@`+#
M,]C\_Y``1^!/\!)/ZI"2*N#_=`&H!PB``L,SV/ST_Y``1H!:D)(JX"3X\*/@
M<!V0DBK@_W0!J`<(@`+#,]C\Q%3P]/^0`$/@7_"`&I"2*N#_=`&H!PB``L,S
MV/S$5/#_D`!#X$_P$D_JD)(JX/]T`:@'"(`"PS/8_/3_D`!#$D_GT-"2KR*.
M#X\0BQ&*$HD3Y)"2&O#OD``Q\!)/ZN4/5`/_D``RX%3\3_`23^J0`#/@5'_P
M$D_JD``SX"#G#I"2&N##E&10!>`$\(#KD)(:X,.49%`0D``PX*L1JA*I$Q)"
M37\!(G\`(N20DJ;PH_"0!?C@<`^CX'`+H^!P!Z/@<`-_`2+3D)*GX)3HD)*F
MX)0#0`-_`")_,GX`$C=4D)*FY'7P`1)"@8#&D)'_$D-3D("%$BI_?WA^"!(O
MV9"2`Q)#4Y"`A1(J?W\$?@P2+]F0D@<20U.0@(42*G]_`'X($B_9D)(+$D-3
MD("%$BI_?W!^#A(OV9"`61(JBP`#+97D_?\2-(&0DG[@M`$1D(!9$BJ+``,M
ME>3]?P$2-($B?WA^"!(GWI"1_Q(J?W\$?@P2)]Z0D@,2*G]_`'X($B?>D)('
M$BI_D))^X)"1_[0!#1)#4^]4Q__M5,?]@`<20U/O5,?_[)"`A1(J?W]X?@@2
M+]F0D@,20U/O5`__[)"`A1(J?W\$?@P2+]F0D@<20U/O1`+_[)"`A1(J?W\`
M?@@2+]E_<'X.$B?>D)(+$BI_D("%$BJ+`!LEH']P?@X2+]F0@%D2*HL`````
MY/W_$C2!D))^X+0!$9"`61(JBP````#D_7\!$C2!(N]P`P)YG9"2#^!@`P)]
M:)"1^Q)#4Y"`A1(J?W^,?@@2+]F0D:<20U.0@(42*G]_1'X($B_9D)&K$D-3
MD("%$BI_?UQ^"!(OV9"1KQ)#4Y"`A1(J?W]L?@X2+]F0D;,20U.0@(42*G]_
M<'X.$B_9D)&W$D-3D("%$BI_?W1^#A(OV9"1NQ)#4Y"`A1(J?W]X?@X2+]F0
MD;\20U.0@(42*G]_?'X.$B_9D)'#$D-3D("%$BI_?X!^#A(OV9"1QQ)#4Y"`
MA1(J?W^$?@X2+]F0D<L20U.0@(42*G]_B'X.$B_9D)'/$D-3D("%$BI_?XQ^
M#A(OV9"1TQ)#4Y"`A1(J?W_0?@X2+]F0D=<20U.0@(42*G]_U'X.$B_9D)';
M$D-3D("%$BI_?]A^#A(OV9"1WQ)#4Y"`A1(J?W_<?@X2+]F0D>,20U.0@(42
M*G]_X'X.$B_9D)'G$D-3D("%$BI_?^Q^#A(OV9"1ZQ)#4Y"`A1(J?W\$?@P2
M+]F0D>\20U.0@(42*G]_!'X-$B_9D)'S$D-3D("%$BI_?PQ^"1(OV9"1]Q)#
M4Y"`A1(J?W\$?@@2+]F0D@]T`?`BD)(/X&0!8`*A:'^,?@@2)]Z0D?L2*G]_
M1'X($B?>D)&G$BI_?UQ^"!(GWI"1JQ(J?W]L?@X2)]Z0D:\2*G]_<'X.$B?>
MD)&S$BI_?W1^#A(GWI"1MQ(J?W]X?@X2)]Z0D;L2*G]_?'X.$B?>D)&_$BI_
M?X!^#A(GWI"1PQ(J?W^$?@X2)]Z0D<<2*G]_B'X.$B?>D)'+$BI_?XQ^#A(G
MWI"1SQ(J?W_0?@X2)]Z0D=,2*G]_U'X.$B?>D)'7$BI_?]A^#A(GWI"1VQ(J
M?W_<?@X2)]Z0D=\2*G]_X'X.$B?>D)'C$BI_?^Q^#A(GWI"1YQ(J?W\$?@P2
M)]Z0D>L2*G]_!'X-$B?>D)'O$BI_?PQ^"1(GWI"1\Q(J?W\$?@@2)]Z0D?<2
M*G]_C'X($B?>D)*>$BI_D)*>$D-3[43`_>R0DIX2*G^0DIX20U.0@(42*G]_
MC'X($B_9D("%$BJ+``$``']$?@@2+]F0@(42*HL`VR6D?UQ^"!(OV9"`A1(J
MBR#;):1_;'X.$B_9D("%$BJ+(-LEI']P?@X2+]F0@(42*HL$&R6D?W1^#A(O
MV9"`A1(JBP0;):1_>'X.$B_9D("%$BJ+!!LEI']\?@X2+]F0@(42*HL$&R6D
M?X!^#A(OV9"`A1(JBV/;):1_A'X.$B_9D("%$BJ+!!LEI'^(?@X2+]F0@(42
M*HL@VR6D?XQ^#A(OV9"`A1(JBR#;):1_T'X.$B_9D("%$BJ+(-LEI'_4?@X2
M+]F0@(42*HL@VR6D?]A^#A(OV9"`A1(JBP`;):1_W'X.$B_9D("%$BJ+`!LE
MI'_@?@X2+]F0@(42*HLDVR6D?^Q^#A(OV7\$?@P2)]Z0DIX2*G^0DIX20U/D
M_^R0DIX2*G^0DIX20U/O1!'_[)"2GA(J?Y"2GA)#4Y"`A1(J?W\$?@P2+]E_
M!'X-$B?>D)*>$BI_D)*>$D-3[U3P_^R0DIX2*G^0DIX20U/O1`'_[)"2GA(J
M?Y"2GA)#4Y"`A1(J?W\$?@T2+]E_#'X)$B?>D)*>$BI_D)*>$D-3Y/_LD)*>
M$BI_D)*>$D-3[T01_^R0DIX2*G^0DIX20U.0@(42*G]_#'X)$B_9?PQ^"1(G
MWI"2GA(J?Y"2GA)#4^U4#_WL5/#\D)*>$BI_D)*>$D-3[400_>Q$`?R0DIX2
M*G^0DIX20U.0@(42*G]_#'X)$B_9?P1^"!(GWI"2GA(J?Y"2GA)#4^]4\/_L
MD)*>$BI_D)*>$D-3[T0!_^R0DIX2*G^0DIX20U.0@(42*G]_!'X($B_9Y)"2
M#_`BBP^*$(D1D``"$D(@D))"\.`PX$N0DCET`?!_@'X($B?>D)([$BI_JP^J
M$*D1D``!$D(@_^3\_?YX&A(J;*@$J06J!JL'D)([$D-3[%0#_!)#1I"211(J
M?Y`%(N3P@"WDD)(Y\'^`?@@2)][L5`/\[$3`_)"2.Q(J?Y"2.Q)#4Y"`A1(J
M?W^`?@@2+]F0DD+@,.$;?0Q_1Q)-0I``2.!$#/U_2!)-0I``1N!$$(`>D`!'
MX%3S_7]'$DU"D`!(X%3S_7]($DU"D`!&X%3O_7]&$DU"Y)"2/_`BD``"$D(@
MD))#\.!@!.#T<"&BK^0S]0_"KY``1^!4^_U_1Q)-0GU`?P$2-J_E#R3_DJ\B
MY/U_11)-0I`$_>3PH_"0DD/PD)))\)"23/"0DDKPD))-\)"22_"0DD[PD)(U
M!/#DH_"C\*/PD)(Z\)"2/_"0DD'PD))3\)"21/"0DD#PD)(Y\)``4>!$P/U_
M40)-0I"24^!D`6`(D))!X&`"X:F0DC7@PY3_4`7@!/"`.Y"2-N##E/]0!N`$
M\.2`*)"2-^##E/]0"N`$\.20DC;P@!60DCC@PY3_4!#@!/#DD)(W\)"2-O"0
MDC7PD`!$X%0,8';@,.(RD)))X,.4_U`%X`3P@"20DDK@PY3_4`;@!/#D@!&0
MDDO@PY3_4`S@!/#DD))*\)"22?"0`$3@,.,RD)),X,.4_U`%X`3P@"20DDW@
JPY3_4`;@!/#D@!&0DD[@PY3_4`S@!/#DD))-\)"23/"0!/W@1`'P(GP.
`
end

View File

@ -53,6 +53,7 @@ struct sha1_ctxt {
} m;
u_int8_t count;
};
typedef struct sha1_ctxt SHA1_CTX;
#ifdef _KERNEL
extern void sha1_init(struct sha1_ctxt *);
@ -61,7 +62,6 @@ extern void sha1_loop(struct sha1_ctxt *, const u_int8_t *, size_t);
extern void sha1_result(struct sha1_ctxt *, caddr_t);
/* compatibilty with other SHA1 source codes */
typedef struct sha1_ctxt SHA1_CTX;
#define SHA1Init(x) sha1_init((x))
#define SHA1Update(x, y, z) sha1_loop((x), (y), (z))
#define SHA1Final(x, y) sha1_result((y), (x))

View File

@ -215,7 +215,7 @@ resolve_entry(struct adapter *sc, struct l2t_entry *e)
struct tom_data *td = sc->tom_softc;
struct toedev *tod = &td->tod;
struct sockaddr_in sin = {0};
uint8_t dmac[ETHER_ADDR_LEN];
uint8_t dmac[ETHER_HDR_LEN];
uint16_t vtag = EVL_VLID_MASK;
int rc;

View File

@ -233,7 +233,7 @@ resolve_entry(struct adapter *sc, struct l2t_entry *e)
struct sockaddr_in sin = {0};
struct sockaddr_in6 sin6 = {0};
struct sockaddr *sa;
uint8_t dmac[ETHER_ADDR_LEN];
uint8_t dmac[ETHER_HDR_LEN];
uint16_t vtag = VLAN_NONE;
int rc;

3490
sys/dev/rtwn/if_rtwn.c Normal file

File diff suppressed because it is too large Load Diff

2106
sys/dev/rtwn/if_rtwnreg.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -175,6 +175,7 @@ static const STRUCT_USB_HOST_ID axe_devs[] = {
AXE_DEV(PLANEX3, GU1000T, AXE_FLAG_178),
AXE_DEV(SITECOM, LN029, 0),
AXE_DEV(SITECOMEU, LN028, AXE_FLAG_178),
AXE_DEV(SITECOMEU, LN031, AXE_FLAG_178),
AXE_DEV(SYSTEMTALKS, SGCX2UL, 0),
#undef AXE_DEV
};

View File

@ -4203,6 +4203,7 @@ product SITECOMEU RTL8188CU_1 0x0052 RTL8188CU
product SITECOMEU RTL8188CU_2 0x005c RTL8188CU
product SITECOMEU RTL8192CU 0x0061 RTL8192CU
product SITECOMEU LN032 0x0072 LN-032
product SITECOMEU LN031 0x0056 LN-031
product SITECOMEU LN028 0x061c LN-028
product SITECOMEU WL113 0x9071 WL-113
product SITECOMEU ZD1211B 0x9075 ZD1211B

View File

@ -568,14 +568,16 @@ static int
null_remove(struct vop_remove_args *ap)
{
int retval, vreleit;
struct vnode *lvp;
struct vnode *lvp, *vp;
if (vrefcnt(ap->a_vp) > 1) {
lvp = NULLVPTOLOWERVP(ap->a_vp);
vp = ap->a_vp;
if (vrefcnt(vp) > 1) {
lvp = NULLVPTOLOWERVP(vp);
VREF(lvp);
vreleit = 1;
} else
vreleit = 0;
VTONULL(vp)->null_flags |= NULLV_DROP;
retval = null_bypass(&ap->a_gen);
if (vreleit != 0)
vrele(lvp);

View File

@ -311,6 +311,8 @@ SUBDIR= \
re \
reiserfs \
rl \
rtwn \
rtwnfw \
${_s3} \
${_safe} \
${_sbni} \

View File

@ -0,0 +1,5 @@
# $FreeBSD$
SUBDIR= rtwnrtl8192cU rtwnrtl8192cUB
.include <bsd.subdir.mk>

View File

@ -0,0 +1,15 @@
# $FreeBSD$
#
# Common rules for building firmware. Note this gets auto-included
# by the subdir Makefile's as a consequence of included bsd.kmod.mk.
_FIRM= ${IMG}.fw
CLEANFILES+= ${_FIRM}
FIRMWS= ${_FIRM}:${KMOD}:111
FIRMWARE_LICENSE= realtek
${_FIRM}: ${.CURDIR}/../../../contrib/dev/rtwn/${_FIRM}.uu
uudecode -p $? > ${.TARGET}

View File

@ -0,0 +1,6 @@
# $FreeBSD$
KMOD= rtwn-rtl8192cfwU
IMG= rtwn-rtl8192cfwU
.include <bsd.kmod.mk>

View File

@ -0,0 +1,6 @@
# $FreeBSD$
KMOD= rtwn-rtl8192cfwU_B
IMG= rtwn-rtl8192cfwU_B
.include <bsd.kmod.mk>

View File

@ -69,6 +69,7 @@ __FBSDID("$FreeBSD$");
#include <net/if.h>
#include <net/if_var.h>
#include <net/if_dl.h>
#include <net/bpf.h>
#include <net/bpf_buffer.h>
#ifdef BPF_JITTER
@ -76,6 +77,7 @@ __FBSDID("$FreeBSD$");
#endif
#include <net/bpf_zerocopy.h>
#include <net/bpfdesc.h>
#include <net/route.h>
#include <net/vnet.h>
#include <netinet/in.h>
@ -164,7 +166,7 @@ static void bpf_detachd(struct bpf_d *);
static void bpf_detachd_locked(struct bpf_d *);
static void bpf_freed(struct bpf_d *);
static int bpf_movein(struct uio *, int, struct ifnet *, struct mbuf **,
struct sockaddr *, int *, struct bpf_insn *);
struct sockaddr *, int *, struct bpf_d *);
static int bpf_setif(struct bpf_d *, struct ifreq *);
static void bpf_timed_out(void *);
static __inline void
@ -454,7 +456,7 @@ bpf_ioctl_setzbuf(struct thread *td, struct bpf_d *d, struct bpf_zbuf *bz)
*/
static int
bpf_movein(struct uio *uio, int linktype, struct ifnet *ifp, struct mbuf **mp,
struct sockaddr *sockp, int *hdrlen, struct bpf_insn *wfilter)
struct sockaddr *sockp, int *hdrlen, struct bpf_d *d)
{
const struct ieee80211_bpf_params *p;
struct ether_header *eh;
@ -549,7 +551,7 @@ bpf_movein(struct uio *uio, int linktype, struct ifnet *ifp, struct mbuf **mp,
if (error)
goto bad;
slen = bpf_filter(wfilter, mtod(m, u_char *), len, len);
slen = bpf_filter(d->bd_wfilter, mtod(m, u_char *), len, len);
if (slen == 0) {
error = EPERM;
goto bad;
@ -566,6 +568,10 @@ bpf_movein(struct uio *uio, int linktype, struct ifnet *ifp, struct mbuf **mp,
else
m->m_flags |= M_MCAST;
}
if (d->bd_hdrcmplt == 0) {
memcpy(eh->ether_shost, IF_LLADDR(ifp),
sizeof(eh->ether_shost));
}
break;
}
@ -1088,6 +1094,7 @@ bpfwrite(struct cdev *dev, struct uio *uio, int ioflag)
struct ifnet *ifp;
struct mbuf *m, *mc;
struct sockaddr dst;
struct route ro;
int error, hlen;
error = devfs_get_cdevpriv((void **)&d);
@ -1119,7 +1126,7 @@ bpfwrite(struct cdev *dev, struct uio *uio, int ioflag)
hlen = 0;
/* XXX: bpf_movein() can sleep */
error = bpf_movein(uio, (int)d->bd_bif->bif_dlt, ifp,
&m, &dst, &hlen, d->bd_wfilter);
&m, &dst, &hlen, d);
if (error) {
d->bd_wdcount++;
return (error);
@ -1151,7 +1158,14 @@ bpfwrite(struct cdev *dev, struct uio *uio, int ioflag)
BPFD_UNLOCK(d);
#endif
error = (*ifp->if_output)(ifp, m, &dst, NULL);
bzero(&ro, sizeof(ro));
if (hlen != 0) {
ro.ro_prepend = (u_char *)&dst.sa_data;
ro.ro_plen = hlen;
ro.ro_flags = RT_HAS_HEADER;
}
error = (*ifp->if_output)(ifp, m, &dst, &ro);
if (error)
d->bd_wdcount++;

View File

@ -665,6 +665,7 @@ int
flowtable_lookup(sa_family_t sa, struct mbuf *m, struct route *ro)
{
struct flentry *fle;
struct llentry *lle;
if (V_flowtable_enable == 0)
return (ENXIO);
@ -693,8 +694,15 @@ flowtable_lookup(sa_family_t sa, struct mbuf *m, struct route *ro)
}
ro->ro_rt = fle->f_rt;
ro->ro_lle = fle->f_lle;
ro->ro_flags |= RT_NORTREF;
lle = fle->f_lle;
if (lle != NULL && (lle->la_flags & LLE_VALID)) {
ro->ro_prepend = lle->r_linkdata;
ro->ro_plen = lle->r_hdrlen;
ro->ro_flags |= RT_MAY_LOOP;
if (lle->la_flags & LLE_IFADDR)
ro->ro_flags |= RT_L2_ME;
}
return (0);
}

View File

@ -161,6 +161,7 @@ static int ifconf(u_long, caddr_t);
static void if_freemulti(struct ifmultiaddr *);
static void if_grow(void);
static void if_input_default(struct ifnet *, struct mbuf *);
static int if_requestencap_default(struct ifnet *, struct if_encap_req *);
static void if_route(struct ifnet *, int flag, int fam);
static int if_setflag(struct ifnet *, int, int, int *, int);
static int if_transmit(struct ifnet *ifp, struct mbuf *m);
@ -673,6 +674,9 @@ if_attach_internal(struct ifnet *ifp, int vmove, struct if_clone *ifc)
if (ifp->if_input == NULL)
ifp->if_input = if_input_default;
if (ifp->if_requestencap == NULL)
ifp->if_requestencap = if_requestencap_default;
if (!vmove) {
#ifdef MAC
mac_ifnet_create(ifp);
@ -3397,6 +3401,43 @@ if_setlladdr(struct ifnet *ifp, const u_char *lladdr, int len)
return (0);
}
/*
* Compat function for handling basic encapsulation requests.
* Not converted stacks (FDDI, IB, ..) supports traditional
* output model: ARP (and other similar L2 protocols) are handled
* inside output routine, arpresolve/nd6_resolve() returns MAC
* address instead of full prepend.
*
* This function creates calculated header==MAC for IPv4/IPv6 and
* returns EAFNOSUPPORT (which is then handled in ARP code) for other
* address families.
*/
static int
if_requestencap_default(struct ifnet *ifp, struct if_encap_req *req)
{
if (req->rtype != IFENCAP_LL)
return (EOPNOTSUPP);
if (req->bufsize < req->lladdr_len)
return (ENOMEM);
switch (req->family) {
case AF_INET:
case AF_INET6:
break;
default:
return (EAFNOSUPPORT);
}
/* Copy lladdr to storage as is */
memmove(req->buf, req->lladdr, req->lladdr_len);
req->bufsize = req->lladdr_len;
req->lladdr_off = 0;
return (0);
}
/*
* The name argument must be a pointer to storage which will last as
* long as the interface does. For physical devices, the result of

View File

@ -113,6 +113,7 @@ static int ether_resolvemulti(struct ifnet *, struct sockaddr **,
#ifdef VIMAGE
static void ether_reassign(struct ifnet *, struct vnet *, char *);
#endif
static int ether_requestencap(struct ifnet *, struct if_encap_req *);
#define ETHER_IS_BROADCAST(addr) \
(bcmp(etherbroadcastaddr, (addr), ETHER_ADDR_LEN) == 0)
@ -135,6 +136,138 @@ update_mbuf_csumflags(struct mbuf *src, struct mbuf *dst)
dst->m_pkthdr.csum_data = 0xffff;
}
/*
* Handle link-layer encapsulation requests.
*/
static int
ether_requestencap(struct ifnet *ifp, struct if_encap_req *req)
{
struct ether_header *eh;
struct arphdr *ah;
uint16_t etype;
const u_char *lladdr;
if (req->rtype != IFENCAP_LL)
return (EOPNOTSUPP);
if (req->bufsize < ETHER_HDR_LEN)
return (ENOMEM);
eh = (struct ether_header *)req->buf;
lladdr = req->lladdr;
req->lladdr_off = 0;
switch (req->family) {
case AF_INET:
etype = htons(ETHERTYPE_IP);
break;
case AF_INET6:
etype = htons(ETHERTYPE_IPV6);
break;
case AF_ARP:
ah = (struct arphdr *)req->hdata;
ah->ar_hrd = htons(ARPHRD_ETHER);
switch(ntohs(ah->ar_op)) {
case ARPOP_REVREQUEST:
case ARPOP_REVREPLY:
etype = htons(ETHERTYPE_REVARP);
break;
case ARPOP_REQUEST:
case ARPOP_REPLY:
default:
etype = htons(ETHERTYPE_ARP);
break;
}
if (req->flags & IFENCAP_FLAG_BROADCAST)
lladdr = ifp->if_broadcastaddr;
break;
default:
return (EAFNOSUPPORT);
}
memcpy(&eh->ether_type, &etype, sizeof(eh->ether_type));
memcpy(eh->ether_dhost, lladdr, ETHER_ADDR_LEN);
memcpy(eh->ether_shost, IF_LLADDR(ifp), ETHER_ADDR_LEN);
req->bufsize = sizeof(struct ether_header);
return (0);
}
static int
ether_resolve_addr(struct ifnet *ifp, struct mbuf *m,
const struct sockaddr *dst, struct route *ro, u_char *phdr,
uint32_t *pflags)
{
struct ether_header *eh;
struct rtentry *rt;
uint32_t lleflags = 0;
int error = 0;
#if defined(INET) || defined(INET6)
uint16_t etype;
#endif
eh = (struct ether_header *)phdr;
switch (dst->sa_family) {
#ifdef INET
case AF_INET:
if ((m->m_flags & (M_BCAST | M_MCAST)) == 0)
error = arpresolve(ifp, 0, m, dst, phdr, &lleflags);
else {
if (m->m_flags & M_BCAST)
memcpy(eh->ether_dhost, ifp->if_broadcastaddr,
ETHER_ADDR_LEN);
else {
const struct in_addr *a;
a = &(((const struct sockaddr_in *)dst)->sin_addr);
ETHER_MAP_IP_MULTICAST(a, eh->ether_dhost);
}
etype = htons(ETHERTYPE_IP);
memcpy(&eh->ether_type, &etype, sizeof(etype));
memcpy(eh->ether_shost, IF_LLADDR(ifp), ETHER_ADDR_LEN);
}
break;
#endif
#ifdef INET6
case AF_INET6:
if ((m->m_flags & M_MCAST) == 0)
error = nd6_resolve(ifp, 0, m, dst, phdr, &lleflags);
else {
const struct in6_addr *a6;
a6 = &(((const struct sockaddr_in6 *)dst)->sin6_addr);
ETHER_MAP_IPV6_MULTICAST(a6, eh->ether_dhost);
etype = htons(ETHERTYPE_IPV6);
memcpy(&eh->ether_type, &etype, sizeof(etype));
memcpy(eh->ether_shost, IF_LLADDR(ifp), ETHER_ADDR_LEN);
}
break;
#endif
default:
if_printf(ifp, "can't handle af%d\n", dst->sa_family);
if (m != NULL)
m_freem(m);
return (EAFNOSUPPORT);
}
if (error == EHOSTDOWN) {
rt = (ro != NULL) ? ro->ro_rt : NULL;
if (rt != NULL && (rt->rt_flags & RTF_GATEWAY) != 0)
error = EHOSTUNREACH;
}
if (error != 0)
return (error);
*pflags = RT_MAY_LOOP;
if (lleflags & LLE_IFADDR)
*pflags |= RT_L2_ME;
return (0);
}
/*
* Ethernet output routine.
* Encapsulate a packet of type family for the local net.
@ -145,27 +278,20 @@ int
ether_output(struct ifnet *ifp, struct mbuf *m,
const struct sockaddr *dst, struct route *ro)
{
short type;
int error = 0, hdrcmplt = 0;
u_char edst[ETHER_ADDR_LEN];
struct llentry *lle = NULL;
struct rtentry *rt0 = NULL;
int error = 0;
char linkhdr[ETHER_HDR_LEN], *phdr;
struct ether_header *eh;
struct pf_mtag *t;
int loop_copy = 1;
int hlen; /* link layer header length */
int is_gw = 0;
uint32_t pflags = 0;
uint32_t pflags;
phdr = NULL;
pflags = 0;
if (ro != NULL) {
if (!(m->m_flags & (M_BCAST | M_MCAST))) {
lle = ro->ro_lle;
if (lle != NULL)
pflags = lle->la_flags;
}
rt0 = ro->ro_rt;
if (rt0 != NULL && (rt0->rt_flags & RTF_GATEWAY) != 0)
is_gw = 1;
phdr = ro->ro_prepend;
hlen = ro->ro_plen;
pflags = ro->ro_flags;
}
#ifdef MAC
error = mac_ifnet_check_transmit(ifp, m);
@ -180,94 +306,31 @@ ether_output(struct ifnet *ifp, struct mbuf *m,
(ifp->if_drv_flags & IFF_DRV_RUNNING)))
senderr(ENETDOWN);
hlen = ETHER_HDR_LEN;
switch (dst->sa_family) {
#ifdef INET
case AF_INET:
if (lle != NULL && (pflags & LLE_VALID) != 0)
memcpy(edst, &lle->ll_addr.mac16, sizeof(edst));
else
error = arpresolve(ifp, is_gw, m, dst, edst, &pflags);
if (error)
if (phdr == NULL) {
/* No prepend data supplied. Try to calculate ourselves. */
phdr = linkhdr;
hlen = ETHER_HDR_LEN;
error = ether_resolve_addr(ifp, m, dst, ro, phdr, &pflags);
if (error != 0)
return (error == EWOULDBLOCK ? 0 : error);
type = htons(ETHERTYPE_IP);
break;
case AF_ARP:
{
struct arphdr *ah;
ah = mtod(m, struct arphdr *);
ah->ar_hrd = htons(ARPHRD_ETHER);
loop_copy = 0; /* if this is for us, don't do it */
switch(ntohs(ah->ar_op)) {
case ARPOP_REVREQUEST:
case ARPOP_REVREPLY:
type = htons(ETHERTYPE_REVARP);
break;
case ARPOP_REQUEST:
case ARPOP_REPLY:
default:
type = htons(ETHERTYPE_ARP);
break;
}
if (m->m_flags & M_BCAST)
bcopy(ifp->if_broadcastaddr, edst, ETHER_ADDR_LEN);
else
bcopy(ar_tha(ah), edst, ETHER_ADDR_LEN);
}
break;
#endif
#ifdef INET6
case AF_INET6:
if (lle != NULL && (pflags & LLE_VALID))
memcpy(edst, &lle->ll_addr.mac16, sizeof(edst));
else
error = nd6_resolve(ifp, is_gw, m, dst, (u_char *)edst,
&pflags);
if (error)
return (error == EWOULDBLOCK ? 0 : error);
type = htons(ETHERTYPE_IPV6);
break;
#endif
case pseudo_AF_HDRCMPLT:
{
const struct ether_header *eh;
hdrcmplt = 1;
/* FALLTHROUGH */
case AF_UNSPEC:
loop_copy = 0; /* if this is for us, don't do it */
eh = (const struct ether_header *)dst->sa_data;
(void)memcpy(edst, eh->ether_dhost, sizeof (edst));
type = eh->ether_type;
break;
}
default:
if_printf(ifp, "can't handle af%d\n", dst->sa_family);
senderr(EAFNOSUPPORT);
}
if ((pflags & LLE_IFADDR) != 0) {
if ((pflags & RT_L2_ME) != 0) {
update_mbuf_csumflags(m, m);
return (if_simloop(ifp, m, dst->sa_family, 0));
}
loop_copy = pflags & RT_MAY_LOOP;
/*
* Add local net header. If no space in first mbuf,
* allocate another.
*/
M_PREPEND(m, ETHER_HDR_LEN, M_NOWAIT);
M_PREPEND(m, hlen, M_NOWAIT);
if (m == NULL)
senderr(ENOBUFS);
eh = mtod(m, struct ether_header *);
if (hdrcmplt == 0) {
memcpy(&eh->ether_type, &type, sizeof(eh->ether_type));
memcpy(eh->ether_dhost, edst, sizeof (edst));
memcpy(eh->ether_shost, IF_LLADDR(ifp),sizeof(eh->ether_shost));
if ((pflags & RT_HAS_HEADER) == 0) {
eh = mtod(m, struct ether_header *);
memcpy(eh, phdr, hlen);
}
/*
@ -279,34 +342,27 @@ ether_output(struct ifnet *ifp, struct mbuf *m,
* on the wire). However, we don't do that here for security
* reasons and compatibility with the original behavior.
*/
if ((ifp->if_flags & IFF_SIMPLEX) && loop_copy &&
if ((m->m_flags & M_BCAST) && loop_copy && (ifp->if_flags & IFF_SIMPLEX) &&
((t = pf_find_mtag(m)) == NULL || !t->routed)) {
if (m->m_flags & M_BCAST) {
struct mbuf *n;
struct mbuf *n;
/*
* Because if_simloop() modifies the packet, we need a
* writable copy through m_dup() instead of a readonly
* one as m_copy[m] would give us. The alternative would
* be to modify if_simloop() to handle the readonly mbuf,
* but performancewise it is mostly equivalent (trading
* extra data copying vs. extra locking).
*
* XXX This is a local workaround. A number of less
* often used kernel parts suffer from the same bug.
* See PR kern/105943 for a proposed general solution.
*/
if ((n = m_dup(m, M_NOWAIT)) != NULL) {
update_mbuf_csumflags(m, n);
(void)if_simloop(ifp, n, dst->sa_family, hlen);
} else
if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1);
} else if (bcmp(eh->ether_dhost, eh->ether_shost,
ETHER_ADDR_LEN) == 0) {
update_mbuf_csumflags(m, m);
(void) if_simloop(ifp, m, dst->sa_family, hlen);
return (0); /* XXX */
}
/*
* Because if_simloop() modifies the packet, we need a
* writable copy through m_dup() instead of a readonly
* one as m_copy[m] would give us. The alternative would
* be to modify if_simloop() to handle the readonly mbuf,
* but performancewise it is mostly equivalent (trading
* extra data copying vs. extra locking).
*
* XXX This is a local workaround. A number of less
* often used kernel parts suffer from the same bug.
* See PR kern/105943 for a proposed general solution.
*/
if ((n = m_dup(m, M_NOWAIT)) != NULL) {
update_mbuf_csumflags(m, n);
(void)if_simloop(ifp, n, dst->sa_family, hlen);
} else
if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1);
}
/*
@ -798,6 +854,7 @@ ether_ifattach(struct ifnet *ifp, const u_int8_t *lla)
ifp->if_output = ether_output;
ifp->if_input = ether_input;
ifp->if_resolvemulti = ether_resolvemulti;
ifp->if_requestencap = ether_requestencap;
#ifdef VIMAGE
ifp->if_reassign = ether_reassign;
#endif

View File

@ -529,7 +529,6 @@ gif_input(struct mbuf *m, struct ifnet *ifp, int proto, uint8_t ecn)
struct gif_softc *sc;
struct ether_header *eh;
struct ifnet *oldifp;
uint32_t gif_options;
int isr, n, af;
if (ifp == NULL) {
@ -538,7 +537,6 @@ gif_input(struct mbuf *m, struct ifnet *ifp, int proto, uint8_t ecn)
return;
}
sc = ifp->if_softc;
gif_options = sc->gif_options;
m->m_pkthdr.rcvif = ifp;
m_clrprotoflags(m);
switch (proto) {

View File

@ -682,7 +682,10 @@ gre_input(struct mbuf **mp, int *offp, int proto)
struct grehdr *gh;
struct ifnet *ifp;
struct mbuf *m;
uint32_t *opts, key;
uint32_t *opts;
#ifdef notyet
uint32_t key;
#endif
uint16_t flags;
int hlen, isr, af;
@ -715,17 +718,28 @@ gre_input(struct mbuf **mp, int *offp, int proto)
opts++;
}
if (flags & GRE_FLAGS_KP) {
#ifdef notyet
/*
* XXX: The current implementation uses the key only for outgoing
* packets. But we can check the key value here, or even in the
* encapcheck function.
*/
key = ntohl(*opts);
#endif
hlen += sizeof(uint32_t);
opts++;
}
#ifdef notyet
} else
key = 0;
/*
if (sc->gre_key != 0 && (key != sc->gre_key || key != 0))
goto drop;
*/
#endif
if (flags & GRE_FLAGS_SP) {
/* seq = ntohl(*opts); */
#ifdef notyet
seq = ntohl(*opts);
#endif
hlen += sizeof(uint32_t);
}
switch (ntohs(gh->gre_proto)) {

View File

@ -278,10 +278,12 @@ lltable_drop_entry_queue(struct llentry *lle)
void
lltable_set_entry_addr(struct ifnet *ifp, struct llentry *lle,
const char *lladdr)
const char *linkhdr, size_t linkhdrsize, int lladdr_off)
{
bcopy(lladdr, &lle->ll_addr, ifp->if_addrlen);
memcpy(lle->r_linkdata, linkhdr, linkhdrsize);
lle->r_hdrlen = linkhdrsize;
lle->ll_addr = &lle->r_linkdata[lladdr_off];
lle->la_flags |= LLE_VALID;
lle->r_flags |= RLLE_VALID;
}
@ -296,7 +298,7 @@ lltable_set_entry_addr(struct ifnet *ifp, struct llentry *lle,
*/
int
lltable_try_set_entry_addr(struct ifnet *ifp, struct llentry *lle,
const char *lladdr)
const char *linkhdr, size_t linkhdrsize, int lladdr_off)
{
/* Perform real LLE update */
@ -318,7 +320,7 @@ lltable_try_set_entry_addr(struct ifnet *ifp, struct llentry *lle,
}
/* Update data */
lltable_set_entry_addr(ifp, lle, lladdr);
lltable_set_entry_addr(ifp, lle, linkhdr, linkhdrsize, lladdr_off);
IF_AFDATA_WUNLOCK(ifp);
@ -327,6 +329,84 @@ lltable_try_set_entry_addr(struct ifnet *ifp, struct llentry *lle,
return (1);
}
/*
* Helper function used to pre-compute full/partial link-layer
* header data suitable for feeding into if_output().
*/
int
lltable_calc_llheader(struct ifnet *ifp, int family, char *lladdr,
char *buf, size_t *bufsize, int *lladdr_off)
{
struct if_encap_req ereq;
int error;
bzero(buf, *bufsize);
bzero(&ereq, sizeof(ereq));
ereq.buf = buf;
ereq.bufsize = *bufsize;
ereq.rtype = IFENCAP_LL;
ereq.family = family;
ereq.lladdr = lladdr;
ereq.lladdr_len = ifp->if_addrlen;
error = ifp->if_requestencap(ifp, &ereq);
if (error == 0) {
*bufsize = ereq.bufsize;
*lladdr_off = ereq.lladdr_off;
}
return (error);
}
/*
* Update link-layer header for given @lle after
* interface lladdr was changed.
*/
static int
llentry_update_ifaddr(struct lltable *llt, struct llentry *lle, void *farg)
{
struct ifnet *ifp;
u_char linkhdr[LLE_MAX_LINKHDR];
size_t linkhdrsize;
u_char *lladdr;
int lladdr_off;
ifp = (struct ifnet *)farg;
lladdr = lle->ll_addr;
LLE_WLOCK(lle);
if ((lle->la_flags & LLE_VALID) == 0) {
LLE_WUNLOCK(lle);
return (0);
}
if ((lle->la_flags & LLE_IFADDR) != 0)
lladdr = IF_LLADDR(ifp);
linkhdrsize = sizeof(linkhdr);
lltable_calc_llheader(ifp, llt->llt_af, lladdr, linkhdr, &linkhdrsize,
&lladdr_off);
memcpy(lle->r_linkdata, linkhdr, linkhdrsize);
LLE_WUNLOCK(lle);
return (0);
}
/*
* Update all calculated headers for given @llt
*/
void
lltable_update_ifaddr(struct lltable *llt)
{
if (llt->llt_ifp->if_flags & IFF_LOOPBACK)
return;
IF_AFDATA_WLOCK(llt->llt_ifp);
lltable_foreach_lle(llt, llentry_update_ifaddr, llt->llt_ifp);
IF_AFDATA_WUNLOCK(llt->llt_ifp);
}
/*
*
* Performes generic cleanup routines and frees lle.
@ -642,6 +722,9 @@ lla_rt_output(struct rt_msghdr *rtm, struct rt_addrinfo *info)
struct ifnet *ifp;
struct lltable *llt;
struct llentry *lle, *lle_tmp;
uint8_t linkhdr[LLE_MAX_LINKHDR];
size_t linkhdrsize;
int lladdr_off;
u_int laflags = 0;
int error;
@ -677,11 +760,14 @@ lla_rt_output(struct rt_msghdr *rtm, struct rt_addrinfo *info)
if (lle == NULL)
return (ENOMEM);
bcopy(LLADDR(dl), &lle->ll_addr, ifp->if_addrlen);
linkhdrsize = sizeof(linkhdr);
if (lltable_calc_llheader(ifp, dst->sa_family, LLADDR(dl),
linkhdr, &linkhdrsize, &lladdr_off) != 0)
return (EINVAL);
lltable_set_entry_addr(ifp, lle, linkhdr, linkhdrsize,
lladdr_off);
if ((rtm->rtm_flags & RTF_ANNOUNCE))
lle->la_flags |= LLE_PUB;
lle->la_flags |= LLE_VALID;
lle->r_flags |= RLLE_VALID;
lle->la_expire = rtm->rtm_rmx.rmx_expire;
laflags = lle->la_flags;
@ -767,7 +853,7 @@ llatbl_lle_show(struct llentry_sa *la)
db_printf(" ln_router=%u\n", lle->ln_router);
db_printf(" ln_ntick=%ju\n", (uintmax_t)lle->ln_ntick);
db_printf(" lle_refcnt=%d\n", lle->lle_refcnt);
bcopy(&lle->ll_addr.mac16, octet, sizeof(octet));
bcopy(lle->ll_addr, octet, sizeof(octet));
db_printf(" ll_addr=%02x:%02x:%02x:%02x:%02x:%02x\n",
octet[0], octet[1], octet[2], octet[3], octet[4], octet[5]);
db_printf(" lle_timer=%p\n", &lle->lle_timer);

View File

@ -48,6 +48,7 @@ extern struct rwlock lltable_rwlock;
#define LLTABLE_WUNLOCK() rw_wunlock(&lltable_rwlock)
#define LLTABLE_LOCK_ASSERT() rw_assert(&lltable_rwlock, RA_LOCKED)
#define LLE_MAX_LINKHDR 24 /* Full IB header */
/*
* Code referencing llentry must at least hold
* a shared lock
@ -58,14 +59,11 @@ struct llentry {
struct in_addr addr4;
struct in6_addr addr6;
} r_l3addr;
union {
uint64_t mac_aligned;
uint16_t mac16[3];
uint8_t mac8[20]; /* IB needs 20 bytes. */
} ll_addr;
char r_linkdata[LLE_MAX_LINKHDR]; /* L2 data */
uint8_t r_hdrlen; /* length for LL header */
uint8_t spare0[3];
uint16_t r_flags; /* LLE runtime flags */
uint16_t r_skip_req; /* feedback from fast path */
uint64_t spare1;
struct lltable *lle_tbl;
struct llentries *lle_head;
@ -82,6 +80,7 @@ struct llentry {
time_t lle_remtime; /* Real time remaining */
time_t lle_hittime; /* Time when r_skip_req was unset */
int lle_refcnt;
char *ll_addr; /* link-layer address */
LIST_ENTRY(llentry) lle_chain; /* chain of deleted items */
struct callout lle_timer;
@ -198,6 +197,8 @@ MALLOC_DECLARE(M_LLTABLE);
/* LLE request flags */
#define LLE_EXCLUSIVE 0x2000 /* return lle xlocked */
#define LLE_UNLOCKED 0x4000 /* return lle unlocked */
#define LLE_ADDRONLY 0x4000 /* return lladdr instead of full header */
#define LLE_CREATE 0x8000 /* hint to avoid lle lookup */
/* LLE flags used by fastpath code */
#define RLLE_VALID 0x0001 /* entry is valid */
@ -223,10 +224,13 @@ struct llentry *llentry_alloc(struct ifnet *, struct lltable *,
/* helper functions */
size_t lltable_drop_entry_queue(struct llentry *);
void lltable_set_entry_addr(struct ifnet *ifp, struct llentry *lle,
const char *lladdr);
const char *linkhdr, size_t linkhdrsize, int lladdr_off);
int lltable_try_set_entry_addr(struct ifnet *ifp, struct llentry *lle,
const char *lladdr);
const char *linkhdr, size_t linkhdrsize, int lladdr_off);
int lltable_calc_llheader(struct ifnet *ifp, int family, char *lladdr,
char *buf, size_t *bufsize, int *lladdr_off);
void lltable_update_ifaddr(struct lltable *llt);
struct llentry *lltable_alloc_entry(struct lltable *llt, u_int flags,
const struct sockaddr *l4addr);
void lltable_free_entry(struct lltable *llt, struct llentry *lle);

View File

@ -134,6 +134,48 @@ struct ifnet_hw_tsomax {
u_int tsomaxsegsize; /* TSO maximum segment size in bytes */
};
/* Interface encap request types */
typedef enum {
IFENCAP_LL = 1 /* pre-calculate link-layer header */
} ife_type;
/*
* The structure below allows to request various pre-calculated L2/L3 headers
* for different media. Requests varies by type (rtype field).
*
* IFENCAP_LL type: pre-calculates link header based on address family
* and destination lladdr.
*
* Input data fields:
* buf: pointer to destination buffer
* bufsize: buffer size
* flags: IFENCAP_FLAG_BROADCAST if destination is broadcast
* family: address family defined by AF_ constant.
* lladdr: pointer to link-layer address
* lladdr_len: length of link-layer address
* hdata: pointer to L3 header (optional, used for ARP requests).
* Output data fields:
* buf: encap data is stored here
* bufsize: resulting encap length is stored here
* lladdr_off: offset of link-layer address from encap hdr start
* hdata: L3 header may be altered if necessary
*/
struct if_encap_req {
u_char *buf; /* Destination buffer (w) */
size_t bufsize; /* size of provided buffer (r) */
ife_type rtype; /* request type (r) */
uint32_t flags; /* Request flags (r) */
int family; /* Address family AF_* (r) */
int lladdr_off; /* offset from header start (w) */
int lladdr_len; /* lladdr length (r) */
char *lladdr; /* link-level address pointer (r) */
char *hdata; /* Upper layer header data (rw) */
};
#define IFENCAP_FLAG_BROADCAST 0x02 /* Destination is broadcast */
/*
* Structure defining a network interface.
*
@ -235,6 +277,8 @@ struct ifnet {
void (*if_reassign) /* reassign to vnet routine */
(struct ifnet *, struct vnet *, char *);
if_get_counter_t if_get_counter; /* get counter values */
int (*if_requestencap) /* make link header from request */
(struct ifnet *, struct if_encap_req *);
/* Statistics. */
counter_u64_t if_counters[IFCOUNTERS];

View File

@ -51,14 +51,21 @@
*/
struct route {
struct rtentry *ro_rt;
struct llentry *ro_lle;
struct in_ifaddr *ro_ia;
int ro_flags;
char *ro_prepend;
uint16_t ro_plen;
uint16_t ro_flags;
struct sockaddr ro_dst;
};
#define RT_L2_ME_BIT 2 /* dst L2 addr is our address */
#define RT_MAY_LOOP_BIT 3 /* dst may require loop copy */
#define RT_HAS_HEADER_BIT 4 /* mbuf already have its header prepended */
#define RT_CACHING_CONTEXT 0x1 /* XXX: not used anywhere */
#define RT_NORTREF 0x2 /* doesn't hold reference on ro_rt */
#define RT_L2_ME (1 << RT_L2_ME_BIT)
#define RT_MAY_LOOP (1 << RT_MAY_LOOP_BIT)
#define RT_HAS_HEADER (1 << RT_HAS_HEADER_BIT)
struct rt_metrics {
u_long rmx_locks; /* Kernel must leave these values alone */

View File

@ -281,6 +281,37 @@ arptimer(void *arg)
CURVNET_RESTORE();
}
/*
* Stores link-layer header for @ifp in format suitable for if_output()
* into buffer @buf. Resulting header length is stored in @bufsize.
*
* Returns 0 on success.
*/
static int
arp_fillheader(struct ifnet *ifp, struct arphdr *ah, int bcast, u_char *buf,
size_t *bufsize)
{
struct if_encap_req ereq;
int error;
bzero(buf, *bufsize);
bzero(&ereq, sizeof(ereq));
ereq.buf = buf;
ereq.bufsize = *bufsize;
ereq.rtype = IFENCAP_LL;
ereq.family = AF_ARP;
ereq.lladdr = ar_tha(ah);
ereq.hdata = (u_char *)ah;
if (bcast)
ereq.flags = IFENCAP_FLAG_BROADCAST;
error = ifp->if_requestencap(ifp, &ereq);
if (error == 0)
*bufsize = ereq.bufsize;
return (error);
}
/*
* Broadcast an ARP request. Caller specifies:
* - arp header source ip address
@ -295,6 +326,10 @@ arprequest(struct ifnet *ifp, const struct in_addr *sip,
struct arphdr *ah;
struct sockaddr sa;
u_char *carpaddr = NULL;
uint8_t linkhdr[LLE_MAX_LINKHDR];
size_t linkhdrsize;
struct route ro;
int error;
if (sip == NULL) {
/*
@ -350,12 +385,28 @@ arprequest(struct ifnet *ifp, const struct in_addr *sip,
bcopy(tip, ar_tpa(ah), ah->ar_pln);
sa.sa_family = AF_ARP;
sa.sa_len = 2;
/* Calculate link header for sending frame */
bzero(&ro, sizeof(ro));
linkhdrsize = sizeof(linkhdr);
error = arp_fillheader(ifp, ah, 1, linkhdr, &linkhdrsize);
if (error != 0 && error != EAFNOSUPPORT) {
ARP_LOG(LOG_ERR, "Failed to calculate ARP header on %s: %d\n",
if_name(ifp), error);
return;
}
ro.ro_prepend = linkhdr;
ro.ro_plen = linkhdrsize;
ro.ro_flags = 0;
m->m_flags |= M_BCAST;
m_clrprotoflags(m); /* Avoid confusing lower layers. */
(*ifp->if_output)(ifp, m, &sa, NULL);
(*ifp->if_output)(ifp, m, &sa, &ro);
ARPSTAT_INC(txrequests);
}
/*
* Resolve an IP address into an ethernet address - heavy version.
* Used internally by arpresolve().
@ -368,18 +419,20 @@ arprequest(struct ifnet *ifp, const struct in_addr *sip,
* Note that m_freem() handles NULL.
*/
static int
arpresolve_full(struct ifnet *ifp, int is_gw, int create, struct mbuf *m,
arpresolve_full(struct ifnet *ifp, int is_gw, int flags, struct mbuf *m,
const struct sockaddr *dst, u_char *desten, uint32_t *pflags)
{
struct llentry *la = NULL, *la_tmp;
struct mbuf *curr = NULL;
struct mbuf *next = NULL;
int error, renew;
char *lladdr;
int ll_len;
if (pflags != NULL)
*pflags = 0;
if (create == 0) {
if ((flags & LLE_CREATE) == 0) {
IF_AFDATA_RLOCK(ifp);
la = lla_lookup(LLTABLE(ifp), LLE_EXCLUSIVE, dst);
IF_AFDATA_RUNLOCK(ifp);
@ -413,7 +466,14 @@ arpresolve_full(struct ifnet *ifp, int is_gw, int create, struct mbuf *m,
if ((la->la_flags & LLE_VALID) &&
((la->la_flags & LLE_STATIC) || la->la_expire > time_uptime)) {
bcopy(&la->ll_addr, desten, ifp->if_addrlen);
if (flags & LLE_ADDRONLY) {
lladdr = la->ll_addr;
ll_len = ifp->if_addrlen;
} else {
lladdr = la->r_linkdata;
ll_len = la->r_hdrlen;
}
bcopy(lladdr, desten, ll_len);
/* Check if we have feedback request from arptimer() */
if (la->r_skip_req != 0) {
@ -485,15 +545,31 @@ arpresolve_full(struct ifnet *ifp, int is_gw, int create, struct mbuf *m,
/*
* Resolve an IP address into an ethernet address.
*/
int
arpresolve_addr(struct ifnet *ifp, int flags, const struct sockaddr *dst,
char *desten, uint32_t *pflags)
{
int error;
flags |= LLE_ADDRONLY;
error = arpresolve_full(ifp, 0, flags, NULL, dst, desten, pflags);
return (error);
}
/*
* Lookups link header based on an IP address.
* On input:
* ifp is the interface we use
* is_gw != 0 if @dst represents gateway to some destination
* m is the mbuf. May be NULL if we don't have a packet.
* dst is the next hop,
* desten is the storage to put LL address.
* desten is the storage to put LL header.
* flags returns subset of lle flags: LLE_VALID | LLE_IFADDR
*
* On success, desten and flags are filled in and the function returns 0;
* On success, full/partial link header and flags are filled in and
* the function returns 0.
* If the packet must be held pending resolution, we return EWOULDBLOCK
* On other errors, we return the corresponding error code.
* Note that m_freem() handles NULL.
@ -525,7 +601,7 @@ arpresolve(struct ifnet *ifp, int is_gw, struct mbuf *m,
la = lla_lookup(LLTABLE(ifp), LLE_UNLOCKED, dst);
if (la != NULL && (la->r_flags & RLLE_VALID) != 0) {
/* Entry found, let's copy lle info */
bcopy(&la->ll_addr, desten, ifp->if_addrlen);
bcopy(la->r_linkdata, desten, la->r_hdrlen);
if (pflags != NULL)
*pflags = LLE_VALID | (la->r_flags & RLLE_IFADDR);
/* Check if we have feedback request from arptimer() */
@ -539,7 +615,8 @@ arpresolve(struct ifnet *ifp, int is_gw, struct mbuf *m,
}
IF_AFDATA_RUNLOCK(ifp);
return (arpresolve_full(ifp, is_gw, 1, m, dst, desten, pflags));
return (arpresolve_full(ifp, is_gw, la == NULL ? LLE_CREATE : 0, m, dst,
desten, pflags));
}
/*
@ -683,6 +760,11 @@ in_arpinput(struct mbuf *m)
struct sockaddr_in sin;
struct sockaddr *dst;
struct nhop4_basic nh4;
uint8_t linkhdr[LLE_MAX_LINKHDR];
struct route ro;
size_t linkhdrsize;
int lladdr_off;
int error;
sin.sin_len = sizeof(struct sockaddr_in);
sin.sin_family = AF_INET;
@ -850,8 +932,14 @@ in_arpinput(struct mbuf *m)
else if (itaddr.s_addr == myaddr.s_addr) {
/*
* Request/reply to our address, but no lle exists yet.
* Try to create new llentry.
* Calculate full link prepend to use in lle.
*/
linkhdrsize = sizeof(linkhdr);
if (lltable_calc_llheader(ifp, AF_INET, ar_sha(ah), linkhdr,
&linkhdrsize, &lladdr_off) != 0)
goto reply;
/* Allocate new entry */
la = lltable_alloc_entry(LLTABLE(ifp), 0, dst);
if (la == NULL) {
@ -863,7 +951,8 @@ in_arpinput(struct mbuf *m)
*/
goto reply;
}
lltable_set_entry_addr(ifp, la, ar_sha(ah));
lltable_set_entry_addr(ifp, la, linkhdr, linkhdrsize,
lladdr_off);
IF_AFDATA_WLOCK(ifp);
LLE_WLOCK(la);
@ -921,7 +1010,7 @@ in_arpinput(struct mbuf *m)
if ((lle != NULL) && (lle->la_flags & LLE_PUB)) {
(void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln);
(void)memcpy(ar_sha(ah), &lle->ll_addr, ah->ar_hln);
(void)memcpy(ar_sha(ah), lle->ll_addr, ah->ar_hln);
LLE_RUNLOCK(lle);
} else {
@ -991,8 +1080,29 @@ in_arpinput(struct mbuf *m)
m->m_pkthdr.rcvif = NULL;
sa.sa_family = AF_ARP;
sa.sa_len = 2;
/* Calculate link header for sending frame */
bzero(&ro, sizeof(ro));
linkhdrsize = sizeof(linkhdr);
error = arp_fillheader(ifp, ah, 0, linkhdr, &linkhdrsize);
/*
* arp_fillheader() may fail due to lack of support inside encap request
* routing. This is not necessary an error, AF_ARP can/should be handled
* by if_output().
*/
if (error != 0 && error != EAFNOSUPPORT) {
ARP_LOG(LOG_ERR, "Failed to calculate ARP header on %s: %d\n",
if_name(ifp), error);
return;
}
ro.ro_prepend = linkhdr;
ro.ro_plen = linkhdrsize;
ro.ro_flags = 0;
m_clrprotoflags(m); /* Avoid confusing lower layers. */
(*ifp->if_output)(ifp, m, &sa, NULL);
(*ifp->if_output)(ifp, m, &sa, &ro);
ARPSTAT_INC(txreplies);
return;
@ -1011,6 +1121,9 @@ arp_check_update_lle(struct arphdr *ah, struct in_addr isaddr, struct ifnet *ifp
{
struct sockaddr sa;
struct mbuf *m_hold, *m_hold_next;
uint8_t linkhdr[LLE_MAX_LINKHDR];
size_t linkhdrsize;
int lladdr_off;
LLE_WLOCK_ASSERT(la);
@ -1027,7 +1140,7 @@ arp_check_update_lle(struct arphdr *ah, struct in_addr isaddr, struct ifnet *ifp
return;
}
if ((la->la_flags & LLE_VALID) &&
bcmp(ar_sha(ah), &la->ll_addr, ifp->if_addrlen)) {
bcmp(ar_sha(ah), la->ll_addr, ifp->if_addrlen)) {
if (la->la_flags & LLE_STATIC) {
LLE_WUNLOCK(la);
if (log_arp_permanent_modify)
@ -1050,31 +1163,19 @@ arp_check_update_lle(struct arphdr *ah, struct in_addr isaddr, struct ifnet *ifp
}
}
/* Calculate full link prepend to use in lle */
linkhdrsize = sizeof(linkhdr);
if (lltable_calc_llheader(ifp, AF_INET, ar_sha(ah), linkhdr,
&linkhdrsize, &lladdr_off) != 0)
return;
/* Check if something has changed */
if (memcmp(&la->ll_addr, ar_sha(ah), ifp->if_addrlen) != 0 ||
if (memcmp(la->r_linkdata, linkhdr, linkhdrsize) != 0 ||
(la->la_flags & LLE_VALID) == 0) {
/* Perform real LLE update */
/* use afdata WLOCK to update fields */
LLE_ADDREF(la);
LLE_WUNLOCK(la);
IF_AFDATA_WLOCK(ifp);
LLE_WLOCK(la);
/*
* Since we droppped LLE lock, other thread might have deleted
* this lle. Check and return
*/
if ((la->la_flags & LLE_DELETED) != 0) {
IF_AFDATA_WUNLOCK(ifp);
LLE_FREE_LOCKED(la);
/* Try to perform LLE update */
if (lltable_try_set_entry_addr(ifp, la, linkhdr, linkhdrsize,
lladdr_off) == 0)
return;
}
/* Update data */
lltable_set_entry_addr(ifp, la, ar_sha(ah));
IF_AFDATA_WUNLOCK(ifp);
LLE_REMREF(la);
/* Clear fast path feedback request if set */
la->r_skip_req = 0;
@ -1215,10 +1316,12 @@ arp_handle_ifllchange(struct ifnet *ifp)
/*
* A handler for interface link layer address change event.
*/
static __noinline void
static void
arp_iflladdr(void *arg __unused, struct ifnet *ifp)
{
lltable_update_ifaddr(LLTABLE(ifp));
if ((ifp->if_flags & IFF_UP) != 0)
arp_handle_ifllchange(ifp);
}
@ -1231,5 +1334,8 @@ arp_init(void)
if (IS_DEFAULT_VNET(curvnet))
iflladdr_tag = EVENTHANDLER_REGISTER(iflladdr_event,
arp_iflladdr, NULL, EVENTHANDLER_PRI_ANY);
if (IS_DEFAULT_VNET(curvnet))
iflladdr_tag = EVENTHANDLER_REGISTER(iflladdr_event,
arp_iflladdr, NULL, EVENTHANDLER_PRI_ANY);
}
SYSINIT(arp, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY, arp_init, 0);

View File

@ -114,6 +114,8 @@ extern u_char ether_ipmulticast_max[ETHER_ADDR_LEN];
struct ifaddr;
int arpresolve_addr(struct ifnet *ifp, int flags,
const struct sockaddr *dst, char *desten, uint32_t *pflags);
int arpresolve(struct ifnet *ifp, int is_gw, struct mbuf *m,
const struct sockaddr *dst, u_char *desten, uint32_t *pflags);
void arprequest(struct ifnet *, const struct in_addr *,

View File

@ -1240,6 +1240,9 @@ in_lltable_alloc(struct lltable *llt, u_int flags, const struct sockaddr *l3addr
const struct sockaddr_in *sin = (const struct sockaddr_in *)l3addr;
struct ifnet *ifp = llt->llt_ifp;
struct llentry *lle;
char linkhdr[LLE_MAX_LINKHDR];
size_t linkhdrsize;
int lladdr_off;
KASSERT(l3addr->sa_family == AF_INET,
("sin_family %d", l3addr->sa_family));
@ -1262,7 +1265,12 @@ in_lltable_alloc(struct lltable *llt, u_int flags, const struct sockaddr *l3addr
if (flags & LLE_STATIC)
lle->r_flags |= RLLE_VALID;
if ((flags & LLE_IFADDR) == LLE_IFADDR) {
lltable_set_entry_addr(ifp, lle, IF_LLADDR(ifp));
linkhdrsize = LLE_MAX_LINKHDR;
if (lltable_calc_llheader(ifp, AF_INET, IF_LLADDR(ifp),
linkhdr, &linkhdrsize, &lladdr_off) != 0)
return (NULL);
lltable_set_entry_addr(ifp, lle, linkhdr, linkhdrsize,
lladdr_off);
lle->la_flags |= LLE_STATIC;
lle->r_flags |= (RLLE_VALID | RLLE_IFADDR);
}
@ -1349,7 +1357,7 @@ in_lltable_dump_entry(struct lltable *llt, struct llentry *lle,
sdl->sdl_type = ifp->if_type;
if ((lle->la_flags & LLE_VALID) == LLE_VALID) {
sdl->sdl_alen = ifp->if_addrlen;
bcopy(&lle->ll_addr, LLADDR(sdl), ifp->if_addrlen);
bcopy(lle->ll_addr, LLADDR(sdl), ifp->if_addrlen);
} else {
sdl->sdl_alen = 0;
bzero(LLADDR(sdl), ifp->if_addrlen);

View File

@ -567,7 +567,7 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
RO_RTFREE(ro);
if (have_ia_ref)
ifa_free(&ia->ia_ifa);
ro->ro_lle = NULL;
ro->ro_prepend = NULL;
rte = NULL;
gw = dst;
ip = mtod(m, struct ip *);

View File

@ -428,7 +428,7 @@ toe_lle_event(void *arg __unused, struct llentry *lle, int evt)
KASSERT(lle->la_flags & LLE_VALID,
("%s: %p resolved but not valid?", __func__, lle));
lladdr = (uint8_t *)&lle->ll_addr;
lladdr = (uint8_t *)lle->ll_addr;
#ifdef VLAN_TAG
VLAN_TAG(ifp, &vtag);
#endif

View File

@ -2632,7 +2632,7 @@ icmp6_redirect_output(struct mbuf *m0, struct rtentry *rt)
nd_opt->nd_opt_type = ND_OPT_TARGET_LINKADDR;
nd_opt->nd_opt_len = len >> 3;
lladdr = (char *)(nd_opt + 1);
bcopy(&ln->ll_addr, lladdr, ifp->if_addrlen);
bcopy(ln->ll_addr, lladdr, ifp->if_addrlen);
p += len;
}
}

View File

@ -1552,7 +1552,7 @@ in6ifa_llaonifp(struct ifnet *ifp)
if (ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED)
return (NULL);
if_addr_rlock(ifp);
IF_ADDR_RLOCK(ifp);
TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
if (ifa->ifa_addr->sa_family != AF_INET6)
continue;
@ -1562,7 +1562,7 @@ in6ifa_llaonifp(struct ifnet *ifp)
IN6_IS_ADDR_MC_NODELOCAL(&sin6->sin6_addr))
break;
}
if_addr_runlock(ifp);
IF_ADDR_RUNLOCK(ifp);
return ((struct in6_ifaddr *)ifa);
}
@ -2245,6 +2245,9 @@ in6_lltable_alloc(struct lltable *llt, u_int flags,
const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)l3addr;
struct ifnet *ifp = llt->llt_ifp;
struct llentry *lle;
char linkhdr[LLE_MAX_LINKHDR];
size_t linkhdrsize;
int lladdr_off;
KASSERT(l3addr->sa_family == AF_INET6,
("sin_family %d", l3addr->sa_family));
@ -2265,7 +2268,12 @@ in6_lltable_alloc(struct lltable *llt, u_int flags,
}
lle->la_flags = flags;
if ((flags & LLE_IFADDR) == LLE_IFADDR) {
lltable_set_entry_addr(ifp, lle, IF_LLADDR(ifp));
linkhdrsize = LLE_MAX_LINKHDR;
if (lltable_calc_llheader(ifp, AF_INET6, IF_LLADDR(ifp),
linkhdr, &linkhdrsize, &lladdr_off) != 0)
return (NULL);
lltable_set_entry_addr(ifp, lle, linkhdr, linkhdrsize,
lladdr_off);
lle->la_flags |= LLE_STATIC;
}

View File

@ -375,9 +375,9 @@ extern const struct in6_addr in6addr_linklocal_allv2routers;
#if __BSD_VISIBLE
struct route_in6 {
struct rtentry *ro_rt;
struct llentry *ro_lle;
struct in6_addr *ro_ia6;
int ro_flags;
char *ro_prepend;
uint16_t ro_plen;
uint16_t ro_flags;
struct sockaddr_in6 ro_dst;
};
#endif

View File

@ -1830,6 +1830,7 @@ do { \
case IPV6_RSSBUCKETID:
case IPV6_RECVRSSBUCKETID:
#endif
case IPV6_BINDMULTI:
switch (optname) {
case IPV6_RECVHOPOPTS:

View File

@ -111,7 +111,7 @@ VNET_DEFINE(int, nd6_debug) = 1;
VNET_DEFINE(int, nd6_debug) = 0;
#endif
static eventhandler_tag lle_event_eh;
static eventhandler_tag lle_event_eh, iflladdr_event_eh;
/* for debugging? */
#if 0
@ -137,7 +137,7 @@ static void nd6_llinfo_timer(void *);
static void nd6_llinfo_settimer_locked(struct llentry *, long);
static void clear_llinfo_pqueue(struct llentry *);
static void nd6_rtrequest(int, struct rtentry *, struct rt_addrinfo *);
static int nd6_resolve_slow(struct ifnet *, struct mbuf *,
static int nd6_resolve_slow(struct ifnet *, int, struct mbuf *,
const struct sockaddr_in6 *, u_char *, uint32_t *);
static int nd6_need_cache(struct ifnet *);
@ -188,7 +188,7 @@ nd6_lle_event(void *arg __unused, struct llentry *lle, int evt)
gw.sdl_index = ifp->if_index;
gw.sdl_type = ifp->if_type;
if (evt == LLENTRY_RESOLVED)
bcopy(&lle->ll_addr, gw.sdl_data, ifp->if_addrlen);
bcopy(lle->ll_addr, gw.sdl_data, ifp->if_addrlen);
rtinfo.rti_info[RTAX_DST] = (struct sockaddr *)&dst;
rtinfo.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&gw;
rtinfo.rti_addrs = RTA_DST | RTA_GATEWAY;
@ -196,6 +196,16 @@ nd6_lle_event(void *arg __unused, struct llentry *lle, int evt)
type == RTM_ADD ? RTF_UP: 0), 0, RT_DEFAULT_FIB);
}
/*
* A handler for interface link layer address change event.
*/
static void
nd6_iflladdr(void *arg __unused, struct ifnet *ifp)
{
lltable_update_ifaddr(LLTABLE6(ifp));
}
void
nd6_init(void)
{
@ -211,9 +221,12 @@ nd6_init(void)
nd6_slowtimo, curvnet);
nd6_dad_init();
if (IS_DEFAULT_VNET(curvnet))
if (IS_DEFAULT_VNET(curvnet)) {
lle_event_eh = EVENTHANDLER_REGISTER(lle_event, nd6_lle_event,
NULL, EVENTHANDLER_PRI_ANY);
iflladdr_event_eh = EVENTHANDLER_REGISTER(iflladdr_event,
nd6_iflladdr, NULL, EVENTHANDLER_PRI_ANY);
}
}
#ifdef VIMAGE
@ -223,8 +236,10 @@ nd6_destroy()
callout_drain(&V_nd6_slowtimo_ch);
callout_drain(&V_nd6_timer_ch);
if (IS_DEFAULT_VNET(curvnet))
if (IS_DEFAULT_VNET(curvnet)) {
EVENTHANDLER_DEREGISTER(lle_event, lle_event_eh);
EVENTHANDLER_DEREGISTER(iflladdr_event, iflladdr_event_eh);
}
}
#endif
@ -1844,6 +1859,9 @@ nd6_cache_lladdr(struct ifnet *ifp, struct in6_addr *from, char *lladdr,
uint16_t router = 0;
struct sockaddr_in6 sin6;
struct mbuf *chain = NULL;
u_char linkhdr[LLE_MAX_LINKHDR];
size_t linkhdrsize;
int lladdr_off;
IF_AFDATA_UNLOCK_ASSERT(ifp);
@ -1878,8 +1896,15 @@ nd6_cache_lladdr(struct ifnet *ifp, struct in6_addr *from, char *lladdr,
* Since we already know all the data for the new entry,
* fill it before insertion.
*/
if (lladdr != NULL)
lltable_set_entry_addr(ifp, ln, lladdr);
if (lladdr != NULL) {
linkhdrsize = sizeof(linkhdr);
if (lltable_calc_llheader(ifp, AF_INET6, lladdr,
linkhdr, &linkhdrsize, &lladdr_off) != 0)
return;
lltable_set_entry_addr(ifp, ln, linkhdr, linkhdrsize,
lladdr_off);
}
IF_AFDATA_WLOCK(ifp);
LLE_WLOCK(ln);
/* Prefer any existing lle over newly-created one */
@ -1911,7 +1936,7 @@ nd6_cache_lladdr(struct ifnet *ifp, struct in6_addr *from, char *lladdr,
olladdr = (ln->la_flags & LLE_VALID) ? 1 : 0;
if (olladdr && lladdr) {
llchange = bcmp(lladdr, &ln->ll_addr,
llchange = bcmp(lladdr, ln->ll_addr,
ifp->if_addrlen);
} else if (!olladdr && lladdr)
llchange = 1;
@ -1937,7 +1962,13 @@ nd6_cache_lladdr(struct ifnet *ifp, struct in6_addr *from, char *lladdr,
* Record source link-layer address
* XXX is it dependent to ifp->if_type?
*/
if (lltable_try_set_entry_addr(ifp, ln, lladdr) == 0) {
linkhdrsize = sizeof(linkhdr);
if (lltable_calc_llheader(ifp, AF_INET6, lladdr,
linkhdr, &linkhdrsize, &lladdr_off) != 0)
return;
if (lltable_try_set_entry_addr(ifp, ln, linkhdr, linkhdrsize,
lladdr_off) == 0) {
/* Entry was deleted */
return;
}
@ -2093,8 +2124,8 @@ nd6_output_ifp(struct ifnet *ifp, struct ifnet *origifp, struct mbuf *m,
}
/*
* Do L2 address resolution for @sa_dst address. Stores found
* address in @desten buffer. Copy of lle ln_flags can be also
* Lookup link headerfor @sa_dst address. Stores found
* data in @desten buffer. Copy of lle ln_flags can be also
* saved in @pflags if @pflags is non-NULL.
*
* If destination LLE does not exists or lle state modification
@ -2144,7 +2175,7 @@ nd6_resolve(struct ifnet *ifp, int is_gw, struct mbuf *m,
ln = nd6_lookup(&dst6->sin6_addr, LLE_UNLOCKED, ifp);
if (ln != NULL && (ln->r_flags & RLLE_VALID) != 0) {
/* Entry found, let's copy lle info */
bcopy(&ln->ll_addr, desten, ifp->if_addrlen);
bcopy(ln->r_linkdata, desten, ln->r_hdrlen);
if (pflags != NULL)
*pflags = LLE_VALID | (ln->r_flags & RLLE_IFADDR);
/* Check if we have feedback request from nd6 timer */
@ -2159,7 +2190,7 @@ nd6_resolve(struct ifnet *ifp, int is_gw, struct mbuf *m,
}
IF_AFDATA_RUNLOCK(ifp);
return (nd6_resolve_slow(ifp, m, dst6, desten, pflags));
return (nd6_resolve_slow(ifp, 0, m, dst6, desten, pflags));
}
@ -2175,12 +2206,13 @@ nd6_resolve(struct ifnet *ifp, int is_gw, struct mbuf *m,
* Set noinline to be dtrace-friendly
*/
static __noinline int
nd6_resolve_slow(struct ifnet *ifp, struct mbuf *m,
nd6_resolve_slow(struct ifnet *ifp, int flags, struct mbuf *m,
const struct sockaddr_in6 *dst, u_char *desten, uint32_t *pflags)
{
struct llentry *lle = NULL, *lle_tmp;
struct in6_addr *psrc, src;
int send_ns;
int send_ns, ll_len;
char *lladdr;
/*
* Address resolution or Neighbor Unreachability Detection
@ -2252,7 +2284,14 @@ nd6_resolve_slow(struct ifnet *ifp, struct mbuf *m,
* send the packet.
*/
if (lle->ln_state > ND6_LLINFO_INCOMPLETE) {
bcopy(&lle->ll_addr, desten, ifp->if_addrlen);
if (flags & LLE_ADDRONLY) {
lladdr = lle->ll_addr;
ll_len = ifp->if_addrlen;
} else {
lladdr = lle->r_linkdata;
ll_len = lle->r_hdrlen;
}
bcopy(lladdr, desten, ll_len);
if (pflags != NULL)
*pflags = lle->la_flags;
LLE_WUNLOCK(lle);
@ -2312,6 +2351,27 @@ nd6_resolve_slow(struct ifnet *ifp, struct mbuf *m,
return (EWOULDBLOCK);
}
/*
* Do L2 address resolution for @sa_dst address. Stores found
* address in @desten buffer. Copy of lle ln_flags can be also
* saved in @pflags if @pflags is non-NULL.
*
* Return values:
* - 0 on success (address copied to buffer).
* - EWOULDBLOCK (no local error, but address is still unresolved)
* - other errors (alloc failure, etc)
*/
int
nd6_resolve_addr(struct ifnet *ifp, int flags, const struct sockaddr *dst,
char *desten, uint32_t *pflags)
{
int error;
flags |= LLE_ADDRONLY;
error = nd6_resolve_slow(ifp, flags, NULL,
(const struct sockaddr_in6 *)dst, desten, pflags);
return (error);
}
int
nd6_flush_holdchain(struct ifnet *ifp, struct ifnet *origifp, struct mbuf *chain,

View File

@ -410,6 +410,8 @@ void nd6_setmtu(struct ifnet *);
void nd6_llinfo_setstate(struct llentry *lle, int newstate);
void nd6_timer(void *);
void nd6_purge(struct ifnet *);
int nd6_resolve_addr(struct ifnet *ifp, int flags, const struct sockaddr *dst,
char *desten, uint32_t *pflags);
int nd6_resolve(struct ifnet *, int, struct mbuf *,
const struct sockaddr *, u_char *, uint32_t *);
int nd6_ioctl(u_long, caddr_t, struct ifnet *);

View File

@ -643,6 +643,9 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
union nd_opts ndopts;
struct mbuf *chain = NULL;
struct sockaddr_in6 sin6;
u_char linkhdr[LLE_MAX_LINKHDR];
size_t linkhdrsize;
int lladdr_off;
char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN];
if (ip6->ip6_hlim != 255) {
@ -765,7 +768,13 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
/*
* Record link-layer address, and update the state.
*/
if (lltable_try_set_entry_addr(ifp, ln, lladdr) == 0) {
linkhdrsize = sizeof(linkhdr);
if (lltable_calc_llheader(ifp, AF_INET6, lladdr,
linkhdr, &linkhdrsize, &lladdr_off) != 0)
return;
if (lltable_try_set_entry_addr(ifp, ln, linkhdr, linkhdrsize,
lladdr_off) == 0) {
ln = NULL;
goto freeit;
}
@ -792,7 +801,7 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
llchange = 0;
else {
if (ln->la_flags & LLE_VALID) {
if (bcmp(lladdr, &ln->ll_addr, ifp->if_addrlen))
if (bcmp(lladdr, ln->ll_addr, ifp->if_addrlen))
llchange = 1;
else
llchange = 0;
@ -834,9 +843,12 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
* Update link-local address, if any.
*/
if (lladdr != NULL) {
int ret;
ret = lltable_try_set_entry_addr(ifp, ln,lladdr);
if (ret == 0) {
linkhdrsize = sizeof(linkhdr);
if (lltable_calc_llheader(ifp, AF_INET6, lladdr,
linkhdr, &linkhdrsize, &lladdr_off) != 0)
goto freeit;
if (lltable_try_set_entry_addr(ifp, ln, linkhdr,
linkhdrsize, lladdr_off) == 0) {
ln = NULL;
goto freeit;
}

View File

@ -1257,15 +1257,15 @@ ipoib_output(struct ifnet *ifp, struct mbuf *m,
const struct sockaddr *dst, struct route *ro)
{
u_char edst[INFINIBAND_ALEN];
#if defined(INET) || defined(INET6)
struct llentry *lle = NULL;
#endif
struct rtentry *rt0 = NULL;
struct ipoib_header *eh;
int error = 0, is_gw = 0;
short type;
if (ro != NULL) {
if (!(m->m_flags & (M_BCAST | M_MCAST)))
lle = ro->ro_lle;
rt0 = ro->ro_rt;
if (rt0 != NULL && (rt0->rt_flags & RTF_GATEWAY) != 0)
is_gw = 1;
@ -1291,7 +1291,7 @@ ipoib_output(struct ifnet *ifp, struct mbuf *m,
#ifdef INET
case AF_INET:
if (lle != NULL && (lle->la_flags & LLE_VALID))
memcpy(edst, &lle->ll_addr.mac8, sizeof(edst));
memcpy(edst, lle->ll_addr, sizeof(edst));
else if (m->m_flags & M_MCAST)
ip_ib_mc_map(((struct sockaddr_in *)dst)->sin_addr.s_addr, ifp->if_broadcastaddr, edst);
else
@ -1329,7 +1329,7 @@ ipoib_output(struct ifnet *ifp, struct mbuf *m,
#ifdef INET6
case AF_INET6:
if (lle != NULL && (lle->la_flags & LLE_VALID))
memcpy(edst, &lle->ll_addr.mac8, sizeof(edst));
memcpy(edst, lle->ll_addr, sizeof(edst));
else if (m->m_flags & M_MCAST)
ipv6_ib_mc_map(&((struct sockaddr_in6 *)dst)->sin6_addr, ifp->if_broadcastaddr, edst);
else

View File

@ -14,6 +14,11 @@
* 29 May 1998
*/
#ifndef _SKIPJACK_H_
#define _SKIPJACK_H_
extern void skipjack_forwards(u_int8_t *plain, u_int8_t *cipher, u_int8_t **key);
extern void skipjack_backwards(u_int8_t *cipher, u_int8_t *plain, u_int8_t **key);
extern void subkey_table_gen(u_int8_t *key, u_int8_t **key_tables);
#endif

View File

@ -75,196 +75,9 @@ __FBSDID("$FreeBSD$");
#include <opencrypto/cryptodev.h>
#include <opencrypto/xform.h>
static int null_setkey(u_int8_t **, u_int8_t *, int);
static int des1_setkey(u_int8_t **, u_int8_t *, int);
static int des3_setkey(u_int8_t **, u_int8_t *, int);
static int blf_setkey(u_int8_t **, u_int8_t *, int);
static int cast5_setkey(u_int8_t **, u_int8_t *, int);
static int skipjack_setkey(u_int8_t **, u_int8_t *, int);
static int rijndael128_setkey(u_int8_t **, u_int8_t *, int);
static int aes_icm_setkey(u_int8_t **, u_int8_t *, int);
static int aes_xts_setkey(u_int8_t **, u_int8_t *, int);
static int cml_setkey(u_int8_t **, u_int8_t *, int);
static void null_encrypt(caddr_t, u_int8_t *);
static void des1_encrypt(caddr_t, u_int8_t *);
static void des3_encrypt(caddr_t, u_int8_t *);
static void blf_encrypt(caddr_t, u_int8_t *);
static void cast5_encrypt(caddr_t, u_int8_t *);
static void skipjack_encrypt(caddr_t, u_int8_t *);
static void rijndael128_encrypt(caddr_t, u_int8_t *);
static void aes_xts_encrypt(caddr_t, u_int8_t *);
static void cml_encrypt(caddr_t, u_int8_t *);
static void null_decrypt(caddr_t, u_int8_t *);
static void des1_decrypt(caddr_t, u_int8_t *);
static void des3_decrypt(caddr_t, u_int8_t *);
static void blf_decrypt(caddr_t, u_int8_t *);
static void cast5_decrypt(caddr_t, u_int8_t *);
static void skipjack_decrypt(caddr_t, u_int8_t *);
static void rijndael128_decrypt(caddr_t, u_int8_t *);
static void aes_xts_decrypt(caddr_t, u_int8_t *);
static void cml_decrypt(caddr_t, u_int8_t *);
static void aes_icm_crypt(caddr_t, u_int8_t *);
static void null_zerokey(u_int8_t **);
static void des1_zerokey(u_int8_t **);
static void des3_zerokey(u_int8_t **);
static void blf_zerokey(u_int8_t **);
static void cast5_zerokey(u_int8_t **);
static void skipjack_zerokey(u_int8_t **);
static void rijndael128_zerokey(u_int8_t **);
static void aes_icm_zerokey(u_int8_t **);
static void aes_xts_zerokey(u_int8_t **);
static void cml_zerokey(u_int8_t **);
static void aes_icm_reinit(caddr_t, u_int8_t *);
static void aes_xts_reinit(caddr_t, u_int8_t *);
static void aes_gcm_reinit(caddr_t, u_int8_t *);
static void null_init(void *);
static void null_reinit(void *ctx, const u_int8_t *buf, u_int16_t len);
static int null_update(void *, const u_int8_t *, u_int16_t);
static void null_final(u_int8_t *, void *);
static int MD5Update_int(void *, const u_int8_t *, u_int16_t);
static void SHA1Init_int(void *);
static int SHA1Update_int(void *, const u_int8_t *, u_int16_t);
static void SHA1Final_int(u_int8_t *, void *);
static int RMD160Update_int(void *, const u_int8_t *, u_int16_t);
static int SHA256Update_int(void *, const u_int8_t *, u_int16_t);
static int SHA384Update_int(void *, const u_int8_t *, u_int16_t);
static int SHA512Update_int(void *, const u_int8_t *, u_int16_t);
static u_int32_t deflate_compress(u_int8_t *, u_int32_t, u_int8_t **);
static u_int32_t deflate_decompress(u_int8_t *, u_int32_t, u_int8_t **);
#define AESICM_BLOCKSIZE AES_BLOCK_LEN
struct aes_icm_ctx {
u_int32_t ac_ek[4*(RIJNDAEL_MAXNR + 1)];
/* ac_block is initalized to IV */
u_int8_t ac_block[AESICM_BLOCKSIZE];
int ac_nr;
};
MALLOC_DEFINE(M_XDATA, "xform", "xform data buffers");
/* Encryption instances */
struct enc_xform enc_xform_null = {
CRYPTO_NULL_CBC, "NULL",
/* NB: blocksize of 4 is to generate a properly aligned ESP header */
NULL_BLOCK_LEN, 0, NULL_MIN_KEY, NULL_MAX_KEY,
null_encrypt,
null_decrypt,
null_setkey,
null_zerokey,
NULL,
};
struct enc_xform enc_xform_des = {
CRYPTO_DES_CBC, "DES",
DES_BLOCK_LEN, DES_BLOCK_LEN, DES_MIN_KEY, DES_MAX_KEY,
des1_encrypt,
des1_decrypt,
des1_setkey,
des1_zerokey,
NULL,
};
struct enc_xform enc_xform_3des = {
CRYPTO_3DES_CBC, "3DES",
DES3_BLOCK_LEN, DES3_BLOCK_LEN, TRIPLE_DES_MIN_KEY,
TRIPLE_DES_MAX_KEY,
des3_encrypt,
des3_decrypt,
des3_setkey,
des3_zerokey,
NULL,
};
struct enc_xform enc_xform_blf = {
CRYPTO_BLF_CBC, "Blowfish",
BLOWFISH_BLOCK_LEN, BLOWFISH_BLOCK_LEN, BLOWFISH_MIN_KEY,
BLOWFISH_MAX_KEY,
blf_encrypt,
blf_decrypt,
blf_setkey,
blf_zerokey,
NULL,
};
struct enc_xform enc_xform_cast5 = {
CRYPTO_CAST_CBC, "CAST-128",
CAST128_BLOCK_LEN, CAST128_BLOCK_LEN, CAST_MIN_KEY, CAST_MAX_KEY,
cast5_encrypt,
cast5_decrypt,
cast5_setkey,
cast5_zerokey,
NULL,
};
struct enc_xform enc_xform_skipjack = {
CRYPTO_SKIPJACK_CBC, "Skipjack",
SKIPJACK_BLOCK_LEN, SKIPJACK_BLOCK_LEN, SKIPJACK_MIN_KEY,
SKIPJACK_MAX_KEY,
skipjack_encrypt,
skipjack_decrypt, skipjack_setkey,
skipjack_zerokey,
NULL,
};
struct enc_xform enc_xform_rijndael128 = {
CRYPTO_RIJNDAEL128_CBC, "Rijndael-128/AES",
RIJNDAEL128_BLOCK_LEN, RIJNDAEL128_BLOCK_LEN, RIJNDAEL_MIN_KEY,
RIJNDAEL_MAX_KEY,
rijndael128_encrypt,
rijndael128_decrypt,
rijndael128_setkey,
rijndael128_zerokey,
NULL,
};
struct enc_xform enc_xform_aes_icm = {
CRYPTO_AES_ICM, "AES-ICM",
AES_BLOCK_LEN, AES_BLOCK_LEN, AES_MIN_KEY, AES_MAX_KEY,
aes_icm_crypt,
aes_icm_crypt,
aes_icm_setkey,
rijndael128_zerokey,
aes_icm_reinit,
};
struct enc_xform enc_xform_aes_nist_gcm = {
CRYPTO_AES_NIST_GCM_16, "AES-GCM",
AES_ICM_BLOCK_LEN, AES_GCM_IV_LEN, AES_MIN_KEY, AES_MAX_KEY,
aes_icm_crypt,
aes_icm_crypt,
aes_icm_setkey,
aes_icm_zerokey,
aes_gcm_reinit,
};
struct enc_xform enc_xform_aes_nist_gmac = {
CRYPTO_AES_NIST_GMAC, "AES-GMAC",
AES_ICM_BLOCK_LEN, AES_GCM_IV_LEN, AES_MIN_KEY, AES_MAX_KEY,
NULL,
NULL,
NULL,
NULL,
NULL,
};
struct enc_xform enc_xform_aes_xts = {
CRYPTO_AES_XTS, "AES-XTS",
AES_BLOCK_LEN, AES_XTS_IV_LEN, AES_XTS_MIN_KEY, AES_XTS_MAX_KEY,
aes_xts_encrypt,
aes_xts_decrypt,
aes_xts_setkey,
aes_xts_zerokey,
aes_xts_reinit
};
struct enc_xform enc_xform_arc4 = {
CRYPTO_ARC4, "ARC4",
ARC4_BLOCK_LEN, ARC4_IV_LEN, ARC4_MIN_KEY, ARC4_MAX_KEY,
@ -275,711 +88,26 @@ struct enc_xform enc_xform_arc4 = {
NULL,
};
struct enc_xform enc_xform_camellia = {
CRYPTO_CAMELLIA_CBC, "Camellia",
CAMELLIA_BLOCK_LEN, CAMELLIA_BLOCK_LEN, CAMELLIA_MIN_KEY,
CAMELLIA_MAX_KEY,
cml_encrypt,
cml_decrypt,
cml_setkey,
cml_zerokey,
NULL,
};
/* Authentication instances */
struct auth_hash auth_hash_null = { /* NB: context isn't used */
CRYPTO_NULL_HMAC, "NULL-HMAC",
NULL_HMAC_KEY_LEN, NULL_HASH_LEN, sizeof(int), NULL_HMAC_BLOCK_LEN,
null_init, null_reinit, null_reinit, null_update, null_final
};
/* Include the encryption algorithms */
#include "xform_null.c"
#include "xform_des1.c"
#include "xform_des3.c"
#include "xform_blf.c"
#include "xform_cast5.c"
#include "xform_skipjack.c"
#include "xform_rijndael.c"
#include "xform_aes_icm.c"
#include "xform_aes_xts.c"
#include "xform_cml.c"
/* Include the authentication and hashing algorithms */
#include "xform_gmac.c"
#include "xform_md5.c"
#include "xform_rmd160.c"
#include "xform_sha1.c"
#include "xform_sha2.c"
/* Include the compression algorithms */
#include "xform_deflate.c"
struct auth_hash auth_hash_hmac_md5 = {
CRYPTO_MD5_HMAC, "HMAC-MD5",
MD5_HMAC_KEY_LEN, MD5_HASH_LEN, sizeof(MD5_CTX), MD5_HMAC_BLOCK_LEN,
(void (*) (void *)) MD5Init, NULL, NULL, MD5Update_int,
(void (*) (u_int8_t *, void *)) MD5Final
};
struct auth_hash auth_hash_hmac_sha1 = {
CRYPTO_SHA1_HMAC, "HMAC-SHA1",
SHA1_HMAC_KEY_LEN, SHA1_HASH_LEN, sizeof(SHA1_CTX), SHA1_HMAC_BLOCK_LEN,
SHA1Init_int, NULL, NULL, SHA1Update_int, SHA1Final_int
};
struct auth_hash auth_hash_hmac_ripemd_160 = {
CRYPTO_RIPEMD160_HMAC, "HMAC-RIPEMD-160",
RIPEMD160_HMAC_KEY_LEN, RIPEMD160_HASH_LEN, sizeof(RMD160_CTX),
RIPEMD160_HMAC_BLOCK_LEN,
(void (*)(void *)) RMD160Init, NULL, NULL, RMD160Update_int,
(void (*)(u_int8_t *, void *)) RMD160Final
};
struct auth_hash auth_hash_key_md5 = {
CRYPTO_MD5_KPDK, "Keyed MD5",
NULL_HMAC_KEY_LEN, MD5_KPDK_HASH_LEN, sizeof(MD5_CTX), 0,
(void (*)(void *)) MD5Init, NULL, NULL, MD5Update_int,
(void (*)(u_int8_t *, void *)) MD5Final
};
struct auth_hash auth_hash_key_sha1 = {
CRYPTO_SHA1_KPDK, "Keyed SHA1",
NULL_HMAC_KEY_LEN, SHA1_KPDK_HASH_LEN, sizeof(SHA1_CTX), 0,
SHA1Init_int, NULL, NULL, SHA1Update_int, SHA1Final_int
};
struct auth_hash auth_hash_hmac_sha2_256 = {
CRYPTO_SHA2_256_HMAC, "HMAC-SHA2-256",
SHA2_256_HMAC_KEY_LEN, SHA2_256_HASH_LEN, sizeof(SHA256_CTX),
SHA2_256_HMAC_BLOCK_LEN,
(void (*)(void *)) SHA256_Init, NULL, NULL, SHA256Update_int,
(void (*)(u_int8_t *, void *)) SHA256_Final
};
struct auth_hash auth_hash_hmac_sha2_384 = {
CRYPTO_SHA2_384_HMAC, "HMAC-SHA2-384",
SHA2_384_HMAC_KEY_LEN, SHA2_384_HASH_LEN, sizeof(SHA384_CTX),
SHA2_384_HMAC_BLOCK_LEN,
(void (*)(void *)) SHA384_Init, NULL, NULL, SHA384Update_int,
(void (*)(u_int8_t *, void *)) SHA384_Final
};
struct auth_hash auth_hash_hmac_sha2_512 = {
CRYPTO_SHA2_512_HMAC, "HMAC-SHA2-512",
SHA2_512_HMAC_KEY_LEN, SHA2_512_HASH_LEN, sizeof(SHA512_CTX),
SHA2_512_HMAC_BLOCK_LEN,
(void (*)(void *)) SHA512_Init, NULL, NULL, SHA512Update_int,
(void (*)(u_int8_t *, void *)) SHA512_Final
};
struct auth_hash auth_hash_nist_gmac_aes_128 = {
CRYPTO_AES_128_NIST_GMAC, "GMAC-AES-128",
AES_128_GMAC_KEY_LEN, AES_GMAC_HASH_LEN, sizeof(struct aes_gmac_ctx),
GMAC_BLOCK_LEN,
(void (*)(void *)) AES_GMAC_Init,
(void (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Setkey,
(void (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Reinit,
(int (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Update,
(void (*)(u_int8_t *, void *)) AES_GMAC_Final
};
struct auth_hash auth_hash_nist_gmac_aes_192 = {
CRYPTO_AES_192_NIST_GMAC, "GMAC-AES-192",
AES_192_GMAC_KEY_LEN, AES_GMAC_HASH_LEN, sizeof(struct aes_gmac_ctx),
GMAC_BLOCK_LEN,
(void (*)(void *)) AES_GMAC_Init,
(void (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Setkey,
(void (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Reinit,
(int (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Update,
(void (*)(u_int8_t *, void *)) AES_GMAC_Final
};
struct auth_hash auth_hash_nist_gmac_aes_256 = {
CRYPTO_AES_256_NIST_GMAC, "GMAC-AES-256",
AES_256_GMAC_KEY_LEN, AES_GMAC_HASH_LEN, sizeof(struct aes_gmac_ctx),
GMAC_BLOCK_LEN,
(void (*)(void *)) AES_GMAC_Init,
(void (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Setkey,
(void (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Reinit,
(int (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Update,
(void (*)(u_int8_t *, void *)) AES_GMAC_Final
};
/* Compression instance */
struct comp_algo comp_algo_deflate = {
CRYPTO_DEFLATE_COMP, "Deflate",
90, deflate_compress,
deflate_decompress
};
/*
* Encryption wrapper routines.
*/
static void
null_encrypt(caddr_t key, u_int8_t *blk)
{
}
static void
null_decrypt(caddr_t key, u_int8_t *blk)
{
}
static int
null_setkey(u_int8_t **sched, u_int8_t *key, int len)
{
*sched = NULL;
return 0;
}
static void
null_zerokey(u_int8_t **sched)
{
*sched = NULL;
}
static void
des1_encrypt(caddr_t key, u_int8_t *blk)
{
des_cblock *cb = (des_cblock *) blk;
des_key_schedule *p = (des_key_schedule *) key;
des_ecb_encrypt(cb, cb, p[0], DES_ENCRYPT);
}
static void
des1_decrypt(caddr_t key, u_int8_t *blk)
{
des_cblock *cb = (des_cblock *) blk;
des_key_schedule *p = (des_key_schedule *) key;
des_ecb_encrypt(cb, cb, p[0], DES_DECRYPT);
}
static int
des1_setkey(u_int8_t **sched, u_int8_t *key, int len)
{
des_key_schedule *p;
int err;
p = malloc(sizeof (des_key_schedule),
M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
if (p != NULL) {
des_set_key((des_cblock *) key, p[0]);
err = 0;
} else
err = ENOMEM;
*sched = (u_int8_t *) p;
return err;
}
static void
des1_zerokey(u_int8_t **sched)
{
bzero(*sched, sizeof (des_key_schedule));
free(*sched, M_CRYPTO_DATA);
*sched = NULL;
}
static void
des3_encrypt(caddr_t key, u_int8_t *blk)
{
des_cblock *cb = (des_cblock *) blk;
des_key_schedule *p = (des_key_schedule *) key;
des_ecb3_encrypt(cb, cb, p[0], p[1], p[2], DES_ENCRYPT);
}
static void
des3_decrypt(caddr_t key, u_int8_t *blk)
{
des_cblock *cb = (des_cblock *) blk;
des_key_schedule *p = (des_key_schedule *) key;
des_ecb3_encrypt(cb, cb, p[0], p[1], p[2], DES_DECRYPT);
}
static int
des3_setkey(u_int8_t **sched, u_int8_t *key, int len)
{
des_key_schedule *p;
int err;
p = malloc(3*sizeof (des_key_schedule),
M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
if (p != NULL) {
des_set_key((des_cblock *)(key + 0), p[0]);
des_set_key((des_cblock *)(key + 8), p[1]);
des_set_key((des_cblock *)(key + 16), p[2]);
err = 0;
} else
err = ENOMEM;
*sched = (u_int8_t *) p;
return err;
}
static void
des3_zerokey(u_int8_t **sched)
{
bzero(*sched, 3*sizeof (des_key_schedule));
free(*sched, M_CRYPTO_DATA);
*sched = NULL;
}
static void
blf_encrypt(caddr_t key, u_int8_t *blk)
{
BF_LONG t[2];
memcpy(t, blk, sizeof (t));
t[0] = ntohl(t[0]);
t[1] = ntohl(t[1]);
/* NB: BF_encrypt expects the block in host order! */
BF_encrypt(t, (BF_KEY *) key);
t[0] = htonl(t[0]);
t[1] = htonl(t[1]);
memcpy(blk, t, sizeof (t));
}
static void
blf_decrypt(caddr_t key, u_int8_t *blk)
{
BF_LONG t[2];
memcpy(t, blk, sizeof (t));
t[0] = ntohl(t[0]);
t[1] = ntohl(t[1]);
/* NB: BF_decrypt expects the block in host order! */
BF_decrypt(t, (BF_KEY *) key);
t[0] = htonl(t[0]);
t[1] = htonl(t[1]);
memcpy(blk, t, sizeof (t));
}
static int
blf_setkey(u_int8_t **sched, u_int8_t *key, int len)
{
int err;
*sched = malloc(sizeof(BF_KEY),
M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
if (*sched != NULL) {
BF_set_key((BF_KEY *) *sched, len, key);
err = 0;
} else
err = ENOMEM;
return err;
}
static void
blf_zerokey(u_int8_t **sched)
{
bzero(*sched, sizeof(BF_KEY));
free(*sched, M_CRYPTO_DATA);
*sched = NULL;
}
static void
cast5_encrypt(caddr_t key, u_int8_t *blk)
{
cast_encrypt((cast_key *) key, blk, blk);
}
static void
cast5_decrypt(caddr_t key, u_int8_t *blk)
{
cast_decrypt((cast_key *) key, blk, blk);
}
static int
cast5_setkey(u_int8_t **sched, u_int8_t *key, int len)
{
int err;
*sched = malloc(sizeof(cast_key), M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
if (*sched != NULL) {
cast_setkey((cast_key *)*sched, key, len);
err = 0;
} else
err = ENOMEM;
return err;
}
static void
cast5_zerokey(u_int8_t **sched)
{
bzero(*sched, sizeof(cast_key));
free(*sched, M_CRYPTO_DATA);
*sched = NULL;
}
static void
skipjack_encrypt(caddr_t key, u_int8_t *blk)
{
skipjack_forwards(blk, blk, (u_int8_t **) key);
}
static void
skipjack_decrypt(caddr_t key, u_int8_t *blk)
{
skipjack_backwards(blk, blk, (u_int8_t **) key);
}
static int
skipjack_setkey(u_int8_t **sched, u_int8_t *key, int len)
{
int err;
/* NB: allocate all the memory that's needed at once */
*sched = malloc(10 * (sizeof(u_int8_t *) + 0x100),
M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
if (*sched != NULL) {
u_int8_t** key_tables = (u_int8_t**) *sched;
u_int8_t* table = (u_int8_t*) &key_tables[10];
int k;
for (k = 0; k < 10; k++) {
key_tables[k] = table;
table += 0x100;
}
subkey_table_gen(key, (u_int8_t **) *sched);
err = 0;
} else
err = ENOMEM;
return err;
}
static void
skipjack_zerokey(u_int8_t **sched)
{
bzero(*sched, 10 * (sizeof(u_int8_t *) + 0x100));
free(*sched, M_CRYPTO_DATA);
*sched = NULL;
}
static void
rijndael128_encrypt(caddr_t key, u_int8_t *blk)
{
rijndael_encrypt((rijndael_ctx *) key, (u_char *) blk, (u_char *) blk);
}
static void
rijndael128_decrypt(caddr_t key, u_int8_t *blk)
{
rijndael_decrypt(((rijndael_ctx *) key), (u_char *) blk,
(u_char *) blk);
}
static int
rijndael128_setkey(u_int8_t **sched, u_int8_t *key, int len)
{
int err;
if (len != 16 && len != 24 && len != 32)
return (EINVAL);
*sched = malloc(sizeof(rijndael_ctx), M_CRYPTO_DATA,
M_NOWAIT|M_ZERO);
if (*sched != NULL) {
rijndael_set_key((rijndael_ctx *) *sched, (u_char *) key,
len * 8);
err = 0;
} else
err = ENOMEM;
return err;
}
static void
rijndael128_zerokey(u_int8_t **sched)
{
bzero(*sched, sizeof(rijndael_ctx));
free(*sched, M_CRYPTO_DATA);
*sched = NULL;
}
void
aes_icm_reinit(caddr_t key, u_int8_t *iv)
{
struct aes_icm_ctx *ctx;
ctx = (struct aes_icm_ctx *)key;
bcopy(iv, ctx->ac_block, AESICM_BLOCKSIZE);
}
void
aes_gcm_reinit(caddr_t key, u_int8_t *iv)
{
struct aes_icm_ctx *ctx;
aes_icm_reinit(key, iv);
ctx = (struct aes_icm_ctx *)key;
/* GCM starts with 2 as counter 1 is used for final xor of tag. */
bzero(&ctx->ac_block[AESICM_BLOCKSIZE - 4], 4);
ctx->ac_block[AESICM_BLOCKSIZE - 1] = 2;
}
void
aes_icm_crypt(caddr_t key, u_int8_t *data)
{
struct aes_icm_ctx *ctx;
u_int8_t keystream[AESICM_BLOCKSIZE];
int i;
ctx = (struct aes_icm_ctx *)key;
rijndaelEncrypt(ctx->ac_ek, ctx->ac_nr, ctx->ac_block, keystream);
for (i = 0; i < AESICM_BLOCKSIZE; i++)
data[i] ^= keystream[i];
explicit_bzero(keystream, sizeof(keystream));
/* increment counter */
for (i = AESICM_BLOCKSIZE - 1;
i >= 0; i--)
if (++ctx->ac_block[i]) /* continue on overflow */
break;
}
int
aes_icm_setkey(u_int8_t **sched, u_int8_t *key, int len)
{
struct aes_icm_ctx *ctx;
if (len != 16 && len != 24 && len != 32)
return EINVAL;
*sched = malloc(sizeof(struct aes_icm_ctx), M_CRYPTO_DATA,
M_NOWAIT | M_ZERO);
if (*sched == NULL)
return ENOMEM;
ctx = (struct aes_icm_ctx *)*sched;
ctx->ac_nr = rijndaelKeySetupEnc(ctx->ac_ek, (u_char *)key, len * 8);
return 0;
}
void
aes_icm_zerokey(u_int8_t **sched)
{
bzero(*sched, sizeof(struct aes_icm_ctx));
free(*sched, M_CRYPTO_DATA);
*sched = NULL;
}
#define AES_XTS_BLOCKSIZE 16
#define AES_XTS_IVSIZE 8
#define AES_XTS_ALPHA 0x87 /* GF(2^128) generator polynomial */
struct aes_xts_ctx {
rijndael_ctx key1;
rijndael_ctx key2;
u_int8_t tweak[AES_XTS_BLOCKSIZE];
};
void
aes_xts_reinit(caddr_t key, u_int8_t *iv)
{
struct aes_xts_ctx *ctx = (struct aes_xts_ctx *)key;
u_int64_t blocknum;
u_int i;
/*
* Prepare tweak as E_k2(IV). IV is specified as LE representation
* of a 64-bit block number which we allow to be passed in directly.
*/
bcopy(iv, &blocknum, AES_XTS_IVSIZE);
for (i = 0; i < AES_XTS_IVSIZE; i++) {
ctx->tweak[i] = blocknum & 0xff;
blocknum >>= 8;
}
/* Last 64 bits of IV are always zero */
bzero(ctx->tweak + AES_XTS_IVSIZE, AES_XTS_IVSIZE);
rijndael_encrypt(&ctx->key2, ctx->tweak, ctx->tweak);
}
static void
aes_xts_crypt(struct aes_xts_ctx *ctx, u_int8_t *data, u_int do_encrypt)
{
u_int8_t block[AES_XTS_BLOCKSIZE];
u_int i, carry_in, carry_out;
for (i = 0; i < AES_XTS_BLOCKSIZE; i++)
block[i] = data[i] ^ ctx->tweak[i];
if (do_encrypt)
rijndael_encrypt(&ctx->key1, block, data);
else
rijndael_decrypt(&ctx->key1, block, data);
for (i = 0; i < AES_XTS_BLOCKSIZE; i++)
data[i] ^= ctx->tweak[i];
/* Exponentiate tweak */
carry_in = 0;
for (i = 0; i < AES_XTS_BLOCKSIZE; i++) {
carry_out = ctx->tweak[i] & 0x80;
ctx->tweak[i] = (ctx->tweak[i] << 1) | (carry_in ? 1 : 0);
carry_in = carry_out;
}
if (carry_in)
ctx->tweak[0] ^= AES_XTS_ALPHA;
bzero(block, sizeof(block));
}
void
aes_xts_encrypt(caddr_t key, u_int8_t *data)
{
aes_xts_crypt((struct aes_xts_ctx *)key, data, 1);
}
void
aes_xts_decrypt(caddr_t key, u_int8_t *data)
{
aes_xts_crypt((struct aes_xts_ctx *)key, data, 0);
}
int
aes_xts_setkey(u_int8_t **sched, u_int8_t *key, int len)
{
struct aes_xts_ctx *ctx;
if (len != 32 && len != 64)
return EINVAL;
*sched = malloc(sizeof(struct aes_xts_ctx), M_CRYPTO_DATA,
M_NOWAIT | M_ZERO);
if (*sched == NULL)
return ENOMEM;
ctx = (struct aes_xts_ctx *)*sched;
rijndael_set_key(&ctx->key1, key, len * 4);
rijndael_set_key(&ctx->key2, key + (len / 2), len * 4);
return 0;
}
void
aes_xts_zerokey(u_int8_t **sched)
{
bzero(*sched, sizeof(struct aes_xts_ctx));
free(*sched, M_CRYPTO_DATA);
*sched = NULL;
}
static void
cml_encrypt(caddr_t key, u_int8_t *blk)
{
camellia_encrypt((camellia_ctx *) key, (u_char *) blk, (u_char *) blk);
}
static void
cml_decrypt(caddr_t key, u_int8_t *blk)
{
camellia_decrypt(((camellia_ctx *) key), (u_char *) blk,
(u_char *) blk);
}
static int
cml_setkey(u_int8_t **sched, u_int8_t *key, int len)
{
int err;
if (len != 16 && len != 24 && len != 32)
return (EINVAL);
*sched = malloc(sizeof(camellia_ctx), M_CRYPTO_DATA,
M_NOWAIT|M_ZERO);
if (*sched != NULL) {
camellia_set_key((camellia_ctx *) *sched, (u_char *) key,
len * 8);
err = 0;
} else
err = ENOMEM;
return err;
}
static void
cml_zerokey(u_int8_t **sched)
{
bzero(*sched, sizeof(camellia_ctx));
free(*sched, M_CRYPTO_DATA);
*sched = NULL;
}
/*
* And now for auth.
*/
static void
null_init(void *ctx)
{
}
static void
null_reinit(void *ctx, const u_int8_t *buf, u_int16_t len)
{
}
static int
null_update(void *ctx, const u_int8_t *buf, u_int16_t len)
{
return 0;
}
static void
null_final(u_int8_t *buf, void *ctx)
{
if (buf != (u_int8_t *) 0)
bzero(buf, 12);
}
static int
RMD160Update_int(void *ctx, const u_int8_t *buf, u_int16_t len)
{
RMD160Update(ctx, buf, len);
return 0;
}
static int
MD5Update_int(void *ctx, const u_int8_t *buf, u_int16_t len)
{
MD5Update(ctx, buf, len);
return 0;
}
static void
SHA1Init_int(void *ctx)
{
SHA1Init(ctx);
}
static int
SHA1Update_int(void *ctx, const u_int8_t *buf, u_int16_t len)
{
SHA1Update(ctx, buf, len);
return 0;
}
static void
SHA1Final_int(u_int8_t *blk, void *ctx)
{
SHA1Final(blk, ctx);
}
static int
SHA256Update_int(void *ctx, const u_int8_t *buf, u_int16_t len)
{
SHA256_Update(ctx, buf, len);
return 0;
}
static int
SHA384Update_int(void *ctx, const u_int8_t *buf, u_int16_t len)
{
SHA384_Update(ctx, buf, len);
return 0;
}
static int
SHA512Update_int(void *ctx, const u_int8_t *buf, u_int16_t len)
{
SHA512_Update(ctx, buf, len);
return 0;
}
/*
* And compression
*/
static u_int32_t
deflate_compress(data, size, out)
u_int8_t *data;
u_int32_t size;
u_int8_t **out;
{
return deflate_global(data, size, 0, out);
}
static u_int32_t
deflate_decompress(data, size, out)
u_int8_t *data;
u_int32_t size;
u_int8_t **out;
{
return deflate_global(data, size, 1, out);
}

View File

@ -39,83 +39,9 @@
#include <opencrypto/rmd160.h>
#include <opencrypto/gmac.h>
/* Declarations */
struct auth_hash {
int type;
char *name;
u_int16_t keysize;
u_int16_t hashsize;
u_int16_t ctxsize;
u_int16_t blocksize;
void (*Init) (void *);
void (*Setkey) (void *, const u_int8_t *, u_int16_t);
void (*Reinit) (void *, const u_int8_t *, u_int16_t);
int (*Update) (void *, const u_int8_t *, u_int16_t);
void (*Final) (u_int8_t *, void *);
};
/* XXX use a define common with other hash stuff ! */
#define AH_ALEN_MAX 64 /* max authenticator hash length */
struct enc_xform {
int type;
char *name;
u_int16_t blocksize;
u_int16_t ivsize;
u_int16_t minkey, maxkey;
void (*encrypt) (caddr_t, u_int8_t *);
void (*decrypt) (caddr_t, u_int8_t *);
int (*setkey) (u_int8_t **, u_int8_t *, int len);
void (*zerokey) (u_int8_t **);
void (*reinit) (caddr_t, u_int8_t *);
};
struct comp_algo {
int type;
char *name;
size_t minlen;
u_int32_t (*compress) (u_int8_t *, u_int32_t, u_int8_t **);
u_int32_t (*decompress) (u_int8_t *, u_int32_t, u_int8_t **);
};
union authctx {
MD5_CTX md5ctx;
SHA1_CTX sha1ctx;
RMD160_CTX rmd160ctx;
SHA256_CTX sha256ctx;
SHA384_CTX sha384ctx;
SHA512_CTX sha512ctx;
struct aes_gmac_ctx aes_gmac_ctx;
};
extern struct enc_xform enc_xform_null;
extern struct enc_xform enc_xform_des;
extern struct enc_xform enc_xform_3des;
extern struct enc_xform enc_xform_blf;
extern struct enc_xform enc_xform_cast5;
extern struct enc_xform enc_xform_skipjack;
extern struct enc_xform enc_xform_rijndael128;
extern struct enc_xform enc_xform_aes_icm;
extern struct enc_xform enc_xform_aes_nist_gcm;
extern struct enc_xform enc_xform_aes_nist_gmac;
extern struct enc_xform enc_xform_aes_xts;
extern struct enc_xform enc_xform_arc4;
extern struct enc_xform enc_xform_camellia;
extern struct auth_hash auth_hash_null;
extern struct auth_hash auth_hash_key_md5;
extern struct auth_hash auth_hash_key_sha1;
extern struct auth_hash auth_hash_hmac_md5;
extern struct auth_hash auth_hash_hmac_sha1;
extern struct auth_hash auth_hash_hmac_ripemd_160;
extern struct auth_hash auth_hash_hmac_sha2_256;
extern struct auth_hash auth_hash_hmac_sha2_384;
extern struct auth_hash auth_hash_hmac_sha2_512;
extern struct auth_hash auth_hash_nist_gmac_aes_128;
extern struct auth_hash auth_hash_nist_gmac_aes_192;
extern struct auth_hash auth_hash_nist_gmac_aes_256;
extern struct comp_algo comp_algo_deflate;
#include <opencrypto/xform_auth.h>
#include <opencrypto/xform_comp.h>
#include <opencrypto/xform_enc.h>
#ifdef _KERNEL
#include <sys/malloc.h>

View File

@ -0,0 +1,152 @@
/* $OpenBSD: xform.c,v 1.16 2001/08/28 12:20:43 ben Exp $ */
/*-
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr),
* Niels Provos (provos@physnet.uni-hamburg.de) and
* Damien Miller (djm@mindrot.org).
*
* This code was written by John Ioannidis for BSD/OS in Athens, Greece,
* in November 1995.
*
* Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
* by Angelos D. Keromytis.
*
* Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
* and Niels Provos.
*
* Additional features in 1999 by Angelos D. Keromytis.
*
* AES XTS implementation in 2008 by Damien Miller
*
* Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
* Angelos D. Keromytis and Niels Provos.
*
* Copyright (C) 2001, Angelos D. Keromytis.
*
* Copyright (C) 2008, Damien Miller
* Copyright (c) 2014 The FreeBSD Foundation
* All rights reserved.
*
* Portions of this software were developed by John-Mark Gurney
* under sponsorship of the FreeBSD Foundation and
* Rubicon Communications, LLC (Netgate).
*
* Permission to use, copy, and modify this software with or without fee
* is hereby granted, provided that this entire notice is included in
* all copies of any software which is or includes a copy or
* modification of this software.
* You may use this code under the GNU public license if you so wish. Please
* contribute changes back to the authors under this freer than GPL license
* so that we may further the use of strong encryption without limitations to
* all.
*
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
* PURPOSE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <opencrypto/xform_enc.h>
static int aes_icm_setkey(u_int8_t **, u_int8_t *, int);
static void aes_icm_crypt(caddr_t, u_int8_t *);
static void aes_icm_zerokey(u_int8_t **);
static void aes_icm_reinit(caddr_t, u_int8_t *);
static void aes_gcm_reinit(caddr_t, u_int8_t *);
/* Encryption instances */
struct enc_xform enc_xform_aes_icm = {
CRYPTO_AES_ICM, "AES-ICM",
AES_BLOCK_LEN, AES_BLOCK_LEN, AES_MIN_KEY, AES_MAX_KEY,
aes_icm_crypt,
aes_icm_crypt,
aes_icm_setkey,
rijndael128_zerokey,
aes_icm_reinit,
};
struct enc_xform enc_xform_aes_nist_gcm = {
CRYPTO_AES_NIST_GCM_16, "AES-GCM",
AES_ICM_BLOCK_LEN, AES_GCM_IV_LEN, AES_MIN_KEY, AES_MAX_KEY,
aes_icm_crypt,
aes_icm_crypt,
aes_icm_setkey,
aes_icm_zerokey,
aes_gcm_reinit,
};
/*
* Encryption wrapper routines.
*/
static void
aes_icm_reinit(caddr_t key, u_int8_t *iv)
{
struct aes_icm_ctx *ctx;
ctx = (struct aes_icm_ctx *)key;
bcopy(iv, ctx->ac_block, AESICM_BLOCKSIZE);
}
static void
aes_gcm_reinit(caddr_t key, u_int8_t *iv)
{
struct aes_icm_ctx *ctx;
aes_icm_reinit(key, iv);
ctx = (struct aes_icm_ctx *)key;
/* GCM starts with 2 as counter 1 is used for final xor of tag. */
bzero(&ctx->ac_block[AESICM_BLOCKSIZE - 4], 4);
ctx->ac_block[AESICM_BLOCKSIZE - 1] = 2;
}
static void
aes_icm_crypt(caddr_t key, u_int8_t *data)
{
struct aes_icm_ctx *ctx;
u_int8_t keystream[AESICM_BLOCKSIZE];
int i;
ctx = (struct aes_icm_ctx *)key;
rijndaelEncrypt(ctx->ac_ek, ctx->ac_nr, ctx->ac_block, keystream);
for (i = 0; i < AESICM_BLOCKSIZE; i++)
data[i] ^= keystream[i];
explicit_bzero(keystream, sizeof(keystream));
/* increment counter */
for (i = AESICM_BLOCKSIZE - 1;
i >= 0; i--)
if (++ctx->ac_block[i]) /* continue on overflow */
break;
}
static int
aes_icm_setkey(u_int8_t **sched, u_int8_t *key, int len)
{
struct aes_icm_ctx *ctx;
if (len != 16 && len != 24 && len != 32)
return EINVAL;
*sched = KMALLOC(sizeof(struct aes_icm_ctx), M_CRYPTO_DATA,
M_NOWAIT | M_ZERO);
if (*sched == NULL)
return ENOMEM;
ctx = (struct aes_icm_ctx *)*sched;
ctx->ac_nr = rijndaelKeySetupEnc(ctx->ac_ek, (u_char *)key, len * 8);
return 0;
}
static void
aes_icm_zerokey(u_int8_t **sched)
{
bzero(*sched, sizeof(struct aes_icm_ctx));
KFREE(*sched, M_CRYPTO_DATA);
*sched = NULL;
}

View File

@ -0,0 +1,164 @@
/* $OpenBSD: xform.c,v 1.16 2001/08/28 12:20:43 ben Exp $ */
/*-
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr),
* Niels Provos (provos@physnet.uni-hamburg.de) and
* Damien Miller (djm@mindrot.org).
*
* This code was written by John Ioannidis for BSD/OS in Athens, Greece,
* in November 1995.
*
* Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
* by Angelos D. Keromytis.
*
* Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
* and Niels Provos.
*
* Additional features in 1999 by Angelos D. Keromytis.
*
* AES XTS implementation in 2008 by Damien Miller
*
* Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
* Angelos D. Keromytis and Niels Provos.
*
* Copyright (C) 2001, Angelos D. Keromytis.
*
* Copyright (C) 2008, Damien Miller
* Copyright (c) 2014 The FreeBSD Foundation
* All rights reserved.
*
* Portions of this software were developed by John-Mark Gurney
* under sponsorship of the FreeBSD Foundation and
* Rubicon Communications, LLC (Netgate).
*
* Permission to use, copy, and modify this software with or without fee
* is hereby granted, provided that this entire notice is included in
* all copies of any software which is or includes a copy or
* modification of this software.
* You may use this code under the GNU public license if you so wish. Please
* contribute changes back to the authors under this freer than GPL license
* so that we may further the use of strong encryption without limitations to
* all.
*
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
* PURPOSE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <opencrypto/xform_enc.h>
static int aes_xts_setkey(u_int8_t **, u_int8_t *, int);
static void aes_xts_encrypt(caddr_t, u_int8_t *);
static void aes_xts_decrypt(caddr_t, u_int8_t *);
static void aes_xts_zerokey(u_int8_t **);
static void aes_xts_reinit(caddr_t, u_int8_t *);
/* Encryption instances */
struct enc_xform enc_xform_aes_xts = {
CRYPTO_AES_XTS, "AES-XTS",
AES_BLOCK_LEN, AES_XTS_IV_LEN, AES_XTS_MIN_KEY, AES_XTS_MAX_KEY,
aes_xts_encrypt,
aes_xts_decrypt,
aes_xts_setkey,
aes_xts_zerokey,
aes_xts_reinit
};
/*
* Encryption wrapper routines.
*/
static void
aes_xts_reinit(caddr_t key, u_int8_t *iv)
{
struct aes_xts_ctx *ctx = (struct aes_xts_ctx *)key;
u_int64_t blocknum;
u_int i;
/*
* Prepare tweak as E_k2(IV). IV is specified as LE representation
* of a 64-bit block number which we allow to be passed in directly.
*/
bcopy(iv, &blocknum, AES_XTS_IVSIZE);
for (i = 0; i < AES_XTS_IVSIZE; i++) {
ctx->tweak[i] = blocknum & 0xff;
blocknum >>= 8;
}
/* Last 64 bits of IV are always zero */
bzero(ctx->tweak + AES_XTS_IVSIZE, AES_XTS_IVSIZE);
rijndael_encrypt(&ctx->key2, ctx->tweak, ctx->tweak);
}
static void
aes_xts_crypt(struct aes_xts_ctx *ctx, u_int8_t *data, u_int do_encrypt)
{
u_int8_t block[AES_XTS_BLOCKSIZE];
u_int i, carry_in, carry_out;
for (i = 0; i < AES_XTS_BLOCKSIZE; i++)
block[i] = data[i] ^ ctx->tweak[i];
if (do_encrypt)
rijndael_encrypt(&ctx->key1, block, data);
else
rijndael_decrypt(&ctx->key1, block, data);
for (i = 0; i < AES_XTS_BLOCKSIZE; i++)
data[i] ^= ctx->tweak[i];
/* Exponentiate tweak */
carry_in = 0;
for (i = 0; i < AES_XTS_BLOCKSIZE; i++) {
carry_out = ctx->tweak[i] & 0x80;
ctx->tweak[i] = (ctx->tweak[i] << 1) | (carry_in ? 1 : 0);
carry_in = carry_out;
}
if (carry_in)
ctx->tweak[0] ^= AES_XTS_ALPHA;
bzero(block, sizeof(block));
}
static void
aes_xts_encrypt(caddr_t key, u_int8_t *data)
{
aes_xts_crypt((struct aes_xts_ctx *)key, data, 1);
}
static void
aes_xts_decrypt(caddr_t key, u_int8_t *data)
{
aes_xts_crypt((struct aes_xts_ctx *)key, data, 0);
}
static int
aes_xts_setkey(u_int8_t **sched, u_int8_t *key, int len)
{
struct aes_xts_ctx *ctx;
if (len != 32 && len != 64)
return EINVAL;
*sched = KMALLOC(sizeof(struct aes_xts_ctx), M_CRYPTO_DATA,
M_NOWAIT | M_ZERO);
if (*sched == NULL)
return ENOMEM;
ctx = (struct aes_xts_ctx *)*sched;
rijndael_set_key(&ctx->key1, key, len * 4);
rijndael_set_key(&ctx->key2, key + (len / 2), len * 4);
return 0;
}
static void
aes_xts_zerokey(u_int8_t **sched)
{
bzero(*sched, sizeof(struct aes_xts_ctx));
KFREE(*sched, M_CRYPTO_DATA);
*sched = NULL;
}

View File

@ -0,0 +1,89 @@
/* $FreeBSD$ */
/* $OpenBSD: xform.h,v 1.8 2001/08/28 12:20:43 ben Exp $ */
/*-
* The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
*
* This code was written by Angelos D. Keromytis in Athens, Greece, in
* February 2000. Network Security Technologies Inc. (NSTI) kindly
* supported the development of this code.
*
* Copyright (c) 2000 Angelos D. Keromytis
* Copyright (c) 2014 The FreeBSD Foundation
* All rights reserved.
*
* Portions of this software were developed by John-Mark Gurney
* under sponsorship of the FreeBSD Foundation and
* Rubicon Communications, LLC (Netgate).
*
* Permission to use, copy, and modify this software without fee
* is hereby granted, provided that this entire notice is included in
* all source code copies of any software which is or includes a copy or
* modification of this software.
*
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
* PURPOSE.
*/
#ifndef _CRYPTO_XFORM_AUTH_H_
#define _CRYPTO_XFORM_AUTH_H_
#include <sys/malloc.h>
#include <sys/errno.h>
#include <sys/md5.h>
#include <crypto/sha1.h>
#include <crypto/sha2/sha256.h>
#include <crypto/sha2/sha384.h>
#include <crypto/sha2/sha512.h>
#include <opencrypto/rmd160.h>
#include <opencrypto/gmac.h>
#include <opencrypto/cryptodev.h>
#include <opencrypto/xform_userland.h>
/* XXX use a define common with other hash stuff ! */
#define AH_ALEN_MAX 64 /* max authenticator hash length */
/* Declarations */
struct auth_hash {
int type;
char *name;
u_int16_t keysize;
u_int16_t hashsize;
u_int16_t ctxsize;
u_int16_t blocksize;
void (*Init) (void *);
void (*Setkey) (void *, const u_int8_t *, u_int16_t);
void (*Reinit) (void *, const u_int8_t *, u_int16_t);
int (*Update) (void *, const u_int8_t *, u_int16_t);
void (*Final) (u_int8_t *, void *);
};
extern struct auth_hash auth_hash_null;
extern struct auth_hash auth_hash_key_md5;
extern struct auth_hash auth_hash_key_sha1;
extern struct auth_hash auth_hash_hmac_md5;
extern struct auth_hash auth_hash_hmac_sha1;
extern struct auth_hash auth_hash_hmac_ripemd_160;
extern struct auth_hash auth_hash_hmac_sha2_256;
extern struct auth_hash auth_hash_hmac_sha2_384;
extern struct auth_hash auth_hash_hmac_sha2_512;
extern struct auth_hash auth_hash_nist_gmac_aes_128;
extern struct auth_hash auth_hash_nist_gmac_aes_192;
extern struct auth_hash auth_hash_nist_gmac_aes_256;
union authctx {
MD5_CTX md5ctx;
SHA1_CTX sha1ctx;
RMD160_CTX rmd160ctx;
SHA256_CTX sha256ctx;
SHA384_CTX sha384ctx;
SHA512_CTX sha512ctx;
struct aes_gmac_ctx aes_gmac_ctx;
};
#endif /* _CRYPTO_XFORM_AUTH_H_ */

127
sys/opencrypto/xform_blf.c Normal file
View File

@ -0,0 +1,127 @@
/* $OpenBSD: xform.c,v 1.16 2001/08/28 12:20:43 ben Exp $ */
/*-
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr),
* Niels Provos (provos@physnet.uni-hamburg.de) and
* Damien Miller (djm@mindrot.org).
*
* This code was written by John Ioannidis for BSD/OS in Athens, Greece,
* in November 1995.
*
* Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
* by Angelos D. Keromytis.
*
* Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
* and Niels Provos.
*
* Additional features in 1999 by Angelos D. Keromytis.
*
* AES XTS implementation in 2008 by Damien Miller
*
* Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
* Angelos D. Keromytis and Niels Provos.
*
* Copyright (C) 2001, Angelos D. Keromytis.
*
* Copyright (C) 2008, Damien Miller
* Copyright (c) 2014 The FreeBSD Foundation
* All rights reserved.
*
* Portions of this software were developed by John-Mark Gurney
* under sponsorship of the FreeBSD Foundation and
* Rubicon Communications, LLC (Netgate).
*
* Permission to use, copy, and modify this software with or without fee
* is hereby granted, provided that this entire notice is included in
* all copies of any software which is or includes a copy or
* modification of this software.
* You may use this code under the GNU public license if you so wish. Please
* contribute changes back to the authors under this freer than GPL license
* so that we may further the use of strong encryption without limitations to
* all.
*
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
* PURPOSE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <crypto/blowfish/blowfish.h>
#include <opencrypto/xform_enc.h>
static int blf_setkey(u_int8_t **, u_int8_t *, int);
static void blf_encrypt(caddr_t, u_int8_t *);
static void blf_decrypt(caddr_t, u_int8_t *);
static void blf_zerokey(u_int8_t **);
/* Encryption instances */
struct enc_xform enc_xform_blf = {
CRYPTO_BLF_CBC, "Blowfish",
BLOWFISH_BLOCK_LEN, BLOWFISH_BLOCK_LEN, BLOWFISH_MIN_KEY,
BLOWFISH_MAX_KEY,
blf_encrypt,
blf_decrypt,
blf_setkey,
blf_zerokey,
NULL,
};
/*
* Encryption wrapper routines.
*/
static void
blf_encrypt(caddr_t key, u_int8_t *blk)
{
BF_LONG t[2];
memcpy(t, blk, sizeof (t));
t[0] = ntohl(t[0]);
t[1] = ntohl(t[1]);
/* NB: BF_encrypt expects the block in host order! */
BF_encrypt(t, (BF_KEY *) key);
t[0] = htonl(t[0]);
t[1] = htonl(t[1]);
memcpy(blk, t, sizeof (t));
}
static void
blf_decrypt(caddr_t key, u_int8_t *blk)
{
BF_LONG t[2];
memcpy(t, blk, sizeof (t));
t[0] = ntohl(t[0]);
t[1] = ntohl(t[1]);
/* NB: BF_decrypt expects the block in host order! */
BF_decrypt(t, (BF_KEY *) key);
t[0] = htonl(t[0]);
t[1] = htonl(t[1]);
memcpy(blk, t, sizeof (t));
}
static int
blf_setkey(u_int8_t **sched, u_int8_t *key, int len)
{
int err;
*sched = KMALLOC(sizeof(BF_KEY),
M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
if (*sched != NULL) {
BF_set_key((BF_KEY *) *sched, len, key);
err = 0;
} else
err = ENOMEM;
return err;
}
static void
blf_zerokey(u_int8_t **sched)
{
bzero(*sched, sizeof(BF_KEY));
KFREE(*sched, M_CRYPTO_DATA);
*sched = NULL;
}

View File

@ -0,0 +1,107 @@
/* $OpenBSD: xform.c,v 1.16 2001/08/28 12:20:43 ben Exp $ */
/*-
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr),
* Niels Provos (provos@physnet.uni-hamburg.de) and
* Damien Miller (djm@mindrot.org).
*
* This code was written by John Ioannidis for BSD/OS in Athens, Greece,
* in November 1995.
*
* Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
* by Angelos D. Keromytis.
*
* Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
* and Niels Provos.
*
* Additional features in 1999 by Angelos D. Keromytis.
*
* AES XTS implementation in 2008 by Damien Miller
*
* Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
* Angelos D. Keromytis and Niels Provos.
*
* Copyright (C) 2001, Angelos D. Keromytis.
*
* Copyright (C) 2008, Damien Miller
* Copyright (c) 2014 The FreeBSD Foundation
* All rights reserved.
*
* Portions of this software were developed by John-Mark Gurney
* under sponsorship of the FreeBSD Foundation and
* Rubicon Communications, LLC (Netgate).
*
* Permission to use, copy, and modify this software with or without fee
* is hereby granted, provided that this entire notice is included in
* all copies of any software which is or includes a copy or
* modification of this software.
* You may use this code under the GNU public license if you so wish. Please
* contribute changes back to the authors under this freer than GPL license
* so that we may further the use of strong encryption without limitations to
* all.
*
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
* PURPOSE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <opencrypto/cast.h>
#include <opencrypto/xform_enc.h>
static int cast5_setkey(u_int8_t **, u_int8_t *, int);
static void cast5_encrypt(caddr_t, u_int8_t *);
static void cast5_decrypt(caddr_t, u_int8_t *);
static void cast5_zerokey(u_int8_t **);
/* Encryption instances */
struct enc_xform enc_xform_cast5 = {
CRYPTO_CAST_CBC, "CAST-128",
CAST128_BLOCK_LEN, CAST128_BLOCK_LEN, CAST_MIN_KEY, CAST_MAX_KEY,
cast5_encrypt,
cast5_decrypt,
cast5_setkey,
cast5_zerokey,
NULL,
};
/*
* Encryption wrapper routines.
*/
static void
cast5_encrypt(caddr_t key, u_int8_t *blk)
{
cast_encrypt((cast_key *) key, blk, blk);
}
static void
cast5_decrypt(caddr_t key, u_int8_t *blk)
{
cast_decrypt((cast_key *) key, blk, blk);
}
static int
cast5_setkey(u_int8_t **sched, u_int8_t *key, int len)
{
int err;
*sched = KMALLOC(sizeof(cast_key), M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
if (*sched != NULL) {
cast_setkey((cast_key *)*sched, key, len);
err = 0;
} else
err = ENOMEM;
return err;
}
static void
cast5_zerokey(u_int8_t **sched)
{
bzero(*sched, sizeof(cast_key));
KFREE(*sched, M_CRYPTO_DATA);
*sched = NULL;
}

113
sys/opencrypto/xform_cml.c Normal file
View File

@ -0,0 +1,113 @@
/* $OpenBSD: xform.c,v 1.16 2001/08/28 12:20:43 ben Exp $ */
/*-
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr),
* Niels Provos (provos@physnet.uni-hamburg.de) and
* Damien Miller (djm@mindrot.org).
*
* This code was written by John Ioannidis for BSD/OS in Athens, Greece,
* in November 1995.
*
* Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
* by Angelos D. Keromytis.
*
* Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
* and Niels Provos.
*
* Additional features in 1999 by Angelos D. Keromytis.
*
* AES XTS implementation in 2008 by Damien Miller
*
* Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
* Angelos D. Keromytis and Niels Provos.
*
* Copyright (C) 2001, Angelos D. Keromytis.
*
* Copyright (C) 2008, Damien Miller
* Copyright (c) 2014 The FreeBSD Foundation
* All rights reserved.
*
* Portions of this software were developed by John-Mark Gurney
* under sponsorship of the FreeBSD Foundation and
* Rubicon Communications, LLC (Netgate).
*
* Permission to use, copy, and modify this software with or without fee
* is hereby granted, provided that this entire notice is included in
* all copies of any software which is or includes a copy or
* modification of this software.
* You may use this code under the GNU public license if you so wish. Please
* contribute changes back to the authors under this freer than GPL license
* so that we may further the use of strong encryption without limitations to
* all.
*
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
* PURPOSE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <crypto/camellia/camellia.h>
#include <opencrypto/xform_enc.h>
static int cml_setkey(u_int8_t **, u_int8_t *, int);
static void cml_encrypt(caddr_t, u_int8_t *);
static void cml_decrypt(caddr_t, u_int8_t *);
static void cml_zerokey(u_int8_t **);
/* Encryption instances */
struct enc_xform enc_xform_camellia = {
CRYPTO_CAMELLIA_CBC, "Camellia",
CAMELLIA_BLOCK_LEN, CAMELLIA_BLOCK_LEN, CAMELLIA_MIN_KEY,
CAMELLIA_MAX_KEY,
cml_encrypt,
cml_decrypt,
cml_setkey,
cml_zerokey,
NULL,
};
/*
* Encryption wrapper routines.
*/
static void
cml_encrypt(caddr_t key, u_int8_t *blk)
{
camellia_encrypt((camellia_ctx *) key, (u_char *) blk, (u_char *) blk);
}
static void
cml_decrypt(caddr_t key, u_int8_t *blk)
{
camellia_decrypt(((camellia_ctx *) key), (u_char *) blk,
(u_char *) blk);
}
static int
cml_setkey(u_int8_t **sched, u_int8_t *key, int len)
{
int err;
if (len != 16 && len != 24 && len != 32)
return (EINVAL);
*sched = KMALLOC(sizeof(camellia_ctx), M_CRYPTO_DATA,
M_NOWAIT|M_ZERO);
if (*sched != NULL) {
camellia_set_key((camellia_ctx *) *sched, (u_char *) key,
len * 8);
err = 0;
} else
err = ENOMEM;
return err;
}
static void
cml_zerokey(u_int8_t **sched)
{
bzero(*sched, sizeof(camellia_ctx));
KFREE(*sched, M_CRYPTO_DATA);
*sched = NULL;
}

View File

@ -0,0 +1,52 @@
/* $FreeBSD$ */
/* $OpenBSD: xform.h,v 1.8 2001/08/28 12:20:43 ben Exp $ */
/*-
* The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
*
* This code was written by Angelos D. Keromytis in Athens, Greece, in
* February 2000. Network Security Technologies Inc. (NSTI) kindly
* supported the development of this code.
*
* Copyright (c) 2000 Angelos D. Keromytis
* Copyright (c) 2014 The FreeBSD Foundation
* All rights reserved.
*
* Portions of this software were developed by John-Mark Gurney
* under sponsorship of the FreeBSD Foundation and
* Rubicon Communications, LLC (Netgate).
*
* Permission to use, copy, and modify this software without fee
* is hereby granted, provided that this entire notice is included in
* all source code copies of any software which is or includes a copy or
* modification of this software.
*
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
* PURPOSE.
*/
#ifndef _CRYPTO_XFORM_COMP_H_
#define _CRYPTO_XFORM_COMP_H_
#include <sys/malloc.h>
#include <sys/errno.h>
#include <opencrypto/deflate.h>
#include <opencrypto/cryptodev.h>
#include <opencrypto/xform_userland.h>
/* Declarations */
struct comp_algo {
int type;
char *name;
size_t minlen;
u_int32_t (*compress) (u_int8_t *, u_int32_t, u_int8_t **);
u_int32_t (*decompress) (u_int8_t *, u_int32_t, u_int8_t **);
};
extern struct comp_algo comp_algo_deflate;
#endif /* _CRYPTO_XFORM_COMP_H_ */

View File

@ -0,0 +1,86 @@
/* $OpenBSD: xform.c,v 1.16 2001/08/28 12:20:43 ben Exp $ */
/*-
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr),
* Niels Provos (provos@physnet.uni-hamburg.de) and
* Damien Miller (djm@mindrot.org).
*
* This code was written by John Ioannidis for BSD/OS in Athens, Greece,
* in November 1995.
*
* Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
* by Angelos D. Keromytis.
*
* Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
* and Niels Provos.
*
* Additional features in 1999 by Angelos D. Keromytis.
*
* AES XTS implementation in 2008 by Damien Miller
*
* Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
* Angelos D. Keromytis and Niels Provos.
*
* Copyright (C) 2001, Angelos D. Keromytis.
*
* Copyright (C) 2008, Damien Miller
* Copyright (c) 2014 The FreeBSD Foundation
* All rights reserved.
*
* Portions of this software were developed by John-Mark Gurney
* under sponsorship of the FreeBSD Foundation and
* Rubicon Communications, LLC (Netgate).
*
* Permission to use, copy, and modify this software with or without fee
* is hereby granted, provided that this entire notice is included in
* all copies of any software which is or includes a copy or
* modification of this software.
* You may use this code under the GNU public license if you so wish. Please
* contribute changes back to the authors under this freer than GPL license
* so that we may further the use of strong encryption without limitations to
* all.
*
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
* PURPOSE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <opencrypto/deflate.h>
#include <opencrypto/xform_comp.h>
static u_int32_t deflate_compress(u_int8_t *, u_int32_t, u_int8_t **);
static u_int32_t deflate_decompress(u_int8_t *, u_int32_t, u_int8_t **);
/* Compression instance */
struct comp_algo comp_algo_deflate = {
CRYPTO_DEFLATE_COMP, "Deflate",
90, deflate_compress,
deflate_decompress
};
/*
* And compression
*/
static u_int32_t
deflate_compress(data, size, out)
u_int8_t *data;
u_int32_t size;
u_int8_t **out;
{
return deflate_global(data, size, 0, out);
}
static u_int32_t
deflate_decompress(data, size, out)
u_int8_t *data;
u_int32_t size;
u_int8_t **out;
{
return deflate_global(data, size, 1, out);
}

116
sys/opencrypto/xform_des1.c Normal file
View File

@ -0,0 +1,116 @@
/* $OpenBSD: xform.c,v 1.16 2001/08/28 12:20:43 ben Exp $ */
/*-
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr),
* Niels Provos (provos@physnet.uni-hamburg.de) and
* Damien Miller (djm@mindrot.org).
*
* This code was written by John Ioannidis for BSD/OS in Athens, Greece,
* in November 1995.
*
* Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
* by Angelos D. Keromytis.
*
* Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
* and Niels Provos.
*
* Additional features in 1999 by Angelos D. Keromytis.
*
* AES XTS implementation in 2008 by Damien Miller
*
* Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
* Angelos D. Keromytis and Niels Provos.
*
* Copyright (C) 2001, Angelos D. Keromytis.
*
* Copyright (C) 2008, Damien Miller
* Copyright (c) 2014 The FreeBSD Foundation
* All rights reserved.
*
* Portions of this software were developed by John-Mark Gurney
* under sponsorship of the FreeBSD Foundation and
* Rubicon Communications, LLC (Netgate).
*
* Permission to use, copy, and modify this software with or without fee
* is hereby granted, provided that this entire notice is included in
* all copies of any software which is or includes a copy or
* modification of this software.
* You may use this code under the GNU public license if you so wish. Please
* contribute changes back to the authors under this freer than GPL license
* so that we may further the use of strong encryption without limitations to
* all.
*
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
* PURPOSE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <crypto/des/des.h>
#include <opencrypto/xform_enc.h>
static int des1_setkey(u_int8_t **, u_int8_t *, int);
static void des1_encrypt(caddr_t, u_int8_t *);
static void des1_decrypt(caddr_t, u_int8_t *);
static void des1_zerokey(u_int8_t **);
/* Encryption instances */
struct enc_xform enc_xform_des = {
CRYPTO_DES_CBC, "DES",
DES_BLOCK_LEN, DES_BLOCK_LEN, DES_MIN_KEY, DES_MAX_KEY,
des1_encrypt,
des1_decrypt,
des1_setkey,
des1_zerokey,
NULL,
};
/*
* Encryption wrapper routines.
*/
static void
des1_encrypt(caddr_t key, u_int8_t *blk)
{
des_cblock *cb = (des_cblock *) blk;
des_key_schedule *p = (des_key_schedule *) key;
des_ecb_encrypt(cb, cb, p[0], DES_ENCRYPT);
}
static void
des1_decrypt(caddr_t key, u_int8_t *blk)
{
des_cblock *cb = (des_cblock *) blk;
des_key_schedule *p = (des_key_schedule *) key;
des_ecb_encrypt(cb, cb, p[0], DES_DECRYPT);
}
static int
des1_setkey(u_int8_t **sched, u_int8_t *key, int len)
{
des_key_schedule *p;
int err;
p = KMALLOC(sizeof (des_key_schedule),
M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
if (p != NULL) {
des_set_key((des_cblock *) key, p[0]);
err = 0;
} else
err = ENOMEM;
*sched = (u_int8_t *) p;
return err;
}
static void
des1_zerokey(u_int8_t **sched)
{
bzero(*sched, sizeof (des_key_schedule));
KFREE(*sched, M_CRYPTO_DATA);
*sched = NULL;
}

119
sys/opencrypto/xform_des3.c Normal file
View File

@ -0,0 +1,119 @@
/* $OpenBSD: xform.c,v 1.16 2001/08/28 12:20:43 ben Exp $ */
/*-
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr),
* Niels Provos (provos@physnet.uni-hamburg.de) and
* Damien Miller (djm@mindrot.org).
*
* This code was written by John Ioannidis for BSD/OS in Athens, Greece,
* in November 1995.
*
* Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
* by Angelos D. Keromytis.
*
* Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
* and Niels Provos.
*
* Additional features in 1999 by Angelos D. Keromytis.
*
* AES XTS implementation in 2008 by Damien Miller
*
* Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
* Angelos D. Keromytis and Niels Provos.
*
* Copyright (C) 2001, Angelos D. Keromytis.
*
* Copyright (C) 2008, Damien Miller
* Copyright (c) 2014 The FreeBSD Foundation
* All rights reserved.
*
* Portions of this software were developed by John-Mark Gurney
* under sponsorship of the FreeBSD Foundation and
* Rubicon Communications, LLC (Netgate).
*
* Permission to use, copy, and modify this software with or without fee
* is hereby granted, provided that this entire notice is included in
* all copies of any software which is or includes a copy or
* modification of this software.
* You may use this code under the GNU public license if you so wish. Please
* contribute changes back to the authors under this freer than GPL license
* so that we may further the use of strong encryption without limitations to
* all.
*
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
* PURPOSE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <crypto/des/des.h>
#include <opencrypto/xform_enc.h>
static int des3_setkey(u_int8_t **, u_int8_t *, int);
static void des3_encrypt(caddr_t, u_int8_t *);
static void des3_decrypt(caddr_t, u_int8_t *);
static void des3_zerokey(u_int8_t **);
/* Encryption instances */
struct enc_xform enc_xform_3des = {
CRYPTO_3DES_CBC, "3DES",
DES3_BLOCK_LEN, DES3_BLOCK_LEN, TRIPLE_DES_MIN_KEY,
TRIPLE_DES_MAX_KEY,
des3_encrypt,
des3_decrypt,
des3_setkey,
des3_zerokey,
NULL,
};
/*
* Encryption wrapper routines.
*/
static void
des3_encrypt(caddr_t key, u_int8_t *blk)
{
des_cblock *cb = (des_cblock *) blk;
des_key_schedule *p = (des_key_schedule *) key;
des_ecb3_encrypt(cb, cb, p[0], p[1], p[2], DES_ENCRYPT);
}
static void
des3_decrypt(caddr_t key, u_int8_t *blk)
{
des_cblock *cb = (des_cblock *) blk;
des_key_schedule *p = (des_key_schedule *) key;
des_ecb3_encrypt(cb, cb, p[0], p[1], p[2], DES_DECRYPT);
}
static int
des3_setkey(u_int8_t **sched, u_int8_t *key, int len)
{
des_key_schedule *p;
int err;
p = KMALLOC(3*sizeof (des_key_schedule),
M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
if (p != NULL) {
des_set_key((des_cblock *)(key + 0), p[0]);
des_set_key((des_cblock *)(key + 8), p[1]);
des_set_key((des_cblock *)(key + 16), p[2]);
err = 0;
} else
err = ENOMEM;
*sched = (u_int8_t *) p;
return err;
}
static void
des3_zerokey(u_int8_t **sched)
{
bzero(*sched, 3*sizeof (des_key_schedule));
KFREE(*sched, M_CRYPTO_DATA);
*sched = NULL;
}

View File

@ -0,0 +1,92 @@
/* $FreeBSD$ */
/* $OpenBSD: xform.h,v 1.8 2001/08/28 12:20:43 ben Exp $ */
/*-
* The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
*
* This code was written by Angelos D. Keromytis in Athens, Greece, in
* February 2000. Network Security Technologies Inc. (NSTI) kindly
* supported the development of this code.
*
* Copyright (c) 2000 Angelos D. Keromytis
* Copyright (c) 2014 The FreeBSD Foundation
* All rights reserved.
*
* Portions of this software were developed by John-Mark Gurney
* under sponsorship of the FreeBSD Foundation and
* Rubicon Communications, LLC (Netgate).
*
* Permission to use, copy, and modify this software without fee
* is hereby granted, provided that this entire notice is included in
* all source code copies of any software which is or includes a copy or
* modification of this software.
*
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
* PURPOSE.
*/
#ifndef _CRYPTO_XFORM_ENC_H_
#define _CRYPTO_XFORM_ENC_H_
#include <sys/malloc.h>
#include <sys/errno.h>
#include <crypto/blowfish/blowfish.h>
#include <crypto/des/des.h>
#include <crypto/rijndael/rijndael.h>
#include <crypto/camellia/camellia.h>
#include <opencrypto/cast.h>
#include <opencrypto/skipjack.h>
#include <opencrypto/cryptodev.h>
#include <opencrypto/xform_userland.h>
#define AESICM_BLOCKSIZE AES_BLOCK_LEN
#define AES_XTS_BLOCKSIZE 16
#define AES_XTS_IVSIZE 8
#define AES_XTS_ALPHA 0x87 /* GF(2^128) generator polynomial */
/* Declarations */
struct enc_xform {
int type;
char *name;
u_int16_t blocksize;
u_int16_t ivsize;
u_int16_t minkey, maxkey;
void (*encrypt) (caddr_t, u_int8_t *);
void (*decrypt) (caddr_t, u_int8_t *);
int (*setkey) (u_int8_t **, u_int8_t *, int len);
void (*zerokey) (u_int8_t **);
void (*reinit) (caddr_t, u_int8_t *);
};
extern struct enc_xform enc_xform_null;
extern struct enc_xform enc_xform_des;
extern struct enc_xform enc_xform_3des;
extern struct enc_xform enc_xform_blf;
extern struct enc_xform enc_xform_cast5;
extern struct enc_xform enc_xform_skipjack;
extern struct enc_xform enc_xform_rijndael128;
extern struct enc_xform enc_xform_aes_icm;
extern struct enc_xform enc_xform_aes_nist_gcm;
extern struct enc_xform enc_xform_aes_nist_gmac;
extern struct enc_xform enc_xform_aes_xts;
extern struct enc_xform enc_xform_arc4;
extern struct enc_xform enc_xform_camellia;
struct aes_icm_ctx {
u_int32_t ac_ek[4*(RIJNDAEL_MAXNR + 1)];
/* ac_block is initalized to IV */
u_int8_t ac_block[AESICM_BLOCKSIZE];
int ac_nr;
};
struct aes_xts_ctx {
rijndael_ctx key1;
rijndael_ctx key2;
u_int8_t tweak[AES_XTS_BLOCKSIZE];
};
#endif /* _CRYPTO_XFORM_ENC_H_ */

View File

@ -0,0 +1,99 @@
/* $OpenBSD: xform.c,v 1.16 2001/08/28 12:20:43 ben Exp $ */
/*-
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr),
* Niels Provos (provos@physnet.uni-hamburg.de) and
* Damien Miller (djm@mindrot.org).
*
* This code was written by John Ioannidis for BSD/OS in Athens, Greece,
* in November 1995.
*
* Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
* by Angelos D. Keromytis.
*
* Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
* and Niels Provos.
*
* Additional features in 1999 by Angelos D. Keromytis.
*
* AES XTS implementation in 2008 by Damien Miller
*
* Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
* Angelos D. Keromytis and Niels Provos.
*
* Copyright (C) 2001, Angelos D. Keromytis.
*
* Copyright (C) 2008, Damien Miller
* Copyright (c) 2014 The FreeBSD Foundation
* All rights reserved.
*
* Portions of this software were developed by John-Mark Gurney
* under sponsorship of the FreeBSD Foundation and
* Rubicon Communications, LLC (Netgate).
*
* Permission to use, copy, and modify this software with or without fee
* is hereby granted, provided that this entire notice is included in
* all copies of any software which is or includes a copy or
* modification of this software.
* You may use this code under the GNU public license if you so wish. Please
* contribute changes back to the authors under this freer than GPL license
* so that we may further the use of strong encryption without limitations to
* all.
*
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
* PURPOSE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <opencrypto/gmac.h>
#include <opencrypto/xform_auth.h>
/* Encryption instances */
struct enc_xform enc_xform_aes_nist_gmac = {
CRYPTO_AES_NIST_GMAC, "AES-GMAC",
AES_ICM_BLOCK_LEN, AES_GCM_IV_LEN, AES_MIN_KEY, AES_MAX_KEY,
NULL,
NULL,
NULL,
NULL,
NULL,
};
/* Authentication instances */
struct auth_hash auth_hash_nist_gmac_aes_128 = {
CRYPTO_AES_128_NIST_GMAC, "GMAC-AES-128",
AES_128_GMAC_KEY_LEN, AES_GMAC_HASH_LEN, sizeof(struct aes_gmac_ctx),
GMAC_BLOCK_LEN,
(void (*)(void *)) AES_GMAC_Init,
(void (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Setkey,
(void (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Reinit,
(int (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Update,
(void (*)(u_int8_t *, void *)) AES_GMAC_Final
};
struct auth_hash auth_hash_nist_gmac_aes_192 = {
CRYPTO_AES_192_NIST_GMAC, "GMAC-AES-192",
AES_192_GMAC_KEY_LEN, AES_GMAC_HASH_LEN, sizeof(struct aes_gmac_ctx),
GMAC_BLOCK_LEN,
(void (*)(void *)) AES_GMAC_Init,
(void (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Setkey,
(void (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Reinit,
(int (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Update,
(void (*)(u_int8_t *, void *)) AES_GMAC_Final
};
struct auth_hash auth_hash_nist_gmac_aes_256 = {
CRYPTO_AES_256_NIST_GMAC, "GMAC-AES-256",
AES_256_GMAC_KEY_LEN, AES_GMAC_HASH_LEN, sizeof(struct aes_gmac_ctx),
GMAC_BLOCK_LEN,
(void (*)(void *)) AES_GMAC_Init,
(void (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Setkey,
(void (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Reinit,
(int (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Update,
(void (*)(u_int8_t *, void *)) AES_GMAC_Final
};

View File

@ -0,0 +1,81 @@
/* $OpenBSD: xform.c,v 1.16 2001/08/28 12:20:43 ben Exp $ */
/*-
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr),
* Niels Provos (provos@physnet.uni-hamburg.de) and
* Damien Miller (djm@mindrot.org).
*
* This code was written by John Ioannidis for BSD/OS in Athens, Greece,
* in November 1995.
*
* Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
* by Angelos D. Keromytis.
*
* Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
* and Niels Provos.
*
* Additional features in 1999 by Angelos D. Keromytis.
*
* AES XTS implementation in 2008 by Damien Miller
*
* Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
* Angelos D. Keromytis and Niels Provos.
*
* Copyright (C) 2001, Angelos D. Keromytis.
*
* Copyright (C) 2008, Damien Miller
* Copyright (c) 2014 The FreeBSD Foundation
* All rights reserved.
*
* Portions of this software were developed by John-Mark Gurney
* under sponsorship of the FreeBSD Foundation and
* Rubicon Communications, LLC (Netgate).
*
* Permission to use, copy, and modify this software with or without fee
* is hereby granted, provided that this entire notice is included in
* all copies of any software which is or includes a copy or
* modification of this software.
* You may use this code under the GNU public license if you so wish. Please
* contribute changes back to the authors under this freer than GPL license
* so that we may further the use of strong encryption without limitations to
* all.
*
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
* PURPOSE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/md5.h>
#include <opencrypto/xform_auth.h>
static int MD5Update_int(void *, const u_int8_t *, u_int16_t);
/* Authentication instances */
struct auth_hash auth_hash_hmac_md5 = {
CRYPTO_MD5_HMAC, "HMAC-MD5",
MD5_HMAC_KEY_LEN, MD5_HASH_LEN, sizeof(MD5_CTX), MD5_HMAC_BLOCK_LEN,
(void (*) (void *)) MD5Init, NULL, NULL, MD5Update_int,
(void (*) (u_int8_t *, void *)) MD5Final
};
struct auth_hash auth_hash_key_md5 = {
CRYPTO_MD5_KPDK, "Keyed MD5",
NULL_HMAC_KEY_LEN, MD5_KPDK_HASH_LEN, sizeof(MD5_CTX), 0,
(void (*)(void *)) MD5Init, NULL, NULL, MD5Update_int,
(void (*)(u_int8_t *, void *)) MD5Final
};
/*
* And now for auth.
*/
static int
MD5Update_int(void *ctx, const u_int8_t *buf, u_int16_t len)
{
MD5Update(ctx, buf, len);
return 0;
}

136
sys/opencrypto/xform_null.c Normal file
View File

@ -0,0 +1,136 @@
/* $OpenBSD: xform.c,v 1.16 2001/08/28 12:20:43 ben Exp $ */
/*-
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr),
* Niels Provos (provos@physnet.uni-hamburg.de) and
* Damien Miller (djm@mindrot.org).
*
* This code was written by John Ioannidis for BSD/OS in Athens, Greece,
* in November 1995.
*
* Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
* by Angelos D. Keromytis.
*
* Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
* and Niels Provos.
*
* Additional features in 1999 by Angelos D. Keromytis.
*
* AES XTS implementation in 2008 by Damien Miller
*
* Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
* Angelos D. Keromytis and Niels Provos.
*
* Copyright (C) 2001, Angelos D. Keromytis.
*
* Copyright (C) 2008, Damien Miller
* Copyright (c) 2014 The FreeBSD Foundation
* All rights reserved.
*
* Portions of this software were developed by John-Mark Gurney
* under sponsorship of the FreeBSD Foundation and
* Rubicon Communications, LLC (Netgate).
*
* Permission to use, copy, and modify this software with or without fee
* is hereby granted, provided that this entire notice is included in
* all copies of any software which is or includes a copy or
* modification of this software.
* You may use this code under the GNU public license if you so wish. Please
* contribute changes back to the authors under this freer than GPL license
* so that we may further the use of strong encryption without limitations to
* all.
*
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
* PURPOSE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <opencrypto/xform_auth.h>
#include <opencrypto/xform_enc.h>
static int null_setkey(u_int8_t **, u_int8_t *, int);
static void null_encrypt(caddr_t, u_int8_t *);
static void null_decrypt(caddr_t, u_int8_t *);
static void null_zerokey(u_int8_t **);
static void null_init(void *);
static void null_reinit(void *ctx, const u_int8_t *buf, u_int16_t len);
static int null_update(void *, const u_int8_t *, u_int16_t);
static void null_final(u_int8_t *, void *);
/* Encryption instances */
struct enc_xform enc_xform_null = {
CRYPTO_NULL_CBC, "NULL",
/* NB: blocksize of 4 is to generate a properly aligned ESP header */
NULL_BLOCK_LEN, 0, NULL_MIN_KEY, NULL_MAX_KEY,
null_encrypt,
null_decrypt,
null_setkey,
null_zerokey,
NULL,
};
/* Authentication instances */
struct auth_hash auth_hash_null = { /* NB: context isn't used */
CRYPTO_NULL_HMAC, "NULL-HMAC",
NULL_HMAC_KEY_LEN, NULL_HASH_LEN, sizeof(int), NULL_HMAC_BLOCK_LEN,
null_init, null_reinit, null_reinit, null_update, null_final
};
/*
* Encryption wrapper routines.
*/
static void
null_encrypt(caddr_t key, u_int8_t *blk)
{
}
static void
null_decrypt(caddr_t key, u_int8_t *blk)
{
}
static int
null_setkey(u_int8_t **sched, u_int8_t *key, int len)
{
*sched = NULL;
return 0;
}
static void
null_zerokey(u_int8_t **sched)
{
*sched = NULL;
}
/*
* And now for auth.
*/
static void
null_init(void *ctx)
{
}
static void
null_reinit(void *ctx, const u_int8_t *buf, u_int16_t len)
{
}
static int
null_update(void *ctx, const u_int8_t *buf, u_int16_t len)
{
return 0;
}
static void
null_final(u_int8_t *buf, void *ctx)
{
if (buf != (u_int8_t *) 0)
bzero(buf, 12);
}

View File

@ -0,0 +1,113 @@
/* $OpenBSD: xform.c,v 1.16 2001/08/28 12:20:43 ben Exp $ */
/*-
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr),
* Niels Provos (provos@physnet.uni-hamburg.de) and
* Damien Miller (djm@mindrot.org).
*
* This code was written by John Ioannidis for BSD/OS in Athens, Greece,
* in November 1995.
*
* Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
* by Angelos D. Keromytis.
*
* Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
* and Niels Provos.
*
* Additional features in 1999 by Angelos D. Keromytis.
*
* AES XTS implementation in 2008 by Damien Miller
*
* Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
* Angelos D. Keromytis and Niels Provos.
*
* Copyright (C) 2001, Angelos D. Keromytis.
*
* Copyright (C) 2008, Damien Miller
* Copyright (c) 2014 The FreeBSD Foundation
* All rights reserved.
*
* Portions of this software were developed by John-Mark Gurney
* under sponsorship of the FreeBSD Foundation and
* Rubicon Communications, LLC (Netgate).
*
* Permission to use, copy, and modify this software with or without fee
* is hereby granted, provided that this entire notice is included in
* all copies of any software which is or includes a copy or
* modification of this software.
* You may use this code under the GNU public license if you so wish. Please
* contribute changes back to the authors under this freer than GPL license
* so that we may further the use of strong encryption without limitations to
* all.
*
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
* PURPOSE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <crypto/rijndael/rijndael.h>
#include <opencrypto/xform_enc.h>
static int rijndael128_setkey(u_int8_t **, u_int8_t *, int);
static void rijndael128_encrypt(caddr_t, u_int8_t *);
static void rijndael128_decrypt(caddr_t, u_int8_t *);
static void rijndael128_zerokey(u_int8_t **);
/* Encryption instances */
struct enc_xform enc_xform_rijndael128 = {
CRYPTO_RIJNDAEL128_CBC, "Rijndael-128/AES",
RIJNDAEL128_BLOCK_LEN, RIJNDAEL128_BLOCK_LEN, RIJNDAEL_MIN_KEY,
RIJNDAEL_MAX_KEY,
rijndael128_encrypt,
rijndael128_decrypt,
rijndael128_setkey,
rijndael128_zerokey,
NULL,
};
/*
* Encryption wrapper routines.
*/
static void
rijndael128_encrypt(caddr_t key, u_int8_t *blk)
{
rijndael_encrypt((rijndael_ctx *) key, (u_char *) blk, (u_char *) blk);
}
static void
rijndael128_decrypt(caddr_t key, u_int8_t *blk)
{
rijndael_decrypt(((rijndael_ctx *) key), (u_char *) blk,
(u_char *) blk);
}
static int
rijndael128_setkey(u_int8_t **sched, u_int8_t *key, int len)
{
int err;
if (len != 16 && len != 24 && len != 32)
return (EINVAL);
*sched = KMALLOC(sizeof(rijndael_ctx), M_CRYPTO_DATA,
M_NOWAIT|M_ZERO);
if (*sched != NULL) {
rijndael_set_key((rijndael_ctx *) *sched, (u_char *) key,
len * 8);
err = 0;
} else
err = ENOMEM;
return err;
}
static void
rijndael128_zerokey(u_int8_t **sched)
{
bzero(*sched, sizeof(rijndael_ctx));
KFREE(*sched, M_CRYPTO_DATA);
*sched = NULL;
}

View File

@ -0,0 +1,75 @@
/* $OpenBSD: xform.c,v 1.16 2001/08/28 12:20:43 ben Exp $ */
/*-
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr),
* Niels Provos (provos@physnet.uni-hamburg.de) and
* Damien Miller (djm@mindrot.org).
*
* This code was written by John Ioannidis for BSD/OS in Athens, Greece,
* in November 1995.
*
* Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
* by Angelos D. Keromytis.
*
* Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
* and Niels Provos.
*
* Additional features in 1999 by Angelos D. Keromytis.
*
* AES XTS implementation in 2008 by Damien Miller
*
* Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
* Angelos D. Keromytis and Niels Provos.
*
* Copyright (C) 2001, Angelos D. Keromytis.
*
* Copyright (C) 2008, Damien Miller
* Copyright (c) 2014 The FreeBSD Foundation
* All rights reserved.
*
* Portions of this software were developed by John-Mark Gurney
* under sponsorship of the FreeBSD Foundation and
* Rubicon Communications, LLC (Netgate).
*
* Permission to use, copy, and modify this software with or without fee
* is hereby granted, provided that this entire notice is included in
* all copies of any software which is or includes a copy or
* modification of this software.
* You may use this code under the GNU public license if you so wish. Please
* contribute changes back to the authors under this freer than GPL license
* so that we may further the use of strong encryption without limitations to
* all.
*
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
* PURPOSE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <opencrypto/rmd160.h>
#include <opencrypto/xform_auth.h>
static int RMD160Update_int(void *, const u_int8_t *, u_int16_t);
/* Authentication instances */
struct auth_hash auth_hash_hmac_ripemd_160 = {
CRYPTO_RIPEMD160_HMAC, "HMAC-RIPEMD-160",
RIPEMD160_HMAC_KEY_LEN, RIPEMD160_HASH_LEN, sizeof(RMD160_CTX),
RIPEMD160_HMAC_BLOCK_LEN,
(void (*)(void *)) RMD160Init, NULL, NULL, RMD160Update_int,
(void (*)(u_int8_t *, void *)) RMD160Final
};
/*
* And now for auth.
*/
static int
RMD160Update_int(void *ctx, const u_int8_t *buf, u_int16_t len)
{
RMD160Update(ctx, buf, len);
return 0;
}

View File

@ -0,0 +1,93 @@
/* $OpenBSD: xform.c,v 1.16 2001/08/28 12:20:43 ben Exp $ */
/*-
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr),
* Niels Provos (provos@physnet.uni-hamburg.de) and
* Damien Miller (djm@mindrot.org).
*
* This code was written by John Ioannidis for BSD/OS in Athens, Greece,
* in November 1995.
*
* Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
* by Angelos D. Keromytis.
*
* Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
* and Niels Provos.
*
* Additional features in 1999 by Angelos D. Keromytis.
*
* AES XTS implementation in 2008 by Damien Miller
*
* Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
* Angelos D. Keromytis and Niels Provos.
*
* Copyright (C) 2001, Angelos D. Keromytis.
*
* Copyright (C) 2008, Damien Miller
* Copyright (c) 2014 The FreeBSD Foundation
* All rights reserved.
*
* Portions of this software were developed by John-Mark Gurney
* under sponsorship of the FreeBSD Foundation and
* Rubicon Communications, LLC (Netgate).
*
* Permission to use, copy, and modify this software with or without fee
* is hereby granted, provided that this entire notice is included in
* all copies of any software which is or includes a copy or
* modification of this software.
* You may use this code under the GNU public license if you so wish. Please
* contribute changes back to the authors under this freer than GPL license
* so that we may further the use of strong encryption without limitations to
* all.
*
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
* PURPOSE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <crypto/sha1.h>
#include <opencrypto/xform_auth.h>
static void SHA1Init_int(void *);
static int SHA1Update_int(void *, const u_int8_t *, u_int16_t);
static void SHA1Final_int(u_int8_t *, void *);
/* Authentication instances */
struct auth_hash auth_hash_hmac_sha1 = {
CRYPTO_SHA1_HMAC, "HMAC-SHA1",
SHA1_HMAC_KEY_LEN, SHA1_HASH_LEN, sizeof(SHA1_CTX), SHA1_HMAC_BLOCK_LEN,
SHA1Init_int, NULL, NULL, SHA1Update_int, SHA1Final_int
};
struct auth_hash auth_hash_key_sha1 = {
CRYPTO_SHA1_KPDK, "Keyed SHA1",
NULL_HMAC_KEY_LEN, SHA1_KPDK_HASH_LEN, sizeof(SHA1_CTX), 0,
SHA1Init_int, NULL, NULL, SHA1Update_int, SHA1Final_int
};
/*
* And now for auth.
*/
static void
SHA1Init_int(void *ctx)
{
SHA1Init(ctx);
}
static int
SHA1Update_int(void *ctx, const u_int8_t *buf, u_int16_t len)
{
SHA1Update(ctx, buf, len);
return 0;
}
static void
SHA1Final_int(u_int8_t *blk, void *ctx)
{
SHA1Final(blk, ctx);
}

109
sys/opencrypto/xform_sha2.c Normal file
View File

@ -0,0 +1,109 @@
/* $OpenBSD: xform.c,v 1.16 2001/08/28 12:20:43 ben Exp $ */
/*-
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr),
* Niels Provos (provos@physnet.uni-hamburg.de) and
* Damien Miller (djm@mindrot.org).
*
* This code was written by John Ioannidis for BSD/OS in Athens, Greece,
* in November 1995.
*
* Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
* by Angelos D. Keromytis.
*
* Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
* and Niels Provos.
*
* Additional features in 1999 by Angelos D. Keromytis.
*
* AES XTS implementation in 2008 by Damien Miller
*
* Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
* Angelos D. Keromytis and Niels Provos.
*
* Copyright (C) 2001, Angelos D. Keromytis.
*
* Copyright (C) 2008, Damien Miller
* Copyright (c) 2014 The FreeBSD Foundation
* All rights reserved.
*
* Portions of this software were developed by John-Mark Gurney
* under sponsorship of the FreeBSD Foundation and
* Rubicon Communications, LLC (Netgate).
*
* Permission to use, copy, and modify this software with or without fee
* is hereby granted, provided that this entire notice is included in
* all copies of any software which is or includes a copy or
* modification of this software.
* You may use this code under the GNU public license if you so wish. Please
* contribute changes back to the authors under this freer than GPL license
* so that we may further the use of strong encryption without limitations to
* all.
*
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
* PURPOSE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <crypto/sha2/sha256.h>
#include <crypto/sha2/sha384.h>
#include <crypto/sha2/sha512.h>
#include <opencrypto/xform_auth.h>
static int SHA256Update_int(void *, const u_int8_t *, u_int16_t);
static int SHA384Update_int(void *, const u_int8_t *, u_int16_t);
static int SHA512Update_int(void *, const u_int8_t *, u_int16_t);
/* Authentication instances */
struct auth_hash auth_hash_hmac_sha2_256 = {
CRYPTO_SHA2_256_HMAC, "HMAC-SHA2-256",
SHA2_256_HMAC_KEY_LEN, SHA2_256_HASH_LEN, sizeof(SHA256_CTX),
SHA2_256_HMAC_BLOCK_LEN,
(void (*)(void *)) SHA256_Init, NULL, NULL, SHA256Update_int,
(void (*)(u_int8_t *, void *)) SHA256_Final
};
struct auth_hash auth_hash_hmac_sha2_384 = {
CRYPTO_SHA2_384_HMAC, "HMAC-SHA2-384",
SHA2_384_HMAC_KEY_LEN, SHA2_384_HASH_LEN, sizeof(SHA384_CTX),
SHA2_384_HMAC_BLOCK_LEN,
(void (*)(void *)) SHA384_Init, NULL, NULL, SHA384Update_int,
(void (*)(u_int8_t *, void *)) SHA384_Final
};
struct auth_hash auth_hash_hmac_sha2_512 = {
CRYPTO_SHA2_512_HMAC, "HMAC-SHA2-512",
SHA2_512_HMAC_KEY_LEN, SHA2_512_HASH_LEN, sizeof(SHA512_CTX),
SHA2_512_HMAC_BLOCK_LEN,
(void (*)(void *)) SHA512_Init, NULL, NULL, SHA512Update_int,
(void (*)(u_int8_t *, void *)) SHA512_Final
};
/*
* And now for auth.
*/
static int
SHA256Update_int(void *ctx, const u_int8_t *buf, u_int16_t len)
{
SHA256_Update(ctx, buf, len);
return 0;
}
static int
SHA384Update_int(void *ctx, const u_int8_t *buf, u_int16_t len)
{
SHA384_Update(ctx, buf, len);
return 0;
}
static int
SHA512Update_int(void *ctx, const u_int8_t *buf, u_int16_t len)
{
SHA512_Update(ctx, buf, len);
return 0;
}

View File

@ -0,0 +1,117 @@
/* $OpenBSD: xform.c,v 1.16 2001/08/28 12:20:43 ben Exp $ */
/*-
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr),
* Niels Provos (provos@physnet.uni-hamburg.de) and
* Damien Miller (djm@mindrot.org).
*
* This code was written by John Ioannidis for BSD/OS in Athens, Greece,
* in November 1995.
*
* Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
* by Angelos D. Keromytis.
*
* Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
* and Niels Provos.
*
* Additional features in 1999 by Angelos D. Keromytis.
*
* AES XTS implementation in 2008 by Damien Miller
*
* Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
* Angelos D. Keromytis and Niels Provos.
*
* Copyright (C) 2001, Angelos D. Keromytis.
*
* Copyright (C) 2008, Damien Miller
* Copyright (c) 2014 The FreeBSD Foundation
* All rights reserved.
*
* Portions of this software were developed by John-Mark Gurney
* under sponsorship of the FreeBSD Foundation and
* Rubicon Communications, LLC (Netgate).
*
* Permission to use, copy, and modify this software with or without fee
* is hereby granted, provided that this entire notice is included in
* all copies of any software which is or includes a copy or
* modification of this software.
* You may use this code under the GNU public license if you so wish. Please
* contribute changes back to the authors under this freer than GPL license
* so that we may further the use of strong encryption without limitations to
* all.
*
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
* PURPOSE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <opencrypto/skipjack.h>
#include <opencrypto/xform_enc.h>
static int skipjack_setkey(u_int8_t **, u_int8_t *, int);
static void skipjack_encrypt(caddr_t, u_int8_t *);
static void skipjack_decrypt(caddr_t, u_int8_t *);
static void skipjack_zerokey(u_int8_t **);
/* Encryption instances */
struct enc_xform enc_xform_skipjack = {
CRYPTO_SKIPJACK_CBC, "Skipjack",
SKIPJACK_BLOCK_LEN, SKIPJACK_BLOCK_LEN, SKIPJACK_MIN_KEY,
SKIPJACK_MAX_KEY,
skipjack_encrypt,
skipjack_decrypt, skipjack_setkey,
skipjack_zerokey,
NULL,
};
/*
* Encryption wrapper routines.
*/
static void
skipjack_encrypt(caddr_t key, u_int8_t *blk)
{
skipjack_forwards(blk, blk, (u_int8_t **) key);
}
static void
skipjack_decrypt(caddr_t key, u_int8_t *blk)
{
skipjack_backwards(blk, blk, (u_int8_t **) key);
}
static int
skipjack_setkey(u_int8_t **sched, u_int8_t *key, int len)
{
int err;
/* NB: allocate all the memory that's needed at once */
*sched = KMALLOC(10 * (sizeof(u_int8_t *) + 0x100),
M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
if (*sched != NULL) {
u_int8_t** key_tables = (u_int8_t**) *sched;
u_int8_t* table = (u_int8_t*) &key_tables[10];
int k;
for (k = 0; k < 10; k++) {
key_tables[k] = table;
table += 0x100;
}
subkey_table_gen(key, (u_int8_t **) *sched);
err = 0;
} else
err = ENOMEM;
return err;
}
static void
skipjack_zerokey(u_int8_t **sched)
{
bzero(*sched, 10 * (sizeof(u_int8_t *) + 0x100));
KFREE(*sched, M_CRYPTO_DATA);
*sched = NULL;
}

View File

@ -0,0 +1,48 @@
/*-
* Copyright (c) 2015 Allan Jude <allanjude@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _CRYPTO_XFORM_USERLAND_H_
#define _CRYPTO_XFORM_USERLAND_H_
#ifdef _KERNEL
#include <sys/systm.h>
#define KMALLOC(size, type, flags) malloc(size, type, flags)
#define KFREE(ptr, type) free(ptr, type)
#else /* not _KERNEL */
#ifdef _STAND
#include <stand.h>
#else /* !_STAND */
#include <stdlib.h>
#include <string.h>
#endif /* _STAND */
#define KMALLOC(size, type, flags) malloc(size)
#define KFREE(ptr, type) free(ptr)
#endif /* _KERNEL */
#endif /* _CRYPTO_XFORM_USERLAND_H_ */

View File

@ -59,7 +59,7 @@ l2: add r2, 1, r3 ; \
add r1, r2, r1 ; \
rd %tick, r2 ; \
stx r2, [r1 + KTR_TIMESTAMP] ; \
lduw [PCPU(MID)], r2 ; \
lduw [PCPU(CPUID)], r2 ; \
stw r2, [r1 + KTR_CPU] ; \
stw %g0, [r1 + KTR_LINE] ; \
stx %g0, [r1 + KTR_FILE] ; \

View File

@ -1,5 +1,5 @@
/*-
* Copyright (C) 1992-2015 The FreeBSD Project. All rights reserved.
* Copyright (C) 1992-2016 The FreeBSD Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -34,7 +34,7 @@
/* FreeBSD */
#define COPYRIGHT_FreeBSD \
"Copyright (c) 1992-2015 The FreeBSD Project.\n"
"Copyright (c) 1992-2016 The FreeBSD Project.\n"
/* Foundation */
#define TRADEMARK_Foundation \

View File

@ -58,7 +58,7 @@
* in the range 5 to 9.
*/
#undef __FreeBSD_version
#define __FreeBSD_version 1100092 /* Master, propagated to newvers */
#define __FreeBSD_version 1100093 /* Master, propagated to newvers */
/*
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,

View File

@ -561,7 +561,6 @@ xenbusb_devices_changed(struct xs_watch *watch, const char **vec,
struct xenbusb_softc *xbs;
device_t dev;
char *node;
char *bus;
char *type;
char *id;
char *p;
@ -580,7 +579,6 @@ xenbusb_devices_changed(struct xs_watch *watch, const char **vec,
p = strchr(node, '/');
if (p == NULL)
goto out;
bus = node;
*p = 0;
type = p + 1;

View File

@ -109,7 +109,7 @@ samefile(struct stat *sb1, struct stat *sb2)
}
static void
sendfd_payload(int sockfd, int sendfd, void *payload, size_t paylen)
sendfd_payload(int sockfd, int send_fd, void *payload, size_t paylen)
{
struct iovec iovec;
char message[CMSG_SPACE(sizeof(int))];
@ -133,7 +133,7 @@ sendfd_payload(int sockfd, int sendfd, void *payload, size_t paylen)
cmsghdr->cmsg_len = CMSG_LEN(sizeof(int));
cmsghdr->cmsg_level = SOL_SOCKET;
cmsghdr->cmsg_type = SCM_RIGHTS;
memcpy(CMSG_DATA(cmsghdr), &sendfd, sizeof(int));
memcpy(CMSG_DATA(cmsghdr), &send_fd, sizeof(int));
len = sendmsg(sockfd, &msghdr, 0);
ATF_REQUIRE_MSG(len != -1, "sendmsg failed: %s", strerror(errno));
@ -143,15 +143,15 @@ sendfd_payload(int sockfd, int sendfd, void *payload, size_t paylen)
}
static void
sendfd(int sockfd, int sendfd)
sendfd(int sockfd, int send_fd)
{
char ch = 0;
return (sendfd_payload(sockfd, sendfd, &ch, sizeof(ch)));
return (sendfd_payload(sockfd, send_fd, &ch, sizeof(ch)));
}
static void
recvfd_payload(int sockfd, int *recvfd, void *buf, size_t buflen)
recvfd_payload(int sockfd, int *recv_fd, void *buf, size_t buflen)
{
struct cmsghdr *cmsghdr;
char message[CMSG_SPACE(SOCKCREDSIZE(CMGROUP_MAX)) + sizeof(int)];
@ -178,25 +178,25 @@ recvfd_payload(int sockfd, int *recvfd, void *buf, size_t buflen)
cmsghdr = CMSG_FIRSTHDR(&msghdr);
ATF_REQUIRE_MSG(cmsghdr != NULL,
"recvmsg: did not receive control message");
*recvfd = -1;
*recv_fd = -1;
for (; cmsghdr != NULL; cmsghdr = CMSG_NXTHDR(&msghdr, cmsghdr)) {
if (cmsghdr->cmsg_level == SOL_SOCKET &&
cmsghdr->cmsg_type == SCM_RIGHTS &&
cmsghdr->cmsg_len == CMSG_LEN(sizeof(int))) {
memcpy(recvfd, CMSG_DATA(cmsghdr), sizeof(int));
ATF_REQUIRE(*recvfd != -1);
memcpy(recv_fd, CMSG_DATA(cmsghdr), sizeof(int));
ATF_REQUIRE(*recv_fd != -1);
}
}
ATF_REQUIRE_MSG(*recvfd != -1,
ATF_REQUIRE_MSG(*recv_fd != -1,
"recvmsg: did not receive single-fd message");
}
static void
recvfd(int sockfd, int *recvfd)
recvfd(int sockfd, int *recv_fd)
{
char ch = 0;
return (recvfd_payload(sockfd, recvfd, &ch, sizeof(ch)));
return (recvfd_payload(sockfd, recv_fd, &ch, sizeof(ch)));
}
/*

View File

@ -310,14 +310,13 @@ static int
vmexit_inout(struct vmctx *ctx, struct vm_exit *vme, int *pvcpu)
{
int error;
int bytes, port, in, out, string;
int bytes, port, in, out;
int vcpu;
vcpu = *pvcpu;
port = vme->u.inout.port;
bytes = vme->u.inout.bytes;
string = vme->u.inout.string;
in = vme->u.inout.in;
out = !in;
@ -599,7 +598,7 @@ static vmexit_handler_t handler[VM_EXITCODE_MAX] = {
static void
vm_loop(struct vmctx *ctx, int vcpu, uint64_t startrip)
{
int error, rc, prevcpu;
int error, rc;
enum vm_exitcode exitcode;
cpuset_t active_cpus;
@ -620,8 +619,6 @@ vm_loop(struct vmctx *ctx, int vcpu, uint64_t startrip)
if (error != 0)
break;
prevcpu = vcpu;
exitcode = vmexit[vcpu].exitcode;
if (exitcode >= VM_EXITCODE_MAX || handler[exitcode] == NULL) {
fprintf(stderr, "vm_loop: unexpected exitcode 0x%x\n",
@ -629,7 +626,7 @@ vm_loop(struct vmctx *ctx, int vcpu, uint64_t startrip)
exit(1);
}
rc = (*handler[exitcode])(ctx, &vmexit[vcpu], &vcpu);
rc = (*handler[exitcode])(ctx, &vmexit[vcpu], &vcpu);
switch (rc) {
case VMEXIT_CONTINUE:

View File

@ -863,10 +863,9 @@ msixcap_cfgwrite(struct pci_devinst *pi, int capoff, int offset,
int bytes, uint32_t val)
{
uint16_t msgctrl, rwmask;
int off, table_bar;
int off;
off = offset - capoff;
table_bar = pi->pi_msix.table_bar;
/* Message Control Register */
if (off == 2 && bytes == 2) {
rwmask = PCIM_MSIXCTRL_MSIX_ENABLE | PCIM_MSIXCTRL_FUNCTION_MASK;

View File

@ -1276,7 +1276,6 @@ camdd_probe_pass(struct cam_device *cam_dev, struct camdd_io_opts *io_opts,
struct camdd_dev_pass *pass_dev;
struct kevent ke;
int scsi_dev_type;
int retval;
dev = NULL;
@ -1336,7 +1335,6 @@ camdd_probe_pass(struct cam_device *cam_dev, struct camdd_io_opts *io_opts,
if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
cam_error_print(cam_dev, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
retval = 1;
goto bailout;
}
@ -1371,11 +1369,8 @@ camdd_probe_pass(struct cam_device *cam_dev, struct camdd_io_opts *io_opts,
if (cam_send_ccb(cam_dev, ccb) < 0) {
warn("error sending READ CAPACITY (16) command");
cam_error_print(cam_dev, ccb, CAM_ESF_ALL,
CAM_EPF_ALL, stderr);
retval = 1;
goto bailout;
}