summaryrefslogtreecommitdiffstats
path: root/qemu/roms/ipxe/src/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/roms/ipxe/src/crypto')
-rw-r--r--qemu/roms/ipxe/src/crypto/aes.c808
-rw-r--r--qemu/roms/ipxe/src/crypto/aes_wrap.c124
-rw-r--r--qemu/roms/ipxe/src/crypto/arc4.c132
-rw-r--r--qemu/roms/ipxe/src/crypto/asn1.c851
-rw-r--r--qemu/roms/ipxe/src/crypto/bigint.c139
-rw-r--r--qemu/roms/ipxe/src/crypto/cbc.c108
-rw-r--r--qemu/roms/ipxe/src/crypto/certstore.c279
-rw-r--r--qemu/roms/ipxe/src/crypto/chap.c129
-rw-r--r--qemu/roms/ipxe/src/crypto/cms.c713
-rw-r--r--qemu/roms/ipxe/src/crypto/crc32.c55
-rw-r--r--qemu/roms/ipxe/src/crypto/crypto_null.c141
-rw-r--r--qemu/roms/ipxe/src/crypto/deflate.c1049
-rw-r--r--qemu/roms/ipxe/src/crypto/drbg.c431
-rw-r--r--qemu/roms/ipxe/src/crypto/ecb.c80
-rw-r--r--qemu/roms/ipxe/src/crypto/entropy.c483
-rw-r--r--qemu/roms/ipxe/src/crypto/hash_df.c142
-rw-r--r--qemu/roms/ipxe/src/crypto/hmac.c127
-rw-r--r--qemu/roms/ipxe/src/crypto/hmac_drbg.c363
-rw-r--r--qemu/roms/ipxe/src/crypto/md5.c302
-rw-r--r--qemu/roms/ipxe/src/crypto/mishmash/rsa_aes_cbc_sha1.c48
-rw-r--r--qemu/roms/ipxe/src/crypto/mishmash/rsa_aes_cbc_sha256.c48
-rw-r--r--qemu/roms/ipxe/src/crypto/mishmash/rsa_md5.c51
-rw-r--r--qemu/roms/ipxe/src/crypto/mishmash/rsa_sha1.c62
-rw-r--r--qemu/roms/ipxe/src/crypto/mishmash/rsa_sha224.c62
-rw-r--r--qemu/roms/ipxe/src/crypto/mishmash/rsa_sha256.c62
-rw-r--r--qemu/roms/ipxe/src/crypto/mishmash/rsa_sha384.c62
-rw-r--r--qemu/roms/ipxe/src/crypto/mishmash/rsa_sha512.c62
-rw-r--r--qemu/roms/ipxe/src/crypto/null_entropy.c40
-rw-r--r--qemu/roms/ipxe/src/crypto/ocsp.c960
-rw-r--r--qemu/roms/ipxe/src/crypto/privkey.c122
-rw-r--r--qemu/roms/ipxe/src/crypto/random_nz.c80
-rw-r--r--qemu/roms/ipxe/src/crypto/rbg.c119
-rw-r--r--qemu/roms/ipxe/src/crypto/rootcert.c123
-rw-r--r--qemu/roms/ipxe/src/crypto/rsa.c637
-rw-r--r--qemu/roms/ipxe/src/crypto/sha1.c276
-rw-r--r--qemu/roms/ipxe/src/crypto/sha1extra.c168
-rw-r--r--qemu/roms/ipxe/src/crypto/sha224.c82
-rw-r--r--qemu/roms/ipxe/src/crypto/sha256.c283
-rw-r--r--qemu/roms/ipxe/src/crypto/sha384.c82
-rw-r--r--qemu/roms/ipxe/src/crypto/sha512.c303
-rw-r--r--qemu/roms/ipxe/src/crypto/sha512_224.c83
-rw-r--r--qemu/roms/ipxe/src/crypto/sha512_256.c83
-rw-r--r--qemu/roms/ipxe/src/crypto/x509.c1776
43 files changed, 0 insertions, 12130 deletions
diff --git a/qemu/roms/ipxe/src/crypto/aes.c b/qemu/roms/ipxe/src/crypto/aes.c
deleted file mode 100644
index b9e206bfb..000000000
--- a/qemu/roms/ipxe/src/crypto/aes.c
+++ /dev/null
@@ -1,808 +0,0 @@
-/*
- * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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; either version 2 of the
- * License, or any later version.
- *
- * 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.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-/** @file
- *
- * AES algorithm
- *
- */
-
-#include <stdint.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-#include <byteswap.h>
-#include <ipxe/rotate.h>
-#include <ipxe/crypto.h>
-#include <ipxe/ecb.h>
-#include <ipxe/cbc.h>
-#include <ipxe/aes.h>
-
-/** AES strides
- *
- * These are the strides (modulo 16) used to walk through the AES
- * input state bytes in order of byte position after [Inv]ShiftRows.
- */
-enum aes_stride {
- /** Input stride for ShiftRows
- *
- * 0 4 8 c
- * \ \ \
- * 1 5 9 d
- * \ \ \
- * 2 6 a e
- * \ \ \
- * 3 7 b f
- */
- AES_STRIDE_SHIFTROWS = +5,
- /** Input stride for InvShiftRows
- *
- * 0 4 8 c
- * / / /
- * 1 5 9 d
- * / / /
- * 2 6 a e
- * / / /
- * 3 7 b f
- */
- AES_STRIDE_INVSHIFTROWS = -3,
-};
-
-/** A single AES lookup table entry
- *
- * This represents the product (in the Galois field GF(2^8)) of an
- * eight-byte vector multiplier with a single scalar multiplicand.
- *
- * The vector multipliers used for AES will be {1,1,1,3,2,1,1,3} for
- * MixColumns and {1,9,13,11,14,9,13,11} for InvMixColumns. This
- * allows for the result of multiplying any single column of the
- * [Inv]MixColumns matrix by a scalar value to be obtained simply by
- * extracting the relevant four-byte subset from the lookup table
- * entry.
- *
- * For example, to find the result of multiplying the second column of
- * the MixColumns matrix by the scalar value 0x80:
- *
- * MixColumns column[0]: { 2, 1, 1, 3 }
- * MixColumns column[1]: { 3, 2, 1, 1 }
- * MixColumns column[2]: { 1, 3, 2, 1 }
- * MixColumns column[3]: { 1, 1, 3, 2 }
- * Vector multiplier: { 1, 1, 1, 3, 2, 1, 1, 3 }
- * Scalar multiplicand: 0x80
- * Lookup table entry: { 0x80, 0x80, 0x80, 0x9b, 0x1b, 0x80, 0x80, 0x9b }
- *
- * The second column of the MixColumns matrix is {3,2,1,1}. The
- * product of this column with the scalar value 0x80 can be obtained
- * by extracting the relevant four-byte subset of the lookup table
- * entry:
- *
- * MixColumns column[1]: { 3, 2, 1, 1 }
- * Vector multiplier: { 1, 1, 1, 3, 2, 1, 1, 3 }
- * Lookup table entry: { 0x80, 0x80, 0x80, 0x9b, 0x1b, 0x80, 0x80, 0x9b }
- * Product: { 0x9b, 0x1b, 0x80, 0x80 }
- *
- * The column lookups require only seven bytes of the eight-byte
- * entry: the remaining (first) byte is used to hold the scalar
- * multiplicand itself (i.e. the first byte of the vector multiplier
- * is always chosen to be 1).
- */
-union aes_table_entry {
- /** Viewed as an array of bytes */
- uint8_t byte[8];
-} __attribute__ (( packed ));
-
-/** An AES lookup table
- *
- * This represents the products (in the Galois field GF(2^8)) of a
- * constant eight-byte vector multiplier with all possible 256 scalar
- * multiplicands.
- *
- * The entries are indexed by the AES [Inv]SubBytes S-box output
- * values (denoted S(N)). This allows for the result of multiplying
- * any single column of the [Inv]MixColumns matrix by S(N) to be
- * obtained simply by extracting the relevant four-byte subset from
- * the Nth table entry. For example:
- *
- * Input byte (N): 0x3a
- * SubBytes output S(N): 0x80
- * MixColumns column[1]: { 3, 2, 1, 1 }
- * Vector multiplier: { 1, 1, 1, 3, 2, 1, 1, 3 }
- * Table entry[0x3a]: { 0x80, 0x80, 0x80, 0x9b, 0x1b, 0x80, 0x80, 0x9b }
- * Product: { 0x9b, 0x1b, 0x80, 0x80 }
- *
- * Since the first byte of the eight-byte vector multiplier is always
- * chosen to be 1, the value of S(N) may be lookup up by extracting
- * the first byte of the Nth table entry.
- */
-struct aes_table {
- /** Table entries, indexed by S(N) */
- union aes_table_entry entry[256];
-} __attribute__ (( aligned ( 8 ) ));
-
-/** AES MixColumns lookup table */
-static struct aes_table aes_mixcolumns;
-
-/** AES InvMixColumns lookup table */
-static struct aes_table aes_invmixcolumns;
-
-/**
- * Multiply [Inv]MixColumns matrix column by scalar multiplicand
- *
- * @v entry AES lookup table entry for scalar multiplicand
- * @v column [Inv]MixColumns matrix column index
- * @ret product Product of matrix column with scalar multiplicand
- */
-static inline __attribute__ (( always_inline )) uint32_t
-aes_entry_column ( const union aes_table_entry *entry, unsigned int column ) {
- const union {
- uint8_t byte;
- uint32_t column;
- } __attribute__ (( may_alias )) *product;
-
- /* Locate relevant four-byte subset */
- product = container_of ( &entry->byte[ 4 - column ],
- typeof ( *product ), byte );
-
- /* Extract this four-byte subset */
- return product->column;
-}
-
-/**
- * Multiply [Inv]MixColumns matrix column by S-boxed input byte
- *
- * @v table AES lookup table
- * @v stride AES row shift stride
- * @v in AES input state
- * @v offset Output byte offset (after [Inv]ShiftRows)
- * @ret product Product of matrix column with S(input byte)
- *
- * Note that the specified offset is not the offset of the input byte;
- * it is the offset of the output byte which corresponds to the input
- * byte. This output byte offset is used to calculate both the input
- * byte offset and to select the appropriate matric column.
- *
- * With a compile-time constant offset, this function will optimise
- * down to a single "movzbl" (to extract the input byte) and will
- * generate a single x86 memory reference expression which can then be
- * used directly within a single "xorl" instruction.
- */
-static inline __attribute__ (( always_inline )) uint32_t
-aes_column ( const struct aes_table *table, size_t stride,
- const union aes_matrix *in, size_t offset ) {
- const union aes_table_entry *entry;
- unsigned int byte;
-
- /* Extract input byte corresponding to this output byte offset
- * (i.e. perform [Inv]ShiftRows).
- */
- byte = in->byte[ ( stride * offset ) & 0xf ];
-
- /* Locate lookup table entry for this input byte (i.e. perform
- * [Inv]SubBytes).
- */
- entry = &table->entry[byte];
-
- /* Multiply appropriate matrix column by this input byte
- * (i.e. perform [Inv]MixColumns).
- */
- return aes_entry_column ( entry, ( offset & 0x3 ) );
-}
-
-/**
- * Calculate intermediate round output column
- *
- * @v table AES lookup table
- * @v stride AES row shift stride
- * @v in AES input state
- * @v key AES round key
- * @v column Column index
- * @ret output Output column value
- */
-static inline __attribute__ (( always_inline )) uint32_t
-aes_output ( const struct aes_table *table, size_t stride,
- const union aes_matrix *in, const union aes_matrix *key,
- unsigned int column ) {
- size_t offset = ( column * 4 );
-
- /* Perform [Inv]ShiftRows, [Inv]SubBytes, [Inv]MixColumns, and
- * AddRoundKey for this column. The loop is unrolled to allow
- * for the required compile-time constant optimisations.
- */
- return ( aes_column ( table, stride, in, ( offset + 0 ) ) ^
- aes_column ( table, stride, in, ( offset + 1 ) ) ^
- aes_column ( table, stride, in, ( offset + 2 ) ) ^
- aes_column ( table, stride, in, ( offset + 3 ) ) ^
- key->column[column] );
-}
-
-/**
- * Perform a single intermediate round
- *
- * @v table AES lookup table
- * @v stride AES row shift stride
- * @v in AES input state
- * @v out AES output state
- * @v key AES round key
- */
-static inline __attribute__ (( always_inline )) void
-aes_round ( const struct aes_table *table, size_t stride,
- const union aes_matrix *in, union aes_matrix *out,
- const union aes_matrix *key ) {
-
- /* Perform [Inv]ShiftRows, [Inv]SubBytes, [Inv]MixColumns, and
- * AddRoundKey for all columns. The loop is unrolled to allow
- * for the required compile-time constant optimisations.
- */
- out->column[0] = aes_output ( table, stride, in, key, 0 );
- out->column[1] = aes_output ( table, stride, in, key, 1 );
- out->column[2] = aes_output ( table, stride, in, key, 2 );
- out->column[3] = aes_output ( table, stride, in, key, 3 );
-}
-
-/**
- * Perform encryption intermediate rounds
- *
- * @v in AES input state
- * @v out AES output state
- * @v key Round keys
- * @v rounds Number of rounds (must be odd)
- *
- * This function is deliberately marked as non-inlinable to ensure
- * maximal availability of registers for GCC's register allocator,
- * which has a tendency to otherwise spill performance-critical
- * registers to the stack.
- */
-static __attribute__ (( noinline )) void
-aes_encrypt_rounds ( union aes_matrix *in, union aes_matrix *out,
- const union aes_matrix *key, unsigned int rounds ) {
- union aes_matrix *tmp;
-
- /* Perform intermediate rounds */
- do {
- /* Perform one intermediate round */
- aes_round ( &aes_mixcolumns, AES_STRIDE_SHIFTROWS,
- in, out, key++ );
-
- /* Swap input and output states for next round */
- tmp = in;
- in = out;
- out = tmp;
-
- } while ( --rounds );
-}
-
-/**
- * Perform decryption intermediate rounds
- *
- * @v in AES input state
- * @v out AES output state
- * @v key Round keys
- * @v rounds Number of rounds (must be odd)
- *
- * As with aes_encrypt_rounds(), this function is deliberately marked
- * as non-inlinable.
- *
- * This function could potentially use the same binary code as is used
- * for encryption. To compensate for the difference between ShiftRows
- * and InvShiftRows, half of the input byte offsets would have to be
- * modifiable at runtime (half by an offset of +4/-4, half by an
- * offset of -4/+4 for ShiftRows/InvShiftRows). This can be
- * accomplished in x86 assembly within the number of available
- * registers, but GCC's register allocator struggles to do so,
- * resulting in a significant performance decrease due to registers
- * being spilled to the stack. We therefore use two separate but very
- * similar binary functions based on the same C source.
- */
-static __attribute__ (( noinline )) void
-aes_decrypt_rounds ( union aes_matrix *in, union aes_matrix *out,
- const union aes_matrix *key, unsigned int rounds ) {
- union aes_matrix *tmp;
-
- /* Perform intermediate rounds */
- do {
- /* Perform one intermediate round */
- aes_round ( &aes_invmixcolumns, AES_STRIDE_INVSHIFTROWS,
- in, out, key++ );
-
- /* Swap input and output states for next round */
- tmp = in;
- in = out;
- out = tmp;
-
- } while ( --rounds );
-}
-
-/**
- * Perform standalone AddRoundKey
- *
- * @v state AES state
- * @v key AES round key
- */
-static inline __attribute__ (( always_inline )) void
-aes_addroundkey ( union aes_matrix *state, const union aes_matrix *key ) {
-
- state->column[0] ^= key->column[0];
- state->column[1] ^= key->column[1];
- state->column[2] ^= key->column[2];
- state->column[3] ^= key->column[3];
-}
-
-/**
- * Perform final round
- *
- * @v table AES lookup table
- * @v stride AES row shift stride
- * @v in AES input state
- * @v out AES output state
- * @v key AES round key
- */
-static void aes_final ( const struct aes_table *table, size_t stride,
- const union aes_matrix *in, union aes_matrix *out,
- const union aes_matrix *key ) {
- const union aes_table_entry *entry;
- unsigned int byte;
- size_t out_offset;
- size_t in_offset;
-
- /* Perform [Inv]ShiftRows and [Inv]SubBytes */
- for ( out_offset = 0, in_offset = 0 ; out_offset < 16 ;
- out_offset++, in_offset = ( ( in_offset + stride ) & 0xf ) ) {
-
- /* Extract input byte (i.e. perform [Inv]ShiftRows) */
- byte = in->byte[in_offset];
-
- /* Locate lookup table entry for this input byte
- * (i.e. perform [Inv]SubBytes).
- */
- entry = &table->entry[byte];
-
- /* Store output byte */
- out->byte[out_offset] = entry->byte[0];
- }
-
- /* Perform AddRoundKey */
- aes_addroundkey ( out, key );
-}
-
-/**
- * Encrypt data
- *
- * @v ctx Context
- * @v src Data to encrypt
- * @v dst Buffer for encrypted data
- * @v len Length of data
- */
-static void aes_encrypt ( void *ctx, const void *src, void *dst, size_t len ) {
- struct aes_context *aes = ctx;
- union aes_matrix buffer[2];
- union aes_matrix *in = &buffer[0];
- union aes_matrix *out = &buffer[1];
- unsigned int rounds = aes->rounds;
-
- /* Sanity check */
- assert ( len == sizeof ( *in ) );
-
- /* Initialise input state */
- memcpy ( in, src, sizeof ( *in ) );
-
- /* Perform initial round (AddRoundKey) */
- aes_addroundkey ( in, &aes->encrypt.key[0] );
-
- /* Perform intermediate rounds (ShiftRows, SubBytes,
- * MixColumns, AddRoundKey).
- */
- aes_encrypt_rounds ( in, out, &aes->encrypt.key[1], ( rounds - 2 ) );
- in = out;
-
- /* Perform final round (ShiftRows, SubBytes, AddRoundKey) */
- out = dst;
- aes_final ( &aes_mixcolumns, AES_STRIDE_SHIFTROWS, in, out,
- &aes->encrypt.key[ rounds - 1 ] );
-}
-
-/**
- * Decrypt data
- *
- * @v ctx Context
- * @v src Data to decrypt
- * @v dst Buffer for decrypted data
- * @v len Length of data
- */
-static void aes_decrypt ( void *ctx, const void *src, void *dst, size_t len ) {
- struct aes_context *aes = ctx;
- union aes_matrix buffer[2];
- union aes_matrix *in = &buffer[0];
- union aes_matrix *out = &buffer[1];
- unsigned int rounds = aes->rounds;
-
- /* Sanity check */
- assert ( len == sizeof ( *in ) );
-
- /* Initialise input state */
- memcpy ( in, src, sizeof ( *in ) );
-
- /* Perform initial round (AddRoundKey) */
- aes_addroundkey ( in, &aes->decrypt.key[0] );
-
- /* Perform intermediate rounds (InvShiftRows, InvSubBytes,
- * InvMixColumns, AddRoundKey).
- */
- aes_decrypt_rounds ( in, out, &aes->decrypt.key[1], ( rounds - 2 ) );
- in = out;
-
- /* Perform final round (InvShiftRows, InvSubBytes, AddRoundKey) */
- out = dst;
- aes_final ( &aes_invmixcolumns, AES_STRIDE_INVSHIFTROWS, in, out,
- &aes->decrypt.key[ rounds - 1 ] );
-}
-
-/**
- * Multiply a polynomial by (x) modulo (x^8 + x^4 + x^3 + x^2 + 1) in GF(2^8)
- *
- * @v poly Polynomial to be multiplied
- * @ret result Result
- */
-static __attribute__ (( const )) unsigned int aes_double ( unsigned int poly ) {
-
- /* Multiply polynomial by (x), placing the resulting x^8
- * coefficient in the LSB (i.e. rotate byte left by one).
- */
- poly = rol8 ( poly, 1 );
-
- /* If coefficient of x^8 (in LSB) is non-zero, then reduce by
- * subtracting (x^8 + x^4 + x^3 + x^2 + 1) in GF(2^8).
- */
- if ( poly & 0x01 ) {
- poly ^= 0x01; /* Subtract x^8 (currently in LSB) */
- poly ^= 0x1b; /* Subtract (x^4 + x^3 + x^2 + 1) */
- }
-
- return poly;
-}
-
-/**
- * Fill in MixColumns lookup table entry
- *
- * @v entry AES lookup table entry for scalar multiplicand
- *
- * The MixColumns lookup table vector multiplier is {1,1,1,3,2,1,1,3}.
- */
-static void aes_mixcolumns_entry ( union aes_table_entry *entry ) {
- unsigned int scalar_x_1;
- unsigned int scalar_x;
- unsigned int scalar;
-
- /* Retrieve scalar multiplicand */
- scalar = entry->byte[0];
- entry->byte[1] = scalar;
- entry->byte[2] = scalar;
- entry->byte[5] = scalar;
- entry->byte[6] = scalar;
-
- /* Calculate scalar multiplied by (x) */
- scalar_x = aes_double ( scalar );
- entry->byte[4] = scalar_x;
-
- /* Calculate scalar multiplied by (x + 1) */
- scalar_x_1 = ( scalar_x ^ scalar );
- entry->byte[3] = scalar_x_1;
- entry->byte[7] = scalar_x_1;
-}
-
-/**
- * Fill in InvMixColumns lookup table entry
- *
- * @v entry AES lookup table entry for scalar multiplicand
- *
- * The InvMixColumns lookup table vector multiplier is {1,9,13,11,14,9,13,11}.
- */
-static void aes_invmixcolumns_entry ( union aes_table_entry *entry ) {
- unsigned int scalar_x3_x2_x;
- unsigned int scalar_x3_x2_1;
- unsigned int scalar_x3_x2;
- unsigned int scalar_x3_x_1;
- unsigned int scalar_x3_1;
- unsigned int scalar_x3;
- unsigned int scalar_x2;
- unsigned int scalar_x;
- unsigned int scalar;
-
- /* Retrieve scalar multiplicand */
- scalar = entry->byte[0];
-
- /* Calculate scalar multiplied by (x) */
- scalar_x = aes_double ( scalar );
-
- /* Calculate scalar multiplied by (x^2) */
- scalar_x2 = aes_double ( scalar_x );
-
- /* Calculate scalar multiplied by (x^3) */
- scalar_x3 = aes_double ( scalar_x2 );
-
- /* Calculate scalar multiplied by (x^3 + 1) */
- scalar_x3_1 = ( scalar_x3 ^ scalar );
- entry->byte[1] = scalar_x3_1;
- entry->byte[5] = scalar_x3_1;
-
- /* Calculate scalar multiplied by (x^3 + x + 1) */
- scalar_x3_x_1 = ( scalar_x3_1 ^ scalar_x );
- entry->byte[3] = scalar_x3_x_1;
- entry->byte[7] = scalar_x3_x_1;
-
- /* Calculate scalar multiplied by (x^3 + x^2) */
- scalar_x3_x2 = ( scalar_x3 ^ scalar_x2 );
-
- /* Calculate scalar multiplied by (x^3 + x^2 + 1) */
- scalar_x3_x2_1 = ( scalar_x3_x2 ^ scalar );
- entry->byte[2] = scalar_x3_x2_1;
- entry->byte[6] = scalar_x3_x2_1;
-
- /* Calculate scalar multiplied by (x^3 + x^2 + x) */
- scalar_x3_x2_x = ( scalar_x3_x2 ^ scalar_x );
- entry->byte[4] = scalar_x3_x2_x;
-}
-
-/**
- * Generate AES lookup tables
- *
- */
-static void aes_generate ( void ) {
- union aes_table_entry *entry;
- union aes_table_entry *inventry;
- unsigned int poly = 0x01;
- unsigned int invpoly = 0x01;
- unsigned int transformed;
- unsigned int i;
-
- /* Iterate over non-zero values of GF(2^8) using generator (x + 1) */
- do {
-
- /* Multiply polynomial by (x + 1) */
- poly ^= aes_double ( poly );
-
- /* Divide inverse polynomial by (x + 1). This code
- * fragment is taken directly from the Wikipedia page
- * on the Rijndael S-box. An explanation of why it
- * works would be greatly appreciated.
- */
- invpoly ^= ( invpoly << 1 );
- invpoly ^= ( invpoly << 2 );
- invpoly ^= ( invpoly << 4 );
- if ( invpoly & 0x80 )
- invpoly ^= 0x09;
- invpoly &= 0xff;
-
- /* Apply affine transformation */
- transformed = ( 0x63 ^ invpoly ^ rol8 ( invpoly, 1 ) ^
- rol8 ( invpoly, 2 ) ^ rol8 ( invpoly, 3 ) ^
- rol8 ( invpoly, 4 ) );
-
- /* Populate S-box (within MixColumns lookup table) */
- aes_mixcolumns.entry[poly].byte[0] = transformed;
-
- } while ( poly != 0x01 );
-
- /* Populate zeroth S-box entry (which has no inverse) */
- aes_mixcolumns.entry[0].byte[0] = 0x63;
-
- /* Fill in MixColumns and InvMixColumns lookup tables */
- for ( i = 0 ; i < 256 ; i++ ) {
-
- /* Fill in MixColumns lookup table entry */
- entry = &aes_mixcolumns.entry[i];
- aes_mixcolumns_entry ( entry );
-
- /* Populate inverse S-box (within InvMixColumns lookup table) */
- inventry = &aes_invmixcolumns.entry[ entry->byte[0] ];
- inventry->byte[0] = i;
-
- /* Fill in InvMixColumns lookup table entry */
- aes_invmixcolumns_entry ( inventry );
- }
-}
-
-/**
- * Rotate key column
- *
- * @v column Key column
- * @ret column Updated key column
- */
-static inline __attribute__ (( always_inline )) uint32_t
-aes_key_rotate ( uint32_t column ) {
-
- return ( ( __BYTE_ORDER == __LITTLE_ENDIAN ) ?
- ror32 ( column, 8 ) : rol32 ( column, 8 ) );
-}
-
-/**
- * Apply S-box to key column
- *
- * @v column Key column
- * @ret column Updated key column
- */
-static uint32_t aes_key_sbox ( uint32_t column ) {
- unsigned int i;
- uint8_t byte;
-
- for ( i = 0 ; i < 4 ; i++ ) {
- byte = ( column & 0xff );
- byte = aes_mixcolumns.entry[byte].byte[0];
- column = ( ( column & ~0xff ) | byte );
- column = rol32 ( column, 8 );
- }
- return column;
-}
-
-/**
- * Apply schedule round constant to key column
- *
- * @v column Key column
- * @v rcon Round constant
- * @ret column Updated key column
- */
-static inline __attribute__ (( always_inline )) uint32_t
-aes_key_rcon ( uint32_t column, unsigned int rcon ) {
-
- return ( ( __BYTE_ORDER == __LITTLE_ENDIAN ) ?
- ( column ^ rcon ) : ( column ^ ( rcon << 24 ) ) );
-}
-
-/**
- * Set key
- *
- * @v ctx Context
- * @v key Key
- * @v keylen Key length
- * @ret rc Return status code
- */
-static int aes_setkey ( void *ctx, const void *key, size_t keylen ) {
- struct aes_context *aes = ctx;
- union aes_matrix *enc;
- union aes_matrix *dec;
- union aes_matrix temp;
- union aes_matrix zero;
- unsigned int rcon = 0x01;
- unsigned int rounds;
- size_t offset = 0;
- uint32_t *prev;
- uint32_t *next;
- uint32_t *end;
- uint32_t tmp;
-
- /* Generate lookup tables, if not already done */
- if ( ! aes_mixcolumns.entry[0].byte[0] )
- aes_generate();
-
- /* Validate key length and calculate number of intermediate rounds */
- switch ( keylen ) {
- case ( 128 / 8 ) :
- rounds = 11;
- break;
- case ( 192 / 8 ) :
- rounds = 13;
- break;
- case ( 256 / 8 ) :
- rounds = 15;
- break;
- default:
- DBGC ( aes, "AES %p unsupported key length (%zd bits)\n",
- aes, ( keylen * 8 ) );
- return -EINVAL;
- }
- aes->rounds = rounds;
- enc = aes->encrypt.key;
- end = enc[rounds].column;
-
- /* Copy raw key */
- memcpy ( enc, key, keylen );
- prev = enc->column;
- next = ( ( ( void * ) prev ) + keylen );
- tmp = next[-1];
-
- /* Construct expanded key */
- while ( next < end ) {
-
- /* If this is the first column of an expanded key
- * block, or the middle column of an AES-256 key
- * block, then apply the S-box.
- */
- if ( ( offset == 0 ) || ( ( offset | keylen ) == 48 ) )
- tmp = aes_key_sbox ( tmp );
-
- /* If this is the first column of an expanded key
- * block then rotate and apply the round constant.
- */
- if ( offset == 0 ) {
- tmp = aes_key_rotate ( tmp );
- tmp = aes_key_rcon ( tmp, rcon );
- rcon = aes_double ( rcon );
- }
-
- /* XOR with previous key column */
- tmp ^= *prev;
-
- /* Store column */
- *next = tmp;
-
- /* Move to next column */
- offset += sizeof ( *next );
- if ( offset == keylen )
- offset = 0;
- next++;
- prev++;
- }
- DBGC2 ( aes, "AES %p expanded %zd-bit key:\n", aes, ( keylen * 8 ) );
- DBGC2_HDA ( aes, 0, &aes->encrypt, ( rounds * sizeof ( *enc ) ) );
-
- /* Convert to decryption key */
- memset ( &zero, 0, sizeof ( zero ) );
- dec = &aes->decrypt.key[ rounds - 1 ];
- memcpy ( dec--, enc++, sizeof ( *dec ) );
- while ( dec > aes->decrypt.key ) {
- /* Perform InvMixColumns (by reusing the encryption
- * final-round code to perform ShiftRows+SubBytes and
- * reusing the decryption intermediate-round code to
- * perform InvShiftRows+InvSubBytes+InvMixColumns, all
- * with a zero encryption key).
- */
- aes_final ( &aes_mixcolumns, AES_STRIDE_SHIFTROWS,
- enc++, &temp, &zero );
- aes_decrypt_rounds ( &temp, dec--, &zero, 1 );
- }
- memcpy ( dec--, enc++, sizeof ( *dec ) );
- DBGC2 ( aes, "AES %p inverted %zd-bit key:\n", aes, ( keylen * 8 ) );
- DBGC2_HDA ( aes, 0, &aes->decrypt, ( rounds * sizeof ( *dec ) ) );
-
- return 0;
-}
-
-/**
- * Set initialisation vector
- *
- * @v ctx Context
- * @v iv Initialisation vector
- */
-static void aes_setiv ( void *ctx __unused, const void *iv __unused ) {
- /* Nothing to do */
-}
-
-/** Basic AES algorithm */
-struct cipher_algorithm aes_algorithm = {
- .name = "aes",
- .ctxsize = sizeof ( struct aes_context ),
- .blocksize = AES_BLOCKSIZE,
- .setkey = aes_setkey,
- .setiv = aes_setiv,
- .encrypt = aes_encrypt,
- .decrypt = aes_decrypt,
-};
-
-/* AES in Electronic Codebook mode */
-ECB_CIPHER ( aes_ecb, aes_ecb_algorithm,
- aes_algorithm, struct aes_context, AES_BLOCKSIZE );
-
-/* AES in Cipher Block Chaining mode */
-CBC_CIPHER ( aes_cbc, aes_cbc_algorithm,
- aes_algorithm, struct aes_context, AES_BLOCKSIZE );
diff --git a/qemu/roms/ipxe/src/crypto/aes_wrap.c b/qemu/roms/ipxe/src/crypto/aes_wrap.c
deleted file mode 100644
index c09480e5a..000000000
--- a/qemu/roms/ipxe/src/crypto/aes_wrap.c
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (c) 2009 Joshua Oreman <oremanj@rwcr.net>.
- *
- * 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; either version 2 of the
- * License, or any later version.
- *
- * 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.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include <stdlib.h>
-#include <string.h>
-#include <ipxe/crypto.h>
-#include <ipxe/aes.h>
-
-/**
- * Wrap a key or other data using AES Key Wrap (RFC 3394)
- *
- * @v kek Key Encryption Key, 16 bytes
- * @v src Data to encrypt
- * @v nblk Number of 8-byte blocks in @a data
- * @ret dest Encrypted data (8 bytes longer than input)
- *
- * The algorithm is implemented such that @a src and @a dest may point
- * to the same buffer.
- */
-int aes_wrap ( const void *kek, const void *src, void *dest, int nblk )
-{
- u8 *A = dest;
- u8 B[16];
- u8 *R;
- int i, j;
- void *aes_ctx = malloc ( AES_CTX_SIZE );
-
- if ( ! aes_ctx )
- return -1;
-
- cipher_setkey ( &aes_algorithm, aes_ctx, kek, 16 );
-
- /* Set up */
- memset ( A, 0xA6, 8 );
- memmove ( dest + 8, src, nblk * 8 );
-
- /* Wrap */
- for ( j = 0; j < 6; j++ ) {
- R = dest + 8;
- for ( i = 1; i <= nblk; i++ ) {
- memcpy ( B, A, 8 );
- memcpy ( B + 8, R, 8 );
- cipher_encrypt ( &aes_algorithm, aes_ctx, B, B, 16 );
- memcpy ( A, B, 8 );
- A[7] ^= ( nblk * j ) + i;
- memcpy ( R, B + 8, 8 );
- R += 8;
- }
- }
-
- free ( aes_ctx );
- return 0;
-}
-
-/**
- * Unwrap a key or other data using AES Key Wrap (RFC 3394)
- *
- * @v kek Key Encryption Key, 16 bytes
- * @v src Data to decrypt
- * @v nblk Number of 8-byte blocks in @e plaintext key
- * @ret dest Decrypted data (8 bytes shorter than input)
- * @ret rc Zero on success, nonzero on IV mismatch
- *
- * The algorithm is implemented such that @a src and @a dest may point
- * to the same buffer.
- */
-int aes_unwrap ( const void *kek, const void *src, void *dest, int nblk )
-{
- u8 A[8], B[16];
- u8 *R;
- int i, j;
- void *aes_ctx = malloc ( AES_CTX_SIZE );
-
- if ( ! aes_ctx )
- return -1;
-
- cipher_setkey ( &aes_algorithm, aes_ctx, kek, 16 );
-
- /* Set up */
- memcpy ( A, src, 8 );
- memmove ( dest, src + 8, nblk * 8 );
-
- /* Unwrap */
- for ( j = 5; j >= 0; j-- ) {
- R = dest + ( nblk - 1 ) * 8;
- for ( i = nblk; i >= 1; i-- ) {
- memcpy ( B, A, 8 );
- memcpy ( B + 8, R, 8 );
- B[7] ^= ( nblk * j ) + i;
- cipher_decrypt ( &aes_algorithm, aes_ctx, B, B, 16 );
- memcpy ( A, B, 8 );
- memcpy ( R, B + 8, 8 );
- R -= 8;
- }
- }
-
- free ( aes_ctx );
-
- /* Check IV */
- for ( i = 0; i < 8; i++ ) {
- if ( A[i] != 0xA6 )
- return -1;
- }
-
- return 0;
-}
diff --git a/qemu/roms/ipxe/src/crypto/arc4.c b/qemu/roms/ipxe/src/crypto/arc4.c
deleted file mode 100644
index 91a732019..000000000
--- a/qemu/roms/ipxe/src/crypto/arc4.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * The ARC4 stream cipher.
- *
- * Copyright (c) 2009 Joshua Oreman <oremanj@rwcr.net>.
- *
- * 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; either version 2 of the
- * License, or any later version.
- *
- * 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.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include <ipxe/crypto.h>
-#include <ipxe/arc4.h>
-
-#define SWAP( ary, i, j ) \
- ({ u8 temp = ary[i]; ary[i] = ary[j]; ary[j] = temp; })
-
-/**
- * Set ARC4 key
- *
- * @v ctxv ARC4 encryption context
- * @v keyv Key to set
- * @v keylen Length of key
- *
- * If an initialisation vector is to be used, it should be prepended
- * to the key; ARC4 does not implement the @c setiv function because
- * there is no standard length for an initialisation vector in the
- * cipher.
- */
-static int arc4_setkey ( void *ctxv, const void *keyv, size_t keylen )
-{
- struct arc4_ctx *ctx = ctxv;
- const u8 *key = keyv;
- u8 *S = ctx->state;
- int i, j;
-
- for ( i = 0; i < 256; i++ ) {
- S[i] = i;
- }
-
- for ( i = j = 0; i < 256; i++ ) {
- j = ( j + S[i] + key[i % keylen] ) & 0xff;
- SWAP ( S, i, j );
- }
-
- ctx->i = ctx->j = 0;
- return 0;
-}
-
-/**
- * Perform ARC4 encryption or decryption
- *
- * @v ctxv ARC4 encryption context
- * @v srcv Data to encrypt or decrypt
- * @v dstv Location to store encrypted or decrypted data
- * @v len Length of data to operate on
- *
- * ARC4 is a stream cipher that works by generating a stream of PRNG
- * data based on the key, and XOR'ing it with the data to be
- * encrypted. Since XOR is symmetric, encryption and decryption in
- * ARC4 are the same operation.
- *
- * If you pass a @c NULL source or destination pointer, @a len
- * keystream bytes will be consumed without encrypting any data.
- */
-static void arc4_xor ( void *ctxv, const void *srcv, void *dstv,
- size_t len )
-{
- struct arc4_ctx *ctx = ctxv;
- const u8 *src = srcv;
- u8 *dst = dstv;
- u8 *S = ctx->state;
- int i = ctx->i, j = ctx->j;
-
- while ( len-- ) {
- i = ( i + 1 ) & 0xff;
- j = ( j + S[i] ) & 0xff;
- SWAP ( S, i, j );
- if ( srcv && dstv )
- *dst++ = *src++ ^ S[(S[i] + S[j]) & 0xff];
- }
-
- ctx->i = i;
- ctx->j = j;
-}
-
-static void arc4_setiv ( void *ctx __unused, const void *iv __unused )
-{
- /* ARC4 does not use a fixed-length IV */
-}
-
-
-/**
- * Perform ARC4 encryption or decryption, skipping initial keystream bytes
- *
- * @v key ARC4 encryption key
- * @v keylen Key length
- * @v skip Number of bytes of keystream to skip
- * @v src Message to encrypt or decrypt
- * @v msglen Length of message
- * @ret dst Encrypted or decrypted message
- */
-void arc4_skip ( const void *key, size_t keylen, size_t skip,
- const void *src, void *dst, size_t msglen )
-{
- struct arc4_ctx ctx;
- arc4_setkey ( &ctx, key, keylen );
- arc4_xor ( &ctx, NULL, NULL, skip );
- arc4_xor ( &ctx, src, dst, msglen );
-}
-
-struct cipher_algorithm arc4_algorithm = {
- .name = "ARC4",
- .ctxsize = ARC4_CTX_SIZE,
- .blocksize = 1,
- .setkey = arc4_setkey,
- .setiv = arc4_setiv,
- .encrypt = arc4_xor,
- .decrypt = arc4_xor,
-};
diff --git a/qemu/roms/ipxe/src/crypto/asn1.c b/qemu/roms/ipxe/src/crypto/asn1.c
deleted file mode 100644
index aca12bf30..000000000
--- a/qemu/roms/ipxe/src/crypto/asn1.c
+++ /dev/null
@@ -1,851 +0,0 @@
-/*
- * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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; either version 2 of the
- * License, or any later version.
- *
- * 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.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <stdint.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <errno.h>
-#include <time.h>
-#include <ipxe/tables.h>
-#include <ipxe/asn1.h>
-
-/** @file
- *
- * ASN.1 encoding
- *
- */
-
-/* Disambiguate the various error causes */
-#define EINVAL_ASN1_EMPTY \
- __einfo_error ( EINFO_EINVAL_ASN1_EMPTY )
-#define EINFO_EINVAL_ASN1_EMPTY \
- __einfo_uniqify ( EINFO_EINVAL, 0x01, "Empty or underlength cursor" )
-#define EINVAL_ASN1_LEN_LEN \
- __einfo_error ( EINFO_EINVAL_ASN1_LEN_LEN )
-#define EINFO_EINVAL_ASN1_LEN_LEN \
- __einfo_uniqify ( EINFO_EINVAL, 0x02, "Length field overruns cursor" )
-#define EINVAL_ASN1_LEN \
- __einfo_error ( EINFO_EINVAL_ASN1_LEN )
-#define EINFO_EINVAL_ASN1_LEN \
- __einfo_uniqify ( EINFO_EINVAL, 0x03, "Field overruns cursor" )
-#define EINVAL_ASN1_BOOLEAN \
- __einfo_error ( EINFO_EINVAL_ASN1_BOOLEAN )
-#define EINFO_EINVAL_ASN1_BOOLEAN \
- __einfo_uniqify ( EINFO_EINVAL, 0x04, "Invalid boolean" )
-#define EINVAL_ASN1_INTEGER \
- __einfo_error ( EINFO_EINVAL_ASN1_INTEGER )
-#define EINFO_EINVAL_ASN1_INTEGER \
- __einfo_uniqify ( EINFO_EINVAL, 0x04, "Invalid integer" )
-#define EINVAL_ASN1_TIME \
- __einfo_error ( EINFO_EINVAL_ASN1_TIME )
-#define EINFO_EINVAL_ASN1_TIME \
- __einfo_uniqify ( EINFO_EINVAL, 0x05, "Invalid time" )
-#define EINVAL_ASN1_ALGORITHM \
- __einfo_error ( EINFO_EINVAL_ASN1_ALGORITHM )
-#define EINFO_EINVAL_ASN1_ALGORITHM \
- __einfo_uniqify ( EINFO_EINVAL, 0x06, "Invalid algorithm" )
-#define EINVAL_BIT_STRING \
- __einfo_error ( EINFO_EINVAL_BIT_STRING )
-#define EINFO_EINVAL_BIT_STRING \
- __einfo_uniqify ( EINFO_EINVAL, 0x07, "Invalid bit string" )
-#define ENOTSUP_ALGORITHM \
- __einfo_error ( EINFO_ENOTSUP_ALGORITHM )
-#define EINFO_ENOTSUP_ALGORITHM \
- __einfo_uniqify ( EINFO_ENOTSUP, 0x01, "Unsupported algorithm" )
-#define ENOTTY_ALGORITHM \
- __einfo_error ( EINFO_ENOTTY_ALGORITHM )
-#define EINFO_ENOTTY_ALGORITHM \
- __einfo_uniqify ( EINFO_ENOTTY, 0x01, "Inappropriate algorithm" )
-
-/**
- * Invalidate ASN.1 object cursor
- *
- * @v cursor ASN.1 object cursor
- */
-void asn1_invalidate_cursor ( struct asn1_cursor *cursor ) {
- static uint8_t asn1_invalid_object[] = { ASN1_END, 0 };
-
- cursor->data = asn1_invalid_object;
- cursor->len = 0;
-}
-
-/**
- * Start parsing ASN.1 object
- *
- * @v cursor ASN.1 object cursor
- * @v type Expected type, or ASN1_ANY
- * @ret len Length of object body, or negative error
- *
- * The object cursor will be updated to point to the start of the
- * object body (i.e. the first byte following the length byte(s)), and
- * the length of the object body (i.e. the number of bytes until the
- * following object tag, if any) is returned.
- */
-static int asn1_start ( struct asn1_cursor *cursor, unsigned int type ) {
- unsigned int len_len;
- unsigned int len;
-
- /* Sanity check */
- if ( cursor->len < 2 /* Tag byte and first length byte */ ) {
- if ( cursor->len )
- DBGC ( cursor, "ASN1 %p too short\n", cursor );
- return -EINVAL_ASN1_EMPTY;
- }
-
- /* Check the tag byte */
- if ( ( type != ASN1_ANY ) && ( type != asn1_type ( cursor ) ) ) {
- DBGC ( cursor, "ASN1 %p type mismatch (expected %d, got %d)\n",
- cursor, type, *( ( uint8_t * ) cursor->data ) );
- return -ENXIO;
- }
- cursor->data++;
- cursor->len--;
-
- /* Extract length of the length field and sanity check */
- len_len = *( ( uint8_t * ) cursor->data );
- if ( len_len & 0x80 ) {
- len_len = ( len_len & 0x7f );
- cursor->data++;
- cursor->len--;
- } else {
- len_len = 1;
- }
- if ( cursor->len < len_len ) {
- DBGC ( cursor, "ASN1 %p bad length field length %d (max "
- "%zd)\n", cursor, len_len, cursor->len );
- return -EINVAL_ASN1_LEN_LEN;
- }
-
- /* Extract the length and sanity check */
- for ( len = 0 ; len_len ; len_len-- ) {
- len <<= 8;
- len |= *( ( uint8_t * ) cursor->data );
- cursor->data++;
- cursor->len--;
- }
- if ( cursor->len < len ) {
- DBGC ( cursor, "ASN1 %p bad length %d (max %zd)\n",
- cursor, len, cursor->len );
- return -EINVAL_ASN1_LEN;
- }
-
- return len;
-}
-
-/**
- * Enter ASN.1 object
- *
- * @v cursor ASN.1 object cursor
- * @v type Expected type, or ASN1_ANY
- * @ret rc Return status code
- *
- * The object cursor will be updated to point to the body of the
- * current ASN.1 object. If any error occurs, the object cursor will
- * be invalidated.
- */
-int asn1_enter ( struct asn1_cursor *cursor, unsigned int type ) {
- int len;
-
- len = asn1_start ( cursor, type );
- if ( len < 0 ) {
- asn1_invalidate_cursor ( cursor );
- return len;
- }
-
- cursor->len = len;
- DBGC ( cursor, "ASN1 %p entered object type %02x (len %x)\n",
- cursor, type, len );
-
- return 0;
-}
-
-/**
- * Skip ASN.1 object if present
- *
- * @v cursor ASN.1 object cursor
- * @v type Expected type, or ASN1_ANY
- * @ret rc Return status code
- *
- * The object cursor will be updated to point to the next ASN.1
- * object. If any error occurs, the object cursor will not be
- * modified.
- */
-int asn1_skip_if_exists ( struct asn1_cursor *cursor, unsigned int type ) {
- int len;
-
- len = asn1_start ( cursor, type );
- if ( len < 0 )
- return len;
-
- cursor->data += len;
- cursor->len -= len;
- DBGC ( cursor, "ASN1 %p skipped object type %02x (len %x)\n",
- cursor, type, len );
-
- if ( ! cursor->len ) {
- DBGC ( cursor, "ASN1 %p reached end of object\n", cursor );
- return -ENOENT;
- }
-
- return 0;
-}
-
-/**
- * Skip ASN.1 object
- *
- * @v cursor ASN.1 object cursor
- * @v type Expected type, or ASN1_ANY
- * @ret rc Return status code
- *
- * The object cursor will be updated to point to the next ASN.1
- * object. If any error occurs, the object cursor will be
- * invalidated.
- */
-int asn1_skip ( struct asn1_cursor *cursor, unsigned int type ) {
- int rc;
-
- if ( ( rc = asn1_skip_if_exists ( cursor, type ) ) != 0 ) {
- asn1_invalidate_cursor ( cursor );
- return rc;
- }
-
- return 0;
-}
-
-/**
- * Shrink ASN.1 cursor to fit object
- *
- * @v cursor ASN.1 object cursor
- * @v type Expected type, or ASN1_ANY
- * @ret rc Return status code
- *
- * The object cursor will be shrunk to contain only the current ASN.1
- * object. If any error occurs, the object cursor will be
- * invalidated.
- */
-int asn1_shrink ( struct asn1_cursor *cursor, unsigned int type ) {
- struct asn1_cursor temp;
- const void *end;
- int len;
-
- /* Find end of object */
- memcpy ( &temp, cursor, sizeof ( temp ) );
- len = asn1_start ( &temp, type );
- if ( len < 0 ) {
- asn1_invalidate_cursor ( cursor );
- return len;
- }
- end = ( temp.data + len );
-
- /* Shrink original cursor to contain only its first object */
- cursor->len = ( end - cursor->data );
-
- return 0;
-}
-
-/**
- * Enter ASN.1 object of any type
- *
- * @v cursor ASN.1 object cursor
- * @ret rc Return status code
- */
-int asn1_enter_any ( struct asn1_cursor *cursor ) {
- return asn1_enter ( cursor, ASN1_ANY );
-}
-
-/**
- * Skip ASN.1 object of any type
- *
- * @v cursor ASN.1 object cursor
- * @ret rc Return status code
- */
-int asn1_skip_any ( struct asn1_cursor *cursor ) {
- return asn1_skip ( cursor, ASN1_ANY );
-}
-
-/**
- * Shrink ASN.1 object of any type
- *
- * @v cursor ASN.1 object cursor
- * @ret rc Return status code
- */
-int asn1_shrink_any ( struct asn1_cursor *cursor ) {
- return asn1_shrink ( cursor, ASN1_ANY );
-}
-
-/**
- * Parse value of ASN.1 boolean
- *
- * @v cursor ASN.1 object cursor
- * @ret value Value, or negative error
- */
-int asn1_boolean ( const struct asn1_cursor *cursor ) {
- struct asn1_cursor contents;
- const struct {
- uint8_t value;
- } __attribute__ (( packed )) *boolean;
-
- /* Enter boolean */
- memcpy ( &contents, cursor, sizeof ( contents ) );
- asn1_enter ( &contents, ASN1_BOOLEAN );
- if ( contents.len != sizeof ( *boolean ) )
- return -EINVAL_ASN1_BOOLEAN;
-
- /* Extract value */
- boolean = contents.data;
- return boolean->value;
-}
-
-/**
- * Parse value of ASN.1 integer
- *
- * @v cursor ASN.1 object cursor
- * @v value Value to fill in
- * @ret rc Return status code
- */
-int asn1_integer ( const struct asn1_cursor *cursor, int *value ) {
- struct asn1_cursor contents;
- uint8_t high_byte;
- int rc;
-
- /* Enter integer */
- memcpy ( &contents, cursor, sizeof ( contents ) );
- if ( ( rc = asn1_enter ( &contents, ASN1_INTEGER ) ) != 0 )
- return rc;
- if ( contents.len < 1 )
- return -EINVAL_ASN1_INTEGER;
-
- /* Initialise value according to sign byte */
- *value = *( ( int8_t * ) contents.data );
- contents.data++;
- contents.len--;
-
- /* Process value */
- while ( contents.len ) {
- high_byte = ( (*value) >> ( 8 * ( sizeof ( *value ) - 1 ) ) );
- if ( ( high_byte != 0x00 ) && ( high_byte != 0xff ) ) {
- DBGC ( cursor, "ASN1 %p integer overflow\n", cursor );
- return -EINVAL_ASN1_INTEGER;
- }
- *value = ( ( *value << 8 ) | *( ( uint8_t * ) contents.data ) );
- contents.data++;
- contents.len--;
- }
-
- return 0;
-}
-
-/**
- * Parse ASN.1 bit string
- *
- * @v cursor ASN.1 cursor
- * @v bits Bit string to fill in
- * @ret rc Return status code
- */
-int asn1_bit_string ( const struct asn1_cursor *cursor,
- struct asn1_bit_string *bits ) {
- struct asn1_cursor contents;
- const struct {
- uint8_t unused;
- uint8_t data[0];
- } __attribute__ (( packed )) *bit_string;
- size_t len;
- unsigned int unused;
- uint8_t unused_mask;
- const uint8_t *last;
- int rc;
-
- /* Enter bit string */
- memcpy ( &contents, cursor, sizeof ( contents ) );
- if ( ( rc = asn1_enter ( &contents, ASN1_BIT_STRING ) ) != 0 ) {
- DBGC ( cursor, "ASN1 %p cannot locate bit string:\n", cursor );
- DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
- return rc;
- }
-
- /* Validity checks */
- if ( contents.len < sizeof ( *bit_string ) ) {
- DBGC ( cursor, "ASN1 %p invalid bit string:\n", cursor );
- DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
- return -EINVAL_BIT_STRING;
- }
- bit_string = contents.data;
- len = ( contents.len - offsetof ( typeof ( *bit_string ), data ) );
- unused = bit_string->unused;
- unused_mask = ( 0xff >> ( 8 - unused ) );
- last = ( bit_string->data + len - 1 );
- if ( ( unused >= 8 ) ||
- ( ( unused > 0 ) && ( len == 0 ) ) ||
- ( ( *last & unused_mask ) != 0 ) ) {
- DBGC ( cursor, "ASN1 %p invalid bit string:\n", cursor );
- DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
- return -EINVAL_BIT_STRING;
- }
-
- /* Populate bit string */
- bits->data = &bit_string->data;
- bits->len = len;
- bits->unused = unused;
-
- return 0;
-}
-
-/**
- * Parse ASN.1 bit string that must be an integral number of bytes
- *
- * @v cursor ASN.1 cursor
- * @v bits Bit string to fill in
- * @ret rc Return status code
- */
-int asn1_integral_bit_string ( const struct asn1_cursor *cursor,
- struct asn1_bit_string *bits ) {
- int rc;
-
- /* Parse bit string */
- if ( ( rc = asn1_bit_string ( cursor, bits ) ) != 0 )
- return rc;
-
- /* Check that there are no unused bits at end of string */
- if ( bits->unused ) {
- DBGC ( cursor, "ASN1 %p invalid integral bit string:\n",
- cursor );
- DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
- return -EINVAL_BIT_STRING;
- }
-
- return 0;
-}
-
-/**
- * Compare two ASN.1 objects
- *
- * @v cursor1 ASN.1 object cursor
- * @v cursor2 ASN.1 object cursor
- * @ret difference Difference as returned by memcmp()
- *
- * Note that invalid and empty cursors will compare as equal with each
- * other.
- */
-int asn1_compare ( const struct asn1_cursor *cursor1,
- const struct asn1_cursor *cursor2 ) {
- int difference;
-
- difference = ( cursor2->len - cursor1->len );
- return ( difference ? difference :
- memcmp ( cursor1->data, cursor2->data, cursor1->len ) );
-}
-
-/**
- * Identify ASN.1 algorithm by OID
- *
- * @v cursor ASN.1 object cursor
-
- * @ret algorithm Algorithm, or NULL
- */
-static struct asn1_algorithm *
-asn1_find_algorithm ( const struct asn1_cursor *cursor ) {
- struct asn1_algorithm *algorithm;
-
- for_each_table_entry ( algorithm, ASN1_ALGORITHMS ) {
- if ( asn1_compare ( &algorithm->oid, cursor ) == 0 )
- return algorithm;
- }
-
- return NULL;
-}
-
-/**
- * Parse ASN.1 OID-identified algorithm
- *
- * @v cursor ASN.1 object cursor
- * @ret algorithm Algorithm
- * @ret rc Return status code
- */
-int asn1_algorithm ( const struct asn1_cursor *cursor,
- struct asn1_algorithm **algorithm ) {
- struct asn1_cursor contents;
- int rc;
-
- /* Enter signatureAlgorithm */
- memcpy ( &contents, cursor, sizeof ( contents ) );
- asn1_enter ( &contents, ASN1_SEQUENCE );
-
- /* Enter algorithm */
- if ( ( rc = asn1_enter ( &contents, ASN1_OID ) ) != 0 ) {
- DBGC ( cursor, "ASN1 %p cannot locate algorithm OID:\n",
- cursor );
- DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
- return -EINVAL_ASN1_ALGORITHM;
- }
-
- /* Identify algorithm */
- *algorithm = asn1_find_algorithm ( &contents );
- if ( ! *algorithm ) {
- DBGC ( cursor, "ASN1 %p unrecognised algorithm:\n", cursor );
- DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
- return -ENOTSUP_ALGORITHM;
- }
-
- return 0;
-}
-
-/**
- * Parse ASN.1 OID-identified public-key algorithm
- *
- * @v cursor ASN.1 object cursor
- * @ret algorithm Algorithm
- * @ret rc Return status code
- */
-int asn1_pubkey_algorithm ( const struct asn1_cursor *cursor,
- struct asn1_algorithm **algorithm ) {
- int rc;
-
- /* Parse algorithm */
- if ( ( rc = asn1_algorithm ( cursor, algorithm ) ) != 0 )
- return rc;
-
- /* Check algorithm has a public key */
- if ( ! (*algorithm)->pubkey ) {
- DBGC ( cursor, "ASN1 %p algorithm %s is not a public-key "
- "algorithm:\n", cursor, (*algorithm)->name );
- DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
- return -ENOTTY_ALGORITHM;
- }
-
- return 0;
-}
-
-/**
- * Parse ASN.1 OID-identified digest algorithm
- *
- * @v cursor ASN.1 object cursor
- * @ret algorithm Algorithm
- * @ret rc Return status code
- */
-int asn1_digest_algorithm ( const struct asn1_cursor *cursor,
- struct asn1_algorithm **algorithm ) {
- int rc;
-
- /* Parse algorithm */
- if ( ( rc = asn1_algorithm ( cursor, algorithm ) ) != 0 )
- return rc;
-
- /* Check algorithm has a digest */
- if ( ! (*algorithm)->digest ) {
- DBGC ( cursor, "ASN1 %p algorithm %s is not a digest "
- "algorithm:\n", cursor, (*algorithm)->name );
- DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
- return -ENOTTY_ALGORITHM;
- }
-
- return 0;
-}
-
-/**
- * Parse ASN.1 OID-identified signature algorithm
- *
- * @v cursor ASN.1 object cursor
- * @ret algorithm Algorithm
- * @ret rc Return status code
- */
-int asn1_signature_algorithm ( const struct asn1_cursor *cursor,
- struct asn1_algorithm **algorithm ) {
- int rc;
-
- /* Parse algorithm */
- if ( ( rc = asn1_algorithm ( cursor, algorithm ) ) != 0 )
- return rc;
-
- /* Check algorithm has a public key */
- if ( ! (*algorithm)->pubkey ) {
- DBGC ( cursor, "ASN1 %p algorithm %s is not a signature "
- "algorithm:\n", cursor, (*algorithm)->name );
- DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
- return -ENOTTY_ALGORITHM;
- }
-
- /* Check algorithm has a digest */
- if ( ! (*algorithm)->digest ) {
- DBGC ( cursor, "ASN1 %p algorithm %s is not a signature "
- "algorithm:\n", cursor, (*algorithm)->name );
- DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
- return -ENOTTY_ALGORITHM;
- }
-
- return 0;
-}
-
-/**
- * Parse ASN.1 GeneralizedTime
- *
- * @v cursor ASN.1 cursor
- * @v time Time to fill in
- * @ret rc Return status code
- *
- * RFC 5280 section 4.1.2.5 places several restrictions on the allowed
- * formats for UTCTime and GeneralizedTime, and mandates the
- * interpretation of centuryless year values.
- */
-int asn1_generalized_time ( const struct asn1_cursor *cursor, time_t *time ) {
- struct asn1_cursor contents;
- unsigned int have_century;
- unsigned int type;
- union {
- struct {
- uint8_t century;
- uint8_t year;
- uint8_t month;
- uint8_t day;
- uint8_t hour;
- uint8_t minute;
- uint8_t second;
- } __attribute__ (( packed )) named;
- uint8_t raw[7];
- } pairs;
- struct tm tm;
- const uint8_t *data;
- size_t remaining;
- unsigned int tens;
- unsigned int units;
- unsigned int i;
- int rc;
-
- /* Determine time format utcTime/generalizedTime */
- memcpy ( &contents, cursor, sizeof ( contents ) );
- type = asn1_type ( &contents );
- switch ( type ) {
- case ASN1_UTC_TIME:
- have_century = 0;
- break;
- case ASN1_GENERALIZED_TIME:
- have_century = 1;
- break;
- default:
- DBGC ( cursor, "ASN1 %p invalid time type %02x\n",
- cursor, type );
- DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
- return -EINVAL_ASN1_TIME;
- }
-
- /* Enter utcTime/generalizedTime */
- if ( ( rc = asn1_enter ( &contents, type ) ) != 0 ) {
- DBGC ( cursor, "ASN1 %p cannot locate %s time:\n", cursor,
- ( ( type == ASN1_UTC_TIME ) ? "UTC" : "generalized" ) );
- DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
- return rc;
- }
-
- /* Parse digit string a pair at a time */
- memset ( &pairs, 0, sizeof ( pairs ) );
- data = contents.data;
- remaining = contents.len;
- for ( i = ( have_century ? 0 : 1 ) ; i < sizeof ( pairs.raw ) ; i++ ) {
- if ( remaining < 2 ) {
- /* Some certificates violate the X.509 RFC by
- * omitting the "seconds" value.
- */
- if ( i == ( sizeof ( pairs.raw ) - 1 ) )
- break;
- DBGC ( cursor, "ASN1 %p invalid time:\n", cursor );
- DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
- return -EINVAL_ASN1_TIME;
- }
- tens = data[0];
- units = data[1];
- if ( ! ( isdigit ( tens ) && isdigit ( units ) ) ) {
- DBGC ( cursor, "ASN1 %p invalid time:\n", cursor );
- DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
- return -EINVAL_ASN1_TIME;
- }
- pairs.raw[i] = ( ( 10 * ( tens - '0' ) ) + ( units - '0' ) );
- data += 2;
- remaining -= 2;
- }
-
- /* Determine century if applicable */
- if ( ! have_century )
- pairs.named.century = ( ( pairs.named.year >= 50 ) ? 19 : 20 );
-
- /* Check for trailing "Z" */
- if ( ( remaining != 1 ) || ( data[0] != 'Z' ) ) {
- DBGC ( cursor, "ASN1 %p invalid time:\n", cursor );
- DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
- return -EINVAL_ASN1_TIME;
- }
-
- /* Fill in time */
- tm.tm_year = ( ( ( pairs.named.century - 19 ) * 100 ) +
- pairs.named.year );
- tm.tm_mon = ( pairs.named.month - 1 );
- tm.tm_mday = pairs.named.day;
- tm.tm_hour = pairs.named.hour;
- tm.tm_min = pairs.named.minute;
- tm.tm_sec = pairs.named.second;
-
- /* Convert to seconds since the Epoch */
- *time = mktime ( &tm );
-
- return 0;
-}
-
-/**
- * Construct ASN.1 header
- *
- * @v header ASN.1 builder header
- * @v type Type
- * @v len Content length
- * @ret header_len Header length
- */
-static size_t asn1_header ( struct asn1_builder_header *header,
- unsigned int type, size_t len ) {
- unsigned int header_len = 2;
- unsigned int len_len = 0;
- size_t temp;
-
- /* Construct header */
- header->type = type;
- if ( len < 0x80 ) {
- header->length[0] = len;
- } else {
- for ( temp = len ; temp ; temp >>= 8 )
- len_len++;
- header->length[0] = ( 0x80 | len_len );
- header_len += len_len;
- for ( temp = len ; temp ; temp >>= 8 )
- header->length[len_len--] = ( temp & 0xff );
- }
-
- return header_len;
-}
-
-/**
- * Grow ASN.1 builder
- *
- * @v builder ASN.1 builder
- * @v extra Extra space to prepend
- * @ret rc Return status code
- */
-static int asn1_grow ( struct asn1_builder *builder, size_t extra ) {
- size_t new_len;
- void *new;
-
- /* As with the ASN1 parsing functions, make errors permanent */
- if ( builder->len && ! builder->data )
- return -ENOMEM;
-
- /* Reallocate data buffer */
- new_len = ( builder->len + extra );
- new = realloc ( builder->data, new_len );
- if ( ! new ) {
- free ( builder->data );
- builder->data = NULL;
- return -ENOMEM;
- }
- builder->data = new;
-
- /* Move existing data to end of buffer */
- memmove ( ( builder->data + extra ), builder->data, builder->len );
- builder->len = new_len;
-
- return 0;
-}
-
-/**
- * Prepend raw data to ASN.1 builder
- *
- * @v builder ASN.1 builder
- * @v data Data to prepend
- * @v len Length of data to prepend
- * @ret rc Return status code
- */
-int asn1_prepend_raw ( struct asn1_builder *builder, const void *data,
- size_t len ) {
- int rc;
-
- /* Grow buffer */
- if ( ( rc = asn1_grow ( builder, len ) ) != 0 )
- return rc;
-
- /* Populate data buffer */
- memcpy ( builder->data, data, len );
-
- return 0;
-}
-
-/**
- * Prepend data to ASN.1 builder
- *
- * @v builder ASN.1 builder
- * @v type Type
- * @v data Data to prepend
- * @v len Length of data to prepend
- * @ret rc Return status code
- */
-int asn1_prepend ( struct asn1_builder *builder, unsigned int type,
- const void *data, size_t len ) {
- struct asn1_builder_header header;
- size_t header_len;
- int rc;
-
- /* Construct header */
- header_len = asn1_header ( &header, type, len );
-
- /* Grow buffer */
- if ( ( rc = asn1_grow ( builder, header_len + len ) ) != 0 )
- return rc;
-
- /* Populate data buffer */
- memcpy ( builder->data, &header, header_len );
- memcpy ( ( builder->data + header_len ), data, len );
-
- return 0;
-}
-
-/**
- * Wrap ASN.1 builder
- *
- * @v builder ASN.1 builder
- * @v type Type
- * @ret rc Return status code
- */
-int asn1_wrap ( struct asn1_builder *builder, unsigned int type ) {
- struct asn1_builder_header header;
- size_t header_len;
- int rc;
-
- /* Construct header */
- header_len = asn1_header ( &header, type, builder->len );
-
- /* Grow buffer */
- if ( ( rc = asn1_grow ( builder, header_len ) ) != 0 )
- return rc;
-
- /* Populate data buffer */
- memcpy ( builder->data, &header, header_len );
-
- return 0;
-}
diff --git a/qemu/roms/ipxe/src/crypto/bigint.c b/qemu/roms/ipxe/src/crypto/bigint.c
deleted file mode 100644
index 50f320302..000000000
--- a/qemu/roms/ipxe/src/crypto/bigint.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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; either version 2 of the
- * License, or any later version.
- *
- * 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.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <stdint.h>
-#include <string.h>
-#include <assert.h>
-#include <ipxe/bigint.h>
-
-/** @file
- *
- * Big integer support
- */
-
-/**
- * Perform modular multiplication of big integers
- *
- * @v multiplicand0 Element 0 of big integer to be multiplied
- * @v multiplier0 Element 0 of big integer to be multiplied
- * @v modulus0 Element 0 of big integer modulus
- * @v result0 Element 0 of big integer to hold result
- * @v size Number of elements in base, modulus, and result
- * @v tmp Temporary working space
- */
-void bigint_mod_multiply_raw ( const bigint_element_t *multiplicand0,
- const bigint_element_t *multiplier0,
- const bigint_element_t *modulus0,
- bigint_element_t *result0,
- unsigned int size, void *tmp ) {
- const bigint_t ( size ) __attribute__ (( may_alias )) *multiplicand =
- ( ( const void * ) multiplicand0 );
- const bigint_t ( size ) __attribute__ (( may_alias )) *multiplier =
- ( ( const void * ) multiplier0 );
- const bigint_t ( size ) __attribute__ (( may_alias )) *modulus =
- ( ( const void * ) modulus0 );
- bigint_t ( size ) __attribute__ (( may_alias )) *result =
- ( ( void * ) result0 );
- struct {
- bigint_t ( size * 2 ) result;
- bigint_t ( size * 2 ) modulus;
- } *temp = tmp;
- int rotation;
- int i;
-
- /* Sanity check */
- assert ( sizeof ( *temp ) == bigint_mod_multiply_tmp_len ( modulus ) );
-
- /* Perform multiplication */
- bigint_multiply ( multiplicand, multiplier, &temp->result );
-
- /* Rescale modulus to match result */
- bigint_grow ( modulus, &temp->modulus );
- rotation = ( bigint_max_set_bit ( &temp->result ) -
- bigint_max_set_bit ( &temp->modulus ) );
- for ( i = 0 ; i < rotation ; i++ )
- bigint_rol ( &temp->modulus );
-
- /* Subtract multiples of modulus */
- for ( i = 0 ; i <= rotation ; i++ ) {
- if ( bigint_is_geq ( &temp->result, &temp->modulus ) )
- bigint_subtract ( &temp->modulus, &temp->result );
- bigint_ror ( &temp->modulus );
- }
-
- /* Resize result */
- bigint_shrink ( &temp->result, result );
-
- /* Sanity check */
- assert ( bigint_is_geq ( modulus, result ) );
-}
-
-/**
- * Perform modular exponentiation of big integers
- *
- * @v base0 Element 0 of big integer base
- * @v modulus0 Element 0 of big integer modulus
- * @v exponent0 Element 0 of big integer exponent
- * @v result0 Element 0 of big integer to hold result
- * @v size Number of elements in base, modulus, and result
- * @v exponent_size Number of elements in exponent
- * @v tmp Temporary working space
- */
-void bigint_mod_exp_raw ( const bigint_element_t *base0,
- const bigint_element_t *modulus0,
- const bigint_element_t *exponent0,
- bigint_element_t *result0,
- unsigned int size, unsigned int exponent_size,
- void *tmp ) {
- const bigint_t ( size ) __attribute__ (( may_alias )) *base =
- ( ( const void * ) base0 );
- const bigint_t ( size ) __attribute__ (( may_alias )) *modulus =
- ( ( const void * ) modulus0 );
- const bigint_t ( exponent_size ) __attribute__ (( may_alias ))
- *exponent = ( ( const void * ) exponent0 );
- bigint_t ( size ) __attribute__ (( may_alias )) *result =
- ( ( void * ) result0 );
- size_t mod_multiply_len = bigint_mod_multiply_tmp_len ( modulus );
- struct {
- bigint_t ( size ) base;
- bigint_t ( exponent_size ) exponent;
- uint8_t mod_multiply[mod_multiply_len];
- } *temp = tmp;
- static const uint8_t start[1] = { 0x01 };
-
- memcpy ( &temp->base, base, sizeof ( temp->base ) );
- memcpy ( &temp->exponent, exponent, sizeof ( temp->exponent ) );
- bigint_init ( result, start, sizeof ( start ) );
-
- while ( ! bigint_is_zero ( &temp->exponent ) ) {
- if ( bigint_bit_is_set ( &temp->exponent, 0 ) ) {
- bigint_mod_multiply ( result, &temp->base, modulus,
- result, temp->mod_multiply );
- }
- bigint_ror ( &temp->exponent );
- bigint_mod_multiply ( &temp->base, &temp->base, modulus,
- &temp->base, temp->mod_multiply );
- }
-}
diff --git a/qemu/roms/ipxe/src/crypto/cbc.c b/qemu/roms/ipxe/src/crypto/cbc.c
deleted file mode 100644
index 0ba17ee48..000000000
--- a/qemu/roms/ipxe/src/crypto/cbc.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2009 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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; either version 2 of the
- * License, or any later version.
- *
- * 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.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <string.h>
-#include <assert.h>
-#include <ipxe/crypto.h>
-#include <ipxe/cbc.h>
-
-/** @file
- *
- * Cipher-block chaining
- *
- */
-
-/**
- * XOR data blocks
- *
- * @v src Input data
- * @v dst Second input data and output data buffer
- * @v len Length of data
- */
-static void cbc_xor ( const void *src, void *dst, size_t len ) {
- const uint32_t *srcl = src;
- uint32_t *dstl = dst;
- unsigned int i;
-
- /* Assume that block sizes will always be dword-aligned, for speed */
- assert ( ( len % sizeof ( *srcl ) ) == 0 );
-
- for ( i = 0 ; i < ( len / sizeof ( *srcl ) ) ; i++ )
- dstl[i] ^= srcl[i];
-}
-
-/**
- * Encrypt data
- *
- * @v ctx Context
- * @v src Data to encrypt
- * @v dst Buffer for encrypted data
- * @v len Length of data
- * @v raw_cipher Underlying cipher algorithm
- * @v cbc_ctx CBC context
- */
-void cbc_encrypt ( void *ctx, const void *src, void *dst, size_t len,
- struct cipher_algorithm *raw_cipher, void *cbc_ctx ) {
- size_t blocksize = raw_cipher->blocksize;
-
- assert ( ( len % blocksize ) == 0 );
-
- while ( len ) {
- cbc_xor ( src, cbc_ctx, blocksize );
- cipher_encrypt ( raw_cipher, ctx, cbc_ctx, dst, blocksize );
- memcpy ( cbc_ctx, dst, blocksize );
- dst += blocksize;
- src += blocksize;
- len -= blocksize;
- }
-}
-
-/**
- * Decrypt data
- *
- * @v ctx Context
- * @v src Data to decrypt
- * @v dst Buffer for decrypted data
- * @v len Length of data
- * @v raw_cipher Underlying cipher algorithm
- * @v cbc_ctx CBC context
- */
-void cbc_decrypt ( void *ctx, const void *src, void *dst, size_t len,
- struct cipher_algorithm *raw_cipher, void *cbc_ctx ) {
- size_t blocksize = raw_cipher->blocksize;
- uint8_t next_cbc_ctx[blocksize];
-
- assert ( ( len % blocksize ) == 0 );
-
- while ( len ) {
- memcpy ( next_cbc_ctx, src, blocksize );
- cipher_decrypt ( raw_cipher, ctx, src, dst, blocksize );
- cbc_xor ( cbc_ctx, dst, blocksize );
- memcpy ( cbc_ctx, next_cbc_ctx, blocksize );
- dst += blocksize;
- src += blocksize;
- len -= blocksize;
- }
-}
diff --git a/qemu/roms/ipxe/src/crypto/certstore.c b/qemu/roms/ipxe/src/crypto/certstore.c
deleted file mode 100644
index 503ce499e..000000000
--- a/qemu/roms/ipxe/src/crypto/certstore.c
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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; either version 2 of the
- * License, or any later version.
- *
- * 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.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <string.h>
-#include <stdlib.h>
-#include <ipxe/init.h>
-#include <ipxe/dhcp.h>
-#include <ipxe/settings.h>
-#include <ipxe/malloc.h>
-#include <ipxe/crypto.h>
-#include <ipxe/asn1.h>
-#include <ipxe/x509.h>
-#include <ipxe/certstore.h>
-
-/** @file
- *
- * Certificate store
- *
- */
-
-/** Raw certificate data for all permanent stored certificates */
-#undef CERT
-#define CERT( _index, _path ) \
- extern char stored_cert_ ## _index ## _data[]; \
- extern char stored_cert_ ## _index ## _len[]; \
- __asm__ ( ".section \".rodata\", \"a\", @progbits\n\t" \
- "\nstored_cert_" #_index "_data:\n\t" \
- ".incbin \"" _path "\"\n\t" \
- "\nstored_cert_" #_index "_end:\n\t" \
- ".equ stored_cert_" #_index "_len, " \
- "( stored_cert_" #_index "_end - " \
- " stored_cert_" #_index "_data )\n\t" \
- ".previous\n\t" );
-CERT_ALL
-
-/** Raw certificate cursors for all permanent stored certificates */
-#undef CERT
-#define CERT( _index, _path ) { \
- .data = stored_cert_ ## _index ## _data, \
- .len = ( size_t ) stored_cert_ ## _index ## _len, \
-},
-static struct asn1_cursor certstore_raw[] = {
- CERT_ALL
-};
-
-/** X.509 certificate structures for all permanent stored certificates */
-static struct x509_certificate certstore_certs[ sizeof ( certstore_raw ) /
- sizeof ( certstore_raw[0] ) ];
-
-/** Certificate store */
-struct x509_chain certstore = {
- .refcnt = REF_INIT ( ref_no_free ),
- .links = LIST_HEAD_INIT ( certstore.links ),
-};
-
-/**
- * Mark stored certificate as most recently used
- *
- * @v cert X.509 certificate
- * @ret cert X.509 certificate
- */
-static struct x509_certificate *
-certstore_found ( struct x509_certificate *cert ) {
-
- /* Mark as most recently used */
- list_del ( &cert->store.list );
- list_add ( &cert->store.list, &certstore.links );
- DBGC2 ( &certstore, "CERTSTORE found certificate %s\n",
- x509_name ( cert ) );
-
- return cert;
-}
-
-/**
- * Find certificate in store
- *
- * @v raw Raw certificate data
- * @ret cert X.509 certificate, or NULL if not found
- */
-struct x509_certificate * certstore_find ( struct asn1_cursor *raw ) {
- struct x509_certificate *cert;
-
- /* Search for certificate within store */
- list_for_each_entry ( cert, &certstore.links, store.list ) {
- if ( asn1_compare ( raw, &cert->raw ) == 0 )
- return certstore_found ( cert );
- }
- return NULL;
-}
-
-/**
- * Find certificate in store corresponding to a private key
- *
- * @v key Private key
- * @ret cert X.509 certificate, or NULL if not found
- */
-struct x509_certificate * certstore_find_key ( struct asn1_cursor *key ) {
- struct x509_certificate *cert;
-
- /* Search for certificate within store */
- list_for_each_entry ( cert, &certstore.links, store.list ) {
- if ( pubkey_match ( cert->signature_algorithm->pubkey,
- key->data, key->len,
- cert->subject.public_key.raw.data,
- cert->subject.public_key.raw.len ) == 0 )
- return certstore_found ( cert );
- }
- return NULL;
-}
-
-/**
- * Add certificate to store
- *
- * @v cert X.509 certificate
- */
-void certstore_add ( struct x509_certificate *cert ) {
-
- /* Add certificate to store */
- cert->store.cert = cert;
- x509_get ( cert );
- list_add ( &cert->store.list, &certstore.links );
- DBGC ( &certstore, "CERTSTORE added certificate %s\n",
- x509_name ( cert ) );
-}
-
-/**
- * Discard a stored certificate
- *
- * @ret discarded Number of cached items discarded
- */
-static unsigned int certstore_discard ( void ) {
- struct x509_certificate *cert;
-
- /* Discard the least recently used certificate for which the
- * only reference is held by the store itself.
- */
- list_for_each_entry_reverse ( cert, &certstore.links, store.list ) {
- if ( cert->refcnt.count == 0 ) {
- DBGC ( &certstore, "CERTSTORE discarded certificate "
- "%s\n", x509_name ( cert ) );
- list_del ( &cert->store.list );
- x509_put ( cert );
- return 1;
- }
- }
- return 0;
-}
-
-/** Certificate store cache discarder */
-struct cache_discarder certstore_discarder __cache_discarder ( CACHE_NORMAL ) ={
- .discard = certstore_discard,
-};
-
-/**
- * Construct permanent certificate store
- *
- */
-static void certstore_init ( void ) {
- struct asn1_cursor *raw;
- struct x509_certificate *cert;
- int i;
- int rc;
-
- /* Skip if we have no permanent stored certificates */
- if ( ! sizeof ( certstore_raw ) )
- return;
-
- /* Add certificates */
- for ( i = 0 ; i < ( int ) ( sizeof ( certstore_raw ) /
- sizeof ( certstore_raw[0] ) ) ; i++ ) {
-
- /* Skip if certificate already present in store */
- raw = &certstore_raw[i];
- if ( ( cert = certstore_find ( raw ) ) != NULL ) {
- DBGC ( &certstore, "CERTSTORE permanent certificate %d "
- "is a duplicate of %s\n", i, x509_name ( cert ));
- continue;
- }
-
- /* Parse certificate */
- cert = &certstore_certs[i];
- ref_init ( &cert->refcnt, ref_no_free );
- if ( ( rc = x509_parse ( cert, raw ) ) != 0 ) {
- DBGC ( &certstore, "CERTSTORE could not parse "
- "permanent certificate %d: %s\n",
- i, strerror ( rc ) );
- continue;
- }
-
- /* Add certificate to store. Certificate will never
- * be discarded from the store, since we retain a
- * permanent reference to it.
- */
- certstore_add ( cert );
- DBGC ( &certstore, "CERTSTORE permanent certificate %d is %s\n",
- i, x509_name ( cert ) );
- }
-}
-
-/** Certificate store initialisation function */
-struct init_fn certstore_init_fn __init_fn ( INIT_LATE ) = {
- .initialise = certstore_init,
-};
-
-/** Additional certificate setting */
-static struct setting cert_setting __setting ( SETTING_CRYPTO, cert ) = {
- .name = "cert",
- .description = "Certificate",
- .tag = DHCP_EB_CERT,
- .type = &setting_type_hex,
-};
-
-/**
- * Apply certificate store configuration settings
- *
- * @ret rc Return status code
- */
-static int certstore_apply_settings ( void ) {
- static struct x509_certificate *cert = NULL;
- struct x509_certificate *old_cert;
- void *cert_data;
- int len;
- int rc;
-
- /* Record any existing additional certificate */
- old_cert = cert;
- cert = NULL;
-
- /* Add additional certificate, if any */
- if ( ( len = fetch_raw_setting_copy ( NULL, &cert_setting,
- &cert_data ) ) >= 0 ) {
- if ( ( rc = x509_certificate ( cert_data, len, &cert ) ) == 0 ){
- DBGC ( &certstore, "CERTSTORE added additional "
- "certificate %s\n", x509_name ( cert ) );
- } else {
- DBGC ( &certstore, "CERTSTORE could not parse "
- "additional certificate: %s\n",
- strerror ( rc ) );
- /* Do not fail; leave as an unusable certificate */
- }
- free ( cert_data );
- }
-
- /* Free old additional certificiate. Do this after reparsing
- * the additional certificate; in the common case that the
- * certificate has not changed, this will allow the stored
- * certificate to be reused.
- */
- x509_put ( old_cert );
-
- return 0;
-}
-
-/** Certificate store settings applicator */
-struct settings_applicator certstore_applicator __settings_applicator = {
- .apply = certstore_apply_settings,
-};
diff --git a/qemu/roms/ipxe/src/crypto/chap.c b/qemu/roms/ipxe/src/crypto/chap.c
deleted file mode 100644
index c90c16def..000000000
--- a/qemu/roms/ipxe/src/crypto/chap.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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; either version 2 of the
- * License, or any later version.
- *
- * 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.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-#include <ipxe/crypto.h>
-#include <ipxe/chap.h>
-
-/** @file
- *
- * CHAP protocol
- *
- */
-
-/**
- * Initialise CHAP challenge/response
- *
- * @v chap CHAP challenge/response
- * @v digest Digest algorithm to use
- * @ret rc Return status code
- *
- * Initialises a CHAP challenge/response structure. This routine
- * allocates memory, and so may fail. The allocated memory must
- * eventually be freed by a call to chap_finish().
- */
-int chap_init ( struct chap_response *chap,
- struct digest_algorithm *digest ) {
- size_t state_len;
- void *state;
-
- assert ( chap->digest == NULL );
- assert ( chap->digest_context == NULL );
- assert ( chap->response == NULL );
-
- DBG ( "CHAP %p initialising with %s digest\n", chap, digest->name );
-
- state_len = ( digest->ctxsize + digest->digestsize );
- state = malloc ( state_len );
- if ( ! state ) {
- DBG ( "CHAP %p could not allocate %zd bytes for state\n",
- chap, state_len );
- return -ENOMEM;
- }
-
- chap->digest = digest;
- chap->digest_context = state;
- chap->response = ( state + digest->ctxsize );
- chap->response_len = digest->digestsize;
- digest_init ( chap->digest, chap->digest_context );
- return 0;
-}
-
-/**
- * Add data to the CHAP challenge
- *
- * @v chap CHAP response
- * @v data Data to add
- * @v len Length of data to add
- */
-void chap_update ( struct chap_response *chap, const void *data,
- size_t len ) {
- assert ( chap->digest != NULL );
- assert ( chap->digest_context != NULL );
-
- if ( ! chap->digest )
- return;
-
- digest_update ( chap->digest, chap->digest_context, data, len );
-}
-
-/**
- * Respond to the CHAP challenge
- *
- * @v chap CHAP response
- *
- * Calculates the final CHAP response value, and places it in @c
- * chap->response, with a length of @c chap->response_len.
- */
-void chap_respond ( struct chap_response *chap ) {
- assert ( chap->digest != NULL );
- assert ( chap->digest_context != NULL );
- assert ( chap->response != NULL );
-
- DBG ( "CHAP %p responding to challenge\n", chap );
-
- if ( ! chap->digest )
- return;
-
- digest_final ( chap->digest, chap->digest_context, chap->response );
-}
-
-/**
- * Free resources used by a CHAP response
- *
- * @v chap CHAP response
- */
-void chap_finish ( struct chap_response *chap ) {
- void *state = chap->digest_context;
-
- DBG ( "CHAP %p finished\n", chap );
-
- free ( state );
- memset ( chap, 0, sizeof ( *chap ) );
-}
diff --git a/qemu/roms/ipxe/src/crypto/cms.c b/qemu/roms/ipxe/src/crypto/cms.c
deleted file mode 100644
index bc2148e8a..000000000
--- a/qemu/roms/ipxe/src/crypto/cms.c
+++ /dev/null
@@ -1,713 +0,0 @@
-/*
- * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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; either version 2 of the
- * License, or any later version.
- *
- * 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.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-/** @file
- *
- * Cryptographic Message Syntax (PKCS #7)
- *
- * The format of CMS messages is defined in RFC 5652.
- *
- */
-
-#include <stdint.h>
-#include <string.h>
-#include <time.h>
-#include <errno.h>
-#include <ipxe/asn1.h>
-#include <ipxe/x509.h>
-#include <ipxe/malloc.h>
-#include <ipxe/uaccess.h>
-#include <ipxe/cms.h>
-
-/* Disambiguate the various error causes */
-#define EACCES_NON_SIGNING \
- __einfo_error ( EINFO_EACCES_NON_SIGNING )
-#define EINFO_EACCES_NON_SIGNING \
- __einfo_uniqify ( EINFO_EACCES, 0x01, "Not a signing certificate" )
-#define EACCES_NON_CODE_SIGNING \
- __einfo_error ( EINFO_EACCES_NON_CODE_SIGNING )
-#define EINFO_EACCES_NON_CODE_SIGNING \
- __einfo_uniqify ( EINFO_EACCES, 0x02, "Not a code-signing certificate" )
-#define EACCES_WRONG_NAME \
- __einfo_error ( EINFO_EACCES_WRONG_NAME )
-#define EINFO_EACCES_WRONG_NAME \
- __einfo_uniqify ( EINFO_EACCES, 0x04, "Incorrect certificate name" )
-#define EACCES_NO_SIGNATURES \
- __einfo_error ( EINFO_EACCES_NO_SIGNATURES )
-#define EINFO_EACCES_NO_SIGNATURES \
- __einfo_uniqify ( EINFO_EACCES, 0x05, "No signatures present" )
-#define EINVAL_DIGEST \
- __einfo_error ( EINFO_EINVAL_DIGEST )
-#define EINFO_EINVAL_DIGEST \
- __einfo_uniqify ( EINFO_EINVAL, 0x01, "Not a digest algorithm" )
-#define EINVAL_PUBKEY \
- __einfo_error ( EINFO_EINVAL_PUBKEY )
-#define EINFO_EINVAL_PUBKEY \
- __einfo_uniqify ( EINFO_EINVAL, 0x02, "Not a public-key algorithm" )
-#define ENOTSUP_SIGNEDDATA \
- __einfo_error ( EINFO_ENOTSUP_SIGNEDDATA )
-#define EINFO_ENOTSUP_SIGNEDDATA \
- __einfo_uniqify ( EINFO_ENOTSUP, 0x01, "Not a digital signature" )
-
-/** "pkcs7-signedData" object identifier */
-static uint8_t oid_signeddata[] = { ASN1_OID_SIGNEDDATA };
-
-/** "pkcs7-signedData" object identifier cursor */
-static struct asn1_cursor oid_signeddata_cursor =
- ASN1_OID_CURSOR ( oid_signeddata );
-
-/**
- * Parse CMS signature content type
- *
- * @v sig CMS signature
- * @v raw ASN.1 cursor
- * @ret rc Return status code
- */
-static int cms_parse_content_type ( struct cms_signature *sig,
- const struct asn1_cursor *raw ) {
- struct asn1_cursor cursor;
-
- /* Enter contentType */
- memcpy ( &cursor, raw, sizeof ( cursor ) );
- asn1_enter ( &cursor, ASN1_OID );
-
- /* Check OID is pkcs7-signedData */
- if ( asn1_compare ( &cursor, &oid_signeddata_cursor ) != 0 ) {
- DBGC ( sig, "CMS %p does not contain signedData:\n", sig );
- DBGC_HDA ( sig, 0, raw->data, raw->len );
- return -ENOTSUP_SIGNEDDATA;
- }
-
- DBGC ( sig, "CMS %p contains signedData\n", sig );
- return 0;
-}
-
-/**
- * Parse CMS signature certificate list
- *
- * @v sig CMS signature
- * @v raw ASN.1 cursor
- * @ret rc Return status code
- */
-static int cms_parse_certificates ( struct cms_signature *sig,
- const struct asn1_cursor *raw ) {
- struct asn1_cursor cursor;
- struct x509_certificate *cert;
- int rc;
-
- /* Enter certificates */
- memcpy ( &cursor, raw, sizeof ( cursor ) );
- asn1_enter ( &cursor, ASN1_EXPLICIT_TAG ( 0 ) );
-
- /* Add each certificate */
- while ( cursor.len ) {
-
- /* Add certificate to chain */
- if ( ( rc = x509_append_raw ( sig->certificates, cursor.data,
- cursor.len ) ) != 0 ) {
- DBGC ( sig, "CMS %p could not append certificate: %s\n",
- sig, strerror ( rc) );
- DBGC_HDA ( sig, 0, cursor.data, cursor.len );
- return rc;
- }
- cert = x509_last ( sig->certificates );
- DBGC ( sig, "CMS %p found certificate %s\n",
- sig, x509_name ( cert ) );
-
- /* Move to next certificate */
- asn1_skip_any ( &cursor );
- }
-
- return 0;
-}
-
-/**
- * Identify CMS signature certificate by issuer and serial number
- *
- * @v sig CMS signature
- * @v issuer Issuer
- * @v serial Serial number
- * @ret cert X.509 certificate, or NULL if not found
- */
-static struct x509_certificate *
-cms_find_issuer_serial ( struct cms_signature *sig,
- const struct asn1_cursor *issuer,
- const struct asn1_cursor *serial ) {
- struct x509_link *link;
- struct x509_certificate *cert;
-
- /* Scan through certificate list */
- list_for_each_entry ( link, &sig->certificates->links, list ) {
-
- /* Check issuer and serial number */
- cert = link->cert;
- if ( ( asn1_compare ( issuer, &cert->issuer.raw ) == 0 ) &&
- ( asn1_compare ( serial, &cert->serial.raw ) == 0 ) )
- return cert;
- }
-
- return NULL;
-}
-
-/**
- * Parse CMS signature signer identifier
- *
- * @v sig CMS signature
- * @v info Signer information to fill in
- * @v raw ASN.1 cursor
- * @ret rc Return status code
- */
-static int cms_parse_signer_identifier ( struct cms_signature *sig,
- struct cms_signer_info *info,
- const struct asn1_cursor *raw ) {
- struct asn1_cursor cursor;
- struct asn1_cursor serial;
- struct asn1_cursor issuer;
- struct x509_certificate *cert;
- int rc;
-
- /* Enter issuerAndSerialNumber */
- memcpy ( &cursor, raw, sizeof ( cursor ) );
- asn1_enter ( &cursor, ASN1_SEQUENCE );
-
- /* Identify issuer */
- memcpy ( &issuer, &cursor, sizeof ( issuer ) );
- if ( ( rc = asn1_shrink ( &issuer, ASN1_SEQUENCE ) ) != 0 ) {
- DBGC ( sig, "CMS %p/%p could not locate issuer: %s\n",
- sig, info, strerror ( rc ) );
- DBGC_HDA ( sig, 0, raw->data, raw->len );
- return rc;
- }
- DBGC ( sig, "CMS %p/%p issuer is:\n", sig, info );
- DBGC_HDA ( sig, 0, issuer.data, issuer.len );
- asn1_skip_any ( &cursor );
-
- /* Identify serialNumber */
- memcpy ( &serial, &cursor, sizeof ( serial ) );
- if ( ( rc = asn1_shrink ( &serial, ASN1_INTEGER ) ) != 0 ) {
- DBGC ( sig, "CMS %p/%p could not locate serialNumber: %s\n",
- sig, info, strerror ( rc ) );
- DBGC_HDA ( sig, 0, raw->data, raw->len );
- return rc;
- }
- DBGC ( sig, "CMS %p/%p serial number is:\n", sig, info );
- DBGC_HDA ( sig, 0, serial.data, serial.len );
-
- /* Identify certificate */
- cert = cms_find_issuer_serial ( sig, &issuer, &serial );
- if ( ! cert ) {
- DBGC ( sig, "CMS %p/%p could not identify signer's "
- "certificate\n", sig, info );
- return -ENOENT;
- }
-
- /* Append certificate to chain */
- if ( ( rc = x509_append ( info->chain, cert ) ) != 0 ) {
- DBGC ( sig, "CMS %p/%p could not append certificate: %s\n",
- sig, info, strerror ( rc ) );
- return rc;
- }
-
- /* Append remaining certificates to chain */
- if ( ( rc = x509_auto_append ( info->chain,
- sig->certificates ) ) != 0 ) {
- DBGC ( sig, "CMS %p/%p could not append certificates: %s\n",
- sig, info, strerror ( rc ) );
- return rc;
- }
-
- return 0;
-}
-
-/**
- * Parse CMS signature digest algorithm
- *
- * @v sig CMS signature
- * @v info Signer information to fill in
- * @v raw ASN.1 cursor
- * @ret rc Return status code
- */
-static int cms_parse_digest_algorithm ( struct cms_signature *sig,
- struct cms_signer_info *info,
- const struct asn1_cursor *raw ) {
- struct asn1_algorithm *algorithm;
- int rc;
-
- /* Identify algorithm */
- if ( ( rc = asn1_digest_algorithm ( raw, &algorithm ) ) != 0 ) {
- DBGC ( sig, "CMS %p/%p could not identify digest algorithm: "
- "%s\n", sig, info, strerror ( rc ) );
- DBGC_HDA ( sig, 0, raw->data, raw->len );
- return rc;
- }
-
- /* Record digest algorithm */
- info->digest = algorithm->digest;
- DBGC ( sig, "CMS %p/%p digest algorithm is %s\n",
- sig, info, algorithm->name );
-
- return 0;
-}
-
-/**
- * Parse CMS signature algorithm
- *
- * @v sig CMS signature
- * @v info Signer information to fill in
- * @v raw ASN.1 cursor
- * @ret rc Return status code
- */
-static int cms_parse_signature_algorithm ( struct cms_signature *sig,
- struct cms_signer_info *info,
- const struct asn1_cursor *raw ) {
- struct asn1_algorithm *algorithm;
- int rc;
-
- /* Identify algorithm */
- if ( ( rc = asn1_pubkey_algorithm ( raw, &algorithm ) ) != 0 ) {
- DBGC ( sig, "CMS %p/%p could not identify public-key "
- "algorithm: %s\n", sig, info, strerror ( rc ) );
- DBGC_HDA ( sig, 0, raw->data, raw->len );
- return rc;
- }
-
- /* Record signature algorithm */
- info->pubkey = algorithm->pubkey;
- DBGC ( sig, "CMS %p/%p public-key algorithm is %s\n",
- sig, info, algorithm->name );
-
- return 0;
-}
-
-/**
- * Parse CMS signature value
- *
- * @v sig CMS signature
- * @v info Signer information to fill in
- * @v raw ASN.1 cursor
- * @ret rc Return status code
- */
-static int cms_parse_signature_value ( struct cms_signature *sig,
- struct cms_signer_info *info,
- const struct asn1_cursor *raw ) {
- struct asn1_cursor cursor;
- int rc;
-
- /* Enter signature */
- memcpy ( &cursor, raw, sizeof ( cursor ) );
- if ( ( rc = asn1_enter ( &cursor, ASN1_OCTET_STRING ) ) != 0 ) {
- DBGC ( sig, "CMS %p/%p could not locate signature:\n",
- sig, info );
- DBGC_HDA ( sig, 0, raw->data, raw->len );
- return rc;
- }
-
- /* Record signature */
- info->signature_len = cursor.len;
- info->signature = malloc ( info->signature_len );
- if ( ! info->signature )
- return -ENOMEM;
- memcpy ( info->signature, cursor.data, info->signature_len );
- DBGC ( sig, "CMS %p/%p signature value is:\n", sig, info );
- DBGC_HDA ( sig, 0, info->signature, info->signature_len );
-
- return 0;
-}
-
-/**
- * Parse CMS signature signer information
- *
- * @v sig CMS signature
- * @v info Signer information to fill in
- * @v raw ASN.1 cursor
- * @ret rc Return status code
- */
-static int cms_parse_signer_info ( struct cms_signature *sig,
- struct cms_signer_info *info,
- const struct asn1_cursor *raw ) {
- struct asn1_cursor cursor;
- int rc;
-
- /* Enter signerInfo */
- memcpy ( &cursor, raw, sizeof ( cursor ) );
- asn1_enter ( &cursor, ASN1_SEQUENCE );
-
- /* Skip version */
- asn1_skip ( &cursor, ASN1_INTEGER );
-
- /* Parse sid */
- if ( ( rc = cms_parse_signer_identifier ( sig, info, &cursor ) ) != 0 )
- return rc;
- asn1_skip_any ( &cursor );
-
- /* Parse digestAlgorithm */
- if ( ( rc = cms_parse_digest_algorithm ( sig, info, &cursor ) ) != 0 )
- return rc;
- asn1_skip_any ( &cursor );
-
- /* Skip signedAttrs, if present */
- asn1_skip_if_exists ( &cursor, ASN1_EXPLICIT_TAG ( 0 ) );
-
- /* Parse signatureAlgorithm */
- if ( ( rc = cms_parse_signature_algorithm ( sig, info, &cursor ) ) != 0)
- return rc;
- asn1_skip_any ( &cursor );
-
- /* Parse signature */
- if ( ( rc = cms_parse_signature_value ( sig, info, &cursor ) ) != 0 )
- return rc;
-
- return 0;
-}
-
-/**
- * Parse CMS signature from ASN.1 data
- *
- * @v sig CMS signature
- * @v raw ASN.1 cursor
- * @ret rc Return status code
- */
-static int cms_parse ( struct cms_signature *sig,
- const struct asn1_cursor *raw ) {
- struct asn1_cursor cursor;
- struct cms_signer_info *info;
- int rc;
-
- /* Enter contentInfo */
- memcpy ( &cursor, raw, sizeof ( cursor ) );
- asn1_enter ( &cursor, ASN1_SEQUENCE );
-
- /* Parse contentType */
-
- if ( ( rc = cms_parse_content_type ( sig, &cursor ) ) != 0 )
- return rc;
- asn1_skip_any ( &cursor );
-
- /* Enter content */
- asn1_enter ( &cursor, ASN1_EXPLICIT_TAG ( 0 ) );
-
- /* Enter signedData */
- asn1_enter ( &cursor, ASN1_SEQUENCE );
-
- /* Skip version */
- asn1_skip ( &cursor, ASN1_INTEGER );
-
- /* Skip digestAlgorithms */
- asn1_skip ( &cursor, ASN1_SET );
-
- /* Skip encapContentInfo */
- asn1_skip ( &cursor, ASN1_SEQUENCE );
-
- /* Parse certificates */
- if ( ( rc = cms_parse_certificates ( sig, &cursor ) ) != 0 )
- return rc;
- asn1_skip_any ( &cursor );
-
- /* Skip crls, if present */
- asn1_skip_if_exists ( &cursor, ASN1_EXPLICIT_TAG ( 1 ) );
-
- /* Enter signerInfos */
- asn1_enter ( &cursor, ASN1_SET );
-
- /* Add each signerInfo. Errors are handled by ensuring that
- * cms_put() will always be able to free any allocated memory.
- */
- while ( cursor.len ) {
-
- /* Allocate signer information block */
- info = zalloc ( sizeof ( *info ) );
- if ( ! info )
- return -ENOMEM;
- list_add ( &info->list, &sig->info );
-
- /* Allocate certificate chain */
- info->chain = x509_alloc_chain();
- if ( ! info->chain )
- return -ENOMEM;
-
- /* Parse signerInfo */
- if ( ( rc = cms_parse_signer_info ( sig, info,
- &cursor ) ) != 0 )
- return rc;
- asn1_skip_any ( &cursor );
- }
-
- return 0;
-}
-
-/**
- * Free CMS signature
- *
- * @v refcnt Reference count
- */
-static void cms_free ( struct refcnt *refcnt ) {
- struct cms_signature *sig =
- container_of ( refcnt, struct cms_signature, refcnt );
- struct cms_signer_info *info;
- struct cms_signer_info *tmp;
-
- list_for_each_entry_safe ( info, tmp, &sig->info, list ) {
- list_del ( &info->list );
- x509_chain_put ( info->chain );
- free ( info->signature );
- free ( info );
- }
- x509_chain_put ( sig->certificates );
- free ( sig );
-}
-
-/**
- * Create CMS signature
- *
- * @v data Raw signature data
- * @v len Length of raw data
- * @ret sig CMS signature
- * @ret rc Return status code
- *
- * On success, the caller holds a reference to the CMS signature, and
- * is responsible for ultimately calling cms_put().
- */
-int cms_signature ( const void *data, size_t len, struct cms_signature **sig ) {
- struct asn1_cursor cursor;
- int rc;
-
- /* Allocate and initialise signature */
- *sig = zalloc ( sizeof ( **sig ) );
- if ( ! *sig ) {
- rc = -ENOMEM;
- goto err_alloc;
- }
- ref_init ( &(*sig)->refcnt, cms_free );
- INIT_LIST_HEAD ( &(*sig)->info );
-
- /* Allocate certificate list */
- (*sig)->certificates = x509_alloc_chain();
- if ( ! (*sig)->certificates ) {
- rc = -ENOMEM;
- goto err_alloc_chain;
- }
-
- /* Initialise cursor */
- cursor.data = data;
- cursor.len = len;
- asn1_shrink_any ( &cursor );
-
- /* Parse signature */
- if ( ( rc = cms_parse ( *sig, &cursor ) ) != 0 )
- goto err_parse;
-
- return 0;
-
- err_parse:
- err_alloc_chain:
- cms_put ( *sig );
- err_alloc:
- return rc;
-}
-
-/**
- * Calculate digest of CMS-signed data
- *
- * @v sig CMS signature
- * @v info Signer information
- * @v data Signed data
- * @v len Length of signed data
- * @v out Digest output
- */
-static void cms_digest ( struct cms_signature *sig,
- struct cms_signer_info *info,
- userptr_t data, size_t len, void *out ) {
- struct digest_algorithm *digest = info->digest;
- uint8_t ctx[ digest->ctxsize ];
- uint8_t block[ digest->blocksize ];
- size_t offset = 0;
- size_t frag_len;
-
- /* Initialise digest */
- digest_init ( digest, ctx );
-
- /* Process data one block at a time */
- while ( len ) {
- frag_len = len;
- if ( frag_len > sizeof ( block ) )
- frag_len = sizeof ( block );
- copy_from_user ( block, data, offset, frag_len );
- digest_update ( digest, ctx, block, frag_len );
- offset += frag_len;
- len -= frag_len;
- }
-
- /* Finalise digest */
- digest_final ( digest, ctx, out );
-
- DBGC ( sig, "CMS %p/%p digest value:\n", sig, info );
- DBGC_HDA ( sig, 0, out, digest->digestsize );
-}
-
-/**
- * Verify digest of CMS-signed data
- *
- * @v sig CMS signature
- * @v info Signer information
- * @v cert Corresponding certificate
- * @v data Signed data
- * @v len Length of signed data
- * @ret rc Return status code
- */
-static int cms_verify_digest ( struct cms_signature *sig,
- struct cms_signer_info *info,
- struct x509_certificate *cert,
- userptr_t data, size_t len ) {
- struct digest_algorithm *digest = info->digest;
- struct pubkey_algorithm *pubkey = info->pubkey;
- struct x509_public_key *public_key = &cert->subject.public_key;
- uint8_t digest_out[ digest->digestsize ];
- uint8_t ctx[ pubkey->ctxsize ];
- int rc;
-
- /* Generate digest */
- cms_digest ( sig, info, data, len, digest_out );
-
- /* Initialise public-key algorithm */
- if ( ( rc = pubkey_init ( pubkey, ctx, public_key->raw.data,
- public_key->raw.len ) ) != 0 ) {
- DBGC ( sig, "CMS %p/%p could not initialise public key: %s\n",
- sig, info, strerror ( rc ) );
- goto err_init;
- }
-
- /* Verify digest */
- if ( ( rc = pubkey_verify ( pubkey, ctx, digest, digest_out,
- info->signature,
- info->signature_len ) ) != 0 ) {
- DBGC ( sig, "CMS %p/%p signature verification failed: %s\n",
- sig, info, strerror ( rc ) );
- goto err_verify;
- }
-
- err_verify:
- pubkey_final ( pubkey, ctx );
- err_init:
- return rc;
-}
-
-/**
- * Verify CMS signature signer information
- *
- * @v sig CMS signature
- * @v info Signer information
- * @v data Signed data
- * @v len Length of signed data
- * @v time Time at which to validate certificates
- * @v store Certificate store, or NULL to use default
- * @v root Root certificate list, or NULL to use default
- * @ret rc Return status code
- */
-static int cms_verify_signer_info ( struct cms_signature *sig,
- struct cms_signer_info *info,
- userptr_t data, size_t len,
- time_t time, struct x509_chain *store,
- struct x509_root *root ) {
- struct x509_certificate *cert;
- int rc;
-
- /* Validate certificate chain */
- if ( ( rc = x509_validate_chain ( info->chain, time, store,
- root ) ) != 0 ) {
- DBGC ( sig, "CMS %p/%p could not validate chain: %s\n",
- sig, info, strerror ( rc ) );
- return rc;
- }
-
- /* Extract code-signing certificate */
- cert = x509_first ( info->chain );
- assert ( cert != NULL );
-
- /* Check that certificate can create digital signatures */
- if ( ! ( cert->extensions.usage.bits & X509_DIGITAL_SIGNATURE ) ) {
- DBGC ( sig, "CMS %p/%p certificate cannot create signatures\n",
- sig, info );
- return -EACCES_NON_SIGNING;
- }
-
- /* Check that certificate can sign code */
- if ( ! ( cert->extensions.ext_usage.bits & X509_CODE_SIGNING ) ) {
- DBGC ( sig, "CMS %p/%p certificate is not code-signing\n",
- sig, info );
- return -EACCES_NON_CODE_SIGNING;
- }
-
- /* Verify digest */
- if ( ( rc = cms_verify_digest ( sig, info, cert, data, len ) ) != 0 )
- return rc;
-
- return 0;
-}
-
-/**
- * Verify CMS signature
- *
- * @v sig CMS signature
- * @v data Signed data
- * @v len Length of signed data
- * @v name Required common name, or NULL to check all signatures
- * @v time Time at which to validate certificates
- * @v store Certificate store, or NULL to use default
- * @v root Root certificate list, or NULL to use default
- * @ret rc Return status code
- */
-int cms_verify ( struct cms_signature *sig, userptr_t data, size_t len,
- const char *name, time_t time, struct x509_chain *store,
- struct x509_root *root ) {
- struct cms_signer_info *info;
- struct x509_certificate *cert;
- int count = 0;
- int rc;
-
- /* Verify using all signerInfos */
- list_for_each_entry ( info, &sig->info, list ) {
- cert = x509_first ( info->chain );
- if ( name && ( x509_check_name ( cert, name ) != 0 ) )
- continue;
- if ( ( rc = cms_verify_signer_info ( sig, info, data, len, time,
- store, root ) ) != 0 )
- return rc;
- count++;
- }
-
- /* Check that we have verified at least one signature */
- if ( count == 0 ) {
- if ( name ) {
- DBGC ( sig, "CMS %p had no signatures matching name "
- "%s\n", sig, name );
- return -EACCES_WRONG_NAME;
- } else {
- DBGC ( sig, "CMS %p had no signatures\n", sig );
- return -EACCES_NO_SIGNATURES;
- }
- }
-
- return 0;
-}
diff --git a/qemu/roms/ipxe/src/crypto/crc32.c b/qemu/roms/ipxe/src/crypto/crc32.c
deleted file mode 100644
index cfef68c02..000000000
--- a/qemu/roms/ipxe/src/crypto/crc32.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Little-endian CRC32 implementation.
- *
- * Copyright (c) 2009 Joshua Oreman <oremanj@rwcr.net>.
- *
- * 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; either version 2 of the
- * License, or any later version.
- *
- * 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.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include <ipxe/crc32.h>
-
-#define CRCPOLY 0xedb88320
-
-/**
- * Calculate 32-bit little-endian CRC checksum
- *
- * @v seed Initial value
- * @v data Data to checksum
- * @v len Length of data
- *
- * Usually @a seed is initially zero or all one bits, depending on the
- * protocol. To continue a CRC checksum over multiple calls, pass the
- * return value from one call as the @a seed parameter to the next.
- */
-u32 crc32_le ( u32 seed, const void *data, size_t len )
-{
- u32 crc = seed;
- const u8 *src = data;
- u32 mult;
- int i;
-
- while ( len-- ) {
- crc ^= *src++;
- for ( i = 0; i < 8; i++ ) {
- mult = ( crc & 1 ) ? CRCPOLY : 0;
- crc = ( crc >> 1 ) ^ mult;
- }
- }
-
- return crc;
-}
diff --git a/qemu/roms/ipxe/src/crypto/crypto_null.c b/qemu/roms/ipxe/src/crypto/crypto_null.c
deleted file mode 100644
index 15a1c538b..000000000
--- a/qemu/roms/ipxe/src/crypto/crypto_null.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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; either version 2 of the
- * License, or any later version.
- *
- * 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.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-/**
- * @file
- *
- * Null crypto algorithm
- */
-
-#include <string.h>
-#include <ipxe/crypto.h>
-
-static void digest_null_init ( void *ctx __unused ) {
- /* Do nothing */
-}
-
-static void digest_null_update ( void *ctx __unused, const void *src __unused,
- size_t len __unused ) {
- /* Do nothing */
-}
-
-static void digest_null_final ( void *ctx __unused, void *out __unused ) {
- /* Do nothing */
-}
-
-struct digest_algorithm digest_null = {
- .name = "null",
- .ctxsize = 0,
- .blocksize = 1,
- .digestsize = 0,
- .init = digest_null_init,
- .update = digest_null_update,
- .final = digest_null_final,
-};
-
-static int cipher_null_setkey ( void *ctx __unused, const void *key __unused,
- size_t keylen __unused ) {
- /* Do nothing */
- return 0;
-}
-
-static void cipher_null_setiv ( void *ctx __unused,
- const void *iv __unused ) {
- /* Do nothing */
-}
-
-static void cipher_null_encrypt ( void *ctx __unused, const void *src,
- void *dst, size_t len ) {
- memcpy ( dst, src, len );
-}
-
-static void cipher_null_decrypt ( void *ctx __unused, const void *src,
- void *dst, size_t len ) {
- memcpy ( dst, src, len );
-}
-
-struct cipher_algorithm cipher_null = {
- .name = "null",
- .ctxsize = 0,
- .blocksize = 1,
- .setkey = cipher_null_setkey,
- .setiv = cipher_null_setiv,
- .encrypt = cipher_null_encrypt,
- .decrypt = cipher_null_decrypt,
-};
-
-static int pubkey_null_init ( void *ctx __unused, const void *key __unused,
- size_t key_len __unused ) {
- return 0;
-}
-
-static size_t pubkey_null_max_len ( void *ctx __unused ) {
- return 0;
-}
-
-static int pubkey_null_encrypt ( void *ctx __unused,
- const void *plaintext __unused,
- size_t plaintext_len __unused,
- void *ciphertext __unused ) {
- return 0;
-}
-
-static int pubkey_null_decrypt ( void *ctx __unused,
- const void *ciphertext __unused,
- size_t ciphertext_len __unused,
- void *plaintext __unused ) {
- return 0;
-}
-
-static int pubkey_null_sign ( void *ctx __unused,
- struct digest_algorithm *digest __unused,
- const void *value __unused,
- void *signature __unused ) {
- return 0;
-}
-
-static int pubkey_null_verify ( void *ctx __unused,
- struct digest_algorithm *digest __unused,
- const void *value __unused,
- const void *signature __unused ,
- size_t signature_len __unused ) {
- return 0;
-}
-
-static void pubkey_null_final ( void *ctx __unused ) {
- /* Do nothing */
-}
-
-struct pubkey_algorithm pubkey_null = {
- .name = "null",
- .ctxsize = 0,
- .init = pubkey_null_init,
- .max_len = pubkey_null_max_len,
- .encrypt = pubkey_null_encrypt,
- .decrypt = pubkey_null_decrypt,
- .sign = pubkey_null_sign,
- .verify = pubkey_null_verify,
- .final = pubkey_null_final,
-};
diff --git a/qemu/roms/ipxe/src/crypto/deflate.c b/qemu/roms/ipxe/src/crypto/deflate.c
deleted file mode 100644
index e1c87d5fe..000000000
--- a/qemu/roms/ipxe/src/crypto/deflate.c
+++ /dev/null
@@ -1,1049 +0,0 @@
-/*
- * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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; either version 2 of the
- * License, or any later version.
- *
- * 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.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <string.h>
-#include <strings.h>
-#include <errno.h>
-#include <assert.h>
-#include <ctype.h>
-#include <ipxe/uaccess.h>
-#include <ipxe/deflate.h>
-
-/** @file
- *
- * DEFLATE decompression algorithm
- *
- * This file implements the decompression half of the DEFLATE
- * algorithm specified in RFC 1951.
- *
- * Portions of this code are derived from wimboot's xca.c.
- *
- */
-
-/**
- * Byte reversal table
- *
- * For some insane reason, the DEFLATE format stores some values in
- * bit-reversed order.
- */
-static uint8_t deflate_reverse[256];
-
-/** Literal/length base values
- *
- * We include entries only for literal/length codes 257-284. Code 285
- * does not fit the pattern (it represents a length of 258; following
- * the pattern from the earlier codes would give a length of 259), and
- * has no extra bits. Codes 286-287 are invalid, but can occur. We
- * treat any code greater than 284 as meaning "length 285, no extra
- * bits".
- */
-static uint8_t deflate_litlen_base[28];
-
-/** Distance base values
- *
- * We include entries for all possible codes 0-31, avoiding the need
- * to check for undefined codes 30 and 31 before performing the
- * lookup. Codes 30 and 31 are never initialised, and will therefore
- * be treated as meaning "14 extra bits, base distance 0".
- */
-static uint16_t deflate_distance_base[32];
-
-/** Code length map */
-static uint8_t deflate_codelen_map[19] = {
- 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
-};
-
-/** Static Huffman alphabet length patterns */
-static struct deflate_static_length_pattern deflate_static_length_patterns[] = {
- /* Literal/length code lengths */
- { 0x88, ( ( ( 143 - 0 ) + 1 ) / 2 ) },
- { 0x99, ( ( ( 255 - 144 ) + 1 ) / 2 ) },
- { 0x77, ( ( ( 279 - 256 ) + 1 ) / 2 ) },
- { 0x88, ( ( ( 287 - 280 ) + 1 ) / 2 ) },
- /* Distance code lengths */
- { 0x55, ( ( ( 31 - 0 ) + 1 ) / 2 ) },
- /* End marker */
- { 0, 0 }
-};
-
-/**
- * Transcribe binary value (for debugging)
- *
- * @v value Value
- * @v bits Length of value (in bits)
- * @ret string Transcribed value
- */
-static const char * deflate_bin ( unsigned long value, unsigned int bits ) {
- static char buf[ ( 8 * sizeof ( value ) ) + 1 /* NUL */ ];
- char *out = buf;
-
- /* Sanity check */
- assert ( bits < sizeof ( buf ) );
-
- /* Transcribe value */
- while ( bits-- )
- *(out++) = ( ( value & ( 1 << bits ) ) ? '1' : '0' );
- *out = '\0';
-
- return buf;
-}
-
-/**
- * Set Huffman symbol length
- *
- * @v deflate Decompressor
- * @v index Index within lengths
- * @v bits Symbol length (in bits)
- */
-static void deflate_set_length ( struct deflate *deflate, unsigned int index,
- unsigned int bits ) {
-
- deflate->lengths[ index / 2 ] |= ( bits << ( 4 * ( index % 2 ) ) );
-}
-
-/**
- * Get Huffman symbol length
- *
- * @v deflate Decompressor
- * @v index Index within lengths
- * @ret bits Symbol length (in bits)
- */
-static unsigned int deflate_length ( struct deflate *deflate,
- unsigned int index ) {
-
- return ( ( deflate->lengths[ index / 2 ] >> ( 4 * ( index % 2 ) ) )
- & 0x0f );
-}
-
-/**
- * Determine Huffman alphabet name (for debugging)
- *
- * @v deflate Decompressor
- * @v alphabet Huffman alphabet
- * @ret name Alphabet name
- */
-static const char * deflate_alphabet_name ( struct deflate *deflate,
- struct deflate_alphabet *alphabet ){
-
- if ( alphabet == &deflate->litlen ) {
- return "litlen";
- } else if ( alphabet == &deflate->distance_codelen ) {
- return "distance/codelen";
- } else {
- return "<UNKNOWN>";
- }
-}
-
-/**
- * Dump Huffman alphabet (for debugging)
- *
- * @v deflate Decompressor
- * @v alphabet Huffman alphabet
- */
-static void deflate_dump_alphabet ( struct deflate *deflate,
- struct deflate_alphabet *alphabet ) {
- struct deflate_huf_symbols *huf_sym;
- unsigned int bits;
- unsigned int huf;
- unsigned int i;
-
- /* Do nothing unless debugging is enabled */
- if ( ! DBG_EXTRA )
- return;
-
- /* Dump symbol table for each utilised length */
- for ( bits = 1 ; bits <= ( sizeof ( alphabet->huf ) /
- sizeof ( alphabet->huf[0] ) ) ; bits++ ) {
- huf_sym = &alphabet->huf[ bits - 1 ];
- if ( huf_sym->freq == 0 )
- continue;
- huf = ( huf_sym->start >> huf_sym->shift );
- DBGC2 ( alphabet, "DEFLATE %p \"%s\" length %d start \"%s\" "
- "freq %d:", deflate,
- deflate_alphabet_name ( deflate, alphabet ), bits,
- deflate_bin ( huf, huf_sym->bits ), huf_sym->freq );
- for ( i = 0 ; i < huf_sym->freq ; i++ ) {
- DBGC2 ( alphabet, " %03x",
- huf_sym->raw[ huf + i ] );
- }
- DBGC2 ( alphabet, "\n" );
- }
-
- /* Dump quick lookup table */
- DBGC2 ( alphabet, "DEFLATE %p \"%s\" quick lookup:", deflate,
- deflate_alphabet_name ( deflate, alphabet ) );
- for ( i = 0 ; i < ( sizeof ( alphabet->lookup ) /
- sizeof ( alphabet->lookup[0] ) ) ; i++ ) {
- DBGC2 ( alphabet, " %d", ( alphabet->lookup[i] + 1 ) );
- }
- DBGC2 ( alphabet, "\n" );
-}
-
-/**
- * Construct Huffman alphabet
- *
- * @v deflate Decompressor
- * @v alphabet Huffman alphabet
- * @v count Number of symbols
- * @v offset Starting offset within length table
- * @ret rc Return status code
- */
-static int deflate_alphabet ( struct deflate *deflate,
- struct deflate_alphabet *alphabet,
- unsigned int count, unsigned int offset ) {
- struct deflate_huf_symbols *huf_sym;
- unsigned int huf;
- unsigned int cum_freq;
- unsigned int bits;
- unsigned int raw;
- unsigned int adjustment;
- unsigned int prefix;
- int complete;
-
- /* Clear symbol table */
- memset ( alphabet->huf, 0, sizeof ( alphabet->huf ) );
-
- /* Count number of symbols with each Huffman-coded length */
- for ( raw = 0 ; raw < count ; raw++ ) {
- bits = deflate_length ( deflate, ( raw + offset ) );
- if ( bits )
- alphabet->huf[ bits - 1 ].freq++;
- }
-
- /* Populate Huffman-coded symbol table */
- huf = 0;
- cum_freq = 0;
- for ( bits = 1 ; bits <= ( sizeof ( alphabet->huf ) /
- sizeof ( alphabet->huf[0] ) ) ; bits++ ) {
- huf_sym = &alphabet->huf[ bits - 1 ];
- huf_sym->bits = bits;
- huf_sym->shift = ( 16 - bits );
- huf_sym->start = ( huf << huf_sym->shift );
- huf_sym->raw = &alphabet->raw[cum_freq];
- huf += huf_sym->freq;
- if ( huf > ( 1U << bits ) ) {
- DBGC ( alphabet, "DEFLATE %p \"%s\" has too many "
- "symbols with lengths <=%d\n", deflate,
- deflate_alphabet_name ( deflate, alphabet ),
- bits );
- return -EINVAL;
- }
- huf <<= 1;
- cum_freq += huf_sym->freq;
- }
- complete = ( huf == ( 1U << bits ) );
-
- /* Populate raw symbol table */
- for ( raw = 0 ; raw < count ; raw++ ) {
- bits = deflate_length ( deflate, ( raw + offset ) );
- if ( bits ) {
- huf_sym = &alphabet->huf[ bits - 1 ];
- *(huf_sym->raw++) = raw;
- }
- }
-
- /* Adjust Huffman-coded symbol table raw pointers and populate
- * quick lookup table.
- */
- for ( bits = 1 ; bits <= ( sizeof ( alphabet->huf ) /
- sizeof ( alphabet->huf[0] ) ) ; bits++ ) {
- huf_sym = &alphabet->huf[ bits - 1 ];
-
- /* Adjust raw pointer */
- huf_sym->raw -= huf_sym->freq; /* Reset to first symbol */
- adjustment = ( huf_sym->start >> huf_sym->shift );
- huf_sym->raw -= adjustment; /* Adjust for quick indexing */
-
- /* Populate quick lookup table */
- for ( prefix = ( huf_sym->start >> DEFLATE_HUFFMAN_QL_SHIFT ) ;
- prefix < ( 1 << DEFLATE_HUFFMAN_QL_BITS ) ; prefix++ ) {
- alphabet->lookup[prefix] = ( bits - 1 );
- }
- }
-
- /* Dump alphabet (for debugging) */
- deflate_dump_alphabet ( deflate, alphabet );
-
- /* Check that there are no invalid codes */
- if ( ! complete ) {
- DBGC ( alphabet, "DEFLATE %p \"%s\" is incomplete\n", deflate,
- deflate_alphabet_name ( deflate, alphabet ) );
- return -EINVAL;
- }
-
- return 0;
-}
-
-/**
- * Attempt to accumulate bits from input stream
- *
- * @v deflate Decompressor
- * @v in Compressed input data
- * @v target Number of bits to accumulate
- * @ret excess Number of excess bits accumulated (may be negative)
- */
-static int deflate_accumulate ( struct deflate *deflate,
- struct deflate_chunk *in,
- unsigned int target ) {
- uint8_t byte;
-
- while ( deflate->bits < target ) {
-
- /* Check for end of input */
- if ( in->offset >= in->len )
- break;
-
- /* Acquire byte from input */
- copy_from_user ( &byte, in->data, in->offset++,
- sizeof ( byte ) );
- deflate->accumulator = ( deflate->accumulator |
- ( byte << deflate->bits ) );
- deflate->rotalumucca = ( deflate->rotalumucca |
- ( deflate_reverse[byte] <<
- ( 24 - deflate->bits ) ) );
- deflate->bits += 8;
-
- /* Sanity check */
- assert ( deflate->bits <=
- ( 8 * sizeof ( deflate->accumulator ) ) );
- }
-
- return ( deflate->bits - target );
-}
-
-/**
- * Consume accumulated bits from the input stream
- *
- * @v deflate Decompressor
- * @v count Number of accumulated bits to consume
- * @ret data Consumed bits
- */
-static int deflate_consume ( struct deflate *deflate, unsigned int count ) {
- int data;
-
- /* Sanity check */
- assert ( count <= deflate->bits );
-
- /* Extract data and consume bits */
- data = ( deflate->accumulator & ( ( 1 << count ) - 1 ) );
- deflate->accumulator >>= count;
- deflate->rotalumucca <<= count;
- deflate->bits -= count;
-
- return data;
-}
-
-/**
- * Attempt to extract a fixed number of bits from input stream
- *
- * @v deflate Decompressor
- * @v in Compressed input data
- * @v target Number of bits to extract
- * @ret data Extracted bits (or negative if not yet accumulated)
- */
-static int deflate_extract ( struct deflate *deflate, struct deflate_chunk *in,
- unsigned int target ) {
- int excess;
- int data;
-
- /* Return immediately if we are attempting to extract zero bits */
- if ( target == 0 )
- return 0;
-
- /* Attempt to accumulate bits */
- excess = deflate_accumulate ( deflate, in, target );
- if ( excess < 0 )
- return excess;
-
- /* Extract data and consume bits */
- data = deflate_consume ( deflate, target );
- DBGCP ( deflate, "DEFLATE %p extracted %s = %#x = %d\n", deflate,
- deflate_bin ( data, target ), data, data );
-
- return data;
-}
-
-/**
- * Attempt to decode a Huffman-coded symbol from input stream
- *
- * @v deflate Decompressor
- * @v in Compressed input data
- * @v alphabet Huffman alphabet
- * @ret code Raw code (or negative if not yet accumulated)
- */
-static int deflate_decode ( struct deflate *deflate,
- struct deflate_chunk *in,
- struct deflate_alphabet *alphabet ) {
- struct deflate_huf_symbols *huf_sym;
- uint16_t huf;
- unsigned int lookup_index;
- int excess;
- unsigned int raw;
-
- /* Attempt to accumulate maximum required number of bits.
- * There may be fewer bits than this remaining in the stream,
- * even if the stream still contains some complete
- * Huffman-coded symbols.
- */
- deflate_accumulate ( deflate, in, DEFLATE_HUFFMAN_BITS );
-
- /* Normalise the bit-reversed accumulated value to 16 bits */
- huf = ( deflate->rotalumucca >> 16 );
-
- /* Find symbol set for this length */
- lookup_index = ( huf >> DEFLATE_HUFFMAN_QL_SHIFT );
- huf_sym = &alphabet->huf[ alphabet->lookup[ lookup_index ] ];
- while ( huf < huf_sym->start )
- huf_sym--;
-
- /* Calculate number of excess bits, and return if not yet complete */
- excess = ( deflate->bits - huf_sym->bits );
- if ( excess < 0 )
- return excess;
-
- /* Consume bits */
- deflate_consume ( deflate, huf_sym->bits );
-
- /* Look up raw symbol */
- raw = huf_sym->raw[ huf >> huf_sym->shift ];
- DBGCP ( deflate, "DEFLATE %p decoded %s = %#x = %d\n", deflate,
- deflate_bin ( ( huf >> huf_sym->shift ), huf_sym->bits ),
- raw, raw );
-
- return raw;
-}
-
-/**
- * Discard bits up to the next byte boundary
- *
- * @v deflate Decompressor
- */
-static void deflate_discard_to_byte ( struct deflate *deflate ) {
-
- deflate_consume ( deflate, ( deflate->bits & 7 ) );
-}
-
-/**
- * Copy data to output buffer (if available)
- *
- * @v out Output data buffer
- * @v start Source data
- * @v offset Starting offset within source data
- * @v len Length to copy
- */
-static void deflate_copy ( struct deflate_chunk *out,
- userptr_t start, size_t offset, size_t len ) {
- size_t out_offset = out->offset;
- size_t copy_len;
-
- /* Copy data one byte at a time, to allow for overlap */
- if ( out_offset < out->len ) {
- copy_len = ( out->len - out_offset );
- if ( copy_len > len )
- copy_len = len;
- while ( copy_len-- ) {
- memcpy_user ( out->data, out_offset++,
- start, offset++, 1 );
- }
- }
- out->offset += len;
-}
-
-/**
- * Inflate compressed data
- *
- * @v deflate Decompressor
- * @v in Compressed input data
- * @v out Output data buffer
- * @ret rc Return status code
- *
- * The caller can use deflate_finished() to determine whether a
- * successful return indicates that the decompressor is merely waiting
- * for more input.
- *
- * Data will not be written beyond the specified end of the output
- * data buffer, but the offset within the output data buffer will be
- * updated to reflect the amount that should have been written. The
- * caller can use this to find the length of the decompressed data
- * before allocating the output data buffer.
- */
-int deflate_inflate ( struct deflate *deflate,
- struct deflate_chunk *in,
- struct deflate_chunk *out ) {
-
- /* This could be implemented more neatly if gcc offered a
- * means for enforcing tail recursion.
- */
- if ( deflate->resume ) {
- goto *(deflate->resume);
- } else switch ( deflate->format ) {
- case DEFLATE_RAW: goto block_header;
- case DEFLATE_ZLIB: goto zlib_header;
- default: assert ( 0 );
- }
-
- zlib_header: {
- int header;
- int cm;
-
- /* Extract header */
- header = deflate_extract ( deflate, in, ZLIB_HEADER_BITS );
- if ( header < 0 ) {
- deflate->resume = &&zlib_header;
- return 0;
- }
-
- /* Parse header */
- cm = ( ( header >> ZLIB_HEADER_CM_LSB ) & ZLIB_HEADER_CM_MASK );
- if ( cm != ZLIB_HEADER_CM_DEFLATE ) {
- DBGC ( deflate, "DEFLATE %p unsupported ZLIB "
- "compression method %d\n", deflate, cm );
- return -ENOTSUP;
- }
- if ( header & ( 1 << ZLIB_HEADER_FDICT_BIT ) ) {
- DBGC ( deflate, "DEFLATE %p unsupported ZLIB preset "
- "dictionary\n", deflate );
- return -ENOTSUP;
- }
-
- /* Process first block header */
- goto block_header;
- }
-
- block_header: {
- int header;
- int bfinal;
- int btype;
-
- /* Extract block header */
- header = deflate_extract ( deflate, in, DEFLATE_HEADER_BITS );
- if ( header < 0 ) {
- deflate->resume = &&block_header;
- return 0;
- }
-
- /* Parse header */
- deflate->header = header;
- bfinal = ( header & ( 1 << DEFLATE_HEADER_BFINAL_BIT ) );
- btype = ( header >> DEFLATE_HEADER_BTYPE_LSB );
- DBGC ( deflate, "DEFLATE %p found %sblock type %#x\n",
- deflate, ( bfinal ? "final " : "" ), btype );
- switch ( btype ) {
- case DEFLATE_HEADER_BTYPE_LITERAL:
- goto literal_block;
- case DEFLATE_HEADER_BTYPE_STATIC:
- goto static_block;
- case DEFLATE_HEADER_BTYPE_DYNAMIC:
- goto dynamic_block;
- default:
- DBGC ( deflate, "DEFLATE %p unsupported block type "
- "%#x\n", deflate, btype );
- return -ENOTSUP;
- }
- }
-
- literal_block: {
-
- /* Discard any bits up to the next byte boundary */
- deflate_discard_to_byte ( deflate );
- }
-
- literal_len: {
- int len;
-
- /* Extract LEN field */
- len = deflate_extract ( deflate, in, DEFLATE_LITERAL_LEN_BITS );
- if ( len < 0 ) {
- deflate->resume = &&literal_len;
- return 0;
- }
-
- /* Record length of literal data */
- deflate->remaining = len;
- DBGC2 ( deflate, "DEFLATE %p literal block length %#04zx\n",
- deflate, deflate->remaining );
- }
-
- literal_nlen: {
- int nlen;
-
- /* Extract NLEN field */
- nlen = deflate_extract ( deflate, in, DEFLATE_LITERAL_LEN_BITS);
- if ( nlen < 0 ) {
- deflate->resume = &&literal_nlen;
- return 0;
- }
-
- /* Verify NLEN */
- if ( ( ( deflate->remaining ^ ~nlen ) &
- ( ( 1 << DEFLATE_LITERAL_LEN_BITS ) - 1 ) ) != 0 ) {
- DBGC ( deflate, "DEFLATE %p invalid len/nlen "
- "%#04zx/%#04x\n", deflate,
- deflate->remaining, nlen );
- return -EINVAL;
- }
- }
-
- literal_data: {
- size_t in_remaining;
- size_t len;
-
- /* Calculate available amount of literal data */
- in_remaining = ( in->len - in->offset );
- len = deflate->remaining;
- if ( len > in_remaining )
- len = in_remaining;
-
- /* Copy data to output buffer */
- deflate_copy ( out, in->data, in->offset, len );
-
- /* Consume data from input buffer */
- in->offset += len;
- deflate->remaining -= len;
-
- /* Finish processing if we are blocked */
- if ( deflate->remaining ) {
- deflate->resume = &&literal_data;
- return 0;
- }
-
- /* Otherwise, finish block */
- goto block_done;
- }
-
- static_block: {
- struct deflate_static_length_pattern *pattern;
- uint8_t *lengths = deflate->lengths;
-
- /* Construct static Huffman lengths as per RFC 1950 */
- for ( pattern = deflate_static_length_patterns ;
- pattern->count ; pattern++ ) {
- memset ( lengths, pattern->fill, pattern->count );
- lengths += pattern->count;
- }
- deflate->litlen_count = 288;
- deflate->distance_count = 32;
- goto construct_alphabets;
- }
-
- dynamic_block:
-
- dynamic_header: {
- int header;
- unsigned int hlit;
- unsigned int hdist;
- unsigned int hclen;
-
- /* Extract block header */
- header = deflate_extract ( deflate, in, DEFLATE_DYNAMIC_BITS );
- if ( header < 0 ) {
- deflate->resume = &&dynamic_header;
- return 0;
- }
-
- /* Parse header */
- hlit = ( ( header >> DEFLATE_DYNAMIC_HLIT_LSB ) &
- DEFLATE_DYNAMIC_HLIT_MASK );
- hdist = ( ( header >> DEFLATE_DYNAMIC_HDIST_LSB ) &
- DEFLATE_DYNAMIC_HDIST_MASK );
- hclen = ( ( header >> DEFLATE_DYNAMIC_HCLEN_LSB ) &
- DEFLATE_DYNAMIC_HCLEN_MASK );
- deflate->litlen_count = ( hlit + 257 );
- deflate->distance_count = ( hdist + 1 );
- deflate->length_index = 0;
- deflate->length_target = ( hclen + 4 );
- DBGC2 ( deflate, "DEFLATE %p dynamic block %d codelen, %d "
- "litlen, %d distance\n", deflate,
- deflate->length_target, deflate->litlen_count,
- deflate->distance_count );
-
- /* Prepare for decoding code length code lengths */
- memset ( &deflate->lengths, 0, sizeof ( deflate->lengths ) );
- }
-
- dynamic_codelen: {
- int len;
- unsigned int index;
- int rc;
-
- /* Extract all code lengths */
- while ( deflate->length_index < deflate->length_target ) {
-
- /* Extract code length length */
- len = deflate_extract ( deflate, in,
- DEFLATE_CODELEN_BITS );
- if ( len < 0 ) {
- deflate->resume = &&dynamic_codelen;
- return 0;
- }
-
- /* Store code length */
- index = deflate_codelen_map[deflate->length_index++];
- deflate_set_length ( deflate, index, len );
- DBGCP ( deflate, "DEFLATE %p codelen for %d is %d\n",
- deflate, index, len );
- }
-
- /* Generate code length alphabet */
- if ( ( rc = deflate_alphabet ( deflate,
- &deflate->distance_codelen,
- ( DEFLATE_CODELEN_MAX_CODE + 1 ),
- 0 ) ) != 0 )
- return rc;
-
- /* Prepare for decoding literal/length/distance code lengths */
- memset ( &deflate->lengths, 0, sizeof ( deflate->lengths ) );
- deflate->length_index = 0;
- deflate->length_target = ( deflate->litlen_count +
- deflate->distance_count );
- deflate->length = 0;
- }
-
- dynamic_litlen_distance: {
- int len;
- int index;
-
- /* Decode literal/length/distance code length */
- len = deflate_decode ( deflate, in, &deflate->distance_codelen);
- if ( len < 0 ) {
- deflate->resume = &&dynamic_litlen_distance;
- return 0;
- }
-
- /* Prepare for extra bits */
- if ( len < 16 ) {
- deflate->length = len;
- deflate->extra_bits = 0;
- deflate->dup_len = 1;
- } else {
- static const uint8_t dup_len[3] = { 3, 3, 11 };
- static const uint8_t extra_bits[3] = { 2, 3, 7 };
- index = ( len - 16 );
- deflate->dup_len = dup_len[index];
- deflate->extra_bits = extra_bits[index];
- if ( index )
- deflate->length = 0;
- }
- }
-
- dynamic_litlen_distance_extra: {
- int extra;
- unsigned int dup_len;
-
- /* Extract extra bits */
- extra = deflate_extract ( deflate, in, deflate->extra_bits );
- if ( extra < 0 ) {
- deflate->resume = &&dynamic_litlen_distance_extra;
- return 0;
- }
-
- /* Store code lengths */
- dup_len = ( deflate->dup_len + extra );
- while ( ( deflate->length_index < deflate->length_target ) &&
- dup_len-- ) {
- deflate_set_length ( deflate, deflate->length_index++,
- deflate->length );
- }
-
- /* Process next literal/length or distance code
- * length, if more are required.
- */
- if ( deflate->length_index < deflate->length_target )
- goto dynamic_litlen_distance;
-
- /* Construct alphabets */
- goto construct_alphabets;
- }
-
- construct_alphabets: {
- unsigned int distance_offset = deflate->litlen_count;
- unsigned int distance_count = deflate->distance_count;
- int rc;
-
- /* Generate literal/length alphabet */
- if ( ( rc = deflate_alphabet ( deflate, &deflate->litlen,
- deflate->litlen_count, 0 ) ) !=0)
- return rc;
-
- /* Handle degenerate case of a single distance code
- * (for which it is impossible to construct a valid,
- * complete Huffman alphabet). RFC 1951 states:
- *
- * If only one distance code is used, it is encoded
- * using one bit, not zero bits; in this case there
- * is a single code length of one, with one unused
- * code. One distance code of zero bits means that
- * there are no distance codes used at all (the data
- * is all literals).
- *
- * If we have only a single distance code, then we
- * instead use two distance codes both with length 1.
- * This results in a valid Huffman alphabet. The code
- * "0" will mean distance code 0 (which is either
- * correct or irrelevant), and the code "1" will mean
- * distance code 1 (which is always irrelevant).
- */
- if ( deflate->distance_count == 1 ) {
-
- deflate->lengths[0] = 0x11;
- distance_offset = 0;
- distance_count = 2;
- }
-
- /* Generate distance alphabet */
- if ( ( rc = deflate_alphabet ( deflate,
- &deflate->distance_codelen,
- distance_count,
- distance_offset ) ) != 0 )
- return rc;
- }
-
- lzhuf_litlen: {
- int code;
- uint8_t byte;
- unsigned int extra;
- unsigned int bits;
-
- /* Decode Huffman codes */
- while ( 1 ) {
-
- /* Decode Huffman code */
- code = deflate_decode ( deflate, in, &deflate->litlen );
- if ( code < 0 ) {
- deflate->resume = &&lzhuf_litlen;
- return 0;
- }
-
- /* Handle according to code type */
- if ( code < DEFLATE_LITLEN_END ) {
-
- /* Literal value: copy to output buffer */
- byte = code;
- DBGCP ( deflate, "DEFLATE %p literal %#02x "
- "('%c')\n", deflate, byte,
- ( isprint ( byte ) ? byte : '.' ) );
- deflate_copy ( out, virt_to_user ( &byte ), 0,
- sizeof ( byte ) );
-
- } else if ( code == DEFLATE_LITLEN_END ) {
-
- /* End of block */
- goto block_done;
-
- } else {
-
- /* Length code: process extra bits */
- extra = ( code - DEFLATE_LITLEN_END - 1 );
- if ( extra < 28 ) {
- bits = ( extra / 4 );
- if ( bits )
- bits--;
- deflate->extra_bits = bits;
- deflate->dup_len =
- deflate_litlen_base[extra];
- } else {
- deflate->extra_bits = 0;
- deflate->dup_len = 258;
- }
- goto lzhuf_litlen_extra;
- }
- }
- }
-
- lzhuf_litlen_extra: {
- int extra;
-
- /* Extract extra bits */
- extra = deflate_extract ( deflate, in, deflate->extra_bits );
- if ( extra < 0 ) {
- deflate->resume = &&lzhuf_litlen_extra;
- return 0;
- }
-
- /* Update duplicate length */
- deflate->dup_len += extra;
- }
-
- lzhuf_distance: {
- int code;
- unsigned int extra;
- unsigned int bits;
-
- /* Decode Huffman code */
- code = deflate_decode ( deflate, in,
- &deflate->distance_codelen );
- if ( code < 0 ) {
- deflate->resume = &&lzhuf_distance;
- return 0;
- }
-
- /* Process extra bits */
- extra = code;
- bits = ( extra / 2 );
- if ( bits )
- bits--;
- deflate->extra_bits = bits;
- deflate->dup_distance = deflate_distance_base[extra];
- }
-
- lzhuf_distance_extra: {
- int extra;
- size_t dup_len;
- size_t dup_distance;
-
- /* Extract extra bits */
- extra = deflate_extract ( deflate, in, deflate->extra_bits );
- if ( extra < 0 ) {
- deflate->resume = &&lzhuf_distance_extra;
- return 0;
- }
-
- /* Update duplicate distance */
- dup_distance = ( deflate->dup_distance + extra );
- dup_len = deflate->dup_len;
- DBGCP ( deflate, "DEFLATE %p duplicate length %zd distance "
- "%zd\n", deflate, dup_len, dup_distance );
-
- /* Sanity check */
- if ( dup_distance > out->offset ) {
- DBGC ( deflate, "DEFLATE %p bad distance %zd (max "
- "%zd)\n", deflate, dup_distance, out->offset );
- return -EINVAL;
- }
-
- /* Copy data, allowing for overlap */
- deflate_copy ( out, out->data, ( out->offset - dup_distance ),
- dup_len );
-
- /* Process next literal/length symbol */
- goto lzhuf_litlen;
- }
-
- block_done: {
-
- DBGCP ( deflate, "DEFLATE %p end of block\n", deflate );
-
- /* If this was not the final block, process next block header */
- if ( ! ( deflate->header & ( 1 << DEFLATE_HEADER_BFINAL_BIT ) ))
- goto block_header;
-
- /* Otherwise, process footer (if any) */
- switch ( deflate->format ) {
- case DEFLATE_RAW: goto finished;
- case DEFLATE_ZLIB: goto zlib_footer;
- default: assert ( 0 );
- }
- }
-
- zlib_footer: {
-
- /* Discard any bits up to the next byte boundary */
- deflate_discard_to_byte ( deflate );
- }
-
- zlib_adler32: {
- int excess;
-
- /* Accumulate the 32 bits of checksum. We don't check
- * the value, stop processing immediately afterwards,
- * and so don't have to worry about the nasty corner
- * cases involved in calling deflate_extract() to
- * obtain a full 32 bits.
- */
- excess = deflate_accumulate ( deflate, in, ZLIB_ADLER32_BITS );
- if ( excess < 0 ) {
- deflate->resume = &&zlib_adler32;
- return 0;
- }
-
- /* Finish processing */
- goto finished;
- }
-
- finished: {
- /* Mark as finished and terminate */
- DBGCP ( deflate, "DEFLATE %p finished\n", deflate );
- deflate->resume = NULL;
- return 0;
- }
-}
-
-/**
- * Initialise decompressor
- *
- * @v deflate Decompressor
- * @v format Compression format code
- */
-void deflate_init ( struct deflate *deflate, enum deflate_format format ) {
- static int global_init_done;
- uint8_t i;
- uint8_t bit;
- uint8_t byte;
- unsigned int base;
- unsigned int bits;
-
- /* Perform global initialisation if required */
- if ( ! global_init_done ) {
-
- /* Initialise byte reversal table */
- for ( i = 255 ; i ; i-- ) {
- for ( bit = 1, byte = 0 ; bit ; bit <<= 1 ) {
- byte <<= 1;
- if ( i & bit )
- byte |= 1;
- }
- deflate_reverse[i] = byte;
- }
-
- /* Initialise literal/length extra bits table */
- base = 3;
- for ( i = 0 ; i < 28 ; i++ ) {
- bits = ( i / 4 );
- if ( bits )
- bits--;
- deflate_litlen_base[i] = base;
- base += ( 1 << bits );
- }
- assert ( base == 259 ); /* sic */
-
- /* Initialise distance extra bits table */
- base = 1;
- for ( i = 0 ; i < 30 ; i++ ) {
- bits = ( i / 2 );
- if ( bits )
- bits--;
- deflate_distance_base[i] = base;
- base += ( 1 << bits );
- }
- assert ( base == 32769 );
-
- /* Record global initialisation as complete */
- global_init_done = 1;
- }
-
- /* Initialise structure */
- memset ( deflate, 0, sizeof ( *deflate ) );
- deflate->format = format;
-}
diff --git a/qemu/roms/ipxe/src/crypto/drbg.c b/qemu/roms/ipxe/src/crypto/drbg.c
deleted file mode 100644
index 5c8b5e612..000000000
--- a/qemu/roms/ipxe/src/crypto/drbg.c
+++ /dev/null
@@ -1,431 +0,0 @@
-/*
- * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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; either version 2 of the
- * License, or any later version.
- *
- * 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.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-/** @file
- *
- * DRBG mechanism
- *
- * This mechanism is designed to comply with ANS X9.82 Part 3-2007
- * Section 9. This standard is not freely available, but most of the
- * text appears to be shared with NIST SP 800-90, which can be
- * downloaded from
- *
- * http://csrc.nist.gov/publications/nistpubs/800-90/SP800-90revised_March2007.pdf
- *
- * Where possible, references are given to both documents. In the
- * case of any disagreement, ANS X9.82 takes priority over NIST SP
- * 800-90. (In particular, note that some algorithms that are
- * Approved by NIST SP 800-90 are not Approved by ANS X9.82.)
- */
-
-#include <stdint.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-#include <ipxe/entropy.h>
-#include <ipxe/drbg.h>
-
-/**
- * Instantiate DRBG
- *
- * @v state Algorithm state to be initialised
- * @v personal Personalisation string
- * @v personal_len Length of personalisation string
- * @ret rc Return status code
- *
- * This is the Instantiate_function defined in ANS X9.82 Part 3-2007
- * Section 9.2 (NIST SP 800-90 Section 9.1).
- *
- * Only a single security strength is supported, and prediction
- * resistance is always enabled. The nonce is accounted for by
- * increasing the entropy input, as per ANS X9.82 Part 3-2007 Section
- * 8.4.2 (NIST SP 800-90 Section 8.6.7).
- */
-int drbg_instantiate ( struct drbg_state *state, const void *personal,
- size_t personal_len ) {
- unsigned int entropy_bits = ( ( 3 * DRBG_SECURITY_STRENGTH + 1 ) / 2 );
- size_t min_len = DRBG_MIN_ENTROPY_LEN_BYTES;
- size_t max_len = DRBG_MAX_ENTROPY_LEN_BYTES;
- uint8_t data[max_len];
- int len;
- int rc;
-
- DBGC ( state, "DRBG %p instantiate\n", state );
-
- /* Sanity checks */
- assert ( state != NULL );
-
- /* 1. If requested_instantiation_security_strength >
- * highest_supported_security_strength, then return an
- * ERROR_FLAG
- */
- if ( DRBG_SECURITY_STRENGTH > DRBG_MAX_SECURITY_STRENGTH ) {
- DBGC ( state, "DRBG %p cannot support security strength %d\n",
- state, DRBG_SECURITY_STRENGTH );
- return -ENOTSUP;
- }
-
- /* 2. If prediction_resistance_flag is set, and prediction
- * resistance is not supported, then return an ERROR_FLAG
- *
- * (Nothing to do since prediction resistance is always
- * supported.)
- */
-
- /* 3. If the length of the personalization_string >
- * max_personalization_string_length, return an ERROR_FLAG
- */
- if ( personal_len > DRBG_MAX_PERSONAL_LEN_BYTES ) {
- DBGC ( state, "DRBG %p personalisation string too long (%zd "
- "bytes)\n", state, personal_len );
- return -ERANGE;
- }
-
- /* 4. Set security_strength to the nearest security strength
- * greater than or equal to
- * requested_instantiation_security_strength.
- *
- * (Nothing to do since we support only a single security
- * strength.)
- */
-
- /* 5. Using the security_strength, select appropriate DRBG
- * mechanism parameters.
- *
- * (Nothing to do since we support only a single security
- * strength.)
- */
-
- /* 6. ( status, entropy_input ) = Get_entropy_input (
- * security_strength, min_length, max_length,
- * prediction_resistance_request )
- * 7. If an ERROR is returned in step 6, return a
- * CATASTROPHIC_ERROR_FLAG.
- * 8. Obtain a nonce.
- */
- len = get_entropy_input ( entropy_bits, data, min_len,
- sizeof ( data ) );
- if ( len < 0 ) {
- rc = len;
- DBGC ( state, "DRBG %p could not get entropy input: %s\n",
- state, strerror ( rc ) );
- return rc;
- }
- assert ( len >= ( int ) min_len );
- assert ( len <= ( int ) sizeof ( data ) );
-
- /* 9. initial_working_state = Instantiate_algorithm (
- * entropy_input, nonce, personalization_string ).
- */
- drbg_instantiate_algorithm ( state, data, len, personal, personal_len );
-
- /* 10. Get a state_handle for a currently empty state. If an
- * empty internal state cannot be found, return an
- * ERROR_FLAG.
- * 11. Set the internal state indicated by state_handle to
- * the initial values for the internal state (i.e. set
- * the working_state to the values returned as
- * initial_working_state in step 9 and any other values
- * required for the working_state, and set the
- * administrative information to the appropriate values.
- *
- * (Almost nothing to do since the memory to hold the state
- * was passed in by the caller and has already been updated
- * in-situ.)
- */
- state->reseed_required = 0;
- state->valid = 1;
-
- /* 12. Return SUCCESS and state_handle. */
- return 0;
-}
-
-/**
- * Reseed DRBG
- *
- * @v state Algorithm state
- * @v additional Additional input
- * @v additional_len Length of additional input
- * @ret rc Return status code
- *
- * This is the Reseed_function defined in ANS X9.82 Part 3-2007
- * Section 9.3 (NIST SP 800-90 Section 9.2).
- *
- * Prediction resistance is always enabled.
- */
-int drbg_reseed ( struct drbg_state *state, const void *additional,
- size_t additional_len ) {
- unsigned int entropy_bits = DRBG_SECURITY_STRENGTH;
- size_t min_len = DRBG_MIN_ENTROPY_LEN_BYTES;
- size_t max_len = DRBG_MAX_ENTROPY_LEN_BYTES;
- uint8_t data[max_len];
- int len;
- int rc;
-
- DBGC ( state, "DRBG %p reseed\n", state );
-
- /* Sanity checks */
- assert ( state != NULL );
-
- /* 1. Using state_handle, obtain the current internal state.
- * If state_handle indicates an invalid or empty internal
- * state, return an ERROR_FLAG.
- *
- * (Almost nothing to do since the memory holding the internal
- * state was passed in by the caller.)
- */
- if ( ! state->valid ) {
- DBGC ( state, "DRBG %p not valid\n", state );
- return -EINVAL;
- }
-
- /* 2. If prediction_resistance_request is set, and
- * prediction_resistance_flag is not set, then return an
- * ERROR_FLAG.
- *
- * (Nothing to do since prediction resistance is always
- * supported.)
- */
-
- /* 3. If the length of the additional_input >
- * max_additional_input_length, return an ERROR_FLAG.
- */
- if ( additional_len > DRBG_MAX_ADDITIONAL_LEN_BYTES ) {
- DBGC ( state, "DRBG %p additional input too long (%zd bytes)\n",
- state, additional_len );
- return -ERANGE;
- }
-
- /* 4. ( status, entropy_input ) = Get_entropy_input (
- * security_strength, min_length, max_length,
- * prediction_resistance_request ).
- *
- * 5. If an ERROR is returned in step 4, return a
- * CATASTROPHIC_ERROR_FLAG.
- */
- len = get_entropy_input ( entropy_bits, data, min_len,
- sizeof ( data ) );
- if ( len < 0 ) {
- rc = len;
- DBGC ( state, "DRBG %p could not get entropy input: %s\n",
- state, strerror ( rc ) );
- return rc;
- }
-
- /* 6. new_working_state = Reseed_algorithm ( working_state,
- * entropy_input, additional_input ).
- */
- drbg_reseed_algorithm ( state, data, len, additional, additional_len );
-
- /* 7. Replace the working_state in the internal state
- * indicated by state_handle with the values of
- * new_working_state obtained in step 6.
- *
- * (Nothing to do since the state has already been updated in-situ.)
- */
-
- /* 8. Return SUCCESS. */
- return 0;
-}
-
-/**
- * Generate pseudorandom bits using DRBG
- *
- * @v state Algorithm state
- * @v additional Additional input
- * @v additional_len Length of additional input
- * @v prediction_resist Prediction resistance is required
- * @v data Output buffer
- * @v len Length of output buffer
- * @ret rc Return status code
- *
- * This is the Generate_function defined in ANS X9.82 Part 3-2007
- * Section 9.4 (NIST SP 800-90 Section 9.3).
- *
- * Requests must be for an integral number of bytes. Only a single
- * security strength is supported. Prediction resistance is supported
- * if requested.
- */
-int drbg_generate ( struct drbg_state *state, const void *additional,
- size_t additional_len, int prediction_resist,
- void *data, size_t len ) {
- int rc;
-
- DBGC ( state, "DRBG %p generate\n", state );
-
- /* Sanity checks */
- assert ( state != NULL );
- assert ( data != NULL );
-
- /* 1. Using state_handle, obtain the current internal state
- * for the instantiation. If state_handle indicates an
- * invalid or empty internal state, then return an ERROR_FLAG.
- *
- * (Almost nothing to do since the memory holding the internal
- * state was passed in by the caller.)
- */
- if ( ! state->valid ) {
- DBGC ( state, "DRBG %p not valid\n", state );
- return -EINVAL;
- }
-
- /* 2. If requested_number_of_bits >
- * max_number_of_bits_per_request, then return an
- * ERROR_FLAG.
- */
- if ( len > DRBG_MAX_GENERATED_LEN_BYTES ) {
- DBGC ( state, "DRBG %p request too long (%zd bytes)\n",
- state, len );
- return -ERANGE;
- }
-
- /* 3. If requested_security_strength > the security_strength
- * indicated in the internal state, then return an
- * ERROR_FLAG.
- *
- * (Nothing to do since only a single security strength is
- * supported.)
- */
-
- /* 4. If the length of the additional_input >
- * max_additional_input_length, then return an ERROR_FLAG.
- */
- if ( additional_len > DRBG_MAX_ADDITIONAL_LEN_BYTES ) {
- DBGC ( state, "DRBG %p additional input too long (%zd bytes)\n",
- state, additional_len );
- return -ERANGE;
- }
-
- /* 5. If prediction_resistance_request is set, and
- * prediction_resistance_flag is not set, then return an
- * ERROR_FLAG.
- *
- * (Nothing to do since prediction resistance is always
- * supported.)
- */
-
- /* 6. Clear the reseed_required_flag. */
- state->reseed_required = 0;
-
- step_7:
- /* 7. If reseed_required_flag is set, or if
- * prediction_resistance_request is set, then
- */
- if ( state->reseed_required || prediction_resist ) {
-
- /* 7.1 status = Reseed_function ( state_handle,
- * prediction_resistance_request,
- * additional_input )
- * 7.2 If status indicates an ERROR, then return
- * status.
- */
- if ( ( rc = drbg_reseed ( state, additional,
- additional_len ) ) != 0 ) {
- DBGC ( state, "DRBG %p could not reseed: %s\n",
- state, strerror ( rc ) );
- return rc;
- }
-
- /* 7.3 Using state_handle, obtain the new internal
- * state.
- *
- * (Nothing to do since the internal state has been
- * updated in-situ.)
- */
-
- /* 7.4 additional_input = the Null string. */
- additional = NULL;
- additional_len = 0;
-
- /* 7.5 Clear the reseed_required_flag. */
- state->reseed_required = 0;
- }
-
- /* 8. ( status, pseudorandom_bits, new_working_state ) =
- * Generate_algorithm ( working_state,
- * requested_number_of_bits, additional_input ).
- */
- rc = drbg_generate_algorithm ( state, additional, additional_len,
- data, len );
-
- /* 9. If status indicates that a reseed is required before
- * the requested bits can be generated, then
- */
- if ( rc != 0 ) {
-
- /* 9.1 Set the reseed_required_flag. */
- state->reseed_required = 1;
-
- /* 9.2 If the prediction_resistance_flag is set, then
- * set the prediction_resistance_request
- * indication.
- */
- prediction_resist = 1;
-
- /* 9.3 Go to step 7. */
- goto step_7;
- }
-
- /* 10. Replace the old working_state in the internal state
- * indicated by state_handle with the values of
- * new_working_state.
- *
- * (Nothing to do since the working state has already been
- * updated in-situ.)
- */
-
- /* 11. Return SUCCESS and pseudorandom_bits. */
- return 0;
-}
-
-/**
- * Uninstantiate DRBG
- *
- * @v state Algorithm state
- *
- * This is the Uninstantiate_function defined in ANS X9.82 Part 3-2007
- * Section 9.5 (NIST SP 800-90 Section 9.4).
- */
-void drbg_uninstantiate ( struct drbg_state *state ) {
-
- DBGC ( state, "DRBG %p uninstantiate\n", state );
-
- /* Sanity checks */
- assert ( state != NULL );
-
- /* 1. If state_handle indicates an invalid state, then return
- * an ERROR_FLAG.
- *
- * (Nothing to do since the memory holding the internal state
- * was passed in by the caller.)
- */
-
- /* 2. Erase the contents of the internal state indicated by
- * state_handle.
- */
- memset ( state, 0, sizeof ( *state ) );
-
- /* 3. Return SUCCESS. */
-}
diff --git a/qemu/roms/ipxe/src/crypto/ecb.c b/qemu/roms/ipxe/src/crypto/ecb.c
deleted file mode 100644
index 3c9cf340c..000000000
--- a/qemu/roms/ipxe/src/crypto/ecb.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2009 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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; either version 2 of the
- * License, or any later version.
- *
- * 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.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <assert.h>
-#include <ipxe/crypto.h>
-#include <ipxe/ecb.h>
-
-/** @file
- *
- * Electronic codebook (ECB)
- *
- */
-
-/**
- * Encrypt data
- *
- * @v ctx Context
- * @v src Data to encrypt
- * @v dst Buffer for encrypted data
- * @v len Length of data
- * @v raw_cipher Underlying cipher algorithm
- */
-void ecb_encrypt ( void *ctx, const void *src, void *dst, size_t len,
- struct cipher_algorithm *raw_cipher ) {
- size_t blocksize = raw_cipher->blocksize;
-
- assert ( ( len % blocksize ) == 0 );
-
- while ( len ) {
- cipher_encrypt ( raw_cipher, ctx, src, dst, blocksize );
- dst += blocksize;
- src += blocksize;
- len -= blocksize;
- }
-}
-
-/**
- * Decrypt data
- *
- * @v ctx Context
- * @v src Data to decrypt
- * @v dst Buffer for decrypted data
- * @v len Length of data
- * @v raw_cipher Underlying cipher algorithm
- */
-void ecb_decrypt ( void *ctx, const void *src, void *dst, size_t len,
- struct cipher_algorithm *raw_cipher ) {
- size_t blocksize = raw_cipher->blocksize;
-
- assert ( ( len % blocksize ) == 0 );
-
- while ( len ) {
- cipher_decrypt ( raw_cipher, ctx, src, dst, blocksize );
- dst += blocksize;
- src += blocksize;
- len -= blocksize;
- }
-}
diff --git a/qemu/roms/ipxe/src/crypto/entropy.c b/qemu/roms/ipxe/src/crypto/entropy.c
deleted file mode 100644
index 5acbc0258..000000000
--- a/qemu/roms/ipxe/src/crypto/entropy.c
+++ /dev/null
@@ -1,483 +0,0 @@
-/*
- * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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; either version 2 of the
- * License, or any later version.
- *
- * 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.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-/** @file
- *
- * Entropy source
- *
- * This algorithm is designed to comply with ANS X9.82 Part 4 (April
- * 2011 Draft) Section 13.3. This standard is unfortunately not
- * freely available.
- */
-
-#include <stdint.h>
-#include <assert.h>
-#include <string.h>
-#include <errno.h>
-#include <ipxe/crypto.h>
-#include <ipxe/hash_df.h>
-#include <ipxe/entropy.h>
-
-/* Disambiguate the various error causes */
-#define EPIPE_REPETITION_COUNT_TEST \
- __einfo_error ( EINFO_EPIPE_REPETITION_COUNT_TEST )
-#define EINFO_EPIPE_REPETITION_COUNT_TEST \
- __einfo_uniqify ( EINFO_EPIPE, 0x01, "Repetition count test failed" )
-#define EPIPE_ADAPTIVE_PROPORTION_TEST \
- __einfo_error ( EINFO_EPIPE_ADAPTIVE_PROPORTION_TEST )
-#define EINFO_EPIPE_ADAPTIVE_PROPORTION_TEST \
- __einfo_uniqify ( EINFO_EPIPE, 0x02, "Adaptive proportion test failed" )
-
-/**
- * Calculate cutoff value for the repetition count test
- *
- * @ret cutoff Cutoff value
- *
- * This is the cutoff value for the Repetition Count Test defined in
- * ANS X9.82 Part 2 (October 2011 Draft) Section 8.5.2.1.2.
- */
-static inline __attribute__ (( always_inline )) unsigned int
-repetition_count_cutoff ( void ) {
- double max_repetitions;
- unsigned int cutoff;
-
- /* The cutoff formula for the repetition test is:
- *
- * C = ( 1 + ( -log2(W) / H_min ) )
- *
- * where W is set at 2^(-30) (in ANS X9.82 Part 2 (October
- * 2011 Draft) Section 8.5.2.1.3.1).
- */
- max_repetitions = ( 1 + ( 30 / min_entropy_per_sample() ) );
-
- /* Round up to a whole number of repetitions. We don't have
- * the ceil() function available, so do the rounding by hand.
- */
- cutoff = max_repetitions;
- if ( cutoff < max_repetitions )
- cutoff++;
- linker_assert ( ( cutoff >= max_repetitions ), rounding_error );
-
- /* Floating-point operations are not allowed in iPXE since we
- * never set up a suitable environment. Abort the build
- * unless the calculated number of repetitions is a
- * compile-time constant.
- */
- linker_assert ( __builtin_constant_p ( cutoff ),
- repetition_count_cutoff_not_constant );
-
- return cutoff;
-}
-
-/**
- * Perform repetition count test
- *
- * @v sample Noise sample
- * @ret rc Return status code
- *
- * This is the Repetition Count Test defined in ANS X9.82 Part 2
- * (October 2011 Draft) Section 8.5.2.1.2.
- */
-static int repetition_count_test ( noise_sample_t sample ) {
- static noise_sample_t most_recent_sample;
- static unsigned int repetition_count = 0;
-
- /* A = the most recently seen sample value
- * B = the number of times that value A has been seen in a row
- * C = the cutoff value above which the repetition test should fail
- */
-
- /* 1. For each new sample processed:
- *
- * (Note that the test for "repetition_count > 0" ensures that
- * the initial value of most_recent_sample is treated as being
- * undefined.)
- */
- if ( ( sample == most_recent_sample ) && ( repetition_count > 0 ) ) {
-
- /* a) If the new sample = A, then B is incremented by one. */
- repetition_count++;
-
- /* i. If B >= C, then an error condition is raised
- * due to a failure of the test
- */
- if ( repetition_count >= repetition_count_cutoff() )
- return -EPIPE_REPETITION_COUNT_TEST;
-
- } else {
-
- /* b) Else:
- * i. A = new sample
- */
- most_recent_sample = sample;
-
- /* ii. B = 1 */
- repetition_count = 1;
- }
-
- return 0;
-}
-
-/**
- * Window size for the adaptive proportion test
- *
- * ANS X9.82 Part 2 (October 2011 Draft) Section 8.5.2.1.3.1.1 allows
- * five possible window sizes: 16, 64, 256, 4096 and 65536.
- *
- * We expect to generate relatively few (<256) entropy samples during
- * a typical iPXE run; the use of a large window size would mean that
- * the test would never complete a single cycle. We use a window size
- * of 64, which is the smallest window size that permits values of
- * H_min down to one bit per sample.
- */
-#define ADAPTIVE_PROPORTION_WINDOW_SIZE 64
-
-/**
- * Combine adaptive proportion test window size and min-entropy
- *
- * @v n N (window size)
- * @v h H (min-entropy)
- * @ret n_h (N,H) combined value
- */
-#define APC_N_H( n, h ) ( ( (n) << 8 ) | (h) )
-
-/**
- * Define a row of the adaptive proportion cutoff table
- *
- * @v h H (min-entropy)
- * @v c16 Cutoff for N=16
- * @v c64 Cutoff for N=64
- * @v c256 Cutoff for N=256
- * @v c4096 Cutoff for N=4096
- * @v c65536 Cutoff for N=65536
- */
-#define APC_TABLE_ROW( h, c16, c64, c256, c4096, c65536) \
- case APC_N_H ( 16, h ) : return c16; \
- case APC_N_H ( 64, h ) : return c64; \
- case APC_N_H ( 256, h ) : return c256; \
- case APC_N_H ( 4096, h ) : return c4096; \
- case APC_N_H ( 65536, h ) : return c65536;
-
-/** Value used to represent "N/A" in adaptive proportion cutoff table */
-#define APC_NA 0
-
-/**
- * Look up value in adaptive proportion test cutoff table
- *
- * @v n N (window size)
- * @v h H (min-entropy)
- * @ret cutoff Cutoff
- *
- * This is the table of cutoff values defined in ANS X9.82 Part 2
- * (October 2011 Draft) Section 8.5.2.1.3.1.2.
- */
-static inline __attribute__ (( always_inline )) unsigned int
-adaptive_proportion_cutoff_lookup ( unsigned int n, unsigned int h ) {
- switch ( APC_N_H ( n, h ) ) {
- APC_TABLE_ROW ( 1, APC_NA, 51, 168, 2240, 33537 );
- APC_TABLE_ROW ( 2, APC_NA, 35, 100, 1193, 17053 );
- APC_TABLE_ROW ( 3, 10, 24, 61, 643, 8705 );
- APC_TABLE_ROW ( 4, 8, 16, 38, 354, 4473 );
- APC_TABLE_ROW ( 5, 6, 12, 25, 200, 2321 );
- APC_TABLE_ROW ( 6, 5, 9, 17, 117, 1220 );
- APC_TABLE_ROW ( 7, 4, 7, 15, 71, 653 );
- APC_TABLE_ROW ( 8, 4, 5, 9, 45, 358 );
- APC_TABLE_ROW ( 9, 3, 4, 7, 30, 202 );
- APC_TABLE_ROW ( 10, 3, 4, 5, 21, 118 );
- APC_TABLE_ROW ( 11, 2, 3, 4, 15, 71 );
- APC_TABLE_ROW ( 12, 2, 3, 4, 11, 45 );
- APC_TABLE_ROW ( 13, 2, 2, 3, 9, 30 );
- APC_TABLE_ROW ( 14, 2, 2, 3, 7, 21 );
- APC_TABLE_ROW ( 15, 1, 2, 2, 6, 15 );
- APC_TABLE_ROW ( 16, 1, 2, 2, 5, 11 );
- APC_TABLE_ROW ( 17, 1, 1, 2, 4, 9 );
- APC_TABLE_ROW ( 18, 1, 1, 2, 4, 7 );
- APC_TABLE_ROW ( 19, 1, 1, 1, 3, 6 );
- APC_TABLE_ROW ( 20, 1, 1, 1, 3, 5 );
- default:
- return APC_NA;
- }
-}
-
-/**
- * Calculate cutoff value for the adaptive proportion test
- *
- * @ret cutoff Cutoff value
- *
- * This is the cutoff value for the Adaptive Proportion Test defined
- * in ANS X9.82 Part 2 (October 2011 Draft) Section 8.5.2.1.3.1.2.
- */
-static inline __attribute__ (( always_inline )) unsigned int
-adaptive_proportion_cutoff ( void ) {
- unsigned int h;
- unsigned int n;
- unsigned int cutoff;
-
- /* Look up cutoff value in cutoff table */
- n = ADAPTIVE_PROPORTION_WINDOW_SIZE;
- h = min_entropy_per_sample();
- cutoff = adaptive_proportion_cutoff_lookup ( n, h );
-
- /* Fail unless cutoff value is a build-time constant */
- linker_assert ( __builtin_constant_p ( cutoff ),
- adaptive_proportion_cutoff_not_constant );
-
- /* Fail if cutoff value is N/A */
- linker_assert ( ( cutoff != APC_NA ),
- adaptive_proportion_cutoff_not_applicable );
-
- return cutoff;
-}
-
-/**
- * Perform adaptive proportion test
- *
- * @v sample Noise sample
- * @ret rc Return status code
- *
- * This is the Adaptive Proportion Test for the Most Common Value
- * defined in ANS X9.82 Part 2 (October 2011 Draft) Section 8.5.2.1.3.
- */
-static int adaptive_proportion_test ( noise_sample_t sample ) {
- static noise_sample_t current_counted_sample;
- static unsigned int sample_count = ADAPTIVE_PROPORTION_WINDOW_SIZE;
- static unsigned int repetition_count;
-
- /* A = the sample value currently being counted
- * B = the number of samples examined in this run of the test so far
- * N = the total number of samples that must be observed in
- * one run of the test, also known as the "window size" of
- * the test
- * B = the current number of times that S (sic) has been seen
- * in the W (sic) samples examined so far
- * C = the cutoff value above which the repetition test should fail
- * W = the probability of a false positive: 2^-30
- */
-
- /* 1. The entropy source draws the current sample from the
- * noise source.
- *
- * (Nothing to do; we already have the current sample.)
- */
-
- /* 2. If S = N, then a new run of the test begins: */
- if ( sample_count == ADAPTIVE_PROPORTION_WINDOW_SIZE ) {
-
- /* a. A = the current sample */
- current_counted_sample = sample;
-
- /* b. S = 0 */
- sample_count = 0;
-
- /* c. B = 0 */
- repetition_count = 0;
-
- } else {
-
- /* Else: (the test is already running)
- * a. S = S + 1
- */
- sample_count++;
-
- /* b. If A = the current sample, then: */
- if ( sample == current_counted_sample ) {
-
- /* i. B = B + 1 */
- repetition_count++;
-
- /* ii. If S (sic) > C then raise an error
- * condition, because the test has
- * detected a failure
- */
- if ( repetition_count > adaptive_proportion_cutoff() )
- return -EPIPE_ADAPTIVE_PROPORTION_TEST;
-
- }
- }
-
- return 0;
-}
-
-/**
- * Get entropy sample
- *
- * @ret entropy Entropy sample
- * @ret rc Return status code
- *
- * This is the GetEntropy function defined in ANS X9.82 Part 2
- * (October 2011 Draft) Section 6.5.1.
- */
-static int get_entropy ( entropy_sample_t *entropy ) {
- static int rc = 0;
- noise_sample_t noise;
-
- /* Any failure is permanent */
- if ( rc != 0 )
- return rc;
-
- /* Get noise sample */
- if ( ( rc = get_noise ( &noise ) ) != 0 )
- return rc;
-
- /* Perform Repetition Count Test and Adaptive Proportion Test
- * as mandated by ANS X9.82 Part 2 (October 2011 Draft)
- * Section 8.5.2.1.1.
- */
- if ( ( rc = repetition_count_test ( noise ) ) != 0 )
- return rc;
- if ( ( rc = adaptive_proportion_test ( noise ) ) != 0 )
- return rc;
-
- /* We do not use any optional conditioning component */
- *entropy = noise;
-
- return 0;
-}
-
-/**
- * Calculate number of samples required for startup tests
- *
- * @ret num_samples Number of samples required
- *
- * ANS X9.82 Part 2 (October 2011 Draft) Section 8.5.2.1.5 requires
- * that at least one full cycle of the continuous tests must be
- * performed at start-up.
- */
-static inline __attribute__ (( always_inline )) unsigned int
-startup_test_count ( void ) {
- unsigned int num_samples;
-
- /* At least max(N,C) samples shall be generated by the noise
- * source for start-up testing.
- */
- num_samples = repetition_count_cutoff();
- if ( num_samples < adaptive_proportion_cutoff() )
- num_samples = adaptive_proportion_cutoff();
- linker_assert ( __builtin_constant_p ( num_samples ),
- startup_test_count_not_constant );
-
- return num_samples;
-}
-
-/**
- * Create next nonce value
- *
- * @ret nonce Nonce
- *
- * This is the MakeNextNonce function defined in ANS X9.82 Part 4
- * (April 2011 Draft) Section 13.3.4.2.
- */
-static uint32_t make_next_nonce ( void ) {
- static uint32_t nonce;
-
- /* The simplest implementation of a nonce uses a large counter */
- nonce++;
-
- return nonce;
-}
-
-/**
- * Obtain entropy input temporary buffer
- *
- * @v num_samples Number of entropy samples
- * @v tmp Temporary buffer
- * @v tmp_len Length of temporary buffer
- * @ret rc Return status code
- *
- * This is (part of) the implementation of the Get_entropy_input
- * function (using an entropy source as the source of entropy input
- * and condensing each entropy source output after each GetEntropy
- * call) as defined in ANS X9.82 Part 4 (April 2011 Draft) Section
- * 13.3.4.2.
- *
- * To minimise code size, the number of samples required is calculated
- * at compilation time.
- */
-int get_entropy_input_tmp ( unsigned int num_samples, uint8_t *tmp,
- size_t tmp_len ) {
- static unsigned int startup_tested = 0;
- struct {
- uint32_t nonce;
- entropy_sample_t sample;
- } __attribute__ (( packed )) data;;
- uint8_t df_buf[tmp_len];
- unsigned int i;
- int rc;
-
- /* Enable entropy gathering */
- if ( ( rc = entropy_enable() ) != 0 )
- return rc;
-
- /* Perform mandatory startup tests, if not yet performed */
- for ( ; startup_tested < startup_test_count() ; startup_tested++ ) {
- if ( ( rc = get_entropy ( &data.sample ) ) != 0 )
- goto err_get_entropy;
- }
-
- /* 3. entropy_total = 0
- *
- * (Nothing to do; the number of entropy samples required has
- * already been precalculated.)
- */
-
- /* 4. tmp = a fixed n-bit value, such as 0^n */
- memset ( tmp, 0, tmp_len );
-
- /* 5. While ( entropy_total < min_entropy ) */
- while ( num_samples-- ) {
- /* 5.1. ( status, entropy_bitstring, assessed_entropy )
- * = GetEntropy()
- * 5.2. If status indicates an error, return ( status, Null )
- */
- if ( ( rc = get_entropy ( &data.sample ) ) != 0 )
- goto err_get_entropy;
-
- /* 5.3. nonce = MakeNextNonce() */
- data.nonce = make_next_nonce();
-
- /* 5.4. tmp = tmp XOR
- * df ( ( nonce || entropy_bitstring ), n )
- */
- hash_df ( &entropy_hash_df_algorithm, &data, sizeof ( data ),
- df_buf, sizeof ( df_buf ) );
- for ( i = 0 ; i < tmp_len ; i++ )
- tmp[i] ^= df_buf[i];
-
- /* 5.5. entropy_total = entropy_total + assessed_entropy
- *
- * (Nothing to do; the number of entropy samples
- * required has already been precalculated.)
- */
- }
-
- /* Disable entropy gathering */
- entropy_disable();
-
- return 0;
-
- err_get_entropy:
- entropy_disable();
- return rc;
-}
diff --git a/qemu/roms/ipxe/src/crypto/hash_df.c b/qemu/roms/ipxe/src/crypto/hash_df.c
deleted file mode 100644
index c1417e683..000000000
--- a/qemu/roms/ipxe/src/crypto/hash_df.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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; either version 2 of the
- * License, or any later version.
- *
- * 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.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-/** @file
- *
- * Hash-based derivation function (Hash_df)
- *
- * This algorithm is designed to comply with ANS X9.82 Part 3-2007
- * Section 10.5.2. This standard is not freely available, but most of
- * the text appears to be shared with NIST SP 800-90, which can be
- * downloaded from
- *
- * http://csrc.nist.gov/publications/nistpubs/800-90/SP800-90revised_March2007.pdf
- *
- * Where possible, references are given to both documents. In the
- * case of any disagreement, ANS X9.82 takes priority over NIST SP
- * 800-90. (In particular, note that some algorithms that are
- * Approved by NIST SP 800-90 are not Approved by ANS X9.82.)
- */
-
-#include <stdint.h>
-#include <string.h>
-#include <assert.h>
-#include <byteswap.h>
-#include <ipxe/crypto.h>
-#include <ipxe/hash_df.h>
-
-/**
- * Distribute entropy throughout a buffer
- *
- * @v hash Underlying hash algorithm
- * @v input Input data
- * @v input_len Length of input data, in bytes
- * @v output Output buffer
- * @v output_len Length of output buffer, in bytes
- *
- * This is the Hash_df function defined in ANS X9.82 Part 3-2007
- * Section 10.5.2 (NIST SP 800-90 Section 10.4.1).
- *
- * The number of bits requested is implicit in the length of the
- * output buffer. Requests must be for an integral number of bytes.
- *
- * The output buffer is filled incrementally with each iteration of
- * the central loop, rather than constructing an overall "temp" and
- * then taking the leftmost(no_of_bits_to_return) bits.
- *
- * There is no way for the Hash_df function to fail. The returned
- * status SUCCESS is implicit.
- */
-void hash_df ( struct digest_algorithm *hash, const void *input,
- size_t input_len, void *output, size_t output_len ) {
- uint8_t context[hash->ctxsize];
- uint8_t digest[hash->digestsize];
- size_t frag_len;
- struct {
- uint8_t pad[3];
- uint8_t counter;
- uint32_t no_of_bits_to_return;
- } __attribute__ (( packed )) prefix;
- void *temp;
- size_t remaining;
-
- DBGC ( &hash_df, "HASH_DF input:\n" );
- DBGC_HDA ( &hash_df, 0, input, input_len );
-
- /* Sanity checks */
- assert ( input != NULL );
- assert ( output != NULL );
-
- /* 1. temp = the Null string
- * 2. len = ceil ( no_of_bits_to_return / outlen )
- *
- * (Nothing to do. We fill the output buffer incrementally,
- * rather than constructing the complete "temp" in-memory.
- * "len" is implicit in the number of iterations required to
- * fill the output buffer, and so is not calculated
- * explicitly.)
- */
-
- /* 3. counter = an 8-bit binary value representing the integer "1" */
- prefix.counter = 1;
-
- /* 4. For i = 1 to len do */
- for ( temp = output, remaining = output_len ; remaining > 0 ; ) {
-
- /* Comment: in step 5.1 (sic), no_of_bits_to_return is
- * used as a 32-bit string.
- *
- * 4.1 temp = temp || Hash ( counter || no_of_bits_to_return
- * || input_string )
- */
- prefix.no_of_bits_to_return = htonl ( output_len * 8 );
- digest_init ( hash, context );
- digest_update ( hash, context, &prefix.counter,
- ( sizeof ( prefix ) -
- offsetof ( typeof ( prefix ), counter ) ) );
- digest_update ( hash, context, input, input_len );
- digest_final ( hash, context, digest );
-
- /* 4.2 counter = counter + 1 */
- prefix.counter++;
-
- /* 5. requested_bits = Leftmost ( no_of_bits_to_return )
- * of temp
- *
- * (We fill the output buffer incrementally.)
- */
- frag_len = sizeof ( digest );
- if ( frag_len > remaining )
- frag_len = remaining;
- memcpy ( temp, digest, frag_len );
- temp += frag_len;
- remaining -= frag_len;
- }
-
- /* 6. Return SUCCESS and requested_bits */
- DBGC ( &hash_df, "HASH_DF output:\n" );
- DBGC_HDA ( &hash_df, 0, output, output_len );
- return;
-}
diff --git a/qemu/roms/ipxe/src/crypto/hmac.c b/qemu/roms/ipxe/src/crypto/hmac.c
deleted file mode 100644
index 95a46195c..000000000
--- a/qemu/roms/ipxe/src/crypto/hmac.c
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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; either version 2 of the
- * License, or any later version.
- *
- * 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.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-/**
- * @file
- *
- * Keyed-Hashing for Message Authentication
- */
-
-#include <string.h>
-#include <assert.h>
-#include <ipxe/crypto.h>
-#include <ipxe/hmac.h>
-
-/**
- * Reduce HMAC key length
- *
- * @v digest Digest algorithm to use
- * @v digest_ctx Digest context
- * @v key Key
- * @v key_len Length of key
- */
-static void hmac_reduce_key ( struct digest_algorithm *digest,
- void *key, size_t *key_len ) {
- uint8_t digest_ctx[digest->ctxsize];
-
- digest_init ( digest, digest_ctx );
- digest_update ( digest, digest_ctx, key, *key_len );
- digest_final ( digest, digest_ctx, key );
- *key_len = digest->digestsize;
-}
-
-/**
- * Initialise HMAC
- *
- * @v digest Digest algorithm to use
- * @v digest_ctx Digest context
- * @v key Key
- * @v key_len Length of key
- *
- * The length of the key should be less than the block size of the
- * digest algorithm being used. (If the key length is greater, it
- * will be replaced with its own digest, and key_len will be updated
- * accordingly).
- */
-void hmac_init ( struct digest_algorithm *digest, void *digest_ctx,
- void *key, size_t *key_len ) {
- unsigned char k_ipad[digest->blocksize];
- unsigned int i;
-
- /* Reduce key if necessary */
- if ( *key_len > sizeof ( k_ipad ) )
- hmac_reduce_key ( digest, key, key_len );
-
- /* Construct input pad */
- memset ( k_ipad, 0, sizeof ( k_ipad ) );
- memcpy ( k_ipad, key, *key_len );
- for ( i = 0 ; i < sizeof ( k_ipad ) ; i++ ) {
- k_ipad[i] ^= 0x36;
- }
-
- /* Start inner hash */
- digest_init ( digest, digest_ctx );
- digest_update ( digest, digest_ctx, k_ipad, sizeof ( k_ipad ) );
-}
-
-/**
- * Finalise HMAC
- *
- * @v digest Digest algorithm to use
- * @v digest_ctx Digest context
- * @v key Key
- * @v key_len Length of key
- * @v hmac HMAC digest to fill in
- *
- * The length of the key should be less than the block size of the
- * digest algorithm being used. (If the key length is greater, it
- * will be replaced with its own digest, and key_len will be updated
- * accordingly).
- */
-void hmac_final ( struct digest_algorithm *digest, void *digest_ctx,
- void *key, size_t *key_len, void *hmac ) {
- unsigned char k_opad[digest->blocksize];
- unsigned int i;
-
- /* Reduce key if necessary */
- if ( *key_len > sizeof ( k_opad ) )
- hmac_reduce_key ( digest, key, key_len );
-
- /* Construct output pad */
- memset ( k_opad, 0, sizeof ( k_opad ) );
- memcpy ( k_opad, key, *key_len );
- for ( i = 0 ; i < sizeof ( k_opad ) ; i++ ) {
- k_opad[i] ^= 0x5c;
- }
-
- /* Finish inner hash */
- digest_final ( digest, digest_ctx, hmac );
-
- /* Perform outer hash */
- digest_init ( digest, digest_ctx );
- digest_update ( digest, digest_ctx, k_opad, sizeof ( k_opad ) );
- digest_update ( digest, digest_ctx, hmac, digest->digestsize );
- digest_final ( digest, digest_ctx, hmac );
-}
diff --git a/qemu/roms/ipxe/src/crypto/hmac_drbg.c b/qemu/roms/ipxe/src/crypto/hmac_drbg.c
deleted file mode 100644
index 6c1d5deb2..000000000
--- a/qemu/roms/ipxe/src/crypto/hmac_drbg.c
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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; either version 2 of the
- * License, or any later version.
- *
- * 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.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-/** @file
- *
- * HMAC_DRBG algorithm
- *
- * This algorithm is designed to comply with ANS X9.82 Part 3-2007
- * Section 10.2.2.2. This standard is not freely available, but most
- * of the text appears to be shared with NIST SP 800-90, which can be
- * downloaded from
- *
- * http://csrc.nist.gov/publications/nistpubs/800-90/SP800-90revised_March2007.pdf
- *
- * Where possible, references are given to both documents. In the
- * case of any disagreement, ANS X9.82 takes priority over NIST SP
- * 800-90. (In particular, note that some algorithms that are
- * Approved by NIST SP 800-90 are not Approved by ANS X9.82.)
- */
-
-#include <stdint.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-#include <ipxe/crypto.h>
-#include <ipxe/hmac.h>
-#include <ipxe/hmac_drbg.h>
-
-/**
- * Update the HMAC_DRBG key
- *
- * @v hash Underlying hash algorithm
- * @v state HMAC_DRBG internal state
- * @v data Provided data
- * @v len Length of provided data
- * @v single Single byte used in concatenation
- *
- * This function carries out the operation
- *
- * K = HMAC ( K, V || single || provided_data )
- *
- * as used by hmac_drbg_update()
- */
-static void hmac_drbg_update_key ( struct digest_algorithm *hash,
- struct hmac_drbg_state *state,
- const void *data, size_t len,
- const uint8_t single ) {
- uint8_t context[ hash->ctxsize ];
- size_t out_len = hash->digestsize;
-
- DBGC ( state, "HMAC_DRBG_%s %p provided data :\n", hash->name, state );
- DBGC_HDA ( state, 0, data, len );
-
- /* Sanity checks */
- assert ( hash != NULL );
- assert ( state != NULL );
- assert ( ( data != NULL ) || ( len == 0 ) );
- assert ( ( single == 0x00 ) || ( single == 0x01 ) );
-
- /* K = HMAC ( K, V || single || provided_data ) */
- hmac_init ( hash, context, state->key, &out_len );
- assert ( out_len == hash->digestsize );
- hmac_update ( hash, context, state->value, out_len );
- hmac_update ( hash, context, &single, sizeof ( single ) );
- hmac_update ( hash, context, data, len );
- hmac_final ( hash, context, state->key, &out_len, state->key );
- assert ( out_len == hash->digestsize );
-
- DBGC ( state, "HMAC_DRBG_%s %p K = HMAC ( K, V || %#02x || "
- "provided_data ) :\n", hash->name, state, single );
- DBGC_HDA ( state, 0, state->key, out_len );
-}
-
-/**
- * Update the HMAC_DRBG value
- *
- * @v hash Underlying hash algorithm
- * @v state HMAC_DRBG internal state
- * @v data Provided data
- * @v len Length of provided data
- * @v single Single byte used in concatenation
- *
- * This function carries out the operation
- *
- * V = HMAC ( K, V )
- *
- * as used by hmac_drbg_update() and hmac_drbg_generate()
- */
-static void hmac_drbg_update_value ( struct digest_algorithm *hash,
- struct hmac_drbg_state *state ) {
- uint8_t context[ hash->ctxsize ];
- size_t out_len = hash->digestsize;
-
- /* Sanity checks */
- assert ( hash != NULL );
- assert ( state != NULL );
-
- /* V = HMAC ( K, V ) */
- hmac_init ( hash, context, state->key, &out_len );
- assert ( out_len == hash->digestsize );
- hmac_update ( hash, context, state->value, out_len );
- hmac_final ( hash, context, state->key, &out_len, state->value );
- assert ( out_len == hash->digestsize );
-
- DBGC ( state, "HMAC_DRBG_%s %p V = HMAC ( K, V ) :\n",
- hash->name, state );
- DBGC_HDA ( state, 0, state->value, out_len );
-}
-
-/**
- * Update HMAC_DRBG internal state
- *
- * @v hash Underlying hash algorithm
- * @v state HMAC_DRBG internal state
- * @v data Provided data
- * @v len Length of provided data
- *
- * This is the HMAC_DRBG_Update function defined in ANS X9.82 Part
- * 3-2007 Section 10.2.2.2.2 (NIST SP 800-90 Section 10.1.2.2).
- *
- * The key and value are updated in-place within the HMAC_DRBG
- * internal state.
- */
-static void hmac_drbg_update ( struct digest_algorithm *hash,
- struct hmac_drbg_state *state,
- const void *data, size_t len ) {
-
- DBGC ( state, "HMAC_DRBG_%s %p update\n", hash->name, state );
-
- /* Sanity checks */
- assert ( hash != NULL );
- assert ( state != NULL );
- assert ( ( data != NULL ) || ( len == 0 ) );
-
- /* 1. K = HMAC ( K, V || 0x00 || provided_data ) */
- hmac_drbg_update_key ( hash, state, data, len, 0x00 );
-
- /* 2. V = HMAC ( K, V ) */
- hmac_drbg_update_value ( hash, state );
-
- /* 3. If ( provided_data = Null ), then return K and V */
- if ( ! len )
- return;
-
- /* 4. K = HMAC ( K, V || 0x01 || provided_data ) */
- hmac_drbg_update_key ( hash, state, data, len, 0x01 );
-
- /* 5. V = HMAC ( K, V ) */
- hmac_drbg_update_value ( hash, state );
-
- /* 6. Return K and V */
-}
-
-/**
- * Instantiate HMAC_DRBG
- *
- * @v hash Underlying hash algorithm
- * @v state HMAC_DRBG internal state to be initialised
- * @v entropy Entropy input
- * @v entropy_len Length of entropy input
- * @v personal Personalisation string
- * @v personal_len Length of personalisation string
- *
- * This is the HMAC_DRBG_Instantiate_algorithm function defined in ANS
- * X9.82 Part 3-2007 Section 10.2.2.2.3 (NIST SP 800-90 Section
- * 10.1.2.3).
- *
- * The nonce must be included within the entropy input (i.e. the
- * entropy input must contain at least 3/2 * security_strength bits of
- * entropy, as per ANS X9.82 Part 3-2007 Section 8.4.2 (NIST SP 800-90
- * Section 8.6.7).
- *
- * The key, value and reseed counter are updated in-place within the
- * HMAC_DRBG internal state.
- */
-void hmac_drbg_instantiate ( struct digest_algorithm *hash,
- struct hmac_drbg_state *state,
- const void *entropy, size_t entropy_len,
- const void *personal, size_t personal_len ){
- size_t out_len = hash->digestsize;
-
- DBGC ( state, "HMAC_DRBG_%s %p instantiate\n", hash->name, state );
-
- /* Sanity checks */
- assert ( hash != NULL );
- assert ( state != NULL );
- assert ( entropy != NULL );
- assert ( ( personal != NULL ) || ( personal_len == 0 ) );
-
- /* 1. seed_material = entropy_input || nonce ||
- * personalisation_string
- */
-
- /* 2. Key = 0x00 00..00 */
- memset ( state->key, 0x00, out_len );
-
- /* 3. V = 0x01 01...01 */
- memset ( state->value, 0x01, out_len );
-
- /* 4. ( Key, V ) = HMAC_DBRG_Update ( seed_material, Key, V )
- * 5. reseed_counter = 1
- * 6. Return V, Key and reseed_counter as the
- * initial_working_state
- */
- hmac_drbg_reseed ( hash, state, entropy, entropy_len,
- personal, personal_len );
-}
-
-/**
- * Reseed HMAC_DRBG
- *
- * @v hash Underlying hash algorithm
- * @v state HMAC_DRBG internal state
- * @v entropy Entropy input
- * @v entropy_len Length of entropy input
- * @v additional Additional input
- * @v additional_len Length of additional input
- *
- * This is the HMAC_DRBG_Reseed_algorithm function defined in ANS X9.82
- * Part 3-2007 Section 10.2.2.2.4 (NIST SP 800-90 Section 10.1.2.4).
- *
- * The key, value and reseed counter are updated in-place within the
- * HMAC_DRBG internal state.
- */
-void hmac_drbg_reseed ( struct digest_algorithm *hash,
- struct hmac_drbg_state *state,
- const void *entropy, size_t entropy_len,
- const void *additional, size_t additional_len ) {
- uint8_t seed_material[ entropy_len + additional_len ];
-
- DBGC ( state, "HMAC_DRBG_%s %p (re)seed\n", hash->name, state );
-
- /* Sanity checks */
- assert ( hash != NULL );
- assert ( state != NULL );
- assert ( entropy != NULL );
- assert ( ( additional != NULL ) || ( additional_len == 0 ) );
-
- /* 1. seed_material = entropy_input || additional_input */
- memcpy ( seed_material, entropy, entropy_len );
- memcpy ( ( seed_material + entropy_len ), additional, additional_len );
- DBGC ( state, "HMAC_DRBG_%s %p seed material :\n", hash->name, state );
- DBGC_HDA ( state, 0, seed_material, sizeof ( seed_material ) );
-
- /* 2. ( Key, V ) = HMAC_DBRG_Update ( seed_material, Key, V ) */
- hmac_drbg_update ( hash, state, seed_material,
- sizeof ( seed_material ) );
-
- /* 3. reseed_counter = 1 */
- state->reseed_counter = 1;
-
- /* 4. Return V, Key and reseed_counter as the new_working_state */
-}
-
-/**
- * Generate pseudorandom bits using HMAC_DRBG
- *
- * @v hash Underlying hash algorithm
- * @v state HMAC_DRBG internal state
- * @v additional Additional input
- * @v additional_len Length of additional input
- * @v data Output buffer
- * @v len Length of output buffer
- * @ret rc Return status code
- *
- * This is the HMAC_DRBG_Generate_algorithm function defined in ANS X9.82
- * Part 3-2007 Section 10.2.2.2.5 (NIST SP 800-90 Section 10.1.2.5).
- *
- * Requests must be for an integral number of bytes.
- *
- * The key, value and reseed counter are updated in-place within the
- * HMAC_DRBG internal state.
- *
- * Note that the only permitted error is "reseed required".
- */
-int hmac_drbg_generate ( struct digest_algorithm *hash,
- struct hmac_drbg_state *state,
- const void *additional, size_t additional_len,
- void *data, size_t len ) {
- size_t out_len = hash->digestsize;
- void *orig_data = data;
- size_t orig_len = len;
- size_t frag_len;
-
- DBGC ( state, "HMAC_DRBG_%s %p generate\n", hash->name, state );
-
- /* Sanity checks */
- assert ( hash != NULL );
- assert ( state != NULL );
- assert ( data != NULL );
- assert ( ( additional != NULL ) || ( additional_len == 0 ) );
-
- /* 1. If reseed_counter > reseed_interval, then return an
- * indication that a reseed is required
- */
- if ( state->reseed_counter > HMAC_DRBG_RESEED_INTERVAL ) {
- DBGC ( state, "HMAC_DRBG_%s %p reseed interval exceeded\n",
- hash->name, state );
- return -ESTALE;
- }
-
- /* 2. If additional_input != Null, then
- * ( Key, V ) = HMAC_DRBG_Update ( additional_input, Key, V )
- */
- if ( additional_len )
- hmac_drbg_update ( hash, state, additional, additional_len );
-
- /* 3. temp = Null
- * 4. While ( len ( temp ) < requested_number_of_bits ) do:
- */
- while ( len ) {
-
- /* 4.1 V = HMAC ( Key, V ) */
- hmac_drbg_update_value ( hash, state );
-
- /* 4.2. temp = temp || V
- * 5. returned_bits = Leftmost requested_number_of_bits
- * of temp
- */
- frag_len = len;
- if ( frag_len > out_len )
- frag_len = out_len;
- memcpy ( data, state->value, frag_len );
- data += frag_len;
- len -= frag_len;
- }
-
- /* 6. ( Key, V ) = HMAC_DRBG_Update ( additional_input, Key, V ) */
- hmac_drbg_update ( hash, state, additional, additional_len );
-
- /* 7. reseed_counter = reseed_counter + 1 */
- state->reseed_counter++;
-
- DBGC ( state, "HMAC_DRBG_%s %p generated :\n", hash->name, state );
- DBGC_HDA ( state, 0, orig_data, orig_len );
-
- /* 8. Return SUCCESS, returned_bits, and the new values of
- * Key, V and reseed_counter as the new_working_state
- */
- return 0;
-}
diff --git a/qemu/roms/ipxe/src/crypto/md5.c b/qemu/roms/ipxe/src/crypto/md5.c
deleted file mode 100644
index f9738b0ac..000000000
--- a/qemu/roms/ipxe/src/crypto/md5.c
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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; either version 2 of the
- * License, or any later version.
- *
- * 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.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-/** @file
- *
- * MD5 algorithm
- *
- */
-
-#include <stdint.h>
-#include <string.h>
-#include <byteswap.h>
-#include <assert.h>
-#include <ipxe/rotate.h>
-#include <ipxe/crypto.h>
-#include <ipxe/asn1.h>
-#include <ipxe/md5.h>
-
-/** MD5 variables */
-struct md5_variables {
- /* This layout matches that of struct md5_digest_data,
- * allowing for efficient endianness-conversion,
- */
- uint32_t a;
- uint32_t b;
- uint32_t c;
- uint32_t d;
- uint32_t w[16];
-} __attribute__ (( packed ));
-
-/** MD5 constants */
-static const uint32_t k[64] = {
- 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a,
- 0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
- 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 0xf61e2562, 0xc040b340,
- 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
- 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8,
- 0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
- 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 0x289b7ec6, 0xeaa127fa,
- 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
- 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92,
- 0xffeff47d, 0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
- 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
-};
-
-/** MD5 shift amounts */
-static const uint8_t r[64] = {
- 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
- 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
- 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
- 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21
-};
-
-/**
- * f(b,c,d) for steps 0 to 15
- *
- * @v v MD5 variables
- * @ret f f(b,c,d)
- */
-static uint32_t md5_f_0_15 ( struct md5_variables *v ) {
- return ( v->d ^ ( v->b & ( v->c ^ v->d ) ) );
-}
-
-/**
- * f(b,c,d) for steps 16 to 31
- *
- * @v v MD5 variables
- * @ret f f(b,c,d)
- */
-static uint32_t md5_f_16_31 ( struct md5_variables *v ) {
- return ( v->c ^ ( v->d & ( v->b ^ v->c ) ) );
-}
-
-/**
- * f(b,c,d) for steps 32 to 47
- *
- * @v v MD5 variables
- * @ret f f(b,c,d)
- */
-static uint32_t md5_f_32_47 ( struct md5_variables *v ) {
- return ( v->b ^ v->c ^ v->d );
-}
-
-/**
- * f(b,c,d) for steps 48 to 63
- *
- * @v v MD5 variables
- * @ret f f(b,c,d)
- */
-static uint32_t md5_f_48_63 ( struct md5_variables *v ) {
- return ( v->c ^ ( v->b | (~v->d) ) );
-}
-
-/** An MD5 step function */
-struct md5_step {
- /**
- * Calculate f(b,c,d)
- *
- * @v v MD5 variables
- * @ret f f(b,c,d)
- */
- uint32_t ( * f ) ( struct md5_variables *v );
- /** Coefficient of i in g=ni+m */
- uint8_t coefficient;
- /** Constant term in g=ni+m */
- uint8_t constant;
-};
-
-/** MD5 steps */
-static struct md5_step md5_steps[4] = {
- /** 0 to 15 */
- { .f = md5_f_0_15, .coefficient = 1, .constant = 0 },
- /** 16 to 31 */
- { .f = md5_f_16_31, .coefficient = 5, .constant = 1 },
- /** 32 to 47 */
- { .f = md5_f_32_47, .coefficient = 3, .constant = 5 },
- /** 48 to 63 */
- { .f = md5_f_48_63, .coefficient = 7, .constant = 0 },
-};
-
-/**
- * Initialise MD5 algorithm
- *
- * @v ctx MD5 context
- */
-static void md5_init ( void *ctx ) {
- struct md5_context *context = ctx;
-
- context->ddd.dd.digest.h[0] = cpu_to_le32 ( 0x67452301 );
- context->ddd.dd.digest.h[1] = cpu_to_le32 ( 0xefcdab89 );
- context->ddd.dd.digest.h[2] = cpu_to_le32 ( 0x98badcfe );
- context->ddd.dd.digest.h[3] = cpu_to_le32 ( 0x10325476 );
- context->len = 0;
-}
-
-/**
- * Calculate MD5 digest of accumulated data
- *
- * @v context MD5 context
- */
-static void md5_digest ( struct md5_context *context ) {
- union {
- union md5_digest_data_dwords ddd;
- struct md5_variables v;
- } u;
- uint32_t *a = &u.v.a;
- uint32_t *b = &u.v.b;
- uint32_t *c = &u.v.c;
- uint32_t *d = &u.v.d;
- uint32_t *w = u.v.w;
- uint32_t f;
- uint32_t g;
- uint32_t temp;
- struct md5_step *step;
- unsigned int i;
-
- /* Sanity checks */
- assert ( ( context->len % sizeof ( context->ddd.dd.data ) ) == 0 );
- linker_assert ( &u.ddd.dd.digest.h[0] == a, md5_bad_layout );
- linker_assert ( &u.ddd.dd.digest.h[1] == b, md5_bad_layout );
- linker_assert ( &u.ddd.dd.digest.h[2] == c, md5_bad_layout );
- linker_assert ( &u.ddd.dd.digest.h[3] == d, md5_bad_layout );
- linker_assert ( &u.ddd.dd.data.dword[0] == w, md5_bad_layout );
-
- DBGC ( context, "MD5 digesting:\n" );
- DBGC_HDA ( context, 0, &context->ddd.dd.digest,
- sizeof ( context->ddd.dd.digest ) );
- DBGC_HDA ( context, context->len, &context->ddd.dd.data,
- sizeof ( context->ddd.dd.data ) );
-
- /* Convert h[0..3] to host-endian, and initialise a, b, c, d,
- * and w[0..15]
- */
- for ( i = 0 ; i < ( sizeof ( u.ddd.dword ) /
- sizeof ( u.ddd.dword[0] ) ) ; i++ ) {
- le32_to_cpus ( &context->ddd.dword[i] );
- u.ddd.dword[i] = context->ddd.dword[i];
- }
-
- /* Main loop */
- for ( i = 0 ; i < 64 ; i++ ) {
- step = &md5_steps[ i / 16 ];
- f = step->f ( &u.v );
- g = ( ( ( step->coefficient * i ) + step->constant ) % 16 );
- temp = *d;
- *d = *c;
- *c = *b;
- *b = ( *b + rol32 ( ( *a + f + k[i] + w[g] ), r[i] ) );
- *a = temp;
- DBGC2 ( context, "%2d : %08x %08x %08x %08x\n",
- i, *a, *b, *c, *d );
- }
-
- /* Add chunk to hash and convert back to big-endian */
- for ( i = 0 ; i < 4 ; i++ ) {
- context->ddd.dd.digest.h[i] =
- cpu_to_le32 ( context->ddd.dd.digest.h[i] +
- u.ddd.dd.digest.h[i] );
- }
-
- DBGC ( context, "MD5 digested:\n" );
- DBGC_HDA ( context, 0, &context->ddd.dd.digest,
- sizeof ( context->ddd.dd.digest ) );
-}
-
-/**
- * Accumulate data with MD5 algorithm
- *
- * @v ctx MD5 context
- * @v data Data
- * @v len Length of data
- */
-static void md5_update ( void *ctx, const void *data, size_t len ) {
- struct md5_context *context = ctx;
- const uint8_t *byte = data;
- size_t offset;
-
- /* Accumulate data a byte at a time, performing the digest
- * whenever we fill the data buffer
- */
- while ( len-- ) {
- offset = ( context->len % sizeof ( context->ddd.dd.data ) );
- context->ddd.dd.data.byte[offset] = *(byte++);
- context->len++;
- if ( ( context->len % sizeof ( context->ddd.dd.data ) ) == 0 )
- md5_digest ( context );
- }
-}
-
-/**
- * Generate MD5 digest
- *
- * @v ctx MD5 context
- * @v out Output buffer
- */
-static void md5_final ( void *ctx, void *out ) {
- struct md5_context *context = ctx;
- uint64_t len_bits;
- uint8_t pad;
-
- /* Record length before pre-processing */
- len_bits = cpu_to_le64 ( ( ( uint64_t ) context->len ) * 8 );
-
- /* Pad with a single "1" bit followed by as many "0" bits as required */
- pad = 0x80;
- do {
- md5_update ( ctx, &pad, sizeof ( pad ) );
- pad = 0x00;
- } while ( ( context->len % sizeof ( context->ddd.dd.data ) ) !=
- offsetof ( typeof ( context->ddd.dd.data ), final.len ) );
-
- /* Append length (in bits) */
- md5_update ( ctx, &len_bits, sizeof ( len_bits ) );
- assert ( ( context->len % sizeof ( context->ddd.dd.data ) ) == 0 );
-
- /* Copy out final digest */
- memcpy ( out, &context->ddd.dd.digest,
- sizeof ( context->ddd.dd.digest ) );
-}
-
-/** MD5 algorithm */
-struct digest_algorithm md5_algorithm = {
- .name = "md5",
- .ctxsize = sizeof ( struct md5_context ),
- .blocksize = sizeof ( union md5_block ),
- .digestsize = sizeof ( struct md5_digest ),
- .init = md5_init,
- .update = md5_update,
- .final = md5_final,
-};
-
-/** "md5" object identifier */
-static uint8_t oid_md5[] = { ASN1_OID_MD5 };
-
-/** "md5" OID-identified algorithm */
-struct asn1_algorithm oid_md5_algorithm __asn1_algorithm = {
- .name = "md5",
- .digest = &md5_algorithm,
- .oid = ASN1_OID_CURSOR ( oid_md5 ),
-};
diff --git a/qemu/roms/ipxe/src/crypto/mishmash/rsa_aes_cbc_sha1.c b/qemu/roms/ipxe/src/crypto/mishmash/rsa_aes_cbc_sha1.c
deleted file mode 100644
index 06722c0e1..000000000
--- a/qemu/roms/ipxe/src/crypto/mishmash/rsa_aes_cbc_sha1.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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; either version 2 of the
- * License, or (at your option) any later version.
- *
- * 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.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <byteswap.h>
-#include <ipxe/rsa.h>
-#include <ipxe/aes.h>
-#include <ipxe/sha1.h>
-#include <ipxe/tls.h>
-
-/** TLS_RSA_WITH_AES_128_CBC_SHA cipher suite */
-struct tls_cipher_suite tls_rsa_with_aes_128_cbc_sha __tls_cipher_suite (03) = {
- .code = htons ( TLS_RSA_WITH_AES_128_CBC_SHA ),
- .key_len = ( 128 / 8 ),
- .pubkey = &rsa_algorithm,
- .cipher = &aes_cbc_algorithm,
- .digest = &sha1_algorithm,
-};
-
-/** TLS_RSA_WITH_AES_256_CBC_SHA cipher suite */
-struct tls_cipher_suite tls_rsa_with_aes_256_cbc_sha __tls_cipher_suite (04) = {
- .code = htons ( TLS_RSA_WITH_AES_256_CBC_SHA ),
- .key_len = ( 256 / 8 ),
- .pubkey = &rsa_algorithm,
- .cipher = &aes_cbc_algorithm,
- .digest = &sha1_algorithm,
-};
diff --git a/qemu/roms/ipxe/src/crypto/mishmash/rsa_aes_cbc_sha256.c b/qemu/roms/ipxe/src/crypto/mishmash/rsa_aes_cbc_sha256.c
deleted file mode 100644
index c609eacea..000000000
--- a/qemu/roms/ipxe/src/crypto/mishmash/rsa_aes_cbc_sha256.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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; either version 2 of the
- * License, or (at your option) any later version.
- *
- * 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.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <byteswap.h>
-#include <ipxe/rsa.h>
-#include <ipxe/aes.h>
-#include <ipxe/sha256.h>
-#include <ipxe/tls.h>
-
-/** TLS_RSA_WITH_AES_128_CBC_SHA256 cipher suite */
-struct tls_cipher_suite tls_rsa_with_aes_128_cbc_sha256 __tls_cipher_suite(01)={
- .code = htons ( TLS_RSA_WITH_AES_128_CBC_SHA256 ),
- .key_len = ( 128 / 8 ),
- .pubkey = &rsa_algorithm,
- .cipher = &aes_cbc_algorithm,
- .digest = &sha256_algorithm,
-};
-
-/** TLS_RSA_WITH_AES_256_CBC_SHA256 cipher suite */
-struct tls_cipher_suite tls_rsa_with_aes_256_cbc_sha256 __tls_cipher_suite(02)={
- .code = htons ( TLS_RSA_WITH_AES_256_CBC_SHA256 ),
- .key_len = ( 256 / 8 ),
- .pubkey = &rsa_algorithm,
- .cipher = &aes_cbc_algorithm,
- .digest = &sha256_algorithm,
-};
diff --git a/qemu/roms/ipxe/src/crypto/mishmash/rsa_md5.c b/qemu/roms/ipxe/src/crypto/mishmash/rsa_md5.c
deleted file mode 100644
index ac828ac11..000000000
--- a/qemu/roms/ipxe/src/crypto/mishmash/rsa_md5.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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; either version 2 of the
- * License, or (at your option) any later version.
- *
- * 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.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <ipxe/rsa.h>
-#include <ipxe/md5.h>
-#include <ipxe/asn1.h>
-
-/** "md5WithRSAEncryption" object identifier */
-static uint8_t oid_md5_with_rsa_encryption[] =
- { ASN1_OID_MD5WITHRSAENCRYPTION };
-
-/** "md5WithRSAEncryption" OID-identified algorithm */
-struct asn1_algorithm md5_with_rsa_encryption_algorithm __asn1_algorithm = {
- .name = "md5WithRSAEncryption",
- .pubkey = &rsa_algorithm,
- .digest = &md5_algorithm,
- .oid = ASN1_OID_CURSOR ( oid_md5_with_rsa_encryption ),
-};
-
-/** MD5 digestInfo prefix */
-static const uint8_t rsa_md5_prefix_data[] =
- { RSA_DIGESTINFO_PREFIX ( MD5_DIGEST_SIZE, ASN1_OID_MD5 ) };
-
-/** MD5 digestInfo prefix */
-struct rsa_digestinfo_prefix rsa_md5_prefix __rsa_digestinfo_prefix = {
- .digest = &md5_algorithm,
- .data = rsa_md5_prefix_data,
- .len = sizeof ( rsa_md5_prefix_data ),
-};
diff --git a/qemu/roms/ipxe/src/crypto/mishmash/rsa_sha1.c b/qemu/roms/ipxe/src/crypto/mishmash/rsa_sha1.c
deleted file mode 100644
index 39424bf2d..000000000
--- a/qemu/roms/ipxe/src/crypto/mishmash/rsa_sha1.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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; either version 2 of the
- * License, or (at your option) any later version.
- *
- * 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.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <ipxe/rsa.h>
-#include <ipxe/sha1.h>
-#include <ipxe/asn1.h>
-#include <ipxe/tls.h>
-
-/** "sha1WithRSAEncryption" object identifier */
-static uint8_t oid_sha1_with_rsa_encryption[] =
- { ASN1_OID_SHA1WITHRSAENCRYPTION };
-
-/** "sha1WithRSAEncryption" OID-identified algorithm */
-struct asn1_algorithm sha1_with_rsa_encryption_algorithm __asn1_algorithm = {
- .name = "sha1WithRSAEncryption",
- .pubkey = &rsa_algorithm,
- .digest = &sha1_algorithm,
- .oid = ASN1_OID_CURSOR ( oid_sha1_with_rsa_encryption ),
-};
-
-/** SHA-1 digestInfo prefix */
-static const uint8_t rsa_sha1_prefix_data[] =
- { RSA_DIGESTINFO_PREFIX ( SHA1_DIGEST_SIZE, ASN1_OID_SHA1 ) };
-
-/** SHA-1 digestInfo prefix */
-struct rsa_digestinfo_prefix rsa_sha1_prefix __rsa_digestinfo_prefix = {
- .digest = &sha1_algorithm,
- .data = rsa_sha1_prefix_data,
- .len = sizeof ( rsa_sha1_prefix_data ),
-};
-
-/** RSA with SHA-1 signature hash algorithm */
-struct tls_signature_hash_algorithm tls_rsa_sha1 __tls_sig_hash_algorithm = {
- .code = {
- .signature = TLS_RSA_ALGORITHM,
- .hash = TLS_SHA1_ALGORITHM,
- },
- .pubkey = &rsa_algorithm,
- .digest = &sha1_algorithm,
-};
diff --git a/qemu/roms/ipxe/src/crypto/mishmash/rsa_sha224.c b/qemu/roms/ipxe/src/crypto/mishmash/rsa_sha224.c
deleted file mode 100644
index 5e8755aab..000000000
--- a/qemu/roms/ipxe/src/crypto/mishmash/rsa_sha224.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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; either version 2 of the
- * License, or (at your option) any later version.
- *
- * 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.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <ipxe/rsa.h>
-#include <ipxe/sha256.h>
-#include <ipxe/asn1.h>
-#include <ipxe/tls.h>
-
-/** "sha224WithRSAEncryption" object identifier */
-static uint8_t oid_sha224_with_rsa_encryption[] =
- { ASN1_OID_SHA224WITHRSAENCRYPTION };
-
-/** "sha224WithRSAEncryption" OID-identified algorithm */
-struct asn1_algorithm sha224_with_rsa_encryption_algorithm __asn1_algorithm = {
- .name = "sha224WithRSAEncryption",
- .pubkey = &rsa_algorithm,
- .digest = &sha224_algorithm,
- .oid = ASN1_OID_CURSOR ( oid_sha224_with_rsa_encryption ),
-};
-
-/** SHA-224 digestInfo prefix */
-static const uint8_t rsa_sha224_prefix_data[] =
- { RSA_DIGESTINFO_PREFIX ( SHA224_DIGEST_SIZE, ASN1_OID_SHA224 ) };
-
-/** SHA-224 digestInfo prefix */
-struct rsa_digestinfo_prefix rsa_sha224_prefix __rsa_digestinfo_prefix = {
- .digest = &sha224_algorithm,
- .data = rsa_sha224_prefix_data,
- .len = sizeof ( rsa_sha224_prefix_data ),
-};
-
-/** RSA with SHA-224 signature hash algorithm */
-struct tls_signature_hash_algorithm tls_rsa_sha224 __tls_sig_hash_algorithm = {
- .code = {
- .signature = TLS_RSA_ALGORITHM,
- .hash = TLS_SHA224_ALGORITHM,
- },
- .pubkey = &rsa_algorithm,
- .digest = &sha224_algorithm,
-};
diff --git a/qemu/roms/ipxe/src/crypto/mishmash/rsa_sha256.c b/qemu/roms/ipxe/src/crypto/mishmash/rsa_sha256.c
deleted file mode 100644
index b44af5f19..000000000
--- a/qemu/roms/ipxe/src/crypto/mishmash/rsa_sha256.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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; either version 2 of the
- * License, or (at your option) any later version.
- *
- * 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.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <ipxe/rsa.h>
-#include <ipxe/sha256.h>
-#include <ipxe/asn1.h>
-#include <ipxe/tls.h>
-
-/** "sha256WithRSAEncryption" object identifier */
-static uint8_t oid_sha256_with_rsa_encryption[] =
- { ASN1_OID_SHA256WITHRSAENCRYPTION };
-
-/** "sha256WithRSAEncryption" OID-identified algorithm */
-struct asn1_algorithm sha256_with_rsa_encryption_algorithm __asn1_algorithm = {
- .name = "sha256WithRSAEncryption",
- .pubkey = &rsa_algorithm,
- .digest = &sha256_algorithm,
- .oid = ASN1_OID_CURSOR ( oid_sha256_with_rsa_encryption ),
-};
-
-/** SHA-256 digestInfo prefix */
-static const uint8_t rsa_sha256_prefix_data[] =
- { RSA_DIGESTINFO_PREFIX ( SHA256_DIGEST_SIZE, ASN1_OID_SHA256 ) };
-
-/** SHA-256 digestInfo prefix */
-struct rsa_digestinfo_prefix rsa_sha256_prefix __rsa_digestinfo_prefix = {
- .digest = &sha256_algorithm,
- .data = rsa_sha256_prefix_data,
- .len = sizeof ( rsa_sha256_prefix_data ),
-};
-
-/** RSA with SHA-256 signature hash algorithm */
-struct tls_signature_hash_algorithm tls_rsa_sha256 __tls_sig_hash_algorithm = {
- .code = {
- .signature = TLS_RSA_ALGORITHM,
- .hash = TLS_SHA256_ALGORITHM,
- },
- .pubkey = &rsa_algorithm,
- .digest = &sha256_algorithm,
-};
diff --git a/qemu/roms/ipxe/src/crypto/mishmash/rsa_sha384.c b/qemu/roms/ipxe/src/crypto/mishmash/rsa_sha384.c
deleted file mode 100644
index af22a2bf0..000000000
--- a/qemu/roms/ipxe/src/crypto/mishmash/rsa_sha384.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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; either version 2 of the
- * License, or (at your option) any later version.
- *
- * 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.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <ipxe/rsa.h>
-#include <ipxe/sha512.h>
-#include <ipxe/asn1.h>
-#include <ipxe/tls.h>
-
-/** "sha384WithRSAEncryption" object identifier */
-static uint8_t oid_sha384_with_rsa_encryption[] =
- { ASN1_OID_SHA384WITHRSAENCRYPTION };
-
-/** "sha384WithRSAEncryption" OID-identified algorithm */
-struct asn1_algorithm sha384_with_rsa_encryption_algorithm __asn1_algorithm = {
- .name = "sha384WithRSAEncryption",
- .pubkey = &rsa_algorithm,
- .digest = &sha384_algorithm,
- .oid = ASN1_OID_CURSOR ( oid_sha384_with_rsa_encryption ),
-};
-
-/** SHA-384 digestInfo prefix */
-static const uint8_t rsa_sha384_prefix_data[] =
- { RSA_DIGESTINFO_PREFIX ( SHA384_DIGEST_SIZE, ASN1_OID_SHA384 ) };
-
-/** SHA-384 digestInfo prefix */
-struct rsa_digestinfo_prefix rsa_sha384_prefix __rsa_digestinfo_prefix = {
- .digest = &sha384_algorithm,
- .data = rsa_sha384_prefix_data,
- .len = sizeof ( rsa_sha384_prefix_data ),
-};
-
-/** RSA with SHA-384 signature hash algorithm */
-struct tls_signature_hash_algorithm tls_rsa_sha384 __tls_sig_hash_algorithm = {
- .code = {
- .signature = TLS_RSA_ALGORITHM,
- .hash = TLS_SHA384_ALGORITHM,
- },
- .pubkey = &rsa_algorithm,
- .digest = &sha384_algorithm,
-};
diff --git a/qemu/roms/ipxe/src/crypto/mishmash/rsa_sha512.c b/qemu/roms/ipxe/src/crypto/mishmash/rsa_sha512.c
deleted file mode 100644
index 29ee15493..000000000
--- a/qemu/roms/ipxe/src/crypto/mishmash/rsa_sha512.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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; either version 2 of the
- * License, or (at your option) any later version.
- *
- * 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.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <ipxe/rsa.h>
-#include <ipxe/sha512.h>
-#include <ipxe/asn1.h>
-#include <ipxe/tls.h>
-
-/** "sha512WithRSAEncryption" object identifier */
-static uint8_t oid_sha512_with_rsa_encryption[] =
- { ASN1_OID_SHA512WITHRSAENCRYPTION };
-
-/** "sha512WithRSAEncryption" OID-identified algorithm */
-struct asn1_algorithm sha512_with_rsa_encryption_algorithm __asn1_algorithm = {
- .name = "sha512WithRSAEncryption",
- .pubkey = &rsa_algorithm,
- .digest = &sha512_algorithm,
- .oid = ASN1_OID_CURSOR ( oid_sha512_with_rsa_encryption ),
-};
-
-/** SHA-512 digestInfo prefix */
-static const uint8_t rsa_sha512_prefix_data[] =
- { RSA_DIGESTINFO_PREFIX ( SHA512_DIGEST_SIZE, ASN1_OID_SHA512 ) };
-
-/** SHA-512 digestInfo prefix */
-struct rsa_digestinfo_prefix rsa_sha512_prefix __rsa_digestinfo_prefix = {
- .digest = &sha512_algorithm,
- .data = rsa_sha512_prefix_data,
- .len = sizeof ( rsa_sha512_prefix_data ),
-};
-
-/** RSA with SHA-512 signature hash algorithm */
-struct tls_signature_hash_algorithm tls_rsa_sha512 __tls_sig_hash_algorithm = {
- .code = {
- .signature = TLS_RSA_ALGORITHM,
- .hash = TLS_SHA512_ALGORITHM,
- },
- .pubkey = &rsa_algorithm,
- .digest = &sha512_algorithm,
-};
diff --git a/qemu/roms/ipxe/src/crypto/null_entropy.c b/qemu/roms/ipxe/src/crypto/null_entropy.c
deleted file mode 100644
index d1e1a6f73..000000000
--- a/qemu/roms/ipxe/src/crypto/null_entropy.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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; either version 2 of the
- * License, or any later version.
- *
- * 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.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-/** @file
- *
- * Nonexistent entropy source
- *
- *
- * This source provides no entropy and must NOT be used in a
- * security-sensitive environment.
- */
-
-#include <ipxe/entropy.h>
-
-PROVIDE_ENTROPY_INLINE ( null, min_entropy_per_sample );
-PROVIDE_ENTROPY_INLINE ( null, entropy_enable );
-PROVIDE_ENTROPY_INLINE ( null, entropy_disable );
-PROVIDE_ENTROPY_INLINE ( null, get_noise );
diff --git a/qemu/roms/ipxe/src/crypto/ocsp.c b/qemu/roms/ipxe/src/crypto/ocsp.c
deleted file mode 100644
index 5df55bc96..000000000
--- a/qemu/roms/ipxe/src/crypto/ocsp.c
+++ /dev/null
@@ -1,960 +0,0 @@
-/*
- * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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; either version 2 of the
- * License, or (at your option) any later version.
- *
- * 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.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <ipxe/asn1.h>
-#include <ipxe/x509.h>
-#include <ipxe/sha1.h>
-#include <ipxe/base64.h>
-#include <ipxe/uri.h>
-#include <ipxe/ocsp.h>
-#include <config/crypto.h>
-
-/** @file
- *
- * Online Certificate Status Protocol
- *
- */
-
-/* Disambiguate the various error causes */
-#define EACCES_CERT_STATUS \
- __einfo_error ( EINFO_EACCES_CERT_STATUS )
-#define EINFO_EACCES_CERT_STATUS \
- __einfo_uniqify ( EINFO_EACCES, 0x01, \
- "Certificate status not good" )
-#define EACCES_CERT_MISMATCH \
- __einfo_error ( EINFO_EACCES_CERT_MISMATCH )
-#define EINFO_EACCES_CERT_MISMATCH \
- __einfo_uniqify ( EINFO_EACCES, 0x02, \
- "Certificate ID mismatch" )
-#define EACCES_NON_OCSP_SIGNING \
- __einfo_error ( EINFO_EACCES_NON_OCSP_SIGNING )
-#define EINFO_EACCES_NON_OCSP_SIGNING \
- __einfo_uniqify ( EINFO_EACCES, 0x03, \
- "Not an OCSP signing certificate" )
-#define EACCES_STALE \
- __einfo_error ( EINFO_EACCES_STALE )
-#define EINFO_EACCES_STALE \
- __einfo_uniqify ( EINFO_EACCES, 0x04, \
- "Stale (or premature) OCSP repsonse" )
-#define EACCES_NO_RESPONDER \
- __einfo_error ( EINFO_EACCES_NO_RESPONDER )
-#define EINFO_EACCES_NO_RESPONDER \
- __einfo_uniqify ( EINFO_EACCES, 0x05, \
- "Missing OCSP responder certificate" )
-#define ENOTSUP_RESPONSE_TYPE \
- __einfo_error ( EINFO_ENOTSUP_RESPONSE_TYPE )
-#define EINFO_ENOTSUP_RESPONSE_TYPE \
- __einfo_uniqify ( EINFO_ENOTSUP, 0x01, \
- "Unsupported OCSP response type" )
-#define ENOTSUP_RESPONDER_ID \
- __einfo_error ( EINFO_ENOTSUP_RESPONDER_ID )
-#define EINFO_ENOTSUP_RESPONDER_ID \
- __einfo_uniqify ( EINFO_ENOTSUP, 0x02, \
- "Unsupported OCSP responder ID" )
-#define EPROTO_MALFORMED_REQUEST \
- __einfo_error ( EINFO_EPROTO_MALFORMED_REQUEST )
-#define EINFO_EPROTO_MALFORMED_REQUEST \
- __einfo_uniqify ( EINFO_EPROTO, OCSP_STATUS_MALFORMED_REQUEST, \
- "Illegal confirmation request" )
-#define EPROTO_INTERNAL_ERROR \
- __einfo_error ( EINFO_EPROTO_INTERNAL_ERROR )
-#define EINFO_EPROTO_INTERNAL_ERROR \
- __einfo_uniqify ( EINFO_EPROTO, OCSP_STATUS_INTERNAL_ERROR, \
- "Internal error in issuer" )
-#define EPROTO_TRY_LATER \
- __einfo_error ( EINFO_EPROTO_TRY_LATER )
-#define EINFO_EPROTO_TRY_LATER \
- __einfo_uniqify ( EINFO_EPROTO, OCSP_STATUS_TRY_LATER, \
- "Try again later" )
-#define EPROTO_SIG_REQUIRED \
- __einfo_error ( EINFO_EPROTO_SIG_REQUIRED )
-#define EINFO_EPROTO_SIG_REQUIRED \
- __einfo_uniqify ( EINFO_EPROTO, OCSP_STATUS_SIG_REQUIRED, \
- "Must sign the request" )
-#define EPROTO_UNAUTHORIZED \
- __einfo_error ( EINFO_EPROTO_UNAUTHORIZED )
-#define EINFO_EPROTO_UNAUTHORIZED \
- __einfo_uniqify ( EINFO_EPROTO, OCSP_STATUS_UNAUTHORIZED, \
- "Request unauthorized" )
-#define EPROTO_STATUS( status ) \
- EUNIQ ( EINFO_EPROTO, (status), EPROTO_MALFORMED_REQUEST, \
- EPROTO_INTERNAL_ERROR, EPROTO_TRY_LATER, \
- EPROTO_SIG_REQUIRED, EPROTO_UNAUTHORIZED )
-
-/** OCSP digest algorithm */
-#define ocsp_digest_algorithm sha1_algorithm
-
-/** OCSP digest algorithm identifier */
-static const uint8_t ocsp_algorithm_id[] =
- { OCSP_ALGORITHM_IDENTIFIER ( ASN1_OID_SHA1 ) };
-
-/** OCSP basic response type */
-static const uint8_t oid_basic_response_type[] = { ASN1_OID_OCSP_BASIC };
-
-/** OCSP basic response type cursor */
-static struct asn1_cursor oid_basic_response_type_cursor =
- ASN1_OID_CURSOR ( oid_basic_response_type );
-
-/**
- * Free OCSP check
- *
- * @v refcnt Reference count
- */
-static void ocsp_free ( struct refcnt *refcnt ) {
- struct ocsp_check *ocsp =
- container_of ( refcnt, struct ocsp_check, refcnt );
-
- x509_put ( ocsp->cert );
- x509_put ( ocsp->issuer );
- free ( ocsp->uri_string );
- free ( ocsp->request.builder.data );
- free ( ocsp->response.data );
- x509_put ( ocsp->response.signer );
- free ( ocsp );
-}
-
-/**
- * Build OCSP request
- *
- * @v ocsp OCSP check
- * @ret rc Return status code
- */
-static int ocsp_request ( struct ocsp_check *ocsp ) {
- struct digest_algorithm *digest = &ocsp_digest_algorithm;
- struct asn1_builder *builder = &ocsp->request.builder;
- struct asn1_cursor *cert_id = &ocsp->request.cert_id;
- uint8_t digest_ctx[digest->ctxsize];
- uint8_t name_digest[digest->digestsize];
- uint8_t pubkey_digest[digest->digestsize];
- int rc;
-
- /* Generate digests */
- digest_init ( digest, digest_ctx );
- digest_update ( digest, digest_ctx, ocsp->cert->issuer.raw.data,
- ocsp->cert->issuer.raw.len );
- digest_final ( digest, digest_ctx, name_digest );
- digest_init ( digest, digest_ctx );
- digest_update ( digest, digest_ctx,
- ocsp->issuer->subject.public_key.raw_bits.data,
- ocsp->issuer->subject.public_key.raw_bits.len );
- digest_final ( digest, digest_ctx, pubkey_digest );
-
- /* Construct request */
- if ( ( rc = ( asn1_prepend_raw ( builder, ocsp->cert->serial.raw.data,
- ocsp->cert->serial.raw.len ),
- asn1_prepend ( builder, ASN1_OCTET_STRING,
- pubkey_digest, sizeof ( pubkey_digest ) ),
- asn1_prepend ( builder, ASN1_OCTET_STRING,
- name_digest, sizeof ( name_digest ) ),
- asn1_prepend ( builder, ASN1_SEQUENCE,
- ocsp_algorithm_id,
- sizeof ( ocsp_algorithm_id ) ),
- asn1_wrap ( builder, ASN1_SEQUENCE ),
- asn1_wrap ( builder, ASN1_SEQUENCE ),
- asn1_wrap ( builder, ASN1_SEQUENCE ),
- asn1_wrap ( builder, ASN1_SEQUENCE ),
- asn1_wrap ( builder, ASN1_SEQUENCE ) ) ) != 0 ) {
- DBGC ( ocsp, "OCSP %p \"%s\" could not build request: %s\n",
- ocsp, x509_name ( ocsp->cert ), strerror ( rc ) );
- return rc;
- }
- DBGC2 ( ocsp, "OCSP %p \"%s\" request is:\n",
- ocsp, x509_name ( ocsp->cert ) );
- DBGC2_HDA ( ocsp, 0, builder->data, builder->len );
-
- /* Parse certificate ID for comparison with response */
- cert_id->data = builder->data;
- cert_id->len = builder->len;
- if ( ( rc = ( asn1_enter ( cert_id, ASN1_SEQUENCE ),
- asn1_enter ( cert_id, ASN1_SEQUENCE ),
- asn1_enter ( cert_id, ASN1_SEQUENCE ),
- asn1_enter ( cert_id, ASN1_SEQUENCE ) ) ) != 0 ) {
- DBGC ( ocsp, "OCSP %p \"%s\" could not locate certID: %s\n",
- ocsp, x509_name ( ocsp->cert ), strerror ( rc ) );
- return rc;
- }
-
- return 0;
-}
-
-/**
- * Build OCSP URI string
- *
- * @v ocsp OCSP check
- * @ret rc Return status code
- */
-static int ocsp_uri_string ( struct ocsp_check *ocsp ) {
- struct x509_ocsp_responder *responder =
- &ocsp->cert->extensions.auth_info.ocsp;
- struct uri path_uri;
- char *path_base64_string;
- char *path_uri_string;
- size_t path_len;
- size_t len;
- int rc;
-
- /* Sanity check */
- if ( ! responder->uri.len ) {
- DBGC ( ocsp, "OCSP %p \"%s\" has no OCSP URI\n",
- ocsp, x509_name ( ocsp->cert ) );
- rc = -ENOTTY;
- goto err_no_uri;
- }
-
- /* Base64-encode the request as the URI path */
- path_len = ( base64_encoded_len ( ocsp->request.builder.len )
- + 1 /* NUL */ );
- path_base64_string = malloc ( path_len );
- if ( ! path_base64_string ) {
- rc = -ENOMEM;
- goto err_path_base64;
- }
- base64_encode ( ocsp->request.builder.data, ocsp->request.builder.len,
- path_base64_string, path_len );
-
- /* URI-encode the Base64-encoded request */
- memset ( &path_uri, 0, sizeof ( path_uri ) );
- path_uri.path = path_base64_string;
- path_uri_string = format_uri_alloc ( &path_uri );
- if ( ! path_uri_string ) {
- rc = -ENOMEM;
- goto err_path_uri;
- }
-
- /* Construct URI string */
- len = ( responder->uri.len + strlen ( path_uri_string ) + 1 /* NUL */ );
- ocsp->uri_string = zalloc ( len );
- if ( ! ocsp->uri_string ) {
- rc = -ENOMEM;
- goto err_ocsp_uri;
- }
- memcpy ( ocsp->uri_string, responder->uri.data, responder->uri.len );
- strcpy ( &ocsp->uri_string[responder->uri.len], path_uri_string );
- DBGC2 ( ocsp, "OCSP %p \"%s\" URI is %s\n",
- ocsp, x509_name ( ocsp->cert ), ocsp->uri_string );
-
- /* Success */
- rc = 0;
-
- err_ocsp_uri:
- free ( path_uri_string );
- err_path_uri:
- free ( path_base64_string );
- err_path_base64:
- err_no_uri:
- return rc;
-}
-
-/**
- * Create OCSP check
- *
- * @v cert Certificate to check
- * @v issuer Issuing certificate
- * @ret ocsp OCSP check
- * @ret rc Return status code
- */
-int ocsp_check ( struct x509_certificate *cert,
- struct x509_certificate *issuer,
- struct ocsp_check **ocsp ) {
- int rc;
-
- /* Sanity checks */
- assert ( cert != NULL );
- assert ( issuer != NULL );
- assert ( issuer->valid );
-
- /* Allocate and initialise check */
- *ocsp = zalloc ( sizeof ( **ocsp ) );
- if ( ! *ocsp ) {
- rc = -ENOMEM;
- goto err_alloc;
- }
- ref_init ( &(*ocsp)->refcnt, ocsp_free );
- (*ocsp)->cert = x509_get ( cert );
- (*ocsp)->issuer = x509_get ( issuer );
-
- /* Build request */
- if ( ( rc = ocsp_request ( *ocsp ) ) != 0 )
- goto err_request;
-
- /* Build URI string */
- if ( ( rc = ocsp_uri_string ( *ocsp ) ) != 0 )
- goto err_uri_string;
-
- return 0;
-
- err_uri_string:
- err_request:
- ocsp_put ( *ocsp );
- err_alloc:
- *ocsp = NULL;
- return rc;
-}
-
-/**
- * Parse OCSP response status
- *
- * @v ocsp OCSP check
- * @v raw ASN.1 cursor
- * @ret rc Return status code
- */
-static int ocsp_parse_response_status ( struct ocsp_check *ocsp,
- const struct asn1_cursor *raw ) {
- struct asn1_cursor cursor;
- uint8_t status;
- int rc;
-
- /* Enter responseStatus */
- memcpy ( &cursor, raw, sizeof ( cursor ) );
- if ( ( rc = asn1_enter ( &cursor, ASN1_ENUMERATED ) ) != 0 ) {
- DBGC ( ocsp, "OCSP %p \"%s\" could not locate responseStatus: "
- "%s\n", ocsp, x509_name ( ocsp->cert ), strerror ( rc ));
- return rc;
- }
-
- /* Extract response status */
- if ( cursor.len != sizeof ( status ) ) {
- DBGC ( ocsp, "OCSP %p \"%s\" invalid status:\n",
- ocsp, x509_name ( ocsp->cert ) );
- DBGC_HDA ( ocsp, 0, cursor.data, cursor.len );
- return -EINVAL;
- }
- memcpy ( &status, cursor.data, sizeof ( status ) );
-
- /* Check response status */
- if ( status != OCSP_STATUS_SUCCESSFUL ) {
- DBGC ( ocsp, "OCSP %p \"%s\" response status %d\n",
- ocsp, x509_name ( ocsp->cert ), status );
- return EPROTO_STATUS ( status );
- }
-
- return 0;
-}
-
-/**
- * Parse OCSP response type
- *
- * @v ocsp OCSP check
- * @v raw ASN.1 cursor
- * @ret rc Return status code
- */
-static int ocsp_parse_response_type ( struct ocsp_check *ocsp,
- const struct asn1_cursor *raw ) {
- struct asn1_cursor cursor;
-
- /* Enter responseType */
- memcpy ( &cursor, raw, sizeof ( cursor ) );
- asn1_enter ( &cursor, ASN1_OID );
-
- /* Check responseType is "basic" */
- if ( asn1_compare ( &oid_basic_response_type_cursor, &cursor ) != 0 ) {
- DBGC ( ocsp, "OCSP %p \"%s\" response type not supported:\n",
- ocsp, x509_name ( ocsp->cert ) );
- DBGC_HDA ( ocsp, 0, cursor.data, cursor.len );
- return -ENOTSUP_RESPONSE_TYPE;
- }
-
- return 0;
-}
-
-/**
- * Compare responder's certificate name
- *
- * @v ocsp OCSP check
- * @v cert Certificate
- * @ret difference Difference as returned by memcmp()
- */
-static int ocsp_compare_responder_name ( struct ocsp_check *ocsp,
- struct x509_certificate *cert ) {
- struct ocsp_responder *responder = &ocsp->response.responder;
-
- /* Compare responder ID with certificate's subject */
- return asn1_compare ( &responder->id, &cert->subject.raw );
-}
-
-/**
- * Compare responder's certificate public key hash
- *
- * @v ocsp OCSP check
- * @v cert Certificate
- * @ret difference Difference as returned by memcmp()
- */
-static int ocsp_compare_responder_key_hash ( struct ocsp_check *ocsp,
- struct x509_certificate *cert ) {
- struct ocsp_responder *responder = &ocsp->response.responder;
- struct asn1_cursor key_hash;
- uint8_t ctx[SHA1_CTX_SIZE];
- uint8_t digest[SHA1_DIGEST_SIZE];
- int difference;
-
- /* Enter responder key hash */
- memcpy ( &key_hash, &responder->id, sizeof ( key_hash ) );
- asn1_enter ( &key_hash, ASN1_OCTET_STRING );
-
- /* Sanity check */
- difference = ( sizeof ( digest ) - key_hash.len );
- if ( difference )
- return difference;
-
- /* Generate SHA1 hash of certificate's public key */
- digest_init ( &sha1_algorithm, ctx );
- digest_update ( &sha1_algorithm, ctx,
- cert->subject.public_key.raw_bits.data,
- cert->subject.public_key.raw_bits.len );
- digest_final ( &sha1_algorithm, ctx, digest );
-
- /* Compare responder key hash with hash of certificate's public key */
- return memcmp ( digest, key_hash.data, sizeof ( digest ) );
-}
-
-/**
- * Parse OCSP responder ID
- *
- * @v ocsp OCSP check
- * @v raw ASN.1 cursor
- * @ret rc Return status code
- */
-static int ocsp_parse_responder_id ( struct ocsp_check *ocsp,
- const struct asn1_cursor *raw ) {
- struct ocsp_responder *responder = &ocsp->response.responder;
- struct asn1_cursor *responder_id = &responder->id;
- unsigned int type;
-
- /* Enter responder ID */
- memcpy ( responder_id, raw, sizeof ( *responder_id ) );
- type = asn1_type ( responder_id );
- asn1_enter_any ( responder_id );
-
- /* Identify responder ID type */
- switch ( type ) {
- case ASN1_EXPLICIT_TAG ( 1 ) :
- DBGC2 ( ocsp, "OCSP %p \"%s\" responder identified by name\n",
- ocsp, x509_name ( ocsp->cert ) );
- responder->compare = ocsp_compare_responder_name;
- return 0;
- case ASN1_EXPLICIT_TAG ( 2 ) :
- DBGC2 ( ocsp, "OCSP %p \"%s\" responder identified by key "
- "hash\n", ocsp, x509_name ( ocsp->cert ) );
- responder->compare = ocsp_compare_responder_key_hash;
- return 0;
- default:
- DBGC ( ocsp, "OCSP %p \"%s\" unsupported responder ID type "
- "%d\n", ocsp, x509_name ( ocsp->cert ), type );
- return -ENOTSUP_RESPONDER_ID;
- }
-}
-
-/**
- * Parse OCSP certificate ID
- *
- * @v ocsp OCSP check
- * @v raw ASN.1 cursor
- * @ret rc Return status code
- */
-static int ocsp_parse_cert_id ( struct ocsp_check *ocsp,
- const struct asn1_cursor *raw ) {
- struct asn1_cursor cursor;
-
- /* Check certID matches request */
- memcpy ( &cursor, raw, sizeof ( cursor ) );
- asn1_shrink_any ( &cursor );
- if ( asn1_compare ( &cursor, &ocsp->request.cert_id ) != 0 ) {
- DBGC ( ocsp, "OCSP %p \"%s\" certID mismatch:\n",
- ocsp, x509_name ( ocsp->cert ) );
- DBGC_HDA ( ocsp, 0, ocsp->request.cert_id.data,
- ocsp->request.cert_id.len );
- DBGC_HDA ( ocsp, 0, cursor.data, cursor.len );
- return -EACCES_CERT_MISMATCH;
- }
-
- return 0;
-}
-
-/**
- * Parse OCSP responses
- *
- * @v ocsp OCSP check
- * @v raw ASN.1 cursor
- * @ret rc Return status code
- */
-static int ocsp_parse_responses ( struct ocsp_check *ocsp,
- const struct asn1_cursor *raw ) {
- struct ocsp_response *response = &ocsp->response;
- struct asn1_cursor cursor;
- int rc;
-
- /* Enter responses */
- memcpy ( &cursor, raw, sizeof ( cursor ) );
- asn1_enter ( &cursor, ASN1_SEQUENCE );
-
- /* Enter first singleResponse */
- asn1_enter ( &cursor, ASN1_SEQUENCE );
-
- /* Parse certID */
- if ( ( rc = ocsp_parse_cert_id ( ocsp, &cursor ) ) != 0 )
- return rc;
- asn1_skip_any ( &cursor );
-
- /* Check certStatus */
- if ( asn1_type ( &cursor ) != ASN1_IMPLICIT_TAG ( 0 ) ) {
- DBGC ( ocsp, "OCSP %p \"%s\" non-good certStatus:\n",
- ocsp, x509_name ( ocsp->cert ) );
- DBGC_HDA ( ocsp, 0, cursor.data, cursor.len );
- return -EACCES_CERT_STATUS;
- }
- asn1_skip_any ( &cursor );
-
- /* Parse thisUpdate */
- if ( ( rc = asn1_generalized_time ( &cursor,
- &response->this_update ) ) != 0 ) {
- DBGC ( ocsp, "OCSP %p \"%s\" could not parse thisUpdate: %s\n",
- ocsp, x509_name ( ocsp->cert ), strerror ( rc ) );
- return rc;
- }
- DBGC2 ( ocsp, "OCSP %p \"%s\" this update was at time %lld\n",
- ocsp, x509_name ( ocsp->cert ), response->this_update );
- asn1_skip_any ( &cursor );
-
- /* Parse nextUpdate, if present */
- if ( asn1_type ( &cursor ) == ASN1_EXPLICIT_TAG ( 0 ) ) {
- asn1_enter ( &cursor, ASN1_EXPLICIT_TAG ( 0 ) );
- if ( ( rc = asn1_generalized_time ( &cursor,
- &response->next_update ) ) != 0 ) {
- DBGC ( ocsp, "OCSP %p \"%s\" could not parse "
- "nextUpdate: %s\n", ocsp,
- x509_name ( ocsp->cert ), strerror ( rc ) );
- return rc;
- }
- DBGC2 ( ocsp, "OCSP %p \"%s\" next update is at time %lld\n",
- ocsp, x509_name ( ocsp->cert ), response->next_update );
- } else {
- /* If no nextUpdate is present, this indicates that
- * "newer revocation information is available all the
- * time". Actually, this indicates that there is no
- * point to performing the OCSP check, since an
- * attacker could replay the response at any future
- * time and it would still be valid.
- */
- DBGC ( ocsp, "OCSP %p \"%s\" responder is a moron\n",
- ocsp, x509_name ( ocsp->cert ) );
- response->next_update = time ( NULL );
- }
-
- return 0;
-}
-
-/**
- * Parse OCSP response data
- *
- * @v ocsp OCSP check
- * @v raw ASN.1 cursor
- * @ret rc Return status code
- */
-static int ocsp_parse_tbs_response_data ( struct ocsp_check *ocsp,
- const struct asn1_cursor *raw ) {
- struct ocsp_response *response = &ocsp->response;
- struct asn1_cursor cursor;
- int rc;
-
- /* Record raw tbsResponseData */
- memcpy ( &cursor, raw, sizeof ( cursor ) );
- asn1_shrink_any ( &cursor );
- memcpy ( &response->tbs, &cursor, sizeof ( response->tbs ) );
-
- /* Enter tbsResponseData */
- asn1_enter ( &cursor, ASN1_SEQUENCE );
-
- /* Skip version, if present */
- asn1_skip_if_exists ( &cursor, ASN1_EXPLICIT_TAG ( 0 ) );
-
- /* Parse responderID */
- if ( ( rc = ocsp_parse_responder_id ( ocsp, &cursor ) ) != 0 )
- return rc;
- asn1_skip_any ( &cursor );
-
- /* Skip producedAt */
- asn1_skip_any ( &cursor );
-
- /* Parse responses */
- if ( ( rc = ocsp_parse_responses ( ocsp, &cursor ) ) != 0 )
- return rc;
-
- return 0;
-}
-
-/**
- * Parse OCSP certificates
- *
- * @v ocsp OCSP check
- * @v raw ASN.1 cursor
- * @ret rc Return status code
- */
-static int ocsp_parse_certs ( struct ocsp_check *ocsp,
- const struct asn1_cursor *raw ) {
- struct ocsp_response *response = &ocsp->response;
- struct asn1_cursor cursor;
- struct x509_certificate *cert;
- int rc;
-
- /* Enter certs */
- memcpy ( &cursor, raw, sizeof ( cursor ) );
- asn1_enter ( &cursor, ASN1_EXPLICIT_TAG ( 0 ) );
- asn1_enter ( &cursor, ASN1_SEQUENCE );
-
- /* Parse certificate, if present. The data structure permits
- * multiple certificates, but the protocol requires that the
- * OCSP signing certificate must either be the issuer itself,
- * or must be directly issued by the issuer (see RFC2560
- * section 4.2.2.2 "Authorized Responders"). We therefore
- * need to identify only the single certificate matching the
- * Responder ID.
- */
- while ( cursor.len ) {
-
- /* Parse certificate */
- if ( ( rc = x509_certificate ( cursor.data, cursor.len,
- &cert ) ) != 0 ) {
- DBGC ( ocsp, "OCSP %p \"%s\" could not parse "
- "certificate: %s\n", ocsp,
- x509_name ( ocsp->cert ), strerror ( rc ) );
- DBGC_HDA ( ocsp, 0, cursor.data, cursor.len );
- return rc;
- }
-
- /* Use if this certificate matches the responder ID */
- if ( response->responder.compare ( ocsp, cert ) == 0 ) {
- response->signer = cert;
- DBGC2 ( ocsp, "OCSP %p \"%s\" response is signed by ",
- ocsp, x509_name ( ocsp->cert ) );
- DBGC2 ( ocsp, "\"%s\"\n",
- x509_name ( response->signer ) );
- return 0;
- }
-
- /* Otherwise, discard this certificate */
- x509_put ( cert );
- asn1_skip_any ( &cursor );
- }
-
- DBGC ( ocsp, "OCSP %p \"%s\" missing responder certificate\n",
- ocsp, x509_name ( ocsp->cert ) );
- return -EACCES_NO_RESPONDER;
-}
-
-/**
- * Parse OCSP basic response
- *
- * @v ocsp OCSP check
- * @v raw ASN.1 cursor
- * @ret rc Return status code
- */
-static int ocsp_parse_basic_response ( struct ocsp_check *ocsp,
- const struct asn1_cursor *raw ) {
- struct ocsp_response *response = &ocsp->response;
- struct asn1_algorithm **algorithm = &response->algorithm;
- struct asn1_bit_string *signature = &response->signature;
- struct asn1_cursor cursor;
- int rc;
-
- /* Enter BasicOCSPResponse */
- memcpy ( &cursor, raw, sizeof ( cursor ) );
- asn1_enter ( &cursor, ASN1_SEQUENCE );
-
- /* Parse tbsResponseData */
- if ( ( rc = ocsp_parse_tbs_response_data ( ocsp, &cursor ) ) != 0 )
- return rc;
- asn1_skip_any ( &cursor );
-
- /* Parse signatureAlgorithm */
- if ( ( rc = asn1_signature_algorithm ( &cursor, algorithm ) ) != 0 ) {
- DBGC ( ocsp, "OCSP %p \"%s\" cannot parse signature "
- "algorithm: %s\n",
- ocsp, x509_name ( ocsp->cert ), strerror ( rc ) );
- return rc;
- }
- DBGC2 ( ocsp, "OCSP %p \"%s\" signature algorithm is %s\n",
- ocsp, x509_name ( ocsp->cert ), (*algorithm)->name );
- asn1_skip_any ( &cursor );
-
- /* Parse signature */
- if ( ( rc = asn1_integral_bit_string ( &cursor, signature ) ) != 0 ) {
- DBGC ( ocsp, "OCSP %p \"%s\" cannot parse signature: %s\n",
- ocsp, x509_name ( ocsp->cert ), strerror ( rc ) );
- return rc;
- }
- asn1_skip_any ( &cursor );
-
- /* Parse certs, if present */
- if ( ( asn1_type ( &cursor ) == ASN1_EXPLICIT_TAG ( 0 ) ) &&
- ( ( rc = ocsp_parse_certs ( ocsp, &cursor ) ) != 0 ) )
- return rc;
-
- return 0;
-}
-
-/**
- * Parse OCSP response bytes
- *
- * @v ocsp OCSP check
- * @v raw ASN.1 cursor
- * @ret rc Return status code
- */
-static int ocsp_parse_response_bytes ( struct ocsp_check *ocsp,
- const struct asn1_cursor *raw ) {
- struct asn1_cursor cursor;
- int rc;
-
- /* Enter responseBytes */
- memcpy ( &cursor, raw, sizeof ( cursor ) );
- asn1_enter ( &cursor, ASN1_EXPLICIT_TAG ( 0 ) );
- asn1_enter ( &cursor, ASN1_SEQUENCE );
-
- /* Parse responseType */
- if ( ( rc = ocsp_parse_response_type ( ocsp, &cursor ) ) != 0 )
- return rc;
- asn1_skip_any ( &cursor );
-
- /* Enter response */
- asn1_enter ( &cursor, ASN1_OCTET_STRING );
-
- /* Parse response */
- if ( ( rc = ocsp_parse_basic_response ( ocsp, &cursor ) ) != 0 )
- return rc;
-
- return 0;
-}
-
-/**
- * Parse OCSP response
- *
- * @v ocsp OCSP check
- * @v raw ASN.1 cursor
- * @ret rc Return status code
- */
-static int ocsp_parse_response ( struct ocsp_check *ocsp,
- const struct asn1_cursor *raw ) {
- struct asn1_cursor cursor;
- int rc;
-
- /* Enter OCSPResponse */
- memcpy ( &cursor, raw, sizeof ( cursor ) );
- asn1_enter ( &cursor, ASN1_SEQUENCE );
-
- /* Parse responseStatus */
- if ( ( rc = ocsp_parse_response_status ( ocsp, &cursor ) ) != 0 )
- return rc;
- asn1_skip_any ( &cursor );
-
- /* Parse responseBytes */
- if ( ( rc = ocsp_parse_response_bytes ( ocsp, &cursor ) ) != 0 )
- return rc;
-
- return 0;
-}
-
-/**
- * Receive OCSP response
- *
- * @v ocsp OCSP check
- * @v data Response data
- * @v len Length of response data
- * @ret rc Return status code
- */
-int ocsp_response ( struct ocsp_check *ocsp, const void *data, size_t len ) {
- struct ocsp_response *response = &ocsp->response;
- struct asn1_cursor cursor;
- int rc;
-
- /* Duplicate data */
- x509_put ( response->signer );
- response->signer = NULL;
- free ( response->data );
- response->data = malloc ( len );
- if ( ! response->data )
- return -ENOMEM;
- memcpy ( response->data, data, len );
- cursor.data = response->data;
- cursor.len = len;
-
- /* Parse response */
- if ( ( rc = ocsp_parse_response ( ocsp, &cursor ) ) != 0 )
- return rc;
-
- return 0;
-}
-
-/**
- * OCSP dummy root certificate store
- *
- * OCSP validation uses no root certificates, since it takes place
- * only when there already exists a validated issuer certificate.
- */
-static struct x509_root ocsp_root = {
- .digest = &ocsp_digest_algorithm,
- .count = 0,
- .fingerprints = NULL,
-};
-
-/**
- * Check OCSP response signature
- *
- * @v ocsp OCSP check
- * @v signer Signing certificate
- * @ret rc Return status code
- */
-static int ocsp_check_signature ( struct ocsp_check *ocsp,
- struct x509_certificate *signer ) {
- struct ocsp_response *response = &ocsp->response;
- struct digest_algorithm *digest = response->algorithm->digest;
- struct pubkey_algorithm *pubkey = response->algorithm->pubkey;
- struct x509_public_key *public_key = &signer->subject.public_key;
- uint8_t digest_ctx[ digest->ctxsize ];
- uint8_t digest_out[ digest->digestsize ];
- uint8_t pubkey_ctx[ pubkey->ctxsize ];
- int rc;
-
- /* Generate digest */
- digest_init ( digest, digest_ctx );
- digest_update ( digest, digest_ctx, response->tbs.data,
- response->tbs.len );
- digest_final ( digest, digest_ctx, digest_out );
-
- /* Initialise public-key algorithm */
- if ( ( rc = pubkey_init ( pubkey, pubkey_ctx, public_key->raw.data,
- public_key->raw.len ) ) != 0 ) {
- DBGC ( ocsp, "OCSP %p \"%s\" could not initialise public key: "
- "%s\n", ocsp, x509_name ( ocsp->cert ), strerror ( rc ));
- goto err_init;
- }
-
- /* Verify digest */
- if ( ( rc = pubkey_verify ( pubkey, pubkey_ctx, digest, digest_out,
- response->signature.data,
- response->signature.len ) ) != 0 ) {
- DBGC ( ocsp, "OCSP %p \"%s\" signature verification failed: "
- "%s\n", ocsp, x509_name ( ocsp->cert ), strerror ( rc ));
- goto err_verify;
- }
-
- DBGC2 ( ocsp, "OCSP %p \"%s\" signature is correct\n",
- ocsp, x509_name ( ocsp->cert ) );
-
- err_verify:
- pubkey_final ( pubkey, pubkey_ctx );
- err_init:
- return rc;
-}
-
-/**
- * Validate OCSP response
- *
- * @v ocsp OCSP check
- * @v time Time at which to validate response
- * @ret rc Return status code
- */
-int ocsp_validate ( struct ocsp_check *ocsp, time_t time ) {
- struct ocsp_response *response = &ocsp->response;
- struct x509_certificate *signer;
- int rc;
-
- /* Sanity checks */
- assert ( response->data != NULL );
-
- /* The response may include a signer certificate; if this is
- * not present then the response must have been signed
- * directly by the issuer.
- */
- signer = ( response->signer ? response->signer : ocsp->issuer );
-
- /* Validate signer, if applicable. If the signer is not the
- * issuer, then it must be signed directly by the issuer.
- */
- if ( signer != ocsp->issuer ) {
- /* Forcibly invalidate the signer, since we need to
- * ensure that it was signed by our issuer (and not
- * some other issuer). This prevents a sub-CA's OCSP
- * certificate from fraudulently signing OCSP
- * responses from the parent CA.
- */
- x509_invalidate ( signer );
- if ( ( rc = x509_validate ( signer, ocsp->issuer, time,
- &ocsp_root ) ) != 0 ) {
- DBGC ( ocsp, "OCSP %p \"%s\" could not validate ",
- ocsp, x509_name ( ocsp->cert ) );
- DBGC ( ocsp, "signer \"%s\": %s\n",
- x509_name ( signer ), strerror ( rc ) );
- return rc;
- }
-
- /* If signer is not the issuer, then it must have the
- * extendedKeyUsage id-kp-OCSPSigning.
- */
- if ( ! ( signer->extensions.ext_usage.bits &
- X509_OCSP_SIGNING ) ) {
- DBGC ( ocsp, "OCSP %p \"%s\" ",
- ocsp, x509_name ( ocsp->cert ) );
- DBGC ( ocsp, "signer \"%s\" is not an OCSP-signing "
- "certificate\n", x509_name ( signer ) );
- return -EACCES_NON_OCSP_SIGNING;
- }
- }
-
- /* Check OCSP response signature */
- if ( ( rc = ocsp_check_signature ( ocsp, signer ) ) != 0 )
- return rc;
-
- /* Check OCSP response is valid at the specified time
- * (allowing for some margin of error).
- */
- if ( response->this_update > ( time + TIMESTAMP_ERROR_MARGIN ) ) {
- DBGC ( ocsp, "OCSP %p \"%s\" response is not yet valid (at "
- "time %lld)\n", ocsp, x509_name ( ocsp->cert ), time );
- return -EACCES_STALE;
- }
- if ( response->next_update < ( time - TIMESTAMP_ERROR_MARGIN ) ) {
- DBGC ( ocsp, "OCSP %p \"%s\" response is stale (at time "
- "%lld)\n", ocsp, x509_name ( ocsp->cert ), time );
- return -EACCES_STALE;
- }
- DBGC2 ( ocsp, "OCSP %p \"%s\" response is valid (at time %lld)\n",
- ocsp, x509_name ( ocsp->cert ), time );
-
- /* Mark certificate as passing OCSP verification */
- ocsp->cert->extensions.auth_info.ocsp.good = 1;
-
- /* Validate certificate against issuer */
- if ( ( rc = x509_validate ( ocsp->cert, ocsp->issuer, time,
- &ocsp_root ) ) != 0 ) {
- DBGC ( ocsp, "OCSP %p \"%s\" could not validate certificate: "
- "%s\n", ocsp, x509_name ( ocsp->cert ), strerror ( rc ));
- return rc;
- }
- DBGC ( ocsp, "OCSP %p \"%s\" successfully validated ",
- ocsp, x509_name ( ocsp->cert ) );
- DBGC ( ocsp, "using \"%s\"\n", x509_name ( signer ) );
-
- return 0;
-}
diff --git a/qemu/roms/ipxe/src/crypto/privkey.c b/qemu/roms/ipxe/src/crypto/privkey.c
deleted file mode 100644
index a6043bd1e..000000000
--- a/qemu/roms/ipxe/src/crypto/privkey.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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; either version 2 of the
- * License, or any later version.
- *
- * 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.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ipxe/dhcp.h>
-#include <ipxe/settings.h>
-#include <ipxe/x509.h>
-#include <ipxe/privkey.h>
-
-/** @file
- *
- * Private key
- *
- * Life would in theory be easier if we could use a single file to
- * hold both the certificate and corresponding private key.
- * Unfortunately, the only common format which supports this is
- * PKCS#12 (aka PFX), which is too ugly to be allowed anywhere near my
- * codebase. See, for reference and amusement:
- *
- * http://www.cs.auckland.ac.nz/~pgut001/pubs/pfx.html
- */
-
-/* Allow private key to be overridden if not explicitly specified */
-#ifdef PRIVATE_KEY
-#define ALLOW_KEY_OVERRIDE 0
-#else
-#define ALLOW_KEY_OVERRIDE 1
-#endif
-
-/* Raw private key data */
-extern char private_key_data[];
-extern char private_key_len[];
-__asm__ ( ".section \".rodata\", \"a\", @progbits\n\t"
- "\nprivate_key_data:\n\t"
-#ifdef PRIVATE_KEY
- ".incbin \"" PRIVATE_KEY "\"\n\t"
-#endif /* PRIVATE_KEY */
- ".size private_key_data, ( . - private_key_data )\n\t"
- ".equ private_key_len, ( . - private_key_data )\n\t"
- ".previous\n\t" );
-
-/** Private key */
-struct asn1_cursor private_key = {
- .data = private_key_data,
- .len = ( ( size_t ) private_key_len ),
-};
-
-/** Private key setting */
-static struct setting privkey_setting __setting ( SETTING_CRYPTO, privkey ) = {
- .name = "privkey",
- .description = "Private key",
- .tag = DHCP_EB_KEY,
- .type = &setting_type_hex,
-};
-
-/**
- * Apply private key configuration settings
- *
- * @ret rc Return status code
- */
-static int privkey_apply_settings ( void ) {
- static void *key_data = NULL;
- int len;
-
- /* Allow private key to be overridden only if not explicitly
- * specified at build time.
- */
- if ( ALLOW_KEY_OVERRIDE ) {
-
- /* Restore default private key */
- private_key.data = private_key_data;
- private_key.len = ( ( size_t ) private_key_len );
-
- /* Fetch new private key, if any */
- free ( key_data );
- if ( ( len = fetch_raw_setting_copy ( NULL, &privkey_setting,
- &key_data ) ) >= 0 ) {
- private_key.data = key_data;
- private_key.len = len;
- }
- }
-
- /* Debug */
- if ( private_key.len ) {
- DBGC ( &private_key, "PRIVKEY using %s private key:\n",
- ( key_data ? "external" : "built-in" ) );
- DBGC_HDA ( &private_key, 0, private_key.data, private_key.len );
- } else {
- DBGC ( &private_key, "PRIVKEY has no private key\n" );
- }
-
- return 0;
-}
-
-/** Private key settings applicator */
-struct settings_applicator privkey_applicator __settings_applicator = {
- .apply = privkey_apply_settings,
-};
diff --git a/qemu/roms/ipxe/src/crypto/random_nz.c b/qemu/roms/ipxe/src/crypto/random_nz.c
deleted file mode 100644
index 5fe576e05..000000000
--- a/qemu/roms/ipxe/src/crypto/random_nz.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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; either version 2 of the
- * License, or any later version.
- *
- * 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.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-/** @file
- *
- * Random non-zero bytes
- *
- * The RSA algorithm requires the generation of random non-zero bytes,
- * i.e. bytes in the range [0x01,0xff].
- *
- * This algorithm is designed to comply with ANS X9.82 Part 1-2006
- * Section 9.2.1. This standard is not freely available, but most of
- * the text appears to be shared with NIST SP 800-90, which can be
- * downloaded from
- *
- * http://csrc.nist.gov/publications/nistpubs/800-90/SP800-90revised_March2007.pdf
- *
- * Where possible, references are given to both documents. In the
- * case of any disagreement, ANS X9.82 takes priority over NIST SP
- * 800-90. (In particular, note that some algorithms that are
- * Approved by NIST SP 800-90 are not Approved by ANS X9.82.)
- */
-
-#include <stddef.h>
-#include <stdint.h>
-#include <ipxe/rbg.h>
-#include <ipxe/random_nz.h>
-
-/**
- * Get random non-zero bytes
- *
- * @v data Output buffer
- * @v len Length of output buffer
- * @ret rc Return status code
- *
- * This algorithm is designed to be isomorphic to the Simple Discard
- * Method described in ANS X9.82 Part 1-2006 Section 9.2.1 (NIST SP
- * 800-90 Section B.5.1.1).
- */
-int get_random_nz ( void *data, size_t len ) {
- uint8_t *bytes = data;
- int rc;
-
- while ( len ) {
-
- /* Generate random byte */
- if ( ( rc = rbg_generate ( NULL, 0, 0, bytes, 1 ) ) != 0 )
- return rc;
-
- /* Move to next byte if this byte is acceptable */
- if ( *bytes != 0 ) {
- bytes++;
- len--;
- }
- }
-
- return 0;
-}
diff --git a/qemu/roms/ipxe/src/crypto/rbg.c b/qemu/roms/ipxe/src/crypto/rbg.c
deleted file mode 100644
index 943b288c3..000000000
--- a/qemu/roms/ipxe/src/crypto/rbg.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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; either version 2 of the
- * License, or any later version.
- *
- * 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.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-/** @file
- *
- * RBG mechanism
- *
- * This mechanism is designed to comply with ANS X9.82 Part 4 (April
- * 2011 Draft) Section 10. This standard is unfortunately not freely
- * available.
- *
- * The chosen RBG design is that of a DRBG with a live entropy source
- * with no conditioning function. Only a single security strength is
- * supported. No seedfile is used since there may be no non-volatile
- * storage available. The system UUID is used as the personalisation
- * string.
- */
-
-#include <stdint.h>
-#include <string.h>
-#include <ipxe/init.h>
-#include <ipxe/settings.h>
-#include <ipxe/uuid.h>
-#include <ipxe/crypto.h>
-#include <ipxe/drbg.h>
-#include <ipxe/rbg.h>
-
-/** The RBG */
-struct random_bit_generator rbg;
-
-/**
- * Start up RBG
- *
- * @ret rc Return status code
- *
- * This is the RBG_Startup function defined in ANS X9.82 Part 4 (April
- * 2011 Draft) Section 9.1.2.2.
- */
-static int rbg_startup ( void ) {
- union uuid uuid;
- int len;
- int rc;
-
- /* Try to obtain system UUID for use as personalisation
- * string, in accordance with ANS X9.82 Part 3-2007 Section
- * 8.5.2. If no UUID is available, proceed without a
- * personalisation string.
- */
- if ( ( len = fetch_uuid_setting ( NULL, &uuid_setting, &uuid ) ) < 0 ) {
- rc = len;
- DBGC ( &rbg, "RBG could not fetch personalisation string: "
- "%s\n", strerror ( rc ) );
- len = 0;
- }
-
- /* Instantiate DRBG */
- if ( ( rc = drbg_instantiate ( &rbg.state, &uuid, len ) ) != 0 ) {
- DBGC ( &rbg, "RBG could not instantiate DRBG: %s\n",
- strerror ( rc ) );
- return rc;
- }
-
- return 0;
-}
-
-/**
- * Shut down RBG
- *
- */
-static void rbg_shutdown ( void ) {
-
- /* Uninstantiate DRBG */
- drbg_uninstantiate ( &rbg.state );
-}
-
-/** RBG startup function */
-static void rbg_startup_fn ( void ) {
-
- /* Start up RBG. There is no way to report an error at this
- * stage, but a failed startup will result in an invalid DRBG
- * that refuses to generate bits.
- */
- rbg_startup();
-}
-
-/** RBG shutdown function */
-static void rbg_shutdown_fn ( int booting __unused ) {
-
- /* Shut down RBG */
- rbg_shutdown();
-}
-
-/** RBG startup table entry */
-struct startup_fn startup_rbg __startup_fn ( STARTUP_NORMAL ) = {
- .startup = rbg_startup_fn,
- .shutdown = rbg_shutdown_fn,
-};
diff --git a/qemu/roms/ipxe/src/crypto/rootcert.c b/qemu/roms/ipxe/src/crypto/rootcert.c
deleted file mode 100644
index 00ea1647e..000000000
--- a/qemu/roms/ipxe/src/crypto/rootcert.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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; either version 2 of the
- * License, or any later version.
- *
- * 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.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <stdlib.h>
-#include <ipxe/crypto.h>
-#include <ipxe/sha256.h>
-#include <ipxe/x509.h>
-#include <ipxe/settings.h>
-#include <ipxe/dhcp.h>
-#include <ipxe/init.h>
-#include <ipxe/rootcert.h>
-
-/** @file
- *
- * Root certificate store
- *
- */
-
-/** Length of a root certificate fingerprint */
-#define FINGERPRINT_LEN SHA256_DIGEST_SIZE
-
-/* Allow trusted certificates to be overridden if not explicitly specified */
-#ifdef TRUSTED
-#define ALLOW_TRUST_OVERRIDE 0
-#else
-#define ALLOW_TRUST_OVERRIDE 1
-#endif
-
-/* Use iPXE root CA if no trusted certificates are explicitly specified */
-#ifndef TRUSTED
-#define TRUSTED \
- /* iPXE root CA */ \
- 0x9f, 0xaf, 0x71, 0x7b, 0x7f, 0x8c, 0xa2, 0xf9, 0x3c, 0x25, \
- 0x6c, 0x79, 0xf8, 0xac, 0x55, 0x91, 0x89, 0x5d, 0x66, 0xd1, \
- 0xff, 0x3b, 0xee, 0x63, 0x97, 0xa7, 0x0d, 0x29, 0xc6, 0x5e, \
- 0xed, 0x1a,
-#endif
-
-/** Root certificate fingerprints */
-static const uint8_t fingerprints[] = { TRUSTED };
-
-/** Root certificate fingerprint setting */
-static struct setting trust_setting __setting ( SETTING_CRYPTO, trust ) = {
- .name = "trust",
- .description = "Trusted root certificate fingerprints",
- .tag = DHCP_EB_TRUST,
- .type = &setting_type_hex,
-};
-
-/** Root certificates */
-struct x509_root root_certificates = {
- .digest = &sha256_algorithm,
- .count = ( sizeof ( fingerprints ) / FINGERPRINT_LEN ),
- .fingerprints = fingerprints,
-};
-
-/**
- * Initialise root certificate
- *
- * The list of trusted root certificates can be specified at build
- * time using the TRUST= build parameter. If no certificates are
- * specified, then the default iPXE root CA certificate is trusted.
- *
- * If no certificates were explicitly specified, then we allow the
- * list of trusted root certificate fingerprints to be overridden
- * using the "trust" setting, but only at the point of iPXE
- * initialisation. This prevents untrusted sources of settings
- * (e.g. DHCP) from subverting the chain of trust, while allowing
- * trustworthy sources (e.g. VMware GuestInfo or non-volatile stored
- * options) to specify the trusted root certificate without requiring
- * a rebuild.
- */
-static void rootcert_init ( void ) {
- void *external = NULL;
- int len;
-
- /* Allow trusted root certificates to be overridden only if
- * not explicitly specified at build time.
- */
- if ( ALLOW_TRUST_OVERRIDE ) {
-
- /* Fetch copy of "trust" setting, if it exists. This
- * memory will never be freed.
- */
- if ( ( len = fetch_raw_setting_copy ( NULL, &trust_setting,
- &external ) ) >= 0 ) {
- root_certificates.fingerprints = external;
- root_certificates.count = ( len / FINGERPRINT_LEN );
- }
- }
-
- DBGC ( &root_certificates, "ROOTCERT using %d %s certificate(s):\n",
- root_certificates.count, ( external ? "external" : "built-in" ));
- DBGC_HDA ( &root_certificates, 0, root_certificates.fingerprints,
- ( root_certificates.count * FINGERPRINT_LEN ) );
-}
-
-/** Root certificate initialiser */
-struct init_fn rootcert_init_fn __init_fn ( INIT_LATE ) = {
- .initialise = rootcert_init,
-};
diff --git a/qemu/roms/ipxe/src/crypto/rsa.c b/qemu/roms/ipxe/src/crypto/rsa.c
deleted file mode 100644
index 36109280d..000000000
--- a/qemu/roms/ipxe/src/crypto/rsa.c
+++ /dev/null
@@ -1,637 +0,0 @@
-/*
- * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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; either version 2 of the
- * License, or any later version.
- *
- * 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.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-#include <ipxe/asn1.h>
-#include <ipxe/crypto.h>
-#include <ipxe/bigint.h>
-#include <ipxe/random_nz.h>
-#include <ipxe/rsa.h>
-
-/** @file
- *
- * RSA public-key cryptography
- *
- * RSA is documented in RFC 3447.
- */
-
-/* Disambiguate the various error causes */
-#define EACCES_VERIFY \
- __einfo_error ( EINFO_EACCES_VERIFY )
-#define EINFO_EACCES_VERIFY \
- __einfo_uniqify ( EINFO_EACCES, 0x01, "RSA signature incorrect" )
-
-/** "rsaEncryption" object identifier */
-static uint8_t oid_rsa_encryption[] = { ASN1_OID_RSAENCRYPTION };
-
-/** "rsaEncryption" OID-identified algorithm */
-struct asn1_algorithm rsa_encryption_algorithm __asn1_algorithm = {
- .name = "rsaEncryption",
- .pubkey = &rsa_algorithm,
- .digest = NULL,
- .oid = ASN1_OID_CURSOR ( oid_rsa_encryption ),
-};
-
-/**
- * Identify RSA prefix
- *
- * @v digest Digest algorithm
- * @ret prefix RSA prefix, or NULL
- */
-static struct rsa_digestinfo_prefix *
-rsa_find_prefix ( struct digest_algorithm *digest ) {
- struct rsa_digestinfo_prefix *prefix;
-
- for_each_table_entry ( prefix, RSA_DIGESTINFO_PREFIXES ) {
- if ( prefix->digest == digest )
- return prefix;
- }
- return NULL;
-}
-
-/**
- * Free RSA dynamic storage
- *
- * @v context RSA context
- */
-static void rsa_free ( struct rsa_context *context ) {
-
- free ( context->dynamic );
- context->dynamic = NULL;
-}
-
-/**
- * Allocate RSA dynamic storage
- *
- * @v context RSA context
- * @v modulus_len Modulus length
- * @v exponent_len Exponent length
- * @ret rc Return status code
- */
-static int rsa_alloc ( struct rsa_context *context, size_t modulus_len,
- size_t exponent_len ) {
- unsigned int size = bigint_required_size ( modulus_len );
- unsigned int exponent_size = bigint_required_size ( exponent_len );
- bigint_t ( size ) *modulus;
- bigint_t ( exponent_size ) *exponent;
- size_t tmp_len = bigint_mod_exp_tmp_len ( modulus, exponent );
- struct {
- bigint_t ( size ) modulus;
- bigint_t ( exponent_size ) exponent;
- bigint_t ( size ) input;
- bigint_t ( size ) output;
- uint8_t tmp[tmp_len];
- } __attribute__ (( packed )) *dynamic;
-
- /* Free any existing dynamic storage */
- rsa_free ( context );
-
- /* Allocate dynamic storage */
- dynamic = malloc ( sizeof ( *dynamic ) );
- if ( ! dynamic )
- return -ENOMEM;
-
- /* Assign dynamic storage */
- context->dynamic = dynamic;
- context->modulus0 = &dynamic->modulus.element[0];
- context->size = size;
- context->max_len = modulus_len;
- context->exponent0 = &dynamic->exponent.element[0];
- context->exponent_size = exponent_size;
- context->input0 = &dynamic->input.element[0];
- context->output0 = &dynamic->output.element[0];
- context->tmp = &dynamic->tmp;
-
- return 0;
-}
-
-/**
- * Parse RSA integer
- *
- * @v integer Integer to fill in
- * @v raw ASN.1 cursor
- * @ret rc Return status code
- */
-static int rsa_parse_integer ( struct asn1_cursor *integer,
- const struct asn1_cursor *raw ) {
-
- /* Enter integer */
- memcpy ( integer, raw, sizeof ( *integer ) );
- asn1_enter ( integer, ASN1_INTEGER );
-
- /* Skip initial sign byte if applicable */
- if ( ( integer->len > 1 ) &&
- ( *( ( uint8_t * ) integer->data ) == 0x00 ) ) {
- integer->data++;
- integer->len--;
- }
-
- /* Fail if cursor or integer are invalid */
- if ( ! integer->len )
- return -EINVAL;
-
- return 0;
-}
-
-/**
- * Parse RSA modulus and exponent
- *
- * @v modulus Modulus to fill in
- * @v exponent Exponent to fill in
- * @v raw ASN.1 cursor
- * @ret rc Return status code
- */
-static int rsa_parse_mod_exp ( struct asn1_cursor *modulus,
- struct asn1_cursor *exponent,
- const struct asn1_cursor *raw ) {
- struct asn1_bit_string bits;
- struct asn1_cursor cursor;
- int is_private;
- int rc;
-
- /* Enter subjectPublicKeyInfo/RSAPrivateKey */
- memcpy ( &cursor, raw, sizeof ( cursor ) );
- asn1_enter ( &cursor, ASN1_SEQUENCE );
-
- /* Determine key format */
- if ( asn1_type ( &cursor ) == ASN1_INTEGER ) {
-
- /* Private key */
- is_private = 1;
-
- /* Skip version */
- asn1_skip_any ( &cursor );
-
- } else {
-
- /* Public key */
- is_private = 0;
-
- /* Skip algorithm */
- asn1_skip ( &cursor, ASN1_SEQUENCE );
-
- /* Enter subjectPublicKey */
- if ( ( rc = asn1_integral_bit_string ( &cursor, &bits ) ) != 0 )
- return rc;
- cursor.data = bits.data;
- cursor.len = bits.len;
-
- /* Enter RSAPublicKey */
- asn1_enter ( &cursor, ASN1_SEQUENCE );
- }
-
- /* Extract modulus */
- if ( ( rc = rsa_parse_integer ( modulus, &cursor ) ) != 0 )
- return rc;
- asn1_skip_any ( &cursor );
-
- /* Skip public exponent, if applicable */
- if ( is_private )
- asn1_skip ( &cursor, ASN1_INTEGER );
-
- /* Extract publicExponent/privateExponent */
- if ( ( rc = rsa_parse_integer ( exponent, &cursor ) ) != 0 )
- return rc;
-
- return 0;
-}
-
-/**
- * Initialise RSA cipher
- *
- * @v ctx RSA context
- * @v key Key
- * @v key_len Length of key
- * @ret rc Return status code
- */
-static int rsa_init ( void *ctx, const void *key, size_t key_len ) {
- struct rsa_context *context = ctx;
- struct asn1_cursor modulus;
- struct asn1_cursor exponent;
- struct asn1_cursor cursor;
- int rc;
-
- /* Initialise context */
- memset ( context, 0, sizeof ( *context ) );
-
- /* Initialise cursor */
- cursor.data = key;
- cursor.len = key_len;
-
- /* Parse modulus and exponent */
- if ( ( rc = rsa_parse_mod_exp ( &modulus, &exponent, &cursor ) ) != 0 ){
- DBGC ( context, "RSA %p invalid modulus/exponent:\n", context );
- DBGC_HDA ( context, 0, cursor.data, cursor.len );
- goto err_parse;
- }
-
- DBGC ( context, "RSA %p modulus:\n", context );
- DBGC_HDA ( context, 0, modulus.data, modulus.len );
- DBGC ( context, "RSA %p exponent:\n", context );
- DBGC_HDA ( context, 0, exponent.data, exponent.len );
-
- /* Allocate dynamic storage */
- if ( ( rc = rsa_alloc ( context, modulus.len, exponent.len ) ) != 0 )
- goto err_alloc;
-
- /* Construct big integers */
- bigint_init ( ( ( bigint_t ( context->size ) * ) context->modulus0 ),
- modulus.data, modulus.len );
- bigint_init ( ( ( bigint_t ( context->exponent_size ) * )
- context->exponent0 ), exponent.data, exponent.len );
-
- return 0;
-
- rsa_free ( context );
- err_alloc:
- err_parse:
- return rc;
-}
-
-/**
- * Calculate RSA maximum output length
- *
- * @v ctx RSA context
- * @ret max_len Maximum output length
- */
-static size_t rsa_max_len ( void *ctx ) {
- struct rsa_context *context = ctx;
-
- return context->max_len;
-}
-
-/**
- * Perform RSA cipher operation
- *
- * @v context RSA context
- * @v in Input buffer
- * @v out Output buffer
- */
-static void rsa_cipher ( struct rsa_context *context,
- const void *in, void *out ) {
- bigint_t ( context->size ) *input = ( ( void * ) context->input0 );
- bigint_t ( context->size ) *output = ( ( void * ) context->output0 );
- bigint_t ( context->size ) *modulus = ( ( void * ) context->modulus0 );
- bigint_t ( context->exponent_size ) *exponent =
- ( ( void * ) context->exponent0 );
-
- /* Initialise big integer */
- bigint_init ( input, in, context->max_len );
-
- /* Perform modular exponentiation */
- bigint_mod_exp ( input, modulus, exponent, output, context->tmp );
-
- /* Copy out result */
- bigint_done ( output, out, context->max_len );
-}
-
-/**
- * Encrypt using RSA
- *
- * @v ctx RSA context
- * @v plaintext Plaintext
- * @v plaintext_len Length of plaintext
- * @v ciphertext Ciphertext
- * @ret ciphertext_len Length of ciphertext, or negative error
- */
-static int rsa_encrypt ( void *ctx, const void *plaintext,
- size_t plaintext_len, void *ciphertext ) {
- struct rsa_context *context = ctx;
- void *temp;
- uint8_t *encoded;
- size_t max_len = ( context->max_len - 11 );
- size_t random_nz_len = ( max_len - plaintext_len + 8 );
- int rc;
-
- /* Sanity check */
- if ( plaintext_len > max_len ) {
- DBGC ( context, "RSA %p plaintext too long (%zd bytes, max "
- "%zd)\n", context, plaintext_len, max_len );
- return -ERANGE;
- }
- DBGC ( context, "RSA %p encrypting:\n", context );
- DBGC_HDA ( context, 0, plaintext, plaintext_len );
-
- /* Construct encoded message (using the big integer output
- * buffer as temporary storage)
- */
- temp = context->output0;
- encoded = temp;
- encoded[0] = 0x00;
- encoded[1] = 0x02;
- if ( ( rc = get_random_nz ( &encoded[2], random_nz_len ) ) != 0 ) {
- DBGC ( context, "RSA %p could not generate random data: %s\n",
- context, strerror ( rc ) );
- return rc;
- }
- encoded[ 2 + random_nz_len ] = 0x00;
- memcpy ( &encoded[ context->max_len - plaintext_len ],
- plaintext, plaintext_len );
-
- /* Encipher the encoded message */
- rsa_cipher ( context, encoded, ciphertext );
- DBGC ( context, "RSA %p encrypted:\n", context );
- DBGC_HDA ( context, 0, ciphertext, context->max_len );
-
- return context->max_len;
-}
-
-/**
- * Decrypt using RSA
- *
- * @v ctx RSA context
- * @v ciphertext Ciphertext
- * @v ciphertext_len Ciphertext length
- * @v plaintext Plaintext
- * @ret plaintext_len Plaintext length, or negative error
- */
-static int rsa_decrypt ( void *ctx, const void *ciphertext,
- size_t ciphertext_len, void *plaintext ) {
- struct rsa_context *context = ctx;
- void *temp;
- uint8_t *encoded;
- uint8_t *end;
- uint8_t *zero;
- uint8_t *start;
- size_t plaintext_len;
-
- /* Sanity check */
- if ( ciphertext_len != context->max_len ) {
- DBGC ( context, "RSA %p ciphertext incorrect length (%zd "
- "bytes, should be %zd)\n",
- context, ciphertext_len, context->max_len );
- return -ERANGE;
- }
- DBGC ( context, "RSA %p decrypting:\n", context );
- DBGC_HDA ( context, 0, ciphertext, ciphertext_len );
-
- /* Decipher the message (using the big integer input buffer as
- * temporary storage)
- */
- temp = context->input0;
- encoded = temp;
- rsa_cipher ( context, ciphertext, encoded );
-
- /* Parse the message */
- end = ( encoded + context->max_len );
- if ( ( encoded[0] != 0x00 ) || ( encoded[1] != 0x02 ) )
- goto invalid;
- zero = memchr ( &encoded[2], 0, ( end - &encoded[2] ) );
- if ( ! zero )
- goto invalid;
- start = ( zero + 1 );
- plaintext_len = ( end - start );
-
- /* Copy out message */
- memcpy ( plaintext, start, plaintext_len );
- DBGC ( context, "RSA %p decrypted:\n", context );
- DBGC_HDA ( context, 0, plaintext, plaintext_len );
-
- return plaintext_len;
-
- invalid:
- DBGC ( context, "RSA %p invalid decrypted message:\n", context );
- DBGC_HDA ( context, 0, encoded, context->max_len );
- return -EINVAL;
-}
-
-/**
- * Encode RSA digest
- *
- * @v context RSA context
- * @v digest Digest algorithm
- * @v value Digest value
- * @v encoded Encoded digest
- * @ret rc Return status code
- */
-static int rsa_encode_digest ( struct rsa_context *context,
- struct digest_algorithm *digest,
- const void *value, void *encoded ) {
- struct rsa_digestinfo_prefix *prefix;
- size_t digest_len = digest->digestsize;
- uint8_t *temp = encoded;
- size_t digestinfo_len;
- size_t max_len;
- size_t pad_len;
-
- /* Identify prefix */
- prefix = rsa_find_prefix ( digest );
- if ( ! prefix ) {
- DBGC ( context, "RSA %p has no prefix for %s\n",
- context, digest->name );
- return -ENOTSUP;
- }
- digestinfo_len = ( prefix->len + digest_len );
-
- /* Sanity check */
- max_len = ( context->max_len - 11 );
- if ( digestinfo_len > max_len ) {
- DBGC ( context, "RSA %p %s digestInfo too long (%zd bytes, max"
- "%zd)\n",
- context, digest->name, digestinfo_len, max_len );
- return -ERANGE;
- }
- DBGC ( context, "RSA %p encoding %s digest:\n",
- context, digest->name );
- DBGC_HDA ( context, 0, value, digest_len );
-
- /* Construct encoded message */
- *(temp++) = 0x00;
- *(temp++) = 0x01;
- pad_len = ( max_len - digestinfo_len + 8 );
- memset ( temp, 0xff, pad_len );
- temp += pad_len;
- *(temp++) = 0x00;
- memcpy ( temp, prefix->data, prefix->len );
- temp += prefix->len;
- memcpy ( temp, value, digest_len );
- temp += digest_len;
- assert ( temp == ( encoded + context->max_len ) );
- DBGC ( context, "RSA %p encoded %s digest:\n", context, digest->name );
- DBGC_HDA ( context, 0, encoded, context->max_len );
-
- return 0;
-}
-
-/**
- * Sign digest value using RSA
- *
- * @v ctx RSA context
- * @v digest Digest algorithm
- * @v value Digest value
- * @v signature Signature
- * @ret signature_len Signature length, or negative error
- */
-static int rsa_sign ( void *ctx, struct digest_algorithm *digest,
- const void *value, void *signature ) {
- struct rsa_context *context = ctx;
- void *temp;
- int rc;
-
- DBGC ( context, "RSA %p signing %s digest:\n", context, digest->name );
- DBGC_HDA ( context, 0, value, digest->digestsize );
-
- /* Encode digest (using the big integer output buffer as
- * temporary storage)
- */
- temp = context->output0;
- if ( ( rc = rsa_encode_digest ( context, digest, value, temp ) ) != 0 )
- return rc;
-
- /* Encipher the encoded digest */
- rsa_cipher ( context, temp, signature );
- DBGC ( context, "RSA %p signed %s digest:\n", context, digest->name );
- DBGC_HDA ( context, 0, signature, context->max_len );
-
- return context->max_len;
-}
-
-/**
- * Verify signed digest value using RSA
- *
- * @v ctx RSA context
- * @v digest Digest algorithm
- * @v value Digest value
- * @v signature Signature
- * @v signature_len Signature length
- * @ret rc Return status code
- */
-static int rsa_verify ( void *ctx, struct digest_algorithm *digest,
- const void *value, const void *signature,
- size_t signature_len ) {
- struct rsa_context *context = ctx;
- void *temp;
- void *expected;
- void *actual;
- int rc;
-
- /* Sanity check */
- if ( signature_len != context->max_len ) {
- DBGC ( context, "RSA %p signature incorrect length (%zd "
- "bytes, should be %zd)\n",
- context, signature_len, context->max_len );
- return -ERANGE;
- }
- DBGC ( context, "RSA %p verifying %s digest:\n",
- context, digest->name );
- DBGC_HDA ( context, 0, value, digest->digestsize );
- DBGC_HDA ( context, 0, signature, signature_len );
-
- /* Decipher the signature (using the big integer input buffer
- * as temporary storage)
- */
- temp = context->input0;
- expected = temp;
- rsa_cipher ( context, signature, expected );
- DBGC ( context, "RSA %p deciphered signature:\n", context );
- DBGC_HDA ( context, 0, expected, context->max_len );
-
- /* Encode digest (using the big integer output buffer as
- * temporary storage)
- */
- temp = context->output0;
- actual = temp;
- if ( ( rc = rsa_encode_digest ( context, digest, value, actual ) ) !=0 )
- return rc;
-
- /* Verify the signature */
- if ( memcmp ( actual, expected, context->max_len ) != 0 ) {
- DBGC ( context, "RSA %p signature verification failed\n",
- context );
- return -EACCES_VERIFY;
- }
-
- DBGC ( context, "RSA %p signature verified successfully\n", context );
- return 0;
-}
-
-/**
- * Finalise RSA cipher
- *
- * @v ctx RSA context
- */
-static void rsa_final ( void *ctx ) {
- struct rsa_context *context = ctx;
-
- rsa_free ( context );
-}
-
-/**
- * Check for matching RSA public/private key pair
- *
- * @v private_key Private key
- * @v private_key_len Private key length
- * @v public_key Public key
- * @v public_key_len Public key length
- * @ret rc Return status code
- */
-static int rsa_match ( const void *private_key, size_t private_key_len,
- const void *public_key, size_t public_key_len ) {
- struct asn1_cursor private_modulus;
- struct asn1_cursor private_exponent;
- struct asn1_cursor private_cursor;
- struct asn1_cursor public_modulus;
- struct asn1_cursor public_exponent;
- struct asn1_cursor public_cursor;
- int rc;
-
- /* Initialise cursors */
- private_cursor.data = private_key;
- private_cursor.len = private_key_len;
- public_cursor.data = public_key;
- public_cursor.len = public_key_len;
-
- /* Parse moduli and exponents */
- if ( ( rc = rsa_parse_mod_exp ( &private_modulus, &private_exponent,
- &private_cursor ) ) != 0 )
- return rc;
- if ( ( rc = rsa_parse_mod_exp ( &public_modulus, &public_exponent,
- &public_cursor ) ) != 0 )
- return rc;
-
- /* Compare moduli */
- if ( asn1_compare ( &private_modulus, &public_modulus ) != 0 )
- return -ENOTTY;
-
- return 0;
-}
-
-/** RSA public-key algorithm */
-struct pubkey_algorithm rsa_algorithm = {
- .name = "rsa",
- .ctxsize = sizeof ( struct rsa_context ),
- .init = rsa_init,
- .max_len = rsa_max_len,
- .encrypt = rsa_encrypt,
- .decrypt = rsa_decrypt,
- .sign = rsa_sign,
- .verify = rsa_verify,
- .final = rsa_final,
- .match = rsa_match,
-};
diff --git a/qemu/roms/ipxe/src/crypto/sha1.c b/qemu/roms/ipxe/src/crypto/sha1.c
deleted file mode 100644
index 51866f4b7..000000000
--- a/qemu/roms/ipxe/src/crypto/sha1.c
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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; either version 2 of the
- * License, or any later version.
- *
- * 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.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-/** @file
- *
- * SHA-1 algorithm
- *
- */
-
-#include <stdint.h>
-#include <string.h>
-#include <byteswap.h>
-#include <assert.h>
-#include <ipxe/rotate.h>
-#include <ipxe/crypto.h>
-#include <ipxe/asn1.h>
-#include <ipxe/sha1.h>
-
-/** SHA-1 variables */
-struct sha1_variables {
- /* This layout matches that of struct sha1_digest_data,
- * allowing for efficient endianness-conversion,
- */
- uint32_t a;
- uint32_t b;
- uint32_t c;
- uint32_t d;
- uint32_t e;
- uint32_t w[80];
-} __attribute__ (( packed ));
-
-/**
- * f(a,b,c,d) for steps 0 to 19
- *
- * @v v SHA-1 variables
- * @ret f f(a,b,c,d)
- */
-static uint32_t sha1_f_0_19 ( struct sha1_variables *v ) {
- return ( ( v->b & v->c ) | ( (~v->b) & v->d ) );
-}
-
-/**
- * f(a,b,c,d) for steps 20 to 39 and 60 to 79
- *
- * @v v SHA-1 variables
- * @ret f f(a,b,c,d)
- */
-static uint32_t sha1_f_20_39_60_79 ( struct sha1_variables *v ) {
- return ( v->b ^ v->c ^ v->d );
-}
-
-/**
- * f(a,b,c,d) for steps 40 to 59
- *
- * @v v SHA-1 variables
- * @ret f f(a,b,c,d)
- */
-static uint32_t sha1_f_40_59 ( struct sha1_variables *v ) {
- return ( ( v->b & v->c ) | ( v->b & v->d ) | ( v->c & v->d ) );
-}
-
-/** An SHA-1 step function */
-struct sha1_step {
- /**
- * Calculate f(a,b,c,d)
- *
- * @v v SHA-1 variables
- * @ret f f(a,b,c,d)
- */
- uint32_t ( * f ) ( struct sha1_variables *v );
- /** Constant k */
- uint32_t k;
-};
-
-/** SHA-1 steps */
-static struct sha1_step sha1_steps[4] = {
- /** 0 to 19 */
- { .f = sha1_f_0_19, .k = 0x5a827999 },
- /** 20 to 39 */
- { .f = sha1_f_20_39_60_79, .k = 0x6ed9eba1 },
- /** 40 to 59 */
- { .f = sha1_f_40_59, .k = 0x8f1bbcdc },
- /** 60 to 79 */
- { .f = sha1_f_20_39_60_79, .k = 0xca62c1d6 },
-};
-
-/**
- * Initialise SHA-1 algorithm
- *
- * @v ctx SHA-1 context
- */
-static void sha1_init ( void *ctx ) {
- struct sha1_context *context = ctx;
-
- context->ddd.dd.digest.h[0] = cpu_to_be32 ( 0x67452301 );
- context->ddd.dd.digest.h[1] = cpu_to_be32 ( 0xefcdab89 );
- context->ddd.dd.digest.h[2] = cpu_to_be32 ( 0x98badcfe );
- context->ddd.dd.digest.h[3] = cpu_to_be32 ( 0x10325476 );
- context->ddd.dd.digest.h[4] = cpu_to_be32 ( 0xc3d2e1f0 );
- context->len = 0;
-}
-
-/**
- * Calculate SHA-1 digest of accumulated data
- *
- * @v context SHA-1 context
- */
-static void sha1_digest ( struct sha1_context *context ) {
- union {
- union sha1_digest_data_dwords ddd;
- struct sha1_variables v;
- } u;
- uint32_t *a = &u.v.a;
- uint32_t *b = &u.v.b;
- uint32_t *c = &u.v.c;
- uint32_t *d = &u.v.d;
- uint32_t *e = &u.v.e;
- uint32_t *w = u.v.w;
- uint32_t f;
- uint32_t k;
- uint32_t temp;
- struct sha1_step *step;
- unsigned int i;
-
- /* Sanity checks */
- assert ( ( context->len % sizeof ( context->ddd.dd.data ) ) == 0 );
- linker_assert ( &u.ddd.dd.digest.h[0] == a, sha1_bad_layout );
- linker_assert ( &u.ddd.dd.digest.h[1] == b, sha1_bad_layout );
- linker_assert ( &u.ddd.dd.digest.h[2] == c, sha1_bad_layout );
- linker_assert ( &u.ddd.dd.digest.h[3] == d, sha1_bad_layout );
- linker_assert ( &u.ddd.dd.digest.h[4] == e, sha1_bad_layout );
- linker_assert ( &u.ddd.dd.data.dword[0] == w, sha1_bad_layout );
-
- DBGC ( context, "SHA1 digesting:\n" );
- DBGC_HDA ( context, 0, &context->ddd.dd.digest,
- sizeof ( context->ddd.dd.digest ) );
- DBGC_HDA ( context, context->len, &context->ddd.dd.data,
- sizeof ( context->ddd.dd.data ) );
-
- /* Convert h[0..4] to host-endian, and initialise a, b, c, d,
- * e, and w[0..15]
- */
- for ( i = 0 ; i < ( sizeof ( u.ddd.dword ) /
- sizeof ( u.ddd.dword[0] ) ) ; i++ ) {
- be32_to_cpus ( &context->ddd.dword[i] );
- u.ddd.dword[i] = context->ddd.dword[i];
- }
-
- /* Initialise w[16..79] */
- for ( i = 16 ; i < 80 ; i++ )
- w[i] = rol32 ( ( w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16] ), 1 );
-
- /* Main loop */
- for ( i = 0 ; i < 80 ; i++ ) {
- step = &sha1_steps[ i / 20 ];
- f = step->f ( &u.v );
- k = step->k;
- temp = ( rol32 ( *a, 5 ) + f + *e + k + w[i] );
- *e = *d;
- *d = *c;
- *c = rol32 ( *b, 30 );
- *b = *a;
- *a = temp;
- DBGC2 ( context, "%2d : %08x %08x %08x %08x %08x\n",
- i, *a, *b, *c, *d, *e );
- }
-
- /* Add chunk to hash and convert back to big-endian */
- for ( i = 0 ; i < 5 ; i++ ) {
- context->ddd.dd.digest.h[i] =
- cpu_to_be32 ( context->ddd.dd.digest.h[i] +
- u.ddd.dd.digest.h[i] );
- }
-
- DBGC ( context, "SHA1 digested:\n" );
- DBGC_HDA ( context, 0, &context->ddd.dd.digest,
- sizeof ( context->ddd.dd.digest ) );
-}
-
-/**
- * Accumulate data with SHA-1 algorithm
- *
- * @v ctx SHA-1 context
- * @v data Data
- * @v len Length of data
- */
-static void sha1_update ( void *ctx, const void *data, size_t len ) {
- struct sha1_context *context = ctx;
- const uint8_t *byte = data;
- size_t offset;
-
- /* Accumulate data a byte at a time, performing the digest
- * whenever we fill the data buffer
- */
- while ( len-- ) {
- offset = ( context->len % sizeof ( context->ddd.dd.data ) );
- context->ddd.dd.data.byte[offset] = *(byte++);
- context->len++;
- if ( ( context->len % sizeof ( context->ddd.dd.data ) ) == 0 )
- sha1_digest ( context );
- }
-}
-
-/**
- * Generate SHA-1 digest
- *
- * @v ctx SHA-1 context
- * @v out Output buffer
- */
-static void sha1_final ( void *ctx, void *out ) {
- struct sha1_context *context = ctx;
- uint64_t len_bits;
- uint8_t pad;
-
- /* Record length before pre-processing */
- len_bits = cpu_to_be64 ( ( ( uint64_t ) context->len ) * 8 );
-
- /* Pad with a single "1" bit followed by as many "0" bits as required */
- pad = 0x80;
- do {
- sha1_update ( ctx, &pad, sizeof ( pad ) );
- pad = 0x00;
- } while ( ( context->len % sizeof ( context->ddd.dd.data ) ) !=
- offsetof ( typeof ( context->ddd.dd.data ), final.len ) );
-
- /* Append length (in bits) */
- sha1_update ( ctx, &len_bits, sizeof ( len_bits ) );
- assert ( ( context->len % sizeof ( context->ddd.dd.data ) ) == 0 );
-
- /* Copy out final digest */
- memcpy ( out, &context->ddd.dd.digest,
- sizeof ( context->ddd.dd.digest ) );
-}
-
-/** SHA-1 algorithm */
-struct digest_algorithm sha1_algorithm = {
- .name = "sha1",
- .ctxsize = sizeof ( struct sha1_context ),
- .blocksize = sizeof ( union sha1_block ),
- .digestsize = sizeof ( struct sha1_digest ),
- .init = sha1_init,
- .update = sha1_update,
- .final = sha1_final,
-};
-
-/** "sha1" object identifier */
-static uint8_t oid_sha1[] = { ASN1_OID_SHA1 };
-
-/** "sha1" OID-identified algorithm */
-struct asn1_algorithm oid_sha1_algorithm __asn1_algorithm = {
- .name = "sha1",
- .digest = &sha1_algorithm,
- .oid = ASN1_OID_CURSOR ( oid_sha1 ),
-};
diff --git a/qemu/roms/ipxe/src/crypto/sha1extra.c b/qemu/roms/ipxe/src/crypto/sha1extra.c
deleted file mode 100644
index cec0d35e5..000000000
--- a/qemu/roms/ipxe/src/crypto/sha1extra.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Copyright (c) 2009 Joshua Oreman <oremanj@rwcr.net>.
- *
- * 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; either version 2 of the
- * License, or any later version.
- *
- * 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.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include <string.h>
-#include <ipxe/crypto.h>
-#include <ipxe/sha1.h>
-#include <ipxe/hmac.h>
-#include <stdint.h>
-#include <byteswap.h>
-
-/**
- * SHA1 pseudorandom function for creating derived keys
- *
- * @v key Master key with which this call is associated
- * @v key_len Length of key
- * @v label NUL-terminated ASCII string describing purpose of PRF data
- * @v data Further data that should be included in the PRF
- * @v data_len Length of further PRF data
- * @v prf_len Bytes of PRF to generate
- * @ret prf Pseudorandom function bytes
- *
- * This is the PRF variant used by 802.11, defined in IEEE 802.11-2007
- * 8.5.5.1. EAP-FAST uses a different SHA1-based PRF, and TLS uses an
- * MD5-based PRF.
- */
-void prf_sha1 ( const void *key, size_t key_len, const char *label,
- const void *data, size_t data_len, void *prf, size_t prf_len )
-{
- u32 blk;
- u8 keym[key_len]; /* modifiable copy of key */
- u8 in[strlen ( label ) + 1 + data_len + 1]; /* message to HMAC */
- u8 *in_blknr; /* pointer to last byte of in, block number */
- u8 out[SHA1_DIGEST_SIZE]; /* HMAC-SHA1 result */
- u8 sha1_ctx[SHA1_CTX_SIZE]; /* SHA1 context */
- const size_t label_len = strlen ( label );
-
- /* The HMAC-SHA-1 is calculated using the given key on the
- message text `label', followed by a NUL, followed by one
- byte indicating the block number (0 for first). */
-
- memcpy ( keym, key, key_len );
-
- memcpy ( in, label, strlen ( label ) + 1 );
- memcpy ( in + label_len + 1, data, data_len );
- in_blknr = in + label_len + 1 + data_len;
-
- for ( blk = 0 ;; blk++ ) {
- *in_blknr = blk;
-
- hmac_init ( &sha1_algorithm, sha1_ctx, keym, &key_len );
- hmac_update ( &sha1_algorithm, sha1_ctx, in, sizeof ( in ) );
- hmac_final ( &sha1_algorithm, sha1_ctx, keym, &key_len, out );
-
- if ( prf_len <= sizeof ( out ) ) {
- memcpy ( prf, out, prf_len );
- break;
- }
-
- memcpy ( prf, out, sizeof ( out ) );
- prf_len -= sizeof ( out );
- prf += sizeof ( out );
- }
-}
-
-/**
- * PBKDF2 key derivation function inner block operation
- *
- * @v passphrase Passphrase from which to derive key
- * @v pass_len Length of passphrase
- * @v salt Salt to include in key
- * @v salt_len Length of salt
- * @v iterations Number of iterations of SHA1 to perform
- * @v blocknr Index of this block, starting at 1
- * @ret block SHA1_SIZE bytes of PBKDF2 data
- *
- * The operation of this function is described in RFC 2898.
- */
-static void pbkdf2_sha1_f ( const void *passphrase, size_t pass_len,
- const void *salt, size_t salt_len,
- int iterations, u32 blocknr, u8 *block )
-{
- u8 pass[pass_len]; /* modifiable passphrase */
- u8 in[salt_len + 4]; /* input buffer to first round */
- u8 last[SHA1_DIGEST_SIZE]; /* output of round N, input of N+1 */
- u8 sha1_ctx[SHA1_CTX_SIZE];
- u8 *next_in = in; /* changed to `last' after first round */
- int next_size = sizeof ( in );
- int i;
- unsigned int j;
-
- blocknr = htonl ( blocknr );
-
- memcpy ( pass, passphrase, pass_len );
- memcpy ( in, salt, salt_len );
- memcpy ( in + salt_len, &blocknr, 4 );
- memset ( block, 0, sizeof ( last ) );
-
- for ( i = 0; i < iterations; i++ ) {
- hmac_init ( &sha1_algorithm, sha1_ctx, pass, &pass_len );
- hmac_update ( &sha1_algorithm, sha1_ctx, next_in, next_size );
- hmac_final ( &sha1_algorithm, sha1_ctx, pass, &pass_len, last );
-
- for ( j = 0; j < sizeof ( last ); j++ ) {
- block[j] ^= last[j];
- }
-
- next_in = last;
- next_size = sizeof ( last );
- }
-}
-
-/**
- * PBKDF2 key derivation function using SHA1
- *
- * @v passphrase Passphrase from which to derive key
- * @v pass_len Length of passphrase
- * @v salt Salt to include in key
- * @v salt_len Length of salt
- * @v iterations Number of iterations of SHA1 to perform
- * @v key_len Length of key to generate
- * @ret key Generated key bytes
- *
- * This is used most notably in 802.11 WPA passphrase hashing, in
- * which case the salt is the SSID, 4096 iterations are used, and a
- * 32-byte key is generated that serves as the Pairwise Master Key for
- * EAPOL authentication.
- *
- * The operation of this function is further described in RFC 2898.
- */
-void pbkdf2_sha1 ( const void *passphrase, size_t pass_len,
- const void *salt, size_t salt_len,
- int iterations, void *key, size_t key_len )
-{
- u32 blocks = ( key_len + SHA1_DIGEST_SIZE - 1 ) / SHA1_DIGEST_SIZE;
- u32 blk;
- u8 buf[SHA1_DIGEST_SIZE];
-
- for ( blk = 1; blk <= blocks; blk++ ) {
- pbkdf2_sha1_f ( passphrase, pass_len, salt, salt_len,
- iterations, blk, buf );
- if ( key_len <= sizeof ( buf ) ) {
- memcpy ( key, buf, key_len );
- break;
- }
-
- memcpy ( key, buf, sizeof ( buf ) );
- key_len -= sizeof ( buf );
- key += sizeof ( buf );
- }
-}
diff --git a/qemu/roms/ipxe/src/crypto/sha224.c b/qemu/roms/ipxe/src/crypto/sha224.c
deleted file mode 100644
index be25f24e9..000000000
--- a/qemu/roms/ipxe/src/crypto/sha224.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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; either version 2 of the
- * License, or any later version.
- *
- * 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.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-/** @file
- *
- * SHA-224 algorithm
- *
- */
-
-#include <stdint.h>
-#include <byteswap.h>
-#include <ipxe/crypto.h>
-#include <ipxe/asn1.h>
-#include <ipxe/sha256.h>
-
-/** SHA-224 initial digest values */
-static const struct sha256_digest sha224_init_digest = {
- .h = {
- cpu_to_be32 ( 0xc1059ed8 ),
- cpu_to_be32 ( 0x367cd507 ),
- cpu_to_be32 ( 0x3070dd17 ),
- cpu_to_be32 ( 0xf70e5939 ),
- cpu_to_be32 ( 0xffc00b31 ),
- cpu_to_be32 ( 0x68581511 ),
- cpu_to_be32 ( 0x64f98fa7 ),
- cpu_to_be32 ( 0xbefa4fa4 ),
- },
-};
-
-/**
- * Initialise SHA-224 algorithm
- *
- * @v ctx SHA-224 context
- */
-static void sha224_init ( void *ctx ) {
- struct sha256_context *context = ctx;
-
- sha256_family_init ( context, &sha224_init_digest, SHA224_DIGEST_SIZE );
-}
-
-/** SHA-224 algorithm */
-struct digest_algorithm sha224_algorithm = {
- .name = "sha224",
- .ctxsize = sizeof ( struct sha256_context ),
- .blocksize = sizeof ( union sha256_block ),
- .digestsize = SHA224_DIGEST_SIZE,
- .init = sha224_init,
- .update = sha256_update,
- .final = sha256_final,
-};
-
-/** "sha224" object identifier */
-static uint8_t oid_sha224[] = { ASN1_OID_SHA224 };
-
-/** "sha224" OID-identified algorithm */
-struct asn1_algorithm oid_sha224_algorithm __asn1_algorithm = {
- .name = "sha224",
- .digest = &sha224_algorithm,
- .oid = ASN1_OID_CURSOR ( oid_sha224 ),
-};
diff --git a/qemu/roms/ipxe/src/crypto/sha256.c b/qemu/roms/ipxe/src/crypto/sha256.c
deleted file mode 100644
index 0360d8d16..000000000
--- a/qemu/roms/ipxe/src/crypto/sha256.c
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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; either version 2 of the
- * License, or any later version.
- *
- * 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.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-/** @file
- *
- * SHA-256 algorithm
- *
- */
-
-#include <stdint.h>
-#include <string.h>
-#include <byteswap.h>
-#include <assert.h>
-#include <ipxe/rotate.h>
-#include <ipxe/crypto.h>
-#include <ipxe/asn1.h>
-#include <ipxe/sha256.h>
-
-/** SHA-256 variables */
-struct sha256_variables {
- /* This layout matches that of struct sha256_digest_data,
- * allowing for efficient endianness-conversion,
- */
- uint32_t a;
- uint32_t b;
- uint32_t c;
- uint32_t d;
- uint32_t e;
- uint32_t f;
- uint32_t g;
- uint32_t h;
- uint32_t w[SHA256_ROUNDS];
-} __attribute__ (( packed ));
-
-/** SHA-256 constants */
-static const uint32_t k[SHA256_ROUNDS] = {
- 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
- 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
- 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
- 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
- 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
- 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
- 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
- 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
- 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
- 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
- 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
-};
-
-/** SHA-256 initial digest values */
-static const struct sha256_digest sha256_init_digest = {
- .h = {
- cpu_to_be32 ( 0x6a09e667 ),
- cpu_to_be32 ( 0xbb67ae85 ),
- cpu_to_be32 ( 0x3c6ef372 ),
- cpu_to_be32 ( 0xa54ff53a ),
- cpu_to_be32 ( 0x510e527f ),
- cpu_to_be32 ( 0x9b05688c ),
- cpu_to_be32 ( 0x1f83d9ab ),
- cpu_to_be32 ( 0x5be0cd19 ),
- },
-};
-
-/**
- * Initialise SHA-256 family algorithm
- *
- * @v context SHA-256 context
- * @v init Initial digest values
- * @v digestsize Digest size
- */
-void sha256_family_init ( struct sha256_context *context,
- const struct sha256_digest *init,
- size_t digestsize ) {
-
- context->len = 0;
- context->digestsize = digestsize;
- memcpy ( &context->ddd.dd.digest, init,
- sizeof ( context->ddd.dd.digest ) );
-}
-
-/**
- * Initialise SHA-256 algorithm
- *
- * @v ctx SHA-256 context
- */
-static void sha256_init ( void *ctx ) {
- struct sha256_context *context = ctx;
-
- sha256_family_init ( context, &sha256_init_digest,
- sizeof ( struct sha256_digest ) );
-}
-
-/**
- * Calculate SHA-256 digest of accumulated data
- *
- * @v context SHA-256 context
- */
-static void sha256_digest ( struct sha256_context *context ) {
- union {
- union sha256_digest_data_dwords ddd;
- struct sha256_variables v;
- } u;
- uint32_t *a = &u.v.a;
- uint32_t *b = &u.v.b;
- uint32_t *c = &u.v.c;
- uint32_t *d = &u.v.d;
- uint32_t *e = &u.v.e;
- uint32_t *f = &u.v.f;
- uint32_t *g = &u.v.g;
- uint32_t *h = &u.v.h;
- uint32_t *w = u.v.w;
- uint32_t s0;
- uint32_t s1;
- uint32_t maj;
- uint32_t t1;
- uint32_t t2;
- uint32_t ch;
- unsigned int i;
-
- /* Sanity checks */
- assert ( ( context->len % sizeof ( context->ddd.dd.data ) ) == 0 );
- linker_assert ( &u.ddd.dd.digest.h[0] == a, sha256_bad_layout );
- linker_assert ( &u.ddd.dd.digest.h[1] == b, sha256_bad_layout );
- linker_assert ( &u.ddd.dd.digest.h[2] == c, sha256_bad_layout );
- linker_assert ( &u.ddd.dd.digest.h[3] == d, sha256_bad_layout );
- linker_assert ( &u.ddd.dd.digest.h[4] == e, sha256_bad_layout );
- linker_assert ( &u.ddd.dd.digest.h[5] == f, sha256_bad_layout );
- linker_assert ( &u.ddd.dd.digest.h[6] == g, sha256_bad_layout );
- linker_assert ( &u.ddd.dd.digest.h[7] == h, sha256_bad_layout );
- linker_assert ( &u.ddd.dd.data.dword[0] == w, sha256_bad_layout );
-
- DBGC ( context, "SHA256 digesting:\n" );
- DBGC_HDA ( context, 0, &context->ddd.dd.digest,
- sizeof ( context->ddd.dd.digest ) );
- DBGC_HDA ( context, context->len, &context->ddd.dd.data,
- sizeof ( context->ddd.dd.data ) );
-
- /* Convert h[0..7] to host-endian, and initialise a, b, c, d,
- * e, f, g, h, and w[0..15]
- */
- for ( i = 0 ; i < ( sizeof ( u.ddd.dword ) /
- sizeof ( u.ddd.dword[0] ) ) ; i++ ) {
- be32_to_cpus ( &context->ddd.dword[i] );
- u.ddd.dword[i] = context->ddd.dword[i];
- }
-
- /* Initialise w[16..63] */
- for ( i = 16 ; i < SHA256_ROUNDS ; i++ ) {
- s0 = ( ror32 ( w[i-15], 7 ) ^ ror32 ( w[i-15], 18 ) ^
- ( w[i-15] >> 3 ) );
- s1 = ( ror32 ( w[i-2], 17 ) ^ ror32 ( w[i-2], 19 ) ^
- ( w[i-2] >> 10 ) );
- w[i] = ( w[i-16] + s0 + w[i-7] + s1 );
- }
-
- /* Main loop */
- for ( i = 0 ; i < SHA256_ROUNDS ; i++ ) {
- s0 = ( ror32 ( *a, 2 ) ^ ror32 ( *a, 13 ) ^ ror32 ( *a, 22 ) );
- maj = ( ( *a & *b ) ^ ( *a & *c ) ^ ( *b & *c ) );
- t2 = ( s0 + maj );
- s1 = ( ror32 ( *e, 6 ) ^ ror32 ( *e, 11 ) ^ ror32 ( *e, 25 ) );
- ch = ( ( *e & *f ) ^ ( (~*e) & *g ) );
- t1 = ( *h + s1 + ch + k[i] + w[i] );
- *h = *g;
- *g = *f;
- *f = *e;
- *e = ( *d + t1 );
- *d = *c;
- *c = *b;
- *b = *a;
- *a = ( t1 + t2 );
- DBGC2 ( context, "%2d : %08x %08x %08x %08x %08x %08x %08x "
- "%08x\n", i, *a, *b, *c, *d, *e, *f, *g, *h );
- }
-
- /* Add chunk to hash and convert back to big-endian */
- for ( i = 0 ; i < 8 ; i++ ) {
- context->ddd.dd.digest.h[i] =
- cpu_to_be32 ( context->ddd.dd.digest.h[i] +
- u.ddd.dd.digest.h[i] );
- }
-
- DBGC ( context, "SHA256 digested:\n" );
- DBGC_HDA ( context, 0, &context->ddd.dd.digest,
- sizeof ( context->ddd.dd.digest ) );
-}
-
-/**
- * Accumulate data with SHA-256 algorithm
- *
- * @v ctx SHA-256 context
- * @v data Data
- * @v len Length of data
- */
-void sha256_update ( void *ctx, const void *data, size_t len ) {
- struct sha256_context *context = ctx;
- const uint8_t *byte = data;
- size_t offset;
-
- /* Accumulate data a byte at a time, performing the digest
- * whenever we fill the data buffer
- */
- while ( len-- ) {
- offset = ( context->len % sizeof ( context->ddd.dd.data ) );
- context->ddd.dd.data.byte[offset] = *(byte++);
- context->len++;
- if ( ( context->len % sizeof ( context->ddd.dd.data ) ) == 0 )
- sha256_digest ( context );
- }
-}
-
-/**
- * Generate SHA-256 digest
- *
- * @v ctx SHA-256 context
- * @v out Output buffer
- */
-void sha256_final ( void *ctx, void *out ) {
- struct sha256_context *context = ctx;
- uint64_t len_bits;
- uint8_t pad;
-
- /* Record length before pre-processing */
- len_bits = cpu_to_be64 ( ( ( uint64_t ) context->len ) * 8 );
-
- /* Pad with a single "1" bit followed by as many "0" bits as required */
- pad = 0x80;
- do {
- sha256_update ( ctx, &pad, sizeof ( pad ) );
- pad = 0x00;
- } while ( ( context->len % sizeof ( context->ddd.dd.data ) ) !=
- offsetof ( typeof ( context->ddd.dd.data ), final.len ) );
-
- /* Append length (in bits) */
- sha256_update ( ctx, &len_bits, sizeof ( len_bits ) );
- assert ( ( context->len % sizeof ( context->ddd.dd.data ) ) == 0 );
-
- /* Copy out final digest */
- memcpy ( out, &context->ddd.dd.digest, context->digestsize );
-}
-
-/** SHA-256 algorithm */
-struct digest_algorithm sha256_algorithm = {
- .name = "sha256",
- .ctxsize = sizeof ( struct sha256_context ),
- .blocksize = sizeof ( union sha256_block ),
- .digestsize = sizeof ( struct sha256_digest ),
- .init = sha256_init,
- .update = sha256_update,
- .final = sha256_final,
-};
-
-/** "sha256" object identifier */
-static uint8_t oid_sha256[] = { ASN1_OID_SHA256 };
-
-/** "sha256" OID-identified algorithm */
-struct asn1_algorithm oid_sha256_algorithm __asn1_algorithm = {
- .name = "sha256",
- .digest = &sha256_algorithm,
- .oid = ASN1_OID_CURSOR ( oid_sha256 ),
-};
diff --git a/qemu/roms/ipxe/src/crypto/sha384.c b/qemu/roms/ipxe/src/crypto/sha384.c
deleted file mode 100644
index 017751826..000000000
--- a/qemu/roms/ipxe/src/crypto/sha384.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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; either version 2 of the
- * License, or any later version.
- *
- * 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.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-/** @file
- *
- * SHA-384 algorithm
- *
- */
-
-#include <stdint.h>
-#include <byteswap.h>
-#include <ipxe/crypto.h>
-#include <ipxe/asn1.h>
-#include <ipxe/sha512.h>
-
-/** SHA-384 initial digest values */
-static const struct sha512_digest sha384_init_digest = {
- .h = {
- cpu_to_be64 ( 0xcbbb9d5dc1059ed8ULL ),
- cpu_to_be64 ( 0x629a292a367cd507ULL ),
- cpu_to_be64 ( 0x9159015a3070dd17ULL ),
- cpu_to_be64 ( 0x152fecd8f70e5939ULL ),
- cpu_to_be64 ( 0x67332667ffc00b31ULL ),
- cpu_to_be64 ( 0x8eb44a8768581511ULL ),
- cpu_to_be64 ( 0xdb0c2e0d64f98fa7ULL ),
- cpu_to_be64 ( 0x47b5481dbefa4fa4ULL ),
- },
-};
-
-/**
- * Initialise SHA-384 algorithm
- *
- * @v ctx SHA-384 context
- */
-static void sha384_init ( void *ctx ) {
- struct sha512_context *context = ctx;
-
- sha512_family_init ( context, &sha384_init_digest, SHA384_DIGEST_SIZE );
-}
-
-/** SHA-384 algorithm */
-struct digest_algorithm sha384_algorithm = {
- .name = "sha384",
- .ctxsize = sizeof ( struct sha512_context ),
- .blocksize = sizeof ( union sha512_block ),
- .digestsize = SHA384_DIGEST_SIZE,
- .init = sha384_init,
- .update = sha512_update,
- .final = sha512_final,
-};
-
-/** "sha384" object identifier */
-static uint8_t oid_sha384[] = { ASN1_OID_SHA384 };
-
-/** "sha384" OID-identified algorithm */
-struct asn1_algorithm oid_sha384_algorithm __asn1_algorithm = {
- .name = "sha384",
- .digest = &sha384_algorithm,
- .oid = ASN1_OID_CURSOR ( oid_sha384 ),
-};
diff --git a/qemu/roms/ipxe/src/crypto/sha512.c b/qemu/roms/ipxe/src/crypto/sha512.c
deleted file mode 100644
index 814f44563..000000000
--- a/qemu/roms/ipxe/src/crypto/sha512.c
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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; either version 2 of the
- * License, or any later version.
- *
- * 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.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-/** @file
- *
- * SHA-512 algorithm
- *
- */
-
-#include <stdint.h>
-#include <string.h>
-#include <byteswap.h>
-#include <assert.h>
-#include <ipxe/rotate.h>
-#include <ipxe/crypto.h>
-#include <ipxe/asn1.h>
-#include <ipxe/sha512.h>
-
-/** SHA-512 variables */
-struct sha512_variables {
- /* This layout matches that of struct sha512_digest_data,
- * allowing for efficient endianness-conversion,
- */
- uint64_t a;
- uint64_t b;
- uint64_t c;
- uint64_t d;
- uint64_t e;
- uint64_t f;
- uint64_t g;
- uint64_t h;
- uint64_t w[SHA512_ROUNDS];
-} __attribute__ (( packed ));
-
-/** SHA-512 constants */
-static const uint64_t k[SHA512_ROUNDS] = {
- 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL,
- 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
- 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL,
- 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
- 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL,
- 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
- 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL,
- 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
- 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL,
- 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
- 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL,
- 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
- 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL,
- 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
- 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL,
- 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
- 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL,
- 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
- 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL,
- 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
- 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL,
- 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
- 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL,
- 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
- 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL,
- 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
- 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
-};
-
-/** SHA-512 initial digest values */
-static const struct sha512_digest sha512_init_digest = {
- .h = {
- cpu_to_be64 ( 0x6a09e667f3bcc908ULL ),
- cpu_to_be64 ( 0xbb67ae8584caa73bULL ),
- cpu_to_be64 ( 0x3c6ef372fe94f82bULL ),
- cpu_to_be64 ( 0xa54ff53a5f1d36f1ULL ),
- cpu_to_be64 ( 0x510e527fade682d1ULL ),
- cpu_to_be64 ( 0x9b05688c2b3e6c1fULL ),
- cpu_to_be64 ( 0x1f83d9abfb41bd6bULL ),
- cpu_to_be64 ( 0x5be0cd19137e2179ULL ),
- },
-};
-
-/**
- * Initialise SHA-512 family algorithm
- *
- * @v context SHA-512 context
- * @v init Initial digest values
- * @v digestsize Digest size
- */
-void sha512_family_init ( struct sha512_context *context,
- const struct sha512_digest *init,
- size_t digestsize ) {
-
- context->len = 0;
- context->digestsize = digestsize;
- memcpy ( &context->ddq.dd.digest, init,
- sizeof ( context->ddq.dd.digest ) );
-}
-
-/**
- * Initialise SHA-512 algorithm
- *
- * @v ctx SHA-512 context
- */
-static void sha512_init ( void *ctx ) {
- struct sha512_context *context = ctx;
-
- sha512_family_init ( context, &sha512_init_digest,
- sizeof ( struct sha512_digest ) );
-}
-
-/**
- * Calculate SHA-512 digest of accumulated data
- *
- * @v context SHA-512 context
- */
-static void sha512_digest ( struct sha512_context *context ) {
- union {
- union sha512_digest_data_qwords ddq;
- struct sha512_variables v;
- } u;
- uint64_t *a = &u.v.a;
- uint64_t *b = &u.v.b;
- uint64_t *c = &u.v.c;
- uint64_t *d = &u.v.d;
- uint64_t *e = &u.v.e;
- uint64_t *f = &u.v.f;
- uint64_t *g = &u.v.g;
- uint64_t *h = &u.v.h;
- uint64_t *w = u.v.w;
- uint64_t s0;
- uint64_t s1;
- uint64_t maj;
- uint64_t t1;
- uint64_t t2;
- uint64_t ch;
- unsigned int i;
-
- /* Sanity checks */
- assert ( ( context->len % sizeof ( context->ddq.dd.data ) ) == 0 );
- linker_assert ( &u.ddq.dd.digest.h[0] == a, sha512_bad_layout );
- linker_assert ( &u.ddq.dd.digest.h[1] == b, sha512_bad_layout );
- linker_assert ( &u.ddq.dd.digest.h[2] == c, sha512_bad_layout );
- linker_assert ( &u.ddq.dd.digest.h[3] == d, sha512_bad_layout );
- linker_assert ( &u.ddq.dd.digest.h[4] == e, sha512_bad_layout );
- linker_assert ( &u.ddq.dd.digest.h[5] == f, sha512_bad_layout );
- linker_assert ( &u.ddq.dd.digest.h[6] == g, sha512_bad_layout );
- linker_assert ( &u.ddq.dd.digest.h[7] == h, sha512_bad_layout );
- linker_assert ( &u.ddq.dd.data.qword[0] == w, sha512_bad_layout );
-
- DBGC ( context, "SHA512 digesting:\n" );
- DBGC_HDA ( context, 0, &context->ddq.dd.digest,
- sizeof ( context->ddq.dd.digest ) );
- DBGC_HDA ( context, context->len, &context->ddq.dd.data,
- sizeof ( context->ddq.dd.data ) );
-
- /* Convert h[0..7] to host-endian, and initialise a, b, c, d,
- * e, f, g, h, and w[0..15]
- */
- for ( i = 0 ; i < ( sizeof ( u.ddq.qword ) /
- sizeof ( u.ddq.qword[0] ) ) ; i++ ) {
- be64_to_cpus ( &context->ddq.qword[i] );
- u.ddq.qword[i] = context->ddq.qword[i];
- }
-
- /* Initialise w[16..79] */
- for ( i = 16 ; i < SHA512_ROUNDS ; i++ ) {
- s0 = ( ror64 ( w[i-15], 1 ) ^ ror64 ( w[i-15], 8 ) ^
- ( w[i-15] >> 7 ) );
- s1 = ( ror64 ( w[i-2], 19 ) ^ ror64 ( w[i-2], 61 ) ^
- ( w[i-2] >> 6 ) );
- w[i] = ( w[i-16] + s0 + w[i-7] + s1 );
- }
-
- /* Main loop */
- for ( i = 0 ; i < SHA512_ROUNDS ; i++ ) {
- s0 = ( ror64 ( *a, 28 ) ^ ror64 ( *a, 34 ) ^ ror64 ( *a, 39 ) );
- maj = ( ( *a & *b ) ^ ( *a & *c ) ^ ( *b & *c ) );
- t2 = ( s0 + maj );
- s1 = ( ror64 ( *e, 14 ) ^ ror64 ( *e, 18 ) ^ ror64 ( *e, 41 ) );
- ch = ( ( *e & *f ) ^ ( (~*e) & *g ) );
- t1 = ( *h + s1 + ch + k[i] + w[i] );
- *h = *g;
- *g = *f;
- *f = *e;
- *e = ( *d + t1 );
- *d = *c;
- *c = *b;
- *b = *a;
- *a = ( t1 + t2 );
- DBGC2 ( context, "%2d : %016llx %016llx %016llx %016llx "
- "%016llx %016llx %016llx %016llx\n",
- i, *a, *b, *c, *d, *e, *f, *g, *h );
- }
-
- /* Add chunk to hash and convert back to big-endian */
- for ( i = 0 ; i < 8 ; i++ ) {
- context->ddq.dd.digest.h[i] =
- cpu_to_be64 ( context->ddq.dd.digest.h[i] +
- u.ddq.dd.digest.h[i] );
- }
-
- DBGC ( context, "SHA512 digested:\n" );
- DBGC_HDA ( context, 0, &context->ddq.dd.digest,
- sizeof ( context->ddq.dd.digest ) );
-}
-
-/**
- * Accumulate data with SHA-512 algorithm
- *
- * @v ctx SHA-512 context
- * @v data Data
- * @v len Length of data
- */
-void sha512_update ( void *ctx, const void *data, size_t len ) {
- struct sha512_context *context = ctx;
- const uint8_t *byte = data;
- size_t offset;
-
- /* Accumulate data a byte at a time, performing the digest
- * whenever we fill the data buffer
- */
- while ( len-- ) {
- offset = ( context->len % sizeof ( context->ddq.dd.data ) );
- context->ddq.dd.data.byte[offset] = *(byte++);
- context->len++;
- if ( ( context->len % sizeof ( context->ddq.dd.data ) ) == 0 )
- sha512_digest ( context );
- }
-}
-
-/**
- * Generate SHA-512 digest
- *
- * @v ctx SHA-512 context
- * @v out Output buffer
- */
-void sha512_final ( void *ctx, void *out ) {
- struct sha512_context *context = ctx;
- uint64_t len_bits_hi;
- uint64_t len_bits_lo;
- uint8_t pad;
-
- /* Record length before pre-processing */
- len_bits_hi = 0;
- len_bits_lo = cpu_to_be64 ( ( ( uint64_t ) context->len ) * 8 );
-
- /* Pad with a single "1" bit followed by as many "0" bits as required */
- pad = 0x80;
- do {
- sha512_update ( ctx, &pad, sizeof ( pad ) );
- pad = 0x00;
- } while ( ( context->len % sizeof ( context->ddq.dd.data ) ) !=
- offsetof ( typeof ( context->ddq.dd.data ), final.len_hi ) );
-
- /* Append length (in bits) */
- sha512_update ( ctx, &len_bits_hi, sizeof ( len_bits_hi ) );
- sha512_update ( ctx, &len_bits_lo, sizeof ( len_bits_lo ) );
- assert ( ( context->len % sizeof ( context->ddq.dd.data ) ) == 0 );
-
- /* Copy out final digest */
- memcpy ( out, &context->ddq.dd.digest, context->digestsize );
-}
-
-/** SHA-512 algorithm */
-struct digest_algorithm sha512_algorithm = {
- .name = "sha512",
- .ctxsize = sizeof ( struct sha512_context ),
- .blocksize = sizeof ( union sha512_block ),
- .digestsize = sizeof ( struct sha512_digest ),
- .init = sha512_init,
- .update = sha512_update,
- .final = sha512_final,
-};
-
-/** "sha512" object identifier */
-static uint8_t oid_sha512[] = { ASN1_OID_SHA512 };
-
-/** "sha512" OID-identified algorithm */
-struct asn1_algorithm oid_sha512_algorithm __asn1_algorithm = {
- .name = "sha512",
- .digest = &sha512_algorithm,
- .oid = ASN1_OID_CURSOR ( oid_sha512 ),
-};
diff --git a/qemu/roms/ipxe/src/crypto/sha512_224.c b/qemu/roms/ipxe/src/crypto/sha512_224.c
deleted file mode 100644
index 8c37b566b..000000000
--- a/qemu/roms/ipxe/src/crypto/sha512_224.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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; either version 2 of the
- * License, or any later version.
- *
- * 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.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-/** @file
- *
- * SHA-512/224 algorithm
- *
- */
-
-#include <stdint.h>
-#include <byteswap.h>
-#include <ipxe/crypto.h>
-#include <ipxe/asn1.h>
-#include <ipxe/sha512.h>
-
-/** SHA-512/224 initial digest values */
-static const struct sha512_digest sha512_224_init_digest = {
- .h = {
- cpu_to_be64 ( 0x8c3d37c819544da2ULL ),
- cpu_to_be64 ( 0x73e1996689dcd4d6ULL ),
- cpu_to_be64 ( 0x1dfab7ae32ff9c82ULL ),
- cpu_to_be64 ( 0x679dd514582f9fcfULL ),
- cpu_to_be64 ( 0x0f6d2b697bd44da8ULL ),
- cpu_to_be64 ( 0x77e36f7304c48942ULL ),
- cpu_to_be64 ( 0x3f9d85a86a1d36c8ULL ),
- cpu_to_be64 ( 0x1112e6ad91d692a1ULL ),
- },
-};
-
-/**
- * Initialise SHA-512/224 algorithm
- *
- * @v ctx SHA-512/224 context
- */
-static void sha512_224_init ( void *ctx ) {
- struct sha512_context *context = ctx;
-
- sha512_family_init ( context, &sha512_224_init_digest,
- SHA512_224_DIGEST_SIZE );
-}
-
-/** SHA-512/224 algorithm */
-struct digest_algorithm sha512_224_algorithm = {
- .name = "sha512/224",
- .ctxsize = sizeof ( struct sha512_context ),
- .blocksize = sizeof ( union sha512_block ),
- .digestsize = SHA512_224_DIGEST_SIZE,
- .init = sha512_224_init,
- .update = sha512_update,
- .final = sha512_final,
-};
-
-/** "sha512_224" object identifier */
-static uint8_t oid_sha512_224[] = { ASN1_OID_SHA512_224 };
-
-/** "sha512_224" OID-identified algorithm */
-struct asn1_algorithm oid_sha512_224_algorithm __asn1_algorithm = {
- .name = "sha512/224",
- .digest = &sha512_224_algorithm,
- .oid = ASN1_OID_CURSOR ( oid_sha512_224 ),
-};
diff --git a/qemu/roms/ipxe/src/crypto/sha512_256.c b/qemu/roms/ipxe/src/crypto/sha512_256.c
deleted file mode 100644
index f8afaf3e3..000000000
--- a/qemu/roms/ipxe/src/crypto/sha512_256.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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; either version 2 of the
- * License, or any later version.
- *
- * 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.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-/** @file
- *
- * SHA-512/256 algorithm
- *
- */
-
-#include <stdint.h>
-#include <byteswap.h>
-#include <ipxe/crypto.h>
-#include <ipxe/asn1.h>
-#include <ipxe/sha512.h>
-
-/** SHA-512/256 initial digest values */
-static const struct sha512_digest sha512_256_init_digest = {
- .h = {
- cpu_to_be64 ( 0x22312194fc2bf72cULL ),
- cpu_to_be64 ( 0x9f555fa3c84c64c2ULL ),
- cpu_to_be64 ( 0x2393b86b6f53b151ULL ),
- cpu_to_be64 ( 0x963877195940eabdULL ),
- cpu_to_be64 ( 0x96283ee2a88effe3ULL ),
- cpu_to_be64 ( 0xbe5e1e2553863992ULL ),
- cpu_to_be64 ( 0x2b0199fc2c85b8aaULL ),
- cpu_to_be64 ( 0x0eb72ddc81c52ca2ULL ),
- },
-};
-
-/**
- * Initialise SHA-512/256 algorithm
- *
- * @v ctx SHA-512/256 context
- */
-static void sha512_256_init ( void *ctx ) {
- struct sha512_context *context = ctx;
-
- sha512_family_init ( context, &sha512_256_init_digest,
- SHA512_256_DIGEST_SIZE );
-}
-
-/** SHA-512/256 algorithm */
-struct digest_algorithm sha512_256_algorithm = {
- .name = "sha512/256",
- .ctxsize = sizeof ( struct sha512_context ),
- .blocksize = sizeof ( union sha512_block ),
- .digestsize = SHA512_256_DIGEST_SIZE,
- .init = sha512_256_init,
- .update = sha512_update,
- .final = sha512_final,
-};
-
-/** "sha512_256" object identifier */
-static uint8_t oid_sha512_256[] = { ASN1_OID_SHA512_256 };
-
-/** "sha512_256" OID-identified algorithm */
-struct asn1_algorithm oid_sha512_256_algorithm __asn1_algorithm = {
- .name = "sha512/256",
- .digest = &sha512_256_algorithm,
- .oid = ASN1_OID_CURSOR ( oid_sha512_256 ),
-};
diff --git a/qemu/roms/ipxe/src/crypto/x509.c b/qemu/roms/ipxe/src/crypto/x509.c
deleted file mode 100644
index 43a4ca17a..000000000
--- a/qemu/roms/ipxe/src/crypto/x509.c
+++ /dev/null
@@ -1,1776 +0,0 @@
-/*
- * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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; either version 2 of the
- * License, or any later version.
- *
- * 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.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-#include <ipxe/list.h>
-#include <ipxe/base16.h>
-#include <ipxe/asn1.h>
-#include <ipxe/crypto.h>
-#include <ipxe/md5.h>
-#include <ipxe/sha1.h>
-#include <ipxe/sha256.h>
-#include <ipxe/rsa.h>
-#include <ipxe/rootcert.h>
-#include <ipxe/certstore.h>
-#include <ipxe/socket.h>
-#include <ipxe/in.h>
-#include <ipxe/x509.h>
-#include <config/crypto.h>
-
-/** @file
- *
- * X.509 certificates
- *
- * The structure of X.509v3 certificates is documented in RFC 5280
- * section 4.1.
- */
-
-/* Disambiguate the various error causes */
-#define ENOTSUP_ALGORITHM \
- __einfo_error ( EINFO_ENOTSUP_ALGORITHM )
-#define EINFO_ENOTSUP_ALGORITHM \
- __einfo_uniqify ( EINFO_ENOTSUP, 0x01, "Unsupported algorithm" )
-#define ENOTSUP_EXTENSION \
- __einfo_error ( EINFO_ENOTSUP_EXTENSION )
-#define EINFO_ENOTSUP_EXTENSION \
- __einfo_uniqify ( EINFO_ENOTSUP, 0x02, "Unsupported extension" )
-#define EINVAL_ALGORITHM \
- __einfo_error ( EINFO_EINVAL_ALGORITHM )
-#define EINFO_EINVAL_ALGORITHM \
- __einfo_uniqify ( EINFO_EINVAL, 0x01, "Invalid algorithm type" )
-#define EINVAL_ALGORITHM_MISMATCH \
- __einfo_error ( EINFO_EINVAL_ALGORITHM_MISMATCH )
-#define EINFO_EINVAL_ALGORITHM_MISMATCH \
- __einfo_uniqify ( EINFO_EINVAL, 0x04, "Signature algorithm mismatch" )
-#define EINVAL_PATH_LEN \
- __einfo_error ( EINFO_EINVAL_PATH_LEN )
-#define EINFO_EINVAL_PATH_LEN \
- __einfo_uniqify ( EINFO_EINVAL, 0x05, "Invalid pathLenConstraint" )
-#define EINVAL_VERSION \
- __einfo_error ( EINFO_EINVAL_VERSION )
-#define EINFO_EINVAL_VERSION \
- __einfo_uniqify ( EINFO_EINVAL, 0x06, "Invalid version" )
-#define EACCES_WRONG_ISSUER \
- __einfo_error ( EINFO_EACCES_WRONG_ISSUER )
-#define EINFO_EACCES_WRONG_ISSUER \
- __einfo_uniqify ( EINFO_EACCES, 0x01, "Wrong issuer" )
-#define EACCES_NOT_CA \
- __einfo_error ( EINFO_EACCES_NOT_CA )
-#define EINFO_EACCES_NOT_CA \
- __einfo_uniqify ( EINFO_EACCES, 0x02, "Not a CA certificate" )
-#define EACCES_KEY_USAGE \
- __einfo_error ( EINFO_EACCES_KEY_USAGE )
-#define EINFO_EACCES_KEY_USAGE \
- __einfo_uniqify ( EINFO_EACCES, 0x03, "Incorrect key usage" )
-#define EACCES_EXPIRED \
- __einfo_error ( EINFO_EACCES_EXPIRED )
-#define EINFO_EACCES_EXPIRED \
- __einfo_uniqify ( EINFO_EACCES, 0x04, "Expired (or not yet valid)" )
-#define EACCES_PATH_LEN \
- __einfo_error ( EINFO_EACCES_PATH_LEN )
-#define EINFO_EACCES_PATH_LEN \
- __einfo_uniqify ( EINFO_EACCES, 0x05, "Maximum path length exceeded" )
-#define EACCES_UNTRUSTED \
- __einfo_error ( EINFO_EACCES_UNTRUSTED )
-#define EINFO_EACCES_UNTRUSTED \
- __einfo_uniqify ( EINFO_EACCES, 0x06, "Untrusted root certificate" )
-#define EACCES_OUT_OF_ORDER \
- __einfo_error ( EINFO_EACCES_OUT_OF_ORDER )
-#define EINFO_EACCES_OUT_OF_ORDER \
- __einfo_uniqify ( EINFO_EACCES, 0x07, "Validation out of order" )
-#define EACCES_EMPTY \
- __einfo_error ( EINFO_EACCES_EMPTY )
-#define EINFO_EACCES_EMPTY \
- __einfo_uniqify ( EINFO_EACCES, 0x08, "Empty certificate chain" )
-#define EACCES_OCSP_REQUIRED \
- __einfo_error ( EINFO_EACCES_OCSP_REQUIRED )
-#define EINFO_EACCES_OCSP_REQUIRED \
- __einfo_uniqify ( EINFO_EACCES, 0x09, "OCSP check required" )
-#define EACCES_WRONG_NAME \
- __einfo_error ( EINFO_EACCES_WRONG_NAME )
-#define EINFO_EACCES_WRONG_NAME \
- __einfo_uniqify ( EINFO_EACCES, 0x0a, "Incorrect certificate name" )
-#define EACCES_USELESS \
- __einfo_error ( EINFO_EACCES_USELESS )
-#define EINFO_EACCES_USELESS \
- __einfo_uniqify ( EINFO_EACCES, 0x0b, "No usable certificates" )
-
-/**
- * Get X.509 certificate name (for debugging)
- *
- * @v cert X.509 certificate
- * @ret name Name (for debugging)
- */
-const char * x509_name ( struct x509_certificate *cert ) {
- struct asn1_cursor *common_name = &cert->subject.common_name;
- struct digest_algorithm *digest = &sha1_algorithm;
- static char buf[64];
- uint8_t fingerprint[ digest->digestsize ];
- size_t len;
-
- len = common_name->len;
- if ( len ) {
- /* Certificate has a commonName: use that */
- if ( len > ( sizeof ( buf ) - 1 /* NUL */ ) )
- len = ( sizeof ( buf ) - 1 /* NUL */ );
- memcpy ( buf, common_name->data, len );
- buf[len] = '\0';
- } else {
- /* Certificate has no commonName: use SHA-1 fingerprint */
- x509_fingerprint ( cert, digest, fingerprint );
- base16_encode ( fingerprint, sizeof ( fingerprint ),
- buf, sizeof ( buf ) );
- }
- return buf;
-}
-
-/** "commonName" object identifier */
-static uint8_t oid_common_name[] = { ASN1_OID_COMMON_NAME };
-
-/** "commonName" object identifier cursor */
-static struct asn1_cursor oid_common_name_cursor =
- ASN1_OID_CURSOR ( oid_common_name );
-
-/**
- * Parse X.509 certificate version
- *
- * @v cert X.509 certificate
- * @v raw ASN.1 cursor
- * @ret rc Return status code
- */
-static int x509_parse_version ( struct x509_certificate *cert,
- const struct asn1_cursor *raw ) {
- struct asn1_cursor cursor;
- int version;
- int rc;
-
- /* Enter version */
- memcpy ( &cursor, raw, sizeof ( cursor ) );
- asn1_enter ( &cursor, ASN1_EXPLICIT_TAG ( 0 ) );
-
- /* Parse integer */
- if ( ( rc = asn1_integer ( &cursor, &version ) ) != 0 ) {
- DBGC ( cert, "X509 %p cannot parse version: %s\n",
- cert, strerror ( rc ) );
- DBGC_HDA ( cert, 0, raw->data, raw->len );
- return rc;
- }
-
- /* Sanity check */
- if ( version < 0 ) {
- DBGC ( cert, "X509 %p invalid version %d\n", cert, version );
- DBGC_HDA ( cert, 0, raw->data, raw->len );
- return -EINVAL_VERSION;
- }
-
- /* Record version */
- cert->version = version;
- DBGC2 ( cert, "X509 %p is a version %d certificate\n",
- cert, ( cert->version + 1 ) );
-
- return 0;
-}
-
-/**
- * Parse X.509 certificate serial number
- *
- * @v cert X.509 certificate
- * @v raw ASN.1 cursor
- * @ret rc Return status code
- */
-static int x509_parse_serial ( struct x509_certificate *cert,
- const struct asn1_cursor *raw ) {
- struct x509_serial *serial = &cert->serial;
- int rc;
-
- /* Record raw serial number */
- memcpy ( &serial->raw, raw, sizeof ( serial->raw ) );
- if ( ( rc = asn1_shrink ( &serial->raw, ASN1_INTEGER ) ) != 0 ) {
- DBGC ( cert, "X509 %p cannot shrink serialNumber: %s\n",
- cert, strerror ( rc ) );
- return rc;
- }
- DBGC2 ( cert, "X509 %p issuer is:\n", cert );
- DBGC2_HDA ( cert, 0, serial->raw.data, serial->raw.len );
-
- return 0;
-}
-
-/**
- * Parse X.509 certificate issuer
- *
- * @v cert X.509 certificate
- * @v raw ASN.1 cursor
- * @ret rc Return status code
- */
-static int x509_parse_issuer ( struct x509_certificate *cert,
- const struct asn1_cursor *raw ) {
- struct x509_issuer *issuer = &cert->issuer;
- int rc;
-
- /* Record raw issuer */
- memcpy ( &issuer->raw, raw, sizeof ( issuer->raw ) );
- if ( ( rc = asn1_shrink ( &issuer->raw, ASN1_SEQUENCE ) ) != 0 ) {
- DBGC ( cert, "X509 %p cannot shrink issuer: %s\n",
- cert, strerror ( rc ) );
- return rc;
- }
- DBGC2 ( cert, "X509 %p issuer is:\n", cert );
- DBGC2_HDA ( cert, 0, issuer->raw.data, issuer->raw.len );
-
- return 0;
-}
-
-/**
- * Parse X.509 certificate validity
- *
- * @v cert X.509 certificate
- * @v raw ASN.1 cursor
- * @ret rc Return status code
- */
-static int x509_parse_validity ( struct x509_certificate *cert,
- const struct asn1_cursor *raw ) {
- struct x509_validity *validity = &cert->validity;
- struct x509_time *not_before = &validity->not_before;
- struct x509_time *not_after = &validity->not_after;
- struct asn1_cursor cursor;
- int rc;
-
- /* Enter validity */
- memcpy ( &cursor, raw, sizeof ( cursor ) );
- asn1_enter ( &cursor, ASN1_SEQUENCE );
-
- /* Parse notBefore */
- if ( ( rc = asn1_generalized_time ( &cursor,
- &not_before->time ) ) != 0 ) {
- DBGC ( cert, "X509 %p cannot parse notBefore: %s\n",
- cert, strerror ( rc ) );
- return rc;
- }
- DBGC2 ( cert, "X509 %p valid from time %lld\n",
- cert, not_before->time );
- asn1_skip_any ( &cursor );
-
- /* Parse notAfter */
- if ( ( rc = asn1_generalized_time ( &cursor,
- &not_after->time ) ) != 0 ) {
- DBGC ( cert, "X509 %p cannot parse notAfter: %s\n",
- cert, strerror ( rc ) );
- return rc;
- }
- DBGC2 ( cert, "X509 %p valid until time %lld\n",
- cert, not_after->time );
-
- return 0;
-}
-
-/**
- * Parse X.509 certificate common name
- *
- * @v cert X.509 certificate
- * @v raw ASN.1 cursor
- * @ret rc Return status code
- */
-static int x509_parse_common_name ( struct x509_certificate *cert,
- const struct asn1_cursor *raw ) {
- struct asn1_cursor cursor;
- struct asn1_cursor oid_cursor;
- struct asn1_cursor name_cursor;
- int rc;
-
- /* Enter name */
- memcpy ( &cursor, raw, sizeof ( cursor ) );
- asn1_enter ( &cursor, ASN1_SEQUENCE );
-
- /* Scan through name list */
- for ( ; cursor.len ; asn1_skip_any ( &cursor ) ) {
-
- /* Check for "commonName" OID */
- memcpy ( &oid_cursor, &cursor, sizeof ( oid_cursor ) );
- asn1_enter ( &oid_cursor, ASN1_SET );
- asn1_enter ( &oid_cursor, ASN1_SEQUENCE );
- memcpy ( &name_cursor, &oid_cursor, sizeof ( name_cursor ) );
- asn1_enter ( &oid_cursor, ASN1_OID );
- if ( asn1_compare ( &oid_common_name_cursor, &oid_cursor ) != 0)
- continue;
- asn1_skip_any ( &name_cursor );
- if ( ( rc = asn1_enter_any ( &name_cursor ) ) != 0 ) {
- DBGC ( cert, "X509 %p cannot locate name:\n", cert );
- DBGC_HDA ( cert, 0, raw->data, raw->len );
- return rc;
- }
-
- /* Record common name */
- memcpy ( &cert->subject.common_name, &name_cursor,
- sizeof ( cert->subject.common_name ) );
-
- return 0;
- }
-
- /* Certificates may not have a commonName */
- DBGC2 ( cert, "X509 %p no commonName found:\n", cert );
- return 0;
-}
-
-/**
- * Parse X.509 certificate subject
- *
- * @v cert X.509 certificate
- * @v raw ASN.1 cursor
- * @ret rc Return status code
- */
-static int x509_parse_subject ( struct x509_certificate *cert,
- const struct asn1_cursor *raw ) {
- struct x509_subject *subject = &cert->subject;
- int rc;
-
- /* Record raw subject */
- memcpy ( &subject->raw, raw, sizeof ( subject->raw ) );
- asn1_shrink_any ( &subject->raw );
- DBGC2 ( cert, "X509 %p subject is:\n", cert );
- DBGC2_HDA ( cert, 0, subject->raw.data, subject->raw.len );
-
- /* Parse common name */
- if ( ( rc = x509_parse_common_name ( cert, raw ) ) != 0 )
- return rc;
- DBGC2 ( cert, "X509 %p common name is \"%s\":\n", cert,
- x509_name ( cert ) );
-
- return 0;
-}
-
-/**
- * Parse X.509 certificate public key information
- *
- * @v cert X.509 certificate
- * @v raw ASN.1 cursor
- * @ret rc Return status code
- */
-static int x509_parse_public_key ( struct x509_certificate *cert,
- const struct asn1_cursor *raw ) {
- struct x509_public_key *public_key = &cert->subject.public_key;
- struct asn1_algorithm **algorithm = &public_key->algorithm;
- struct asn1_bit_string *raw_bits = &public_key->raw_bits;
- struct asn1_cursor cursor;
- int rc;
-
- /* Record raw subjectPublicKeyInfo */
- memcpy ( &cursor, raw, sizeof ( cursor ) );
- asn1_shrink_any ( &cursor );
- memcpy ( &public_key->raw, &cursor, sizeof ( public_key->raw ) );
- DBGC2 ( cert, "X509 %p public key is:\n", cert );
- DBGC2_HDA ( cert, 0, public_key->raw.data, public_key->raw.len );
-
- /* Enter subjectPublicKeyInfo */
- asn1_enter ( &cursor, ASN1_SEQUENCE );
-
- /* Parse algorithm */
- if ( ( rc = asn1_pubkey_algorithm ( &cursor, algorithm ) ) != 0 ) {
- DBGC ( cert, "X509 %p could not parse public key algorithm: "
- "%s\n", cert, strerror ( rc ) );
- return rc;
- }
- DBGC2 ( cert, "X509 %p public key algorithm is %s\n",
- cert, (*algorithm)->name );
- asn1_skip_any ( &cursor );
-
- /* Parse bit string */
- if ( ( rc = asn1_bit_string ( &cursor, raw_bits ) ) != 0 ) {
- DBGC ( cert, "X509 %p could not parse public key bits: %s\n",
- cert, strerror ( rc ) );
- return rc;
- }
-
- return 0;
-}
-
-/**
- * Parse X.509 certificate basic constraints
- *
- * @v cert X.509 certificate
- * @v raw ASN.1 cursor
- * @ret rc Return status code
- */
-static int x509_parse_basic_constraints ( struct x509_certificate *cert,
- const struct asn1_cursor *raw ) {
- struct x509_basic_constraints *basic = &cert->extensions.basic;
- struct asn1_cursor cursor;
- int ca = 0;
- int path_len;
- int rc;
-
- /* Enter basicConstraints */
- memcpy ( &cursor, raw, sizeof ( cursor ) );
- asn1_enter ( &cursor, ASN1_SEQUENCE );
-
- /* Parse "cA", if present */
- if ( asn1_type ( &cursor ) == ASN1_BOOLEAN ) {
- ca = asn1_boolean ( &cursor );
- if ( ca < 0 ) {
- rc = ca;
- DBGC ( cert, "X509 %p cannot parse cA: %s\n",
- cert, strerror ( rc ) );
- DBGC_HDA ( cert, 0, raw->data, raw->len );
- return rc;
- }
- asn1_skip_any ( &cursor );
- }
- basic->ca = ca;
- DBGC2 ( cert, "X509 %p is %sa CA certificate\n",
- cert, ( basic->ca ? "" : "not " ) );
-
- /* Ignore everything else unless "cA" is true */
- if ( ! ca )
- return 0;
-
- /* Parse "pathLenConstraint", if present and applicable */
- basic->path_len = X509_PATH_LEN_UNLIMITED;
- if ( asn1_type ( &cursor ) == ASN1_INTEGER ) {
- if ( ( rc = asn1_integer ( &cursor, &path_len ) ) != 0 ) {
- DBGC ( cert, "X509 %p cannot parse pathLenConstraint: "
- "%s\n", cert, strerror ( rc ) );
- DBGC_HDA ( cert, 0, raw->data, raw->len );
- return rc;
- }
- if ( path_len < 0 ) {
- DBGC ( cert, "X509 %p invalid pathLenConstraint %d\n",
- cert, path_len );
- DBGC_HDA ( cert, 0, raw->data, raw->len );
- return -EINVAL;
- }
- basic->path_len = path_len;
- DBGC2 ( cert, "X509 %p path length constraint is %d\n",
- cert, basic->path_len );
- }
-
- return 0;
-}
-
-/**
- * Parse X.509 certificate key usage
- *
- * @v cert X.509 certificate
- * @v raw ASN.1 cursor
- * @ret rc Return status code
- */
-static int x509_parse_key_usage ( struct x509_certificate *cert,
- const struct asn1_cursor *raw ) {
- struct x509_key_usage *usage = &cert->extensions.usage;
- struct asn1_bit_string bit_string;
- const uint8_t *bytes;
- size_t len;
- unsigned int i;
- int rc;
-
- /* Mark extension as present */
- usage->present = 1;
-
- /* Parse bit string */
- if ( ( rc = asn1_bit_string ( raw, &bit_string ) ) != 0 ) {
- DBGC ( cert, "X509 %p could not parse key usage: %s\n",
- cert, strerror ( rc ) );
- return rc;
- }
-
- /* Parse key usage bits */
- bytes = bit_string.data;
- len = bit_string.len;
- if ( len > sizeof ( usage->bits ) )
- len = sizeof ( usage->bits );
- for ( i = 0 ; i < len ; i++ ) {
- usage->bits |= ( *(bytes++) << ( 8 * i ) );
- }
- DBGC2 ( cert, "X509 %p key usage is %08x\n", cert, usage->bits );
-
- return 0;
-}
-
-/** "id-kp-codeSigning" object identifier */
-static uint8_t oid_code_signing[] = { ASN1_OID_CODESIGNING };
-
-/** "id-kp-OCSPSigning" object identifier */
-static uint8_t oid_ocsp_signing[] = { ASN1_OID_OCSPSIGNING };
-
-/** Supported key purposes */
-static struct x509_key_purpose x509_key_purposes[] = {
- {
- .name = "codeSigning",
- .bits = X509_CODE_SIGNING,
- .oid = ASN1_OID_CURSOR ( oid_code_signing ),
- },
- {
- .name = "ocspSigning",
- .bits = X509_OCSP_SIGNING,
- .oid = ASN1_OID_CURSOR ( oid_ocsp_signing ),
- },
-};
-
-/**
- * Parse X.509 certificate key purpose identifier
- *
- * @v cert X.509 certificate
- * @v raw ASN.1 cursor
- * @ret rc Return status code
- */
-static int x509_parse_key_purpose ( struct x509_certificate *cert,
- const struct asn1_cursor *raw ) {
- struct x509_extended_key_usage *ext_usage = &cert->extensions.ext_usage;
- struct x509_key_purpose *purpose;
- struct asn1_cursor cursor;
- unsigned int i;
- int rc;
-
- /* Enter keyPurposeId */
- memcpy ( &cursor, raw, sizeof ( cursor ) );
- if ( ( rc = asn1_enter ( &cursor, ASN1_OID ) ) != 0 ) {
- DBGC ( cert, "X509 %p invalid keyPurposeId:\n", cert );
- DBGC_HDA ( cert, 0, raw->data, raw->len );
- return rc;
- }
-
- /* Identify key purpose */
- for ( i = 0 ; i < ( sizeof ( x509_key_purposes ) /
- sizeof ( x509_key_purposes[0] ) ) ; i++ ) {
- purpose = &x509_key_purposes[i];
- if ( asn1_compare ( &cursor, &purpose->oid ) == 0 ) {
- DBGC2 ( cert, "X509 %p has key purpose %s\n",
- cert, purpose->name );
- ext_usage->bits |= purpose->bits;
- return 0;
- }
- }
-
- /* Ignore unrecognised key purposes */
- return 0;
-}
-
-/**
- * Parse X.509 certificate extended key usage
- *
- * @v cert X.509 certificate
- * @v raw ASN.1 cursor
- * @ret rc Return status code
- */
-static int x509_parse_extended_key_usage ( struct x509_certificate *cert,
- const struct asn1_cursor *raw ) {
- struct asn1_cursor cursor;
- int rc;
-
- /* Enter extKeyUsage */
- memcpy ( &cursor, raw, sizeof ( cursor ) );
- asn1_enter ( &cursor, ASN1_SEQUENCE );
-
- /* Parse each extended key usage in turn */
- while ( cursor.len ) {
- if ( ( rc = x509_parse_key_purpose ( cert, &cursor ) ) != 0 )
- return rc;
- asn1_skip_any ( &cursor );
- }
-
- return 0;
-}
-
-/**
- * Parse X.509 certificate OCSP access method
- *
- * @v cert X.509 certificate
- * @v raw ASN.1 cursor
- * @ret rc Return status code
- */
-static int x509_parse_ocsp ( struct x509_certificate *cert,
- const struct asn1_cursor *raw ) {
- struct x509_ocsp_responder *ocsp = &cert->extensions.auth_info.ocsp;
- struct asn1_cursor *uri = &ocsp->uri;
- int rc;
-
- /* Enter accessLocation */
- memcpy ( uri, raw, sizeof ( *uri ) );
- if ( ( rc = asn1_enter ( uri, X509_GENERAL_NAME_URI ) ) != 0 ) {
- DBGC ( cert, "X509 %p OCSP does not contain "
- "uniformResourceIdentifier:\n", cert );
- DBGC_HDA ( cert, 0, raw->data, raw->len );
- return rc;
- }
- DBGC2 ( cert, "X509 %p OCSP URI is:\n", cert );
- DBGC2_HDA ( cert, 0, uri->data, uri->len );
-
- return 0;
-}
-
-/** "id-ad-ocsp" object identifier */
-static uint8_t oid_ad_ocsp[] = { ASN1_OID_OCSP };
-
-/** Supported access methods */
-static struct x509_access_method x509_access_methods[] = {
- {
- .name = "OCSP",
- .oid = ASN1_OID_CURSOR ( oid_ad_ocsp ),
- .parse = x509_parse_ocsp,
- },
-};
-
-/**
- * Identify X.509 access method by OID
- *
- * @v oid OID
- * @ret method Access method, or NULL
- */
-static struct x509_access_method *
-x509_find_access_method ( const struct asn1_cursor *oid ) {
- struct x509_access_method *method;
- unsigned int i;
-
- for ( i = 0 ; i < ( sizeof ( x509_access_methods ) /
- sizeof ( x509_access_methods[0] ) ) ; i++ ) {
- method = &x509_access_methods[i];
- if ( asn1_compare ( &method->oid, oid ) == 0 )
- return method;
- }
-
- return NULL;
-}
-
-/**
- * Parse X.509 certificate access description
- *
- * @v cert X.509 certificate
- * @v raw ASN.1 cursor
- * @ret rc Return status code
- */
-static int x509_parse_access_description ( struct x509_certificate *cert,
- const struct asn1_cursor *raw ) {
- struct asn1_cursor cursor;
- struct asn1_cursor subcursor;
- struct x509_access_method *method;
- int rc;
-
- /* Enter keyPurposeId */
- memcpy ( &cursor, raw, sizeof ( cursor ) );
- asn1_enter ( &cursor, ASN1_SEQUENCE );
-
- /* Try to identify access method */
- memcpy ( &subcursor, &cursor, sizeof ( subcursor ) );
- asn1_enter ( &subcursor, ASN1_OID );
- method = x509_find_access_method ( &subcursor );
- asn1_skip_any ( &cursor );
- DBGC2 ( cert, "X509 %p found access method %s\n",
- cert, ( method ? method->name : "<unknown>" ) );
-
- /* Parse access location, if applicable */
- if ( method && ( ( rc = method->parse ( cert, &cursor ) ) != 0 ) )
- return rc;
-
- return 0;
-}
-
-/**
- * Parse X.509 certificate authority information access
- *
- * @v cert X.509 certificate
- * @v raw ASN.1 cursor
- * @ret rc Return status code
- */
-static int x509_parse_authority_info_access ( struct x509_certificate *cert,
- const struct asn1_cursor *raw ) {
- struct asn1_cursor cursor;
- int rc;
-
- /* Enter authorityInfoAccess */
- memcpy ( &cursor, raw, sizeof ( cursor ) );
- asn1_enter ( &cursor, ASN1_SEQUENCE );
-
- /* Parse each access description in turn */
- while ( cursor.len ) {
- if ( ( rc = x509_parse_access_description ( cert,
- &cursor ) ) != 0 )
- return rc;
- asn1_skip_any ( &cursor );
- }
-
- return 0;
-}
-
-/**
- * Parse X.509 certificate subject alternative name
- *
- * @v cert X.509 certificate
- * @v raw ASN.1 cursor
- * @ret rc Return status code
- */
-static int x509_parse_subject_alt_name ( struct x509_certificate *cert,
- const struct asn1_cursor *raw ) {
- struct x509_subject_alt_name *alt_name = &cert->extensions.alt_name;
- struct asn1_cursor *names = &alt_name->names;
- int rc;
-
- /* Enter subjectAltName */
- memcpy ( names, raw, sizeof ( *names ) );
- if ( ( rc = asn1_enter ( names, ASN1_SEQUENCE ) ) != 0 ) {
- DBGC ( cert, "X509 %p invalid subjectAltName: %s\n",
- cert, strerror ( rc ) );
- DBGC_HDA ( cert, 0, raw->data, raw->len );
- return rc;
- }
- DBGC2 ( cert, "X509 %p has subjectAltName:\n", cert );
- DBGC2_HDA ( cert, 0, names->data, names->len );
-
- return 0;
-}
-
-/** "id-ce-basicConstraints" object identifier */
-static uint8_t oid_ce_basic_constraints[] =
- { ASN1_OID_BASICCONSTRAINTS };
-
-/** "id-ce-keyUsage" object identifier */
-static uint8_t oid_ce_key_usage[] =
- { ASN1_OID_KEYUSAGE };
-
-/** "id-ce-extKeyUsage" object identifier */
-static uint8_t oid_ce_ext_key_usage[] =
- { ASN1_OID_EXTKEYUSAGE };
-
-/** "id-pe-authorityInfoAccess" object identifier */
-static uint8_t oid_pe_authority_info_access[] =
- { ASN1_OID_AUTHORITYINFOACCESS };
-
-/** "id-ce-subjectAltName" object identifier */
-static uint8_t oid_ce_subject_alt_name[] =
- { ASN1_OID_SUBJECTALTNAME };
-
-/** Supported certificate extensions */
-static struct x509_extension x509_extensions[] = {
- {
- .name = "basicConstraints",
- .oid = ASN1_OID_CURSOR ( oid_ce_basic_constraints ),
- .parse = x509_parse_basic_constraints,
- },
- {
- .name = "keyUsage",
- .oid = ASN1_OID_CURSOR ( oid_ce_key_usage ),
- .parse = x509_parse_key_usage,
- },
- {
- .name = "extKeyUsage",
- .oid = ASN1_OID_CURSOR ( oid_ce_ext_key_usage ),
- .parse = x509_parse_extended_key_usage,
- },
- {
- .name = "authorityInfoAccess",
- .oid = ASN1_OID_CURSOR ( oid_pe_authority_info_access ),
- .parse = x509_parse_authority_info_access,
- },
- {
- .name = "subjectAltName",
- .oid = ASN1_OID_CURSOR ( oid_ce_subject_alt_name ),
- .parse = x509_parse_subject_alt_name,
- },
-};
-
-/**
- * Identify X.509 extension by OID
- *
- * @v oid OID
- * @ret extension Extension, or NULL
- */
-static struct x509_extension *
-x509_find_extension ( const struct asn1_cursor *oid ) {
- struct x509_extension *extension;
- unsigned int i;
-
- for ( i = 0 ; i < ( sizeof ( x509_extensions ) /
- sizeof ( x509_extensions[0] ) ) ; i++ ) {
- extension = &x509_extensions[i];
- if ( asn1_compare ( &extension->oid, oid ) == 0 )
- return extension;
- }
-
- return NULL;
-}
-
-/**
- * Parse X.509 certificate extension
- *
- * @v cert X.509 certificate
- * @v raw ASN.1 cursor
- * @ret rc Return status code
- */
-static int x509_parse_extension ( struct x509_certificate *cert,
- const struct asn1_cursor *raw ) {
- struct asn1_cursor cursor;
- struct asn1_cursor subcursor;
- struct x509_extension *extension;
- int is_critical = 0;
- int rc;
-
- /* Enter extension */
- memcpy ( &cursor, raw, sizeof ( cursor ) );
- asn1_enter ( &cursor, ASN1_SEQUENCE );
-
- /* Try to identify extension */
- memcpy ( &subcursor, &cursor, sizeof ( subcursor ) );
- asn1_enter ( &subcursor, ASN1_OID );
- extension = x509_find_extension ( &subcursor );
- asn1_skip_any ( &cursor );
- DBGC2 ( cert, "X509 %p found extension %s\n",
- cert, ( extension ? extension->name : "<unknown>" ) );
-
- /* Identify criticality */
- if ( asn1_type ( &cursor ) == ASN1_BOOLEAN ) {
- is_critical = asn1_boolean ( &cursor );
- if ( is_critical < 0 ) {
- rc = is_critical;
- DBGC ( cert, "X509 %p cannot parse extension "
- "criticality: %s\n", cert, strerror ( rc ) );
- DBGC_HDA ( cert, 0, raw->data, raw->len );
- return rc;
- }
- asn1_skip_any ( &cursor );
- }
-
- /* Handle unknown extensions */
- if ( ! extension ) {
- if ( is_critical ) {
- /* Fail if we cannot handle a critical extension */
- DBGC ( cert, "X509 %p cannot handle critical "
- "extension:\n", cert );
- DBGC_HDA ( cert, 0, raw->data, raw->len );
- return -ENOTSUP_EXTENSION;
- } else {
- /* Ignore unknown non-critical extensions */
- return 0;
- }
- };
-
- /* Extract extnValue */
- if ( ( rc = asn1_enter ( &cursor, ASN1_OCTET_STRING ) ) != 0 ) {
- DBGC ( cert, "X509 %p extension missing extnValue:\n", cert );
- DBGC_HDA ( cert, 0, raw->data, raw->len );
- return rc;
- }
-
- /* Parse extension */
- if ( ( rc = extension->parse ( cert, &cursor ) ) != 0 )
- return rc;
-
- return 0;
-}
-
-/**
- * Parse X.509 certificate extensions, if present
- *
- * @v cert X.509 certificate
- * @v raw ASN.1 cursor
- * @ret rc Return status code
- */
-static int x509_parse_extensions ( struct x509_certificate *cert,
- const struct asn1_cursor *raw ) {
- struct asn1_cursor cursor;
- int rc;
-
- /* Enter extensions, if present */
- memcpy ( &cursor, raw, sizeof ( cursor ) );
- asn1_enter ( &cursor, ASN1_EXPLICIT_TAG ( 3 ) );
- asn1_enter ( &cursor, ASN1_SEQUENCE );
-
- /* Parse each extension in turn */
- while ( cursor.len ) {
- if ( ( rc = x509_parse_extension ( cert, &cursor ) ) != 0 )
- return rc;
- asn1_skip_any ( &cursor );
- }
-
- return 0;
-}
-
-/**
- * Parse X.509 certificate tbsCertificate
- *
- * @v cert X.509 certificate
- * @v raw ASN.1 cursor
- * @ret rc Return status code
- */
-static int x509_parse_tbscertificate ( struct x509_certificate *cert,
- const struct asn1_cursor *raw ) {
- struct asn1_algorithm **algorithm = &cert->signature_algorithm;
- struct asn1_cursor cursor;
- int rc;
-
- /* Record raw tbsCertificate */
- memcpy ( &cursor, raw, sizeof ( cursor ) );
- asn1_shrink_any ( &cursor );
- memcpy ( &cert->tbs, &cursor, sizeof ( cert->tbs ) );
-
- /* Enter tbsCertificate */
- asn1_enter ( &cursor, ASN1_SEQUENCE );
-
- /* Parse version, if present */
- if ( asn1_type ( &cursor ) == ASN1_EXPLICIT_TAG ( 0 ) ) {
- if ( ( rc = x509_parse_version ( cert, &cursor ) ) != 0 )
- return rc;
- asn1_skip_any ( &cursor );
- }
-
- /* Parse serialNumber */
- if ( ( rc = x509_parse_serial ( cert, &cursor ) ) != 0 )
- return rc;
- asn1_skip_any ( &cursor );
-
- /* Parse signature */
- if ( ( rc = asn1_signature_algorithm ( &cursor, algorithm ) ) != 0 ) {
- DBGC ( cert, "X509 %p could not parse signature algorithm: "
- "%s\n", cert, strerror ( rc ) );
- return rc;
- }
- DBGC2 ( cert, "X509 %p tbsCertificate signature algorithm is %s\n",
- cert, (*algorithm)->name );
- asn1_skip_any ( &cursor );
-
- /* Parse issuer */
- if ( ( rc = x509_parse_issuer ( cert, &cursor ) ) != 0 )
- return rc;
- asn1_skip_any ( &cursor );
-
- /* Parse validity */
- if ( ( rc = x509_parse_validity ( cert, &cursor ) ) != 0 )
- return rc;
- asn1_skip_any ( &cursor );
-
- /* Parse subject */
- if ( ( rc = x509_parse_subject ( cert, &cursor ) ) != 0 )
- return rc;
- asn1_skip_any ( &cursor );
-
- /* Parse subjectPublicKeyInfo */
- if ( ( rc = x509_parse_public_key ( cert, &cursor ) ) != 0 )
- return rc;
- asn1_skip_any ( &cursor );
-
- /* Parse extensions, if present */
- if ( ( rc = x509_parse_extensions ( cert, &cursor ) ) != 0 )
- return rc;
-
- return 0;
-}
-
-/**
- * Parse X.509 certificate from ASN.1 data
- *
- * @v cert X.509 certificate
- * @v raw ASN.1 cursor
- * @ret rc Return status code
- */
-int x509_parse ( struct x509_certificate *cert,
- const struct asn1_cursor *raw ) {
- struct x509_signature *signature = &cert->signature;
- struct asn1_algorithm **signature_algorithm = &signature->algorithm;
- struct asn1_bit_string *signature_value = &signature->value;
- struct asn1_cursor cursor;
- int rc;
-
- /* Record raw certificate */
- memcpy ( &cursor, raw, sizeof ( cursor ) );
- memcpy ( &cert->raw, &cursor, sizeof ( cert->raw ) );
-
- /* Enter certificate */
- asn1_enter ( &cursor, ASN1_SEQUENCE );
-
- /* Parse tbsCertificate */
- if ( ( rc = x509_parse_tbscertificate ( cert, &cursor ) ) != 0 )
- return rc;
- asn1_skip_any ( &cursor );
-
- /* Parse signatureAlgorithm */
- if ( ( rc = asn1_signature_algorithm ( &cursor,
- signature_algorithm ) ) != 0 ) {
- DBGC ( cert, "X509 %p could not parse signature algorithm: "
- "%s\n", cert, strerror ( rc ) );
- return rc;
- }
- DBGC2 ( cert, "X509 %p signatureAlgorithm is %s\n",
- cert, (*signature_algorithm)->name );
- asn1_skip_any ( &cursor );
-
- /* Parse signatureValue */
- if ( ( rc = asn1_integral_bit_string ( &cursor,
- signature_value ) ) != 0 ) {
- DBGC ( cert, "X509 %p could not parse signature value: %s\n",
- cert, strerror ( rc ) );
- return rc;
- }
- DBGC2 ( cert, "X509 %p signatureValue is:\n", cert );
- DBGC2_HDA ( cert, 0, signature_value->data, signature_value->len );
-
- /* Check that algorithm in tbsCertificate matches algorithm in
- * signature
- */
- if ( signature->algorithm != (*signature_algorithm) ) {
- DBGC ( cert, "X509 %p signature algorithm %s does not match "
- "signatureAlgorithm %s\n",
- cert, signature->algorithm->name,
- (*signature_algorithm)->name );
- return -EINVAL_ALGORITHM_MISMATCH;
- }
-
- return 0;
-}
-
-/**
- * Create X.509 certificate
- *
- * @v data Raw certificate data
- * @v len Length of raw data
- * @ret cert X.509 certificate
- * @ret rc Return status code
- *
- * On success, the caller holds a reference to the X.509 certificate,
- * and is responsible for ultimately calling x509_put().
- */
-int x509_certificate ( const void *data, size_t len,
- struct x509_certificate **cert ) {
- struct asn1_cursor cursor;
- void *raw;
- int rc;
-
- /* Initialise cursor */
- cursor.data = data;
- cursor.len = len;
- asn1_shrink_any ( &cursor );
-
- /* Return stored certificate, if present */
- if ( ( *cert = certstore_find ( &cursor ) ) != NULL ) {
-
- /* Add caller's reference */
- x509_get ( *cert );
- return 0;
- }
-
- /* Allocate and initialise certificate */
- *cert = zalloc ( sizeof ( **cert ) + cursor.len );
- if ( ! *cert )
- return -ENOMEM;
- ref_init ( &(*cert)->refcnt, NULL );
- raw = ( *cert + 1 );
-
- /* Copy raw data */
- memcpy ( raw, cursor.data, cursor.len );
- cursor.data = raw;
-
- /* Parse certificate */
- if ( ( rc = x509_parse ( *cert, &cursor ) ) != 0 ) {
- x509_put ( *cert );
- *cert = NULL;
- return rc;
- }
-
- /* Add certificate to store */
- certstore_add ( *cert );
-
- return 0;
-}
-
-/**
- * Check X.509 certificate signature
- *
- * @v cert X.509 certificate
- * @v public_key X.509 public key
- * @ret rc Return status code
- */
-static int x509_check_signature ( struct x509_certificate *cert,
- struct x509_public_key *public_key ) {
- struct x509_signature *signature = &cert->signature;
- struct asn1_algorithm *algorithm = signature->algorithm;
- struct digest_algorithm *digest = algorithm->digest;
- struct pubkey_algorithm *pubkey = algorithm->pubkey;
- uint8_t digest_ctx[ digest->ctxsize ];
- uint8_t digest_out[ digest->digestsize ];
- uint8_t pubkey_ctx[ pubkey->ctxsize ];
- int rc;
-
- /* Sanity check */
- assert ( cert->signature_algorithm == cert->signature.algorithm );
-
- /* Calculate certificate digest */
- digest_init ( digest, digest_ctx );
- digest_update ( digest, digest_ctx, cert->tbs.data, cert->tbs.len );
- digest_final ( digest, digest_ctx, digest_out );
- DBGC2 ( cert, "X509 %p \"%s\" digest:\n", cert, x509_name ( cert ) );
- DBGC2_HDA ( cert, 0, digest_out, sizeof ( digest_out ) );
-
- /* Check that signature public key algorithm matches signer */
- if ( public_key->algorithm->pubkey != pubkey ) {
- DBGC ( cert, "X509 %p \"%s\" signature algorithm %s does not "
- "match signer's algorithm %s\n",
- cert, x509_name ( cert ), algorithm->name,
- public_key->algorithm->name );
- rc = -EINVAL_ALGORITHM_MISMATCH;
- goto err_mismatch;
- }
-
- /* Verify signature using signer's public key */
- if ( ( rc = pubkey_init ( pubkey, pubkey_ctx, public_key->raw.data,
- public_key->raw.len ) ) != 0 ) {
- DBGC ( cert, "X509 %p \"%s\" cannot initialise public key: "
- "%s\n", cert, x509_name ( cert ), strerror ( rc ) );
- goto err_pubkey_init;
- }
- if ( ( rc = pubkey_verify ( pubkey, pubkey_ctx, digest, digest_out,
- signature->value.data,
- signature->value.len ) ) != 0 ) {
- DBGC ( cert, "X509 %p \"%s\" signature verification failed: "
- "%s\n", cert, x509_name ( cert ), strerror ( rc ) );
- goto err_pubkey_verify;
- }
-
- /* Success */
- rc = 0;
-
- err_pubkey_verify:
- pubkey_final ( pubkey, pubkey_ctx );
- err_pubkey_init:
- err_mismatch:
- return rc;
-}
-
-/**
- * Check X.509 certificate against issuer certificate
- *
- * @v cert X.509 certificate
- * @v issuer X.509 issuer certificate
- * @ret rc Return status code
- */
-int x509_check_issuer ( struct x509_certificate *cert,
- struct x509_certificate *issuer ) {
- struct x509_public_key *public_key = &issuer->subject.public_key;
- int rc;
-
- /* Check issuer. In theory, this should be a full X.500 DN
- * comparison, which would require support for a plethora of
- * abominations such as TeletexString (which allows the
- * character set to be changed mid-string using escape codes).
- * In practice, we assume that anyone who deliberately changes
- * the encoding of the issuer DN is probably a masochist who
- * will rather enjoy the process of figuring out exactly why
- * their certificate doesn't work.
- *
- * See http://www.cs.auckland.ac.nz/~pgut001/pubs/x509guide.txt
- * for some enjoyable ranting on this subject.
- */
- if ( asn1_compare ( &cert->issuer.raw, &issuer->subject.raw ) != 0 ) {
- DBGC ( cert, "X509 %p \"%s\" issuer does not match ",
- cert, x509_name ( cert ) );
- DBGC ( cert, "X509 %p \"%s\" subject\n",
- issuer, x509_name ( issuer ) );
- DBGC_HDA ( cert, 0, cert->issuer.raw.data,
- cert->issuer.raw.len );
- DBGC_HDA ( issuer, 0, issuer->subject.raw.data,
- issuer->subject.raw.len );
- return -EACCES_WRONG_ISSUER;
- }
-
- /* Check that issuer is allowed to sign certificates */
- if ( ! issuer->extensions.basic.ca ) {
- DBGC ( issuer, "X509 %p \"%s\" cannot sign ",
- issuer, x509_name ( issuer ) );
- DBGC ( issuer, "X509 %p \"%s\": not a CA certificate\n",
- cert, x509_name ( cert ) );
- return -EACCES_NOT_CA;
- }
- if ( issuer->extensions.usage.present &&
- ( ! ( issuer->extensions.usage.bits & X509_KEY_CERT_SIGN ) ) ) {
- DBGC ( issuer, "X509 %p \"%s\" cannot sign ",
- issuer, x509_name ( issuer ) );
- DBGC ( issuer, "X509 %p \"%s\": no keyCertSign usage\n",
- cert, x509_name ( cert ) );
- return -EACCES_KEY_USAGE;
- }
-
- /* Check signature */
- if ( ( rc = x509_check_signature ( cert, public_key ) ) != 0 )
- return rc;
-
- return 0;
-}
-
-/**
- * Calculate X.509 certificate fingerprint
- *
- * @v cert X.509 certificate
- * @v digest Digest algorithm
- * @v fingerprint Fingerprint buffer
- */
-void x509_fingerprint ( struct x509_certificate *cert,
- struct digest_algorithm *digest,
- void *fingerprint ) {
- uint8_t ctx[ digest->ctxsize ];
-
- /* Calculate fingerprint */
- digest_init ( digest, ctx );
- digest_update ( digest, ctx, cert->raw.data, cert->raw.len );
- digest_final ( digest, ctx, fingerprint );
-}
-
-/**
- * Check X.509 root certificate
- *
- * @v cert X.509 certificate
- * @v root X.509 root certificate list
- * @ret rc Return status code
- */
-int x509_check_root ( struct x509_certificate *cert, struct x509_root *root ) {
- struct digest_algorithm *digest = root->digest;
- uint8_t fingerprint[ digest->digestsize ];
- const uint8_t *root_fingerprint = root->fingerprints;
- unsigned int i;
-
- /* Calculate certificate fingerprint */
- x509_fingerprint ( cert, digest, fingerprint );
-
- /* Check fingerprint against all root certificates */
- for ( i = 0 ; i < root->count ; i++ ) {
- if ( memcmp ( fingerprint, root_fingerprint,
- sizeof ( fingerprint ) ) == 0 ) {
- DBGC ( cert, "X509 %p \"%s\" is a root certificate\n",
- cert, x509_name ( cert ) );
- return 0;
- }
- root_fingerprint += sizeof ( fingerprint );
- }
-
- DBGC2 ( cert, "X509 %p \"%s\" is not a root certificate\n",
- cert, x509_name ( cert ) );
- return -ENOENT;
-}
-
-/**
- * Check X.509 certificate validity period
- *
- * @v cert X.509 certificate
- * @v time Time at which to check certificate
- * @ret rc Return status code
- */
-int x509_check_time ( struct x509_certificate *cert, time_t time ) {
- struct x509_validity *validity = &cert->validity;
-
- /* Check validity period */
- if ( validity->not_before.time > ( time + TIMESTAMP_ERROR_MARGIN ) ) {
- DBGC ( cert, "X509 %p \"%s\" is not yet valid (at time %lld)\n",
- cert, x509_name ( cert ), time );
- return -EACCES_EXPIRED;
- }
- if ( validity->not_after.time < ( time - TIMESTAMP_ERROR_MARGIN ) ) {
- DBGC ( cert, "X509 %p \"%s\" has expired (at time %lld)\n",
- cert, x509_name ( cert ), time );
- return -EACCES_EXPIRED;
- }
-
- DBGC2 ( cert, "X509 %p \"%s\" is valid (at time %lld)\n",
- cert, x509_name ( cert ), time );
- return 0;
-}
-
-/**
- * Validate X.509 certificate
- *
- * @v cert X.509 certificate
- * @v issuer Issuing X.509 certificate (or NULL)
- * @v time Time at which to validate certificate
- * @v root Root certificate list, or NULL to use default
- * @ret rc Return status code
- *
- * The issuing certificate must have already been validated.
- *
- * Validation results are cached: if a certificate has already been
- * successfully validated then @c issuer, @c time, and @c root will be
- * ignored.
- */
-int x509_validate ( struct x509_certificate *cert,
- struct x509_certificate *issuer,
- time_t time, struct x509_root *root ) {
- unsigned int max_path_remaining;
- int rc;
-
- /* Use default root certificate store if none specified */
- if ( ! root )
- root = &root_certificates;
-
- /* Return success if certificate has already been validated */
- if ( cert->valid )
- return 0;
-
- /* Fail if certificate is invalid at specified time */
- if ( ( rc = x509_check_time ( cert, time ) ) != 0 )
- return rc;
-
- /* Succeed if certificate is a trusted root certificate */
- if ( x509_check_root ( cert, root ) == 0 ) {
- cert->valid = 1;
- cert->path_remaining = ( cert->extensions.basic.path_len + 1 );
- return 0;
- }
-
- /* Fail unless we have an issuer */
- if ( ! issuer ) {
- DBGC2 ( cert, "X509 %p \"%s\" has no issuer\n",
- cert, x509_name ( cert ) );
- return -EACCES_UNTRUSTED;
- }
-
- /* Fail unless issuer has already been validated */
- if ( ! issuer->valid ) {
- DBGC ( cert, "X509 %p \"%s\" ", cert, x509_name ( cert ) );
- DBGC ( cert, "issuer %p \"%s\" has not yet been validated\n",
- issuer, x509_name ( issuer ) );
- return -EACCES_OUT_OF_ORDER;
- }
-
- /* Fail if issuing certificate cannot validate this certificate */
- if ( ( rc = x509_check_issuer ( cert, issuer ) ) != 0 )
- return rc;
-
- /* Fail if path length constraint is violated */
- if ( issuer->path_remaining == 0 ) {
- DBGC ( cert, "X509 %p \"%s\" ", cert, x509_name ( cert ) );
- DBGC ( cert, "issuer %p \"%s\" path length exceeded\n",
- issuer, x509_name ( issuer ) );
- return -EACCES_PATH_LEN;
- }
-
- /* Fail if OCSP is required */
- if ( cert->extensions.auth_info.ocsp.uri.len &&
- ( ! cert->extensions.auth_info.ocsp.good ) ) {
- DBGC ( cert, "X509 %p \"%s\" requires an OCSP check\n",
- cert, x509_name ( cert ) );
- return -EACCES_OCSP_REQUIRED;
- }
-
- /* Calculate effective path length */
- cert->path_remaining = ( issuer->path_remaining - 1 );
- max_path_remaining = ( cert->extensions.basic.path_len + 1 );
- if ( cert->path_remaining > max_path_remaining )
- cert->path_remaining = max_path_remaining;
-
- /* Mark certificate as valid */
- cert->valid = 1;
-
- DBGC ( cert, "X509 %p \"%s\" successfully validated using ",
- cert, x509_name ( cert ) );
- DBGC ( cert, "issuer %p \"%s\"\n", issuer, x509_name ( issuer ) );
- return 0;
-}
-
-/**
- * Check X.509 certificate alternative dNSName
- *
- * @v cert X.509 certificate
- * @v raw ASN.1 cursor
- * @v name Name
- * @ret rc Return status code
- */
-static int x509_check_dnsname ( struct x509_certificate *cert,
- const struct asn1_cursor *raw,
- const char *name ) {
- const char *fullname = name;
- const char *dnsname = raw->data;
- size_t len = raw->len;
-
- /* Check for wildcards */
- if ( ( len >= 2 ) && ( dnsname[0] == '*' ) && ( dnsname[1] == '.' ) ) {
-
- /* Skip initial "*." */
- dnsname += 2;
- len -= 2;
-
- /* Skip initial portion of name to be tested */
- name = strchr ( name, '.' );
- if ( ! name )
- return -ENOENT;
- name++;
- }
-
- /* Compare names */
- if ( ! ( ( strlen ( name ) == len ) &&
- ( memcmp ( name, dnsname, len ) == 0 ) ) )
- return -ENOENT;
-
- if ( name != fullname ) {
- DBGC2 ( cert, "X509 %p \"%s\" found wildcard match for "
- "\"*.%s\"\n", cert, x509_name ( cert ), name );
- }
- return 0;
-}
-
-/**
- * Check X.509 certificate alternative iPAddress
- *
- * @v cert X.509 certificate
- * @v raw ASN.1 cursor
- * @v name Name
- * @ret rc Return status code
- */
-static int x509_check_ipaddress ( struct x509_certificate *cert,
- const struct asn1_cursor *raw,
- const char *name ) {
- struct sockaddr sa;
- sa_family_t family;
- const void *address;
- int rc;
-
- /* Determine address family */
- if ( raw->len == sizeof ( struct in_addr ) ) {
- struct sockaddr_in *sin = ( ( struct sockaddr_in * ) &sa );
- family = AF_INET;
- address = &sin->sin_addr;
- } else if ( raw->len == sizeof ( struct in6_addr ) ) {
- struct sockaddr_in6 *sin6 = ( ( struct sockaddr_in6 * ) &sa );
- family = AF_INET6;
- address = &sin6->sin6_addr;
- } else {
- DBGC ( cert, "X509 %p \"%s\" has iPAddress with unexpected "
- "length %zd\n", cert, x509_name ( cert ), raw->len );
- DBGC_HDA ( cert, 0, raw->data, raw->len );
- return -EINVAL;
- }
-
- /* Attempt to convert name to a socket address */
- if ( ( rc = sock_aton ( name, &sa ) ) != 0 ) {
- DBGC2 ( cert, "X509 %p \"%s\" cannot parse \"%s\" as "
- "iPAddress: %s\n", cert, x509_name ( cert ), name,
- strerror ( rc ) );
- return rc;
- }
- if ( sa.sa_family != family )
- return -ENOENT;
-
- /* Compare addresses */
- if ( memcmp ( address, raw->data, raw->len ) != 0 )
- return -ENOENT;
-
- DBGC2 ( cert, "X509 %p \"%s\" found iPAddress match for \"%s\"\n",
- cert, x509_name ( cert ), sock_ntoa ( &sa ) );
- return 0;
-}
-
-/**
- * Check X.509 certificate alternative name
- *
- * @v cert X.509 certificate
- * @v raw ASN.1 cursor
- * @v name Name
- * @ret rc Return status code
- */
-static int x509_check_alt_name ( struct x509_certificate *cert,
- const struct asn1_cursor *raw,
- const char *name ) {
- struct asn1_cursor alt_name;
- unsigned int type;
-
- /* Enter generalName */
- memcpy ( &alt_name, raw, sizeof ( alt_name ) );
- type = asn1_type ( &alt_name );
- asn1_enter_any ( &alt_name );
-
- /* Check this name */
- switch ( type ) {
- case X509_GENERAL_NAME_DNS :
- return x509_check_dnsname ( cert, &alt_name, name );
- case X509_GENERAL_NAME_IP :
- return x509_check_ipaddress ( cert, &alt_name, name );
- default:
- DBGC2 ( cert, "X509 %p \"%s\" unknown name of type %#02x:\n",
- cert, x509_name ( cert ), type );
- DBGC2_HDA ( cert, 0, alt_name.data, alt_name.len );
- return -ENOTSUP;
- }
-}
-
-/**
- * Check X.509 certificate name
- *
- * @v cert X.509 certificate
- * @v name Name
- * @ret rc Return status code
- */
-int x509_check_name ( struct x509_certificate *cert, const char *name ) {
- struct asn1_cursor *common_name = &cert->subject.common_name;
- struct asn1_cursor alt_name;
- int rc;
-
- /* Check commonName */
- if ( x509_check_dnsname ( cert, common_name, name ) == 0 ) {
- DBGC2 ( cert, "X509 %p \"%s\" commonName matches \"%s\"\n",
- cert, x509_name ( cert ), name );
- return 0;
- }
-
- /* Check any subjectAlternativeNames */
- memcpy ( &alt_name, &cert->extensions.alt_name.names,
- sizeof ( alt_name ) );
- for ( ; alt_name.len ; asn1_skip_any ( &alt_name ) ) {
- if ( ( rc = x509_check_alt_name ( cert, &alt_name,
- name ) ) == 0 ) {
- DBGC2 ( cert, "X509 %p \"%s\" subjectAltName matches "
- "\"%s\"\n", cert, x509_name ( cert ), name );
- return 0;
- }
- }
-
- DBGC ( cert, "X509 %p \"%s\" does not match name \"%s\"\n",
- cert, x509_name ( cert ), name );
- return -EACCES_WRONG_NAME;
-}
-
-/**
- * Free X.509 certificate chain
- *
- * @v refcnt Reference count
- */
-static void x509_free_chain ( struct refcnt *refcnt ) {
- struct x509_chain *chain =
- container_of ( refcnt, struct x509_chain, refcnt );
- struct x509_link *link;
- struct x509_link *tmp;
-
- DBGC2 ( chain, "X509 chain %p freed\n", chain );
-
- /* Free each link in the chain */
- list_for_each_entry_safe ( link, tmp, &chain->links, list ) {
- x509_put ( link->cert );
- list_del ( &link->list );
- free ( link );
- }
-
- /* Free chain */
- free ( chain );
-}
-
-/**
- * Allocate X.509 certificate chain
- *
- * @ret chain X.509 certificate chain, or NULL
- */
-struct x509_chain * x509_alloc_chain ( void ) {
- struct x509_chain *chain;
-
- /* Allocate chain */
- chain = zalloc ( sizeof ( *chain ) );
- if ( ! chain )
- return NULL;
-
- /* Initialise chain */
- ref_init ( &chain->refcnt, x509_free_chain );
- INIT_LIST_HEAD ( &chain->links );
-
- DBGC2 ( chain, "X509 chain %p allocated\n", chain );
- return chain;
-}
-
-/**
- * Append X.509 certificate to X.509 certificate chain
- *
- * @v chain X.509 certificate chain
- * @v cert X.509 certificate
- * @ret rc Return status code
- */
-int x509_append ( struct x509_chain *chain, struct x509_certificate *cert ) {
- struct x509_link *link;
-
- /* Allocate link */
- link = zalloc ( sizeof ( *link ) );
- if ( ! link )
- return -ENOMEM;
-
- /* Add link to chain */
- link->cert = x509_get ( cert );
- list_add_tail ( &link->list, &chain->links );
- DBGC ( chain, "X509 chain %p added X509 %p \"%s\"\n",
- chain, cert, x509_name ( cert ) );
-
- return 0;
-}
-
-/**
- * Append X.509 certificate to X.509 certificate chain
- *
- * @v chain X.509 certificate chain
- * @v data Raw certificate data
- * @v len Length of raw data
- * @ret rc Return status code
- */
-int x509_append_raw ( struct x509_chain *chain, const void *data,
- size_t len ) {
- struct x509_certificate *cert;
- int rc;
-
- /* Parse certificate */
- if ( ( rc = x509_certificate ( data, len, &cert ) ) != 0 )
- goto err_parse;
-
- /* Append certificate to chain */
- if ( ( rc = x509_append ( chain, cert ) ) != 0 )
- goto err_append;
-
- /* Drop reference to certificate */
- x509_put ( cert );
-
- return 0;
-
- err_append:
- x509_put ( cert );
- err_parse:
- return rc;
-}
-
-/**
- * Identify X.509 certificate by subject
- *
- * @v certs X.509 certificate list
- * @v subject Subject
- * @ret cert X.509 certificate, or NULL if not found
- */
-static struct x509_certificate *
-x509_find_subject ( struct x509_chain *certs,
- const struct asn1_cursor *subject ) {
- struct x509_link *link;
- struct x509_certificate *cert;
-
- /* Scan through certificate list */
- list_for_each_entry ( link, &certs->links, list ) {
-
- /* Check subject */
- cert = link->cert;
- if ( asn1_compare ( subject, &cert->subject.raw ) == 0 )
- return cert;
- }
-
- return NULL;
-}
-
-/**
- * Append X.509 certificates to X.509 certificate chain
- *
- * @v chain X.509 certificate chain
- * @v certs X.509 certificate list
- * @ret rc Return status code
- *
- * Certificates will be automatically appended to the chain based upon
- * the subject and issuer names.
- */
-int x509_auto_append ( struct x509_chain *chain, struct x509_chain *certs ) {
- struct x509_certificate *cert;
- struct x509_certificate *previous;
- int rc;
-
- /* Get current certificate */
- cert = x509_last ( chain );
- if ( ! cert ) {
- DBGC ( chain, "X509 chain %p has no certificates\n", chain );
- return -EACCES_EMPTY;
- }
-
- /* Append certificates, in order */
- while ( 1 ) {
-
- /* Find issuing certificate */
- previous = cert;
- cert = x509_find_subject ( certs, &cert->issuer.raw );
- if ( ! cert )
- break;
- if ( cert == previous )
- break;
-
- /* Append certificate to chain */
- if ( ( rc = x509_append ( chain, cert ) ) != 0 )
- return rc;
- }
-
- return 0;
-}
-
-/**
- * Validate X.509 certificate chain
- *
- * @v chain X.509 certificate chain
- * @v time Time at which to validate certificates
- * @v store Certificate store, or NULL to use default
- * @v root Root certificate list, or NULL to use default
- * @ret rc Return status code
- */
-int x509_validate_chain ( struct x509_chain *chain, time_t time,
- struct x509_chain *store, struct x509_root *root ) {
- struct x509_certificate *issuer = NULL;
- struct x509_link *link;
- int rc;
-
- /* Use default certificate store if none specified */
- if ( ! store )
- store = &certstore;
-
- /* Append any applicable certificates from the certificate store */
- if ( ( rc = x509_auto_append ( chain, store ) ) != 0 )
- return rc;
-
- /* Find first certificate that can be validated as a
- * standalone (i.e. is already valid, or can be validated as
- * a trusted root certificate).
- */
- list_for_each_entry ( link, &chain->links, list ) {
-
- /* Try validating this certificate as a standalone */
- if ( ( rc = x509_validate ( link->cert, NULL, time,
- root ) ) != 0 )
- continue;
-
- /* Work back up to start of chain, performing pairwise
- * validation.
- */
- issuer = link->cert;
- list_for_each_entry_continue_reverse ( link, &chain->links,
- list ) {
-
- /* Validate this certificate against its issuer */
- if ( ( rc = x509_validate ( link->cert, issuer, time,
- root ) ) != 0 )
- return rc;
- issuer = link->cert;
- }
-
- return 0;
- }
-
- DBGC ( chain, "X509 chain %p found no usable certificates\n", chain );
- return -EACCES_USELESS;
-}
-
-/* Drag in objects via x509_validate() */
-REQUIRING_SYMBOL ( x509_validate );
-
-/* Drag in certificate store */
-REQUIRE_OBJECT ( certstore );
-
-/* Drag in crypto configuration */
-REQUIRE_OBJECT ( config_crypto );