mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-27 14:58:30 +00:00
Initial import
This commit is contained in:
commit
c91b3c5006
14915 changed files with 590219 additions and 0 deletions
56
libc/crypto/crypto.mk
Normal file
56
libc/crypto/crypto.mk
Normal file
|
@ -0,0 +1,56 @@
|
|||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
||||
|
||||
PKGS += LIBC_CRYPTO
|
||||
|
||||
LIBC_CRYPTO_ARTIFACTS += LIBC_CRYPTO_A
|
||||
LIBC_CRYPTO = $(LIBC_CRYPTO_A_DEPS) $(LIBC_CRYPTO_A)
|
||||
LIBC_CRYPTO_A = o/$(MODE)/libc/crypto/crypto.a
|
||||
LIBC_CRYPTO_A_FILES := $(wildcard libc/crypto/*)
|
||||
LIBC_CRYPTO_A_HDRS = $(filter %.h,$(LIBC_CRYPTO_A_FILES))
|
||||
LIBC_CRYPTO_A_SRCS_A = $(filter %.s,$(LIBC_CRYPTO_A_FILES))
|
||||
LIBC_CRYPTO_A_SRCS_S = $(filter %.S,$(LIBC_CRYPTO_A_FILES))
|
||||
LIBC_CRYPTO_A_SRCS_C = $(filter %.c,$(LIBC_CRYPTO_A_FILES))
|
||||
|
||||
LIBC_CRYPTO_A_SRCS = \
|
||||
$(LIBC_CRYPTO_A_SRCS_A) \
|
||||
$(LIBC_CRYPTO_A_SRCS_S) \
|
||||
$(LIBC_CRYPTO_A_SRCS_C)
|
||||
|
||||
LIBC_CRYPTO_A_OBJS = \
|
||||
$(LIBC_CRYPTO_A_SRCS:%=o/$(MODE)/%.zip.o) \
|
||||
$(LIBC_CRYPTO_A_SRCS_A:%.s=o/$(MODE)/%.o) \
|
||||
$(LIBC_CRYPTO_A_SRCS_S:%.S=o/$(MODE)/%.o) \
|
||||
$(LIBC_CRYPTO_A_SRCS_C:%.c=o/$(MODE)/%.o)
|
||||
|
||||
LIBC_CRYPTO_A_CHECKS = \
|
||||
$(LIBC_CRYPTO_A).pkg \
|
||||
$(LIBC_CRYPTO_A_HDRS:%=o/$(MODE)/%.ok)
|
||||
|
||||
LIBC_CRYPTO_A_DIRECTDEPS = \
|
||||
LIBC_STUBS \
|
||||
LIBC_NEXGEN32E
|
||||
|
||||
LIBC_CRYPTO_A_DEPS := \
|
||||
$(call uniq,$(foreach x,$(LIBC_CRYPTO_A_DIRECTDEPS),$($(x))))
|
||||
|
||||
$(LIBC_CRYPTO_A): \
|
||||
libc/crypto/ \
|
||||
$(LIBC_CRYPTO_A).pkg \
|
||||
$(LIBC_CRYPTO_A_OBJS)
|
||||
|
||||
$(LIBC_CRYPTO_A).pkg: \
|
||||
$(LIBC_CRYPTO_A_OBJS) \
|
||||
$(foreach x,$(LIBC_CRYPTO_A_DIRECTDEPS),$($(x)_A).pkg)
|
||||
|
||||
LIBC_CRYPTO_LIBS = $(foreach x,$(LIBC_CRYPTO_ARTIFACTS),$($(x)))
|
||||
LIBC_CRYPTO_SRCS = $(foreach x,$(LIBC_CRYPTO_ARTIFACTS),$($(x)_SRCS))
|
||||
LIBC_CRYPTO_HDRS = $(foreach x,$(LIBC_CRYPTO_ARTIFACTS),$($(x)_HDRS))
|
||||
LIBC_CRYPTO_BINS = $(foreach x,$(LIBC_CRYPTO_ARTIFACTS),$($(x)_BINS))
|
||||
LIBC_CRYPTO_CHECKS = $(foreach x,$(LIBC_CRYPTO_ARTIFACTS),$($(x)_CHECKS))
|
||||
LIBC_CRYPTO_OBJS = $(foreach x,$(LIBC_CRYPTO_ARTIFACTS),$($(x)_OBJS))
|
||||
LIBC_CRYPTO_TESTS = $(foreach x,$(LIBC_CRYPTO_ARTIFACTS),$($(x)_TESTS))
|
||||
$(LIBC_CRYPTO_OBJS): $(BUILD_FILES) libc/crypto/crypto.mk
|
||||
|
||||
.PHONY: o/$(MODE)/libc/crypto
|
||||
o/$(MODE)/libc/crypto: $(LIBC_CRYPTO_CHECKS)
|
51
libc/crypto/invmixcolumns.c
Normal file
51
libc/crypto/invmixcolumns.c
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ 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 │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/crypto/rijndael.h"
|
||||
#include "libc/dce.h"
|
||||
|
||||
static noinline aes_block_t xtime(aes_block_t x) {
|
||||
return ((x ^ (x & 0x80808080)) << 1) ^ (((x & 0x80808080) >> 7) * 0x1b);
|
||||
}
|
||||
|
||||
static aes_block_t gf256mulx4(aes_block_t x, aes_block_t c) {
|
||||
return ((((c >> 0 & 0x01010101) * 0xff) & x) ^
|
||||
(((c >> 1 & 0x01010101) * 0xff) & xtime(x)) ^
|
||||
(((c >> 2 & 0x01010101) * 0xff) & xtime(xtime(x))) ^
|
||||
(((c >> 3 & 0x01010101) * 0xff) & xtime(xtime(xtime(x)))) ^
|
||||
(((c >> 4 & 0x01010101) * 0xff) & xtime(xtime(xtime(x)))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies inverse of Rijndael MixColumns() transformation.
|
||||
* @see FIPS-197
|
||||
*/
|
||||
aes_block_t InvMixColumns(aes_block_t x) {
|
||||
uint32_t i;
|
||||
aes_block_t y = {0, 0, 0, 0};
|
||||
aes_block_t c = {0x090D0B0E, 0x090D0B0E, 0x090D0B0E, 0x090D0B0E};
|
||||
for (i = 0; i < 4; ++i) {
|
||||
y ^= gf256mulx4((x & 0xff) * 0x01010101,
|
||||
(((c >> 000) & 0xff) << 000 | ((c >> 010) & 0xff) << 030 |
|
||||
((c >> 020) & 0xff) << 020 | ((c >> 030) & 0xff) << 010));
|
||||
x = x << 8 | x >> 24;
|
||||
c = c << 8 | c >> 24;
|
||||
}
|
||||
return y;
|
||||
}
|
58
libc/crypto/kaessbox.S
Normal file
58
libc/crypto/kaessbox.S
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ 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 │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.h"
|
||||
|
||||
.rodata
|
||||
.align 64 # for cacheline yoinking
|
||||
kAesSbox:
|
||||
.byte 0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5
|
||||
.byte 0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76
|
||||
.byte 0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0
|
||||
.byte 0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0
|
||||
.byte 0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc
|
||||
.byte 0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15
|
||||
.byte 0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a
|
||||
.byte 0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75
|
||||
.byte 0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0
|
||||
.byte 0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84
|
||||
.byte 0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b
|
||||
.byte 0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf
|
||||
.byte 0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85
|
||||
.byte 0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8
|
||||
.byte 0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5
|
||||
.byte 0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2
|
||||
.byte 0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17
|
||||
.byte 0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73
|
||||
.byte 0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88
|
||||
.byte 0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb
|
||||
.byte 0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c
|
||||
.byte 0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79
|
||||
.byte 0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9
|
||||
.byte 0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08
|
||||
.byte 0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6
|
||||
.byte 0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a
|
||||
.byte 0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e
|
||||
.byte 0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e
|
||||
.byte 0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94
|
||||
.byte 0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf
|
||||
.byte 0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68
|
||||
.byte 0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16
|
||||
.endfn kAesSbox,globl,hidden
|
||||
.previous
|
58
libc/crypto/kaessboxinverse.S
Normal file
58
libc/crypto/kaessboxinverse.S
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ 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 │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.h"
|
||||
|
||||
.rodata
|
||||
.align 64 # for cacheline yoinking
|
||||
kAesSboxInverse:
|
||||
.byte 0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38
|
||||
.byte 0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb
|
||||
.byte 0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87
|
||||
.byte 0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb
|
||||
.byte 0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d
|
||||
.byte 0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e
|
||||
.byte 0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2
|
||||
.byte 0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25
|
||||
.byte 0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16
|
||||
.byte 0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92
|
||||
.byte 0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda
|
||||
.byte 0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84
|
||||
.byte 0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a
|
||||
.byte 0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06
|
||||
.byte 0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02
|
||||
.byte 0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b
|
||||
.byte 0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea
|
||||
.byte 0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73
|
||||
.byte 0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85
|
||||
.byte 0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e
|
||||
.byte 0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89
|
||||
.byte 0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b
|
||||
.byte 0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20
|
||||
.byte 0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4
|
||||
.byte 0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31
|
||||
.byte 0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f
|
||||
.byte 0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d
|
||||
.byte 0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef
|
||||
.byte 0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0
|
||||
.byte 0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61
|
||||
.byte 0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26
|
||||
.byte 0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d
|
||||
.endfn kAesSboxInverse,globl,hidden
|
||||
.previous
|
73
libc/crypto/rijndael.c
Normal file
73
libc/crypto/rijndael.c
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ 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 │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/emmintrin.h"
|
||||
#include "libc/crypto/rijndael.h"
|
||||
#include "libc/nexgen32e/x86feature.h"
|
||||
|
||||
forceinline aes_block_t rijndael$westmere(uint32_t n, aes_block_t x,
|
||||
const struct Rijndael *ctx) {
|
||||
uint32_t i;
|
||||
x ^= ctx->rk[0].xmm;
|
||||
for (i = 1; i < n; ++i) {
|
||||
asm("aesenc\t%2,%0" : "=x"(x) : "0"(x), "m"(ctx->rk[i].xmm));
|
||||
}
|
||||
asm("aesenclast\t%2,%0" : "=x"(x) : "0"(x), "m"(ctx->rk[i].xmm));
|
||||
return x;
|
||||
}
|
||||
|
||||
static noinline aes_block_t rijndael$pure(uint32_t n, aes_block_t x,
|
||||
const struct Rijndael *ctx) {
|
||||
uint32_t i, j;
|
||||
__v16qu b1, b2;
|
||||
aes_block_t u1, u2, u3, u4;
|
||||
x ^= ctx->rk[0].xmm;
|
||||
for (i = 1; i < n + 1; ++i) {
|
||||
b2 = b1 = (__v16qu)x;
|
||||
for (j = 0; j < 16; ++j) {
|
||||
b2[j % 4 + 13 * j / 4 % 4 * 4] = kAesSbox[b1[j]];
|
||||
}
|
||||
u1 = (aes_block_t)b2;
|
||||
if (i != n) {
|
||||
u2 = u1 >> 010 | u1 << 030;
|
||||
u3 = u1 ^ u2;
|
||||
u4 = u3 & 0x80808080;
|
||||
u3 = ((u3 ^ u4) << 1) ^ ((u4 >> 7) * 0x1b);
|
||||
u1 = u3 ^ u2 ^ (u1 >> 020 | u1 << 020) ^ (u1 >> 030 | u1 << 010);
|
||||
}
|
||||
x = ctx->rk[i].xmm ^ u1;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts paragraph w/ AES.
|
||||
*
|
||||
* @param n is 14 for AES-256, 12 for AES-192, and 10 for AES-128
|
||||
* @param x is 128-bit chunk of plaintext to encrypt
|
||||
* @param ctx was initialized by rijndaelinit()
|
||||
* @return result of transformation
|
||||
*/
|
||||
aes_block_t rijndael(uint32_t n, aes_block_t x, const struct Rijndael *ctx) {
|
||||
if (X86_HAVE(AES)) {
|
||||
return rijndael$westmere(n, x, ctx);
|
||||
} else {
|
||||
return rijndael$pure(n, x, ctx);
|
||||
}
|
||||
}
|
56
libc/crypto/rijndael.h
Normal file
56
libc/crypto/rijndael.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_CRYPTO_RIJNDAEL_H_
|
||||
#define COSMOPOLITAN_LIBC_CRYPTO_RIJNDAEL_H_
|
||||
#include "libc/str/str.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
/*───────────────────────────────────────────────────────────────────────────│─╗
|
||||
│ cosmopolitan § cryptography » advanced encryption standard ─╬─│┼
|
||||
╚────────────────────────────────────────────────────────────────────────────│─┘
|
||||
AES-256 Latency x86 2010+ SSE2
|
||||
─────────────── ───────── ──────
|
||||
rijndael(14, block, &ctx) 23 ns 218 ns
|
||||
unrijndael(14, block, &ctx) 23 ns 690 ns
|
||||
rijndaelinit(&ctx, 14, k1, k2) 136 ns 135 ns
|
||||
unrijndaelinit(&ctx, 14, k1, k2) 186 ns 639 ns
|
||||
|
||||
Untrustworthy System Viability x86 2010+ SSE2
|
||||
────────────────────────────── ───────── ──────
|
||||
rijndael(14, block, &ctx) A C
|
||||
unrijndael(14, block, &ctx) A C
|
||||
rijndaelinit(&ctx, 14, k1, k2) B B
|
||||
unrijndaelinit(&ctx, 14, k1, k2) B C
|
||||
|
||||
Comparison Cosmo Rijndael Tiny-AES
|
||||
────────────────────────────── ─────── ──────── ────────
|
||||
Generalized Math Yes Yes No
|
||||
Footprint 1,782 b 9,258 b 903 b
|
||||
Performance (New Hardware) ~20 ns ~40 ns ~400 ns
|
||||
Performance (Old Hardware) ~400 ns ~40 ns ~400 ns */
|
||||
|
||||
typedef uint32_t aes_block_t _Vector_size(16) aligned(16);
|
||||
|
||||
struct Rijndael {
|
||||
union {
|
||||
aes_block_t xmm;
|
||||
uint32_t u32[4];
|
||||
uint8_t u8[16];
|
||||
} rk[15];
|
||||
};
|
||||
|
||||
void rijndaelinit(struct Rijndael *, uint32_t, aes_block_t, aes_block_t);
|
||||
aes_block_t rijndael(uint32_t, aes_block_t, const struct Rijndael *);
|
||||
void unrijndaelinit(struct Rijndael *, uint32_t, aes_block_t, aes_block_t);
|
||||
aes_block_t unrijndael(uint32_t, aes_block_t, const struct Rijndael *);
|
||||
|
||||
/*───────────────────────────────────────────────────────────────────────────│─╗
|
||||
│ cosmopolitan § cryptography » implementation details ─╬─│┼
|
||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||
|
||||
aligned(64) extern const uint8_t kAesSbox[256];
|
||||
aligned(64) extern const uint8_t kAesSboxInverse[256];
|
||||
|
||||
aes_block_t InvMixColumns(aes_block_t x) hidden;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_CRYPTO_RIJNDAEL_H_ */
|
67
libc/crypto/rijndaelinit.c
Normal file
67
libc/crypto/rijndaelinit.c
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ 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 │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/bits/xmmintrin.h"
|
||||
#include "libc/crypto/rijndael.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/str/internal.h"
|
||||
|
||||
static const uint8_t Rcon[11] = {0x8d, 0x01, 0x02, 0x04, 0x08, 0x10,
|
||||
0x20, 0x40, 0x80, 0x1b, 0x36};
|
||||
|
||||
forceinline uint32_t SubRot(uint32_t t) {
|
||||
uint32_t j;
|
||||
for (j = 0; j < 4; j++) {
|
||||
t = (t & -256) | kAesSbox[t & 255];
|
||||
t = ROR(t, 8);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes key schedule for rijndael().
|
||||
*
|
||||
* @param ctx receives round keys
|
||||
* @param n is 14 for AES-256, 12 for AES-192, and 10 for AES-128
|
||||
* @param k1/k2 holds the master key
|
||||
*/
|
||||
void rijndaelinit(struct Rijndael *ctx, uint32_t n, aes_block_t k1,
|
||||
aes_block_t k2) {
|
||||
#define Nk (n - 6)
|
||||
#define W(i) (ctx->rk[(i) / 4].u32[(i) % 4])
|
||||
#define K(i) ((i) < 4 ? k1[i] : k2[(i)-4])
|
||||
uint32_t i, t;
|
||||
ctx->rk[0].xmm = k1;
|
||||
ctx->rk[1].xmm = k2;
|
||||
for (i = Nk; i < 4 * (n + 1); ++i) {
|
||||
t = W(i - 1);
|
||||
if (i % Nk == 0) {
|
||||
t = ROR(t, 8);
|
||||
t = SubRot(t);
|
||||
t ^= Rcon[i / Nk];
|
||||
} else if (Nk > 6 && i % Nk == 4) {
|
||||
t = SubRot(t);
|
||||
}
|
||||
W(i) = W(i - Nk) ^ t;
|
||||
}
|
||||
XMM_DESTROY(k1);
|
||||
XMM_DESTROY(k2);
|
||||
}
|
65
libc/crypto/unrijndael.c
Normal file
65
libc/crypto/unrijndael.c
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ 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 │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/emmintrin.h"
|
||||
#include "libc/crypto/rijndael.h"
|
||||
#include "libc/nexgen32e/x86feature.h"
|
||||
|
||||
forceinline aes_block_t unrijndael$westmere(uint32_t n, aes_block_t x,
|
||||
const struct Rijndael *ctx) {
|
||||
x ^= ctx->rk[n--].xmm;
|
||||
do {
|
||||
asm("aesdec\t%2,%0" : "=x"(x) : "0"(x), "m"(ctx->rk[n].xmm));
|
||||
} while (--n);
|
||||
asm("aesdeclast\t%2,%0" : "=x"(x) : "0"(x), "m"(ctx->rk[n].xmm));
|
||||
return x;
|
||||
}
|
||||
|
||||
static noinline aes_block_t unrijndael$pure(uint32_t n, aes_block_t x,
|
||||
const struct Rijndael *ctx) {
|
||||
uint32_t j;
|
||||
__v16qu b1, b2;
|
||||
x ^= ctx->rk[n--].xmm;
|
||||
do {
|
||||
b2 = b1 = (__v16qu)x;
|
||||
for (j = 0; j < 16; ++j) {
|
||||
b2[j] = kAesSboxInverse[b1[j % 4 + j * 13 / 4 % 4 * 4]];
|
||||
}
|
||||
x = (aes_block_t)b2;
|
||||
if (n) x = InvMixColumns(x);
|
||||
x ^= ctx->rk[n].xmm;
|
||||
} while (n--);
|
||||
return x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypts paragraph w/ AES.
|
||||
*
|
||||
* @param n is 14 for AES-256, 12 for AES-192, and 10 for AES-128
|
||||
* @param x is 128-bit chunk of ciphertext to decrypt
|
||||
* @param ctx was initialized by unrijndaelinit()
|
||||
* @return result of transformation
|
||||
*/
|
||||
aes_block_t unrijndael(uint32_t n, aes_block_t x, const struct Rijndael *ctx) {
|
||||
if (X86_HAVE(AES)) {
|
||||
return unrijndael$westmere(n, x, ctx);
|
||||
} else {
|
||||
return unrijndael$pure(n, x, ctx);
|
||||
}
|
||||
}
|
70
libc/crypto/unrijndaelinit.c
Normal file
70
libc/crypto/unrijndaelinit.c
Normal file
|
@ -0,0 +1,70 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ 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 │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/bits/xmmintrin.h"
|
||||
#include "libc/crypto/rijndael.h"
|
||||
#include "libc/nexgen32e/x86feature.h"
|
||||
|
||||
static void unrijndaelinit$westmere(struct Rijndael *ctx, uint32_t n,
|
||||
aes_block_t k1, aes_block_t k2) {
|
||||
uint32_t i;
|
||||
aes_block_t x;
|
||||
assert(n > 1);
|
||||
rijndaelinit(ctx, n, k1, k2);
|
||||
i = 1;
|
||||
do {
|
||||
x = ctx->rk[i].xmm;
|
||||
asm("aesimc\t%1,%0" : "=x"(x) : "0"(x));
|
||||
ctx->rk[i].xmm = x;
|
||||
} while (i++ < n);
|
||||
XMM_DESTROY(x);
|
||||
}
|
||||
|
||||
static relegated noinline void unrijndaelinit$pure(struct Rijndael *ctx,
|
||||
uint32_t n, aes_block_t k1,
|
||||
aes_block_t k2) {
|
||||
uint32_t i;
|
||||
aes_block_t x;
|
||||
assert(n > 1);
|
||||
rijndaelinit(ctx, n, k1, k2);
|
||||
i = 1;
|
||||
do {
|
||||
x = ctx->rk[i].xmm;
|
||||
x = InvMixColumns(x);
|
||||
ctx->rk[i].xmm = x;
|
||||
} while (i++ < n);
|
||||
XMM_DESTROY(x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes key schedule for unrijndael().
|
||||
*
|
||||
* @param rk receives round keys
|
||||
* @param n is 14 for AES-256, 12 for AES-192, and 10 for AES-128
|
||||
* @param k1/k2 holds the master key
|
||||
*/
|
||||
void unrijndaelinit(struct Rijndael *ctx, uint32_t n, aes_block_t k1,
|
||||
aes_block_t k2) {
|
||||
if (X86_HAVE(AES)) {
|
||||
return unrijndaelinit$westmere(ctx, n, k1, k2);
|
||||
} else {
|
||||
return unrijndaelinit$pure(ctx, n, k1, k2);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue