Skip to content

Commit

Permalink
Import CRYPTOGAMS ASM code (from OpenSSL 3.0.0-beta1)
Browse files Browse the repository at this point in the history
The CRYPTOGAMS code is suitably licensed for use in OpenConnect under
LGPLv2.1, and gives us a 40% speedup to ESP AES-SHA1 encryption.

However, not everything is in the standalone CRYPTOGAMS repository, so
we have to import from OpenSSL itself for now, which means the licence
is incompatible.

Once dot-asm/cryptogams#7 is resolved, we can
do this for real. But for now it's worth having it to experiment with.

Really needs SHA256 too...

Signed-off-by: David Woodhouse <[email protected]>
  • Loading branch information
dwmw2 committed Jul 2, 2021
1 parent 3629c27 commit d3ebd62
Show file tree
Hide file tree
Showing 11 changed files with 11,311 additions and 4 deletions.
11 changes: 10 additions & 1 deletion Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ library_srcs += $(lib_srcs_juniper) $(lib_srcs_cisco) $(lib_srcs_oath) \
$(lib_srcs_f5) $(lib_srcs_fortinet) $(lib_srcs_json) \
$(lib_srcs_array)

lib_srcs_aesni = aesni-esp.c aesni-esp.h
lib_srcs_gnutls = gnutls.c gnutls_tpm.c gnutls_tpm2.c
lib_srcs_openssl = openssl.c openssl-pkcs11.c
lib_srcs_win32 = wintun.c tun-win32.c sspi.c
Expand All @@ -69,7 +70,7 @@ lib_srcs_vhost = vhost.c

POTFILES = $(openconnect_SOURCES) gnutls-esp.c gnutls-dtls.c openssl-esp.c openssl-dtls.c \
$(lib_srcs_esp) $(lib_srcs_dtls) gnutls_tpm2_esys.c gnutls_tpm2_ibm.c \
$(lib_srcs_openssl) $(lib_srcs_gnutls) $(library_srcs) \
$(lib_srcs_openssl) $(lib_srcs_gnutls) $(library_srcs) $(lib_srcs_aesni) \
$(lib_srcs_win32) $(lib_srcs_posix) $(lib_srcs_gssapi) $(lib_srcs_iconv) \
$(lib_srcs_yubikey) $(lib_srcs_stoken) $(lib_srcs_oidc) $(lib_srcs_vhost)

Expand Down Expand Up @@ -104,6 +105,9 @@ endif
if OPENCONNECT_DTLS
lib_srcs_cisco += $(lib_srcs_dtls)
endif
if OPENCONNECT_AESNI
lib_srcs_esp += x86_64cpuid.s aesni-sha1-x86_64.s aesni-x86_64.s sha1-x86_64.s $(lib_srcs_aesni)
endif
if OPENCONNECT_ESP
lib_srcs_juniper += $(lib_srcs_esp)
endif
Expand Down Expand Up @@ -184,6 +188,11 @@ bashcompletion_DATA = bash/openconnect
# main.c includes version.c
openconnect-main.$(OBJEXT): version.c

# s/OPENSSL/OPENCONNECT/ here instead of doing it in the .pl files, so
# that they can remain pristine copies from upstream.
%.s: aesni/%.pl
CC="$(CC)" $(PERL) $< $(AESNI_FLAVOUR) | sed s/OPENSSL_ia32/OPENCONNECT_ia32/g > $@

version.c: $(library_srcs) $(lib_openssl_srcs) $(lib_gnutls_srcs) \
$(openconnect_SOURCES) Makefile.am configure.ac \
openconnect.h openconnect-internal.h version.sh @GITVERSIONDEPS@
Expand Down
48 changes: 48 additions & 0 deletions aesni-esp.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* OpenConnect (SSL + DTLS) VPN client
*
* Copyright © 2019 David Woodhouse
*
* Author: David Woodhouse <[email protected]>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* version 2.1, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/

#include <config.h>

#include "openconnect-internal.h"

#include "aesni-esp.h"

#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>

uint64_t OPENCONNECT_ia32cap_P[2];

int aesni_init_esp_ciphers(struct openconnect_info *vpninfo,
struct esp *esp_out, struct esp *esp_in)
{
if (!(OPENCONNECT_ia32cap_P[0] & (1<<10))) {
uint64_t cap = OPENCONNECT_ia32_cpuid(OPENCONNECT_ia32cap_P);

OPENCONNECT_ia32cap_P[0] = cap | (1<<10);

vpn_progress(vpninfo, PRG_DEBUG,
_("CPU capabilities: %08lx %08lx %08lx %08lx\n"),
OPENCONNECT_ia32cap_P[0] & 0xffffffff,
OPENCONNECT_ia32cap_P[0] >> 32,
OPENCONNECT_ia32cap_P[1] & 0xffffffff,
OPENCONNECT_ia32cap_P[1] >> 32);
}

return -EINVAL;
}
61 changes: 61 additions & 0 deletions aesni-esp.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* OpenConnect (SSL + DTLS) VPN client
*
* Copyright © 2019 David Woodhouse
*
* Author: David Woodhouse <[email protected]>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* version 2.1, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/

#ifndef __AESNI_ESP_H__
#define __AESNI_ESP_H__

/* ABI definitions for the CRYPTOGAMS routines */

#define AES_MAXKEYBITS 256
#define AES_MAXROUNDS 14
#define AES_BLOCK 16

struct aesni_key {
uint32_t rd_key[4 * (AES_MAXROUNDS + 1)];
int rounds;
};

/* Not literally AES-NI but we are only using this in the context of the
stitched AES-NI + SHA1 routines. */

#define SHA1_BLOCK 64

struct aesni_sha1 {
uint32_t h0, h1, h2, h3, h4;
uint64_t N; /* The CRYPTOGAMS routines don't touch this */
};


int aesni_set_encrypt_key (const unsigned char *userKey, int bits,
struct aesni_key *key);
int aesni_set_decrypt_key (const unsigned char *userKey, int bits,
struct aesni_key *key);

void aesni_cbc_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const struct aesni_key *key,
unsigned char *ivec, int enc);

void aesni_cbc_sha1_enc(const void *inp, void *out, size_t blocks,
const struct aesni_key *key, unsigned char iv[16],
const struct aesni_sha1 *ctx, const void *in0);

void sha1_block_data_order(struct aesni_sha1 *ctx, const void *p,
size_t n_blocks);

uint64_t OPENCONNECT_ia32_cpuid(uint64_t *cap);

#endif /* AESNI_ESP_H__ */
Loading

0 comments on commit d3ebd62

Please sign in to comment.