Commit Graph

241 Commits (5220bdc5242877d8d6d457b5f4f6f5f3da78a833)

Author SHA1 Message Date
Michael Brown 688646fe6d [tls] Add GCM cipher suites
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2022-11-10 09:58:44 +00:00
Michael Brown 4acded7e57 [crypto] Support in-place decryption for GCM ciphers
The hash calculation is currently performed incorrectly when
decrypting in place, since the ciphertext will have been overwritten
with the plaintext before being used to update the hash value.

Restructure the code to allow for in-place encryption and decryption.
Choose to optimise for the decryption case, since we are likely to
decrypt much more data than we encrypt.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2022-11-10 09:58:37 +00:00
Michael Brown 63577207ab [crypto] Ensure relevant GCM cipher state is cleared by cipher_setiv()
Reset the accumulated authentication state when cipher_setiv() is
called, to allow the cipher to be reused without resetting the key.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2022-11-09 16:48:50 +00:00
Michael Brown 7256a6eb24 [tls] Allow handshake digest algorithm to be specified by cipher suite
All existing cipher suites use SHA-256 as the TLSv1.2 and above
handshake digest algorithm (even when using SHA-1 as the MAC digest
algorithm).  Some GCM cipher suites use SHA-384 as the handshake
digest algorithm.

Allow the cipher suite to specify the handshake (and PRF) digest
algorithm to be used for TLSv1.2 and above.

This requires some restructuring to allow for the fact that the
ClientHello message must be included within the handshake digest, even
though the relevant digest algorithm is not yet known at the point
that the ClientHello is sent.  Fortunately, the ClientHello may be
reproduced verbatim at the point of receiving the ServerHello, so we
rely on reconstructing (rather than storing) this message.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2022-11-09 14:49:42 +00:00
Michael Brown c453b4c284 [tls] Add MAC length as a cipher suite parameter
TLS stream and block ciphers use a MAC with a length equal to the
output length of the digest algorithm in use.  For AEAD ciphers there
is no MAC, with the equivalent functionality provided by the cipher
algorithm's authentication tag.

Allow for the existence of AEAD cipher suites by making the MAC length
a parameter of the cipher suite.

Assume that the MAC key length is equal to the MAC length, since this
is true for all currently supported cipher suites.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2022-11-08 14:09:18 +00:00
Michael Brown 30243ad739 [crypto] Add concept of cipher alignment size
The GCM cipher mode of operation (in common with other counter-based
modes of operation) has a notion of blocksize that does not neatly
fall into our current abstraction: it does operate in 16-byte blocks
but allows for an arbitrary overall data length (i.e. the final block
may be incomplete).

Model this by adding a concept of alignment size.  Each call to
encrypt() or decrypt() must begin at a multiple of the alignment size
from the start of the data stream.  This allows us to model GCM by
using a block size of 1 byte and an alignment size of 16 bytes.

As a side benefit, this same concept allows us to neatly model the
fact that raw AES can encrypt only a single 16-byte block, by
specifying an alignment size of zero on this cipher.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2022-11-07 11:19:48 +00:00
Michael Brown d1bc872a2e [tls] Formalise notions of fixed and record initialisation vectors
TLS block ciphers always use CBC (as per RFC 5246 section 6.2.3.2)
with a record initialisation vector length that is equal to the cipher
block size, and no fixed initialisation vector.

The initialisation vector for AEAD ciphers such as GCM is less
straightforward, and requires both a fixed and per-record component.

Extend the definition of a cipher suite to include fixed and record
initialisation vector lengths, and generate the fixed portion (if any)
as part of key expansion.

Do not add explicit calls to cipher_setiv() in tls_assemble_block()
and tls_split_block(), since the constraints imposed by RFC 5246 are
specifically chosen to allow implementations to avoid doing so.
(Instead, add a sanity check that the record initialisation vector
length is equal to the cipher block size.)

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2022-11-07 11:19:48 +00:00
Michael Brown 8fce26730c [crypto] Add block cipher Galois/Counter mode of operation
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2022-10-25 13:21:30 +01:00
Michael Brown da81214cec [crypto] Add concept of authentication tag to cipher algorithms
Some ciphers (such as GCM) support the concept of a tag that can be
used to authenticate the encrypted data.  Add a cipher method for
generating an authentication tag.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2022-10-25 13:21:30 +01:00
Michael Brown 8e478e648f [crypto] Allow initialisation vector length to vary from cipher blocksize
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2022-10-25 13:21:28 +01:00
Michael Brown 52f72d298a [crypto] Expose null crypto algorithm methods for reuse
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2022-10-25 13:20:22 +01:00
Michael Brown 2c78242732 [tls] Add support for DHE variants of the existing cipher suites
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2022-10-11 15:42:13 +01:00
Michael Brown ea33ea33c0 [tls] Add key exchange mechanism to definition of cipher suite
Allow for the key exchange mechanism to vary depending upon the
selected cipher suite.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2022-10-11 14:37:12 +01:00
Michael Brown 18b861024a [crypto] Add Ephemeral Diffie-Hellman key exchange algorithm
Add an implementation of the Ephemeral Diffie-Hellman key exchange
algorithm as defined in RFC2631, with test vectors taken from the NIST
Cryptographic Toolkit.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2022-10-11 14:33:19 +01:00
Michael Brown 007d3cb800 [crypto] Simplify internal HMAC API
Simplify the internal HMAC API so that the key is provided only at the
point of calling hmac_init(), and the (potentially reduced) key is
stored as part of the context for later use by hmac_final().

This simplifies the calling code, and avoids the need for callers such
as TLS to allocate a potentially variable length block in order to
retain a copy of the unmodified key.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2022-10-10 12:21:54 +01:00
Michael Brown fc8bd4ba1a [x509] Use case-insensitive comparison for certificate names
DNS names are case-insensitive, and RFC 5280 (unlike RFC 3280)
mandates support for case-insensitive name comparison in X.509
certificates.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2021-05-18 11:46:28 +01:00
Josh McSavaney 68f1914aae [x509] Clarify debug message for an untrusted X.509 issuer
We surface this debugging information in cases where a cert actually
lacks an issuer, but also in cases where it *has* an issuer, but we
cannot trust it (e.g. due to issues in establishing a trust chain).

Signed-off-by: Josh McSavaney <me@mcsau.cc>
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-12-28 18:18:58 +00:00
Michael Brown f43a8f8b9f [crypto] Allow private key to be specified as a TLS connection parameter
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-12-15 16:54:06 +00:00
Michael Brown 3475f9162b [x509] Make root of trust a reference-counted structure
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-12-09 16:45:50 +00:00
Michael Brown 39f5293492 [x509] Record root of trust used when validating a certificate
Record the root of trust used at the point that a certificate is
validated, redefine validation as checking a certificate against a
specific root of trust, and pass an explicit root of trust when
creating a TLS connection.

This allows a custom TLS connection to be used with a custom root of
trust, without causing any validated certificates to be treated as
valid for normal purposes.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-12-08 15:04:28 +00:00
Michael Brown 6e92d6213d [ocsp] Remove dummy OCSP certificate root
OCSP currently calls x509_validate() with an empty root certificate
list, on the basis that the OCSP signer certificate (if existent) must
be signed directly by the issuer certificate.

Using an empty root certificate list is not required to achieve this
goal, since x509_validate() already accepts an explicit issuer
certificate parameter.  The explicit empty root certificate list
merely prevents the signer certificate from being evaluated as a
potential trusted root certificate.

Remove the dummy OCSP root certificate list and use the default root
certificate list when calling x509_validate().

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-12-08 15:04:28 +00:00
Michael Brown e4b6328c84 [asn1] Rename ASN1_OID_CURSOR to ASN1_CURSOR
There is nothing OID-specific about the ASN1_OID_CURSOR macro.  Rename
to allow it to be used for constructing ASN.1 cursors with arbitrary
contents.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-12-08 12:38:45 +00:00
Daniel Johnson 8bc85ec6fa [deflate] Fix typo in comment describing length codes
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-07-21 15:59:04 +01:00
Michael Brown 3f637d7462 [ocsp] Accept SHA1 certID responses even if SHA1 is not enabled
Various implementation quirks in OCSP servers make it impractical to
use anything other than SHA1 to construct the issuerNameHash and
issuerKeyHash identifiers in the request certID.  For example: both
the OpenCA OCSP responder used by ipxe.org and the Boulder OCSP
responder used by LetsEncrypt will fail if SHA256 is used in the
request certID.

As of commit 6ffe28a ("[ocsp] Accept response certID with missing
hashAlgorithm parameters") we rely on asn1_digest_algorithm() to parse
the algorithm identifier in the response certID.  This will fail if
SHA1 is disabled via config/crypto.h.

Fix by using a direct ASN.1 object comparison on the OID within the
algorithm identifier.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-06-25 13:04:54 +01:00
Michael Brown bd7a5e4b9c [crypto] Allow algorithms to be included without being OID-identifiable
There are many ways in which the object for a cryptographic algorithm
may be included, even if not explicitly enabled in config/crypto.h.
For example: the MD5 algorithm is required by TLSv1.1 or earlier, by
iSCSI CHAP authentication, by HTTP digest authentication, and by NTLM
authentication.

In the current implementation, inclusion of an algorithm for any
reason will result in the algorithm's ASN.1 object identifier being
included in the "asn1_algorithms" table, which consequently allows the
algorithm to be used for any ASN1-identified purpose.  For example: if
the MD5 algorithm is included in order to support HTTP digest
authentication, then iPXE would accept a (validly signed) TLS
certificate using an MD5 digest.

Split the ASN.1 object identifiers into separate files that are
required only if explicitly enabled in config/crypto.h.  This allows
an algorithm to be omitted from the "asn1_algorithms" table even if
the algorithm implementation is dragged in for some other purpose.

The end result is that only the algorithms that are explicitly enabled
in config/crypto.h can be used for ASN1-identified purposes such as
signature verification.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2020-06-16 17:14:54 +01:00
Michael Brown 0cc12f053c [crypto] Profile the various stages of modular multiplication
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2019-08-17 01:24:51 +01:00
Michael Brown 131635eac0 [crypto] Drag in configured digestInfo prefixes for any use of RSA
Ensure that the configured RSA digestInfo prefixes are included in any
build that includes rsa.o (rather than relying on x509.o or tls.o also
being present in the final binary).

This allows the RSA self-tests to be run in isolation.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2019-08-17 01:18:34 +01:00
Michael Brown b6ffe28a21 [ocsp] Accept response certID with missing hashAlgorithm parameters
One of the design goals of ASN.1 DER is to provide a canonical
serialization of a data structure, thereby allowing for equality of
values to be tested by simply comparing the serialized bytes.

Some OCSP servers will modify the request certID to omit the optional
(and null) "parameters" portion of the hashAlgorithm.  This is
arguably legal but breaks the ability to perform a straightforward
bitwise comparison on the entire certID field between request and
response.

Fix by comparing the OID-identified hashAlgorithm separately from the
remaining certID fields.

Originally-fixed-by: Thilo Fromm <Thilo@kinvolk.io>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2019-03-10 18:13:52 +00:00
Michael Brown 36a4c85f91 [init] Show startup and shutdown function names in debug messages
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2019-01-25 14:53:43 +00:00
Michael Brown 0d35411f88 [rng] Use fixed-point calculations for min-entropy quantities
We currently perform various min-entropy calculations using build-time
floating-point arithmetic.  No floating-point code ends up in the
final binary, since the results are eventually converted to integers
and asserted to be compile-time constants.

Though this mechanism is undoubtedly cute, it inhibits us from using
"-mno-sse" to prevent the use of SSE registers by the compiler.

Fix by using fixed-point arithmetic instead.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2018-03-20 20:56:01 +02:00
Michael Brown a0021a30dd [ocsp] Centralise test for whether or not an OCSP check is required
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2018-03-18 22:25:01 +02:00
Michael Brown fc2f0dd930 [ntlm] Add support for NTLM authentication mechanism
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2017-11-12 18:52:03 +00:00
Michael Brown 0077b0933d [crypto] Add MD4 message digest algorithm
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2017-11-12 18:52:03 +00:00
Michael Brown 32d54691e9 [crypto] Eliminate repetitions in MD5 round constant table
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2017-11-12 18:52:03 +00:00
Michael Brown fb6b66ce13 [crypto] Fix endianness typo in comment
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2017-11-11 23:45:31 +00:00
Michael Brown e5bfa107ba [crypto] Expose asn1_grow()
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2017-06-20 09:49:00 +01:00
Michael Brown 5b608bbfe0 [crypto] Expose RSA_CTX_SIZE constant
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2017-06-20 09:49:00 +01:00
Michael Brown 827dd1bfee [crypto] Mark permanent certificates as permanent
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2016-08-31 17:23:42 +01:00
Michael Brown 1e277ab062 [crypto] Add certstat() to display basic certificate information
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2016-08-31 15:41:15 +01:00
Michael Brown 9a1a42f283 [crypto] Allow certificates to be marked as having been added explicitly
Allow certificates to be marked as having been added explicitly at run
time.  Such certificates will not be discarded via the certificate
store cache discarder.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2016-08-31 15:41:02 +01:00
Michael Brown 534eae4d92 [crypto] Expose certstore_del() to explicitly remove stored certificates
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2016-08-31 15:17:31 +01:00
Michael Brown ff28b22568 [crypto] Generalise X.509 "valid" field to a "flags" field
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2016-08-25 15:41:57 +01:00
Michael Brown e564a4e7d6 [crypto] Add image_x509() to extract X.509 certificates from image
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2016-08-25 15:41:25 +01:00
Michael Brown 942b798c8d [crypto] Enable both DER and PEM formats by default
Enable both IMAGE_DER and IMAGE_PEM by default, and drag in the
relevant objects only when image_asn1() is present in the binary.

This allows "imgverify" to transparently use either DER or PEM
signature files.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2016-07-29 15:40:39 +01:00
Michael Brown 296670a648 [crypto] Allow for parsing of partial ASN.1 cursors
Allow code to create a partial ASN.1 cursor containing only the type
and length bytes, so that asn1_start() may be used to determine the
length of a large ASN.1 blob without first allocating memory to hold
the entire blob.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2016-07-28 15:02:15 +01:00
Michael Brown 2a187f480e [arm] Avoid instruction references to symbols defined via ".equ"
When building for 64-bit ARM, some symbol references may be resolved
via an "adrp" instruction (to obtain the start of the 4kB page
containing the symbol) and a separate 12-bit offset.  For example
(taken from the GNU assembler documentation):

  adrp x0, foo
  ldr  x0, [x0, #:lo12:foo]

We occasionally refer to symbols defined via mechanisms that are not
directly visible to gcc.  For example:

  extern char some_magic_symbol[];
  __asm__ ( ".equ some_magic_symbol, some_magic_expression" );

The subsequent use of the ":lo12:" prefix on such magically-defined
symbols triggers an assertion failure in the assembler.

This problem seems to affect only "private_key_len" in the current
codebase.  Fix by storing this value as static data; this avoids the
need to provide the value as a literal within the instruction stream,
and so avoids the problematic use of the ":lo12:" prefix.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2016-05-08 00:08:48 +01:00
Michael Brown 0141ea3a77 [crypto] Allow trusted certificates to be stored in non-volatile options
The intention of the existing code (as documented in its own comments)
is that it should be possible to override the list of trusted root
certificates using a "trust" setting held in non-volatile stored
options.  However, the rootcert_init() function currently executes
before any devices have been probed, and so will not be able to
retrieve any such non-volatile stored options.

Fix by executing rootcert_init() only after devices have been probed.
Since startup functions may be executed multiple times (unlike
initialisation functions), add an explicit flag to preserve the
property that rootcert_init() should run only once.

As before, if an explicit root of trust is specified at build time,
then any runtime "trust" setting will be ignored.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2016-03-20 17:26:09 +00:00
Michael Brown 1f65ed53da [build] Allow assembler section type character to vary by architecture
On some architectures (such as ARM) the "@" character is used as a
comment delimiter.  A section type argument such as "@progbits"
therefore becomes "%progbits".

This is further complicated by the fact that the "%" character has
special meaning for inline assembly when input or output operands are
used, in which cases "@progbits" becomes "%%progbits".

Allow the section type character(s) to be defined via Makefile
variables.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2016-03-13 11:20:53 +00:00
Michael Brown 5a6ed90a00 [crypto] Allow for zero-length ASN.1 cursors
The assumption in asn1_type() that an ASN.1 cursor will always contain
a type byte is incorrect.  A cursor that has been cleanly invalidated
via asn1_invalidate_cursor() will contain a type byte, but there are
other ways in which to arrive at a zero-length cursor.

Fix by explicitly checking the cursor length in asn1_type().  This
allows asn1_invalidate_cursor() to be reduced to simply zeroing the
length field.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2016-03-11 16:58:51 +00:00
Michael Brown 42c2a6aab7 [ocsp] Avoid including a double path separator in request URI
The OCSP responder URI included within an X.509 certificate may or may
not include a trailing slash.  We currently rely on the fact that
format_uri() incorrectly inserts an initial slash, which we include
unconditionally within the OCSP request URI.

Switch to using uri_encode() directly, and insert a slash only if the
X.509 certificate's OCSP responder URI does not already include a
trailing slash.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2016-01-21 17:50:34 +00:00