aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2024-08-26 23:36:06 +0100
committerMichael Brown <mcb30@ipxe.org>2024-08-28 13:03:55 +0100
commit4b4a362f0713ffa08c9236d66a1881d6234d7717 (patch)
tree70fca07b5f66b4b66a47fe405a04b577c150add4
parentbdb5b4aef46ed34b47094652f3eefc7d0463d166 (diff)
downloadipxe-4b4a362f0713ffa08c9236d66a1881d6234d7717.tar.gz
[crypto] Allow for extraction of ASN.1 algorithm parameters
Some ASN.1 OID-identified algorithms require additional parameters, such as an initialisation vector for a block cipher. The structure of the parameters is defined by the individual algorithm. Extend asn1_algorithm() to allow these additional parameters to be returned via a separate ASN.1 cursor. Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r--src/crypto/asn1.c78
-rw-r--r--src/crypto/mishmash/oid_aes_cbc.c3
-rw-r--r--src/crypto/mishmash/oid_aes_gcm.c3
-rw-r--r--src/include/ipxe/asn1.h19
4 files changed, 92 insertions, 11 deletions
diff --git a/src/crypto/asn1.c b/src/crypto/asn1.c
index 0e5b1a9dd..aa57c6a8b 100644
--- a/src/crypto/asn1.c
+++ b/src/crypto/asn1.c
@@ -32,6 +32,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <time.h>
#include <ipxe/tables.h>
#include <ipxe/image.h>
+#include <ipxe/crypto.h>
#include <ipxe/asn1.h>
/** @file
@@ -509,18 +510,26 @@ asn1_find_algorithm ( const struct asn1_cursor *cursor ) {
*
* @v cursor ASN.1 object cursor
* @ret algorithm Algorithm
+ * @ret params Algorithm parameters, or NULL
* @ret rc Return status code
*/
int asn1_algorithm ( const struct asn1_cursor *cursor,
- struct asn1_algorithm **algorithm ) {
+ struct asn1_algorithm **algorithm,
+ struct asn1_cursor *params ) {
struct asn1_cursor contents;
int rc;
- /* Enter signatureAlgorithm */
+ /* Enter algorithm */
memcpy ( &contents, cursor, sizeof ( contents ) );
asn1_enter ( &contents, ASN1_SEQUENCE );
- /* Enter algorithm */
+ /* Get raw parameters, if applicable */
+ if ( params ) {
+ memcpy ( params, &contents, sizeof ( *params ) );
+ asn1_skip_any ( params );
+ }
+
+ /* Enter algorithm identifier */
if ( ( rc = asn1_enter ( &contents, ASN1_OID ) ) != 0 ) {
DBGC ( cursor, "ASN1 %p cannot locate algorithm OID:\n",
cursor );
@@ -536,6 +545,14 @@ int asn1_algorithm ( const struct asn1_cursor *cursor,
return -ENOTSUP_ALGORITHM;
}
+ /* Parse parameters, if applicable */
+ if ( params && (*algorithm)->parse &&
+ ( ( rc = (*algorithm)->parse ( *algorithm, params ) ) != 0 ) ) {
+ DBGC ( cursor, "ASN1 %p cannot parse %s parameters: %s\n",
+ cursor, (*algorithm)->name, strerror ( rc ) );
+ return rc;
+ }
+
return 0;
}
@@ -551,7 +568,7 @@ int asn1_pubkey_algorithm ( const struct asn1_cursor *cursor,
int rc;
/* Parse algorithm */
- if ( ( rc = asn1_algorithm ( cursor, algorithm ) ) != 0 )
+ if ( ( rc = asn1_algorithm ( cursor, algorithm, NULL ) ) != 0 )
return rc;
/* Check algorithm has a public key */
@@ -577,7 +594,7 @@ int asn1_digest_algorithm ( const struct asn1_cursor *cursor,
int rc;
/* Parse algorithm */
- if ( ( rc = asn1_algorithm ( cursor, algorithm ) ) != 0 )
+ if ( ( rc = asn1_algorithm ( cursor, algorithm, NULL ) ) != 0 )
return rc;
/* Check algorithm has a digest */
@@ -596,14 +613,16 @@ int asn1_digest_algorithm ( const struct asn1_cursor *cursor,
*
* @v cursor ASN.1 object cursor
* @ret algorithm Algorithm
+ * @ret params Algorithm parameters, or NULL
* @ret rc Return status code
*/
int asn1_cipher_algorithm ( const struct asn1_cursor *cursor,
- struct asn1_algorithm **algorithm ) {
+ struct asn1_algorithm **algorithm,
+ struct asn1_cursor *params ) {
int rc;
/* Parse algorithm */
- if ( ( rc = asn1_algorithm ( cursor, algorithm ) ) != 0 )
+ if ( ( rc = asn1_algorithm ( cursor, algorithm, params ) ) != 0 )
return rc;
/* Check algorithm has a cipher */
@@ -629,7 +648,7 @@ int asn1_signature_algorithm ( const struct asn1_cursor *cursor,
int rc;
/* Parse algorithm */
- if ( ( rc = asn1_algorithm ( cursor, algorithm ) ) != 0 )
+ if ( ( rc = asn1_algorithm ( cursor, algorithm, NULL ) ) != 0 )
return rc;
/* Check algorithm has a public key */
@@ -664,7 +683,7 @@ int asn1_check_algorithm ( const struct asn1_cursor *cursor,
int rc;
/* Parse algorithm */
- if ( ( rc = asn1_algorithm ( cursor, &actual ) ) != 0 )
+ if ( ( rc = asn1_algorithm ( cursor, &actual, NULL ) ) != 0 )
return rc;
/* Check algorithm matches */
@@ -678,6 +697,47 @@ int asn1_check_algorithm ( const struct asn1_cursor *cursor,
}
/**
+ * Parse ASN.1 CBC cipher parameters
+ *
+ * @v algorithm Algorithm
+ * @v param Parameters to parse
+ * @ret rc Return status code
+ */
+int asn1_parse_cbc ( struct asn1_algorithm *algorithm,
+ struct asn1_cursor *params ) {
+ struct cipher_algorithm *cipher = algorithm->cipher;
+
+ /* Sanity check */
+ assert ( cipher != NULL );
+
+ /* Enter parameters */
+ asn1_enter ( params, ASN1_OCTET_STRING );
+
+ /* Check length */
+ if ( params->len != cipher->blocksize )
+ return -EINVAL;
+
+ return 0;
+}
+
+/**
+ * Parse ASN.1 GCM cipher parameters
+ *
+ * @v algorithm Algorithm
+ * @v param Parameters to parse
+ * @ret rc Return status code
+ */
+int asn1_parse_gcm ( struct asn1_algorithm *algorithm __unused,
+ struct asn1_cursor *params ) {
+
+ /* Enter parameters */
+ asn1_enter ( params, ASN1_SEQUENCE );
+
+ /* Enter nonce */
+ return asn1_enter ( params, ASN1_OCTET_STRING );
+}
+
+/**
* Parse ASN.1 GeneralizedTime
*
* @v cursor ASN.1 cursor
diff --git a/src/crypto/mishmash/oid_aes_cbc.c b/src/crypto/mishmash/oid_aes_cbc.c
index 0a7951c63..b5f716574 100644
--- a/src/crypto/mishmash/oid_aes_cbc.c
+++ b/src/crypto/mishmash/oid_aes_cbc.c
@@ -40,6 +40,7 @@ struct asn1_algorithm aes_128_cbc_algorithm __asn1_algorithm = {
.name = "aes128-cbc",
.cipher = &aes_cbc_algorithm,
.oid = ASN1_CURSOR ( oid_aes_128_cbc ),
+ .parse = asn1_parse_cbc,
};
/** "aes192-cbc" OID-identified algorithm */
@@ -47,6 +48,7 @@ struct asn1_algorithm aes_192_cbc_algorithm __asn1_algorithm = {
.name = "aes192-cbc",
.cipher = &aes_cbc_algorithm,
.oid = ASN1_CURSOR ( oid_aes_192_cbc ),
+ .parse = asn1_parse_cbc,
};
/** "aes256-cbc" OID-identified algorithm */
@@ -54,4 +56,5 @@ struct asn1_algorithm aes_256_cbc_algorithm __asn1_algorithm = {
.name = "aes256-cbc",
.cipher = &aes_cbc_algorithm,
.oid = ASN1_CURSOR ( oid_aes_256_cbc ),
+ .parse = asn1_parse_cbc,
};
diff --git a/src/crypto/mishmash/oid_aes_gcm.c b/src/crypto/mishmash/oid_aes_gcm.c
index 0f94d5323..af1432d8e 100644
--- a/src/crypto/mishmash/oid_aes_gcm.c
+++ b/src/crypto/mishmash/oid_aes_gcm.c
@@ -40,6 +40,7 @@ struct asn1_algorithm aes_128_gcm_algorithm __asn1_algorithm = {
.name = "aes128-gcm",
.cipher = &aes_gcm_algorithm,
.oid = ASN1_CURSOR ( oid_aes_128_gcm ),
+ .parse = asn1_parse_gcm,
};
/** "aes192-gcm" OID-identified algorithm */
@@ -47,6 +48,7 @@ struct asn1_algorithm aes_192_gcm_algorithm __asn1_algorithm = {
.name = "aes192-gcm",
.cipher = &aes_gcm_algorithm,
.oid = ASN1_CURSOR ( oid_aes_192_gcm ),
+ .parse = asn1_parse_gcm,
};
/** "aes256-gcm" OID-identified algorithm */
@@ -54,4 +56,5 @@ struct asn1_algorithm aes_256_gcm_algorithm __asn1_algorithm = {
.name = "aes256-gcm",
.cipher = &aes_gcm_algorithm,
.oid = ASN1_CURSOR ( oid_aes_256_gcm ),
+ .parse = asn1_parse_gcm,
};
diff --git a/src/include/ipxe/asn1.h b/src/include/ipxe/asn1.h
index 26dc47992..fac94c52e 100644
--- a/src/include/ipxe/asn1.h
+++ b/src/include/ipxe/asn1.h
@@ -363,6 +363,15 @@ struct asn1_algorithm {
struct cipher_algorithm *cipher;
/** Elliptic curve (if applicable) */
struct elliptic_curve *curve;
+ /**
+ * Parse algorithm parameters (optional)
+ *
+ * @v algorithm Algorithm
+ * @v param Parameters to parse (and potentially modify)
+ * @ret rc Return status code
+ */
+ int ( * parse ) ( struct asn1_algorithm *algorithm,
+ struct asn1_cursor *params );
};
/** ASN.1 OID-identified algorithms */
@@ -467,17 +476,23 @@ extern int asn1_integral_bit_string ( const struct asn1_cursor *cursor,
extern int asn1_compare ( const struct asn1_cursor *cursor1,
const struct asn1_cursor *cursor2 );
extern int asn1_algorithm ( const struct asn1_cursor *cursor,
- struct asn1_algorithm **algorithm );
+ struct asn1_algorithm **algorithm,
+ struct asn1_cursor *params );
extern int asn1_pubkey_algorithm ( const struct asn1_cursor *cursor,
struct asn1_algorithm **algorithm );
extern int asn1_digest_algorithm ( const struct asn1_cursor *cursor,
struct asn1_algorithm **algorithm );
extern int asn1_cipher_algorithm ( const struct asn1_cursor *cursor,
- struct asn1_algorithm **algorithm );
+ struct asn1_algorithm **algorithm,
+ struct asn1_cursor *params );
extern int asn1_signature_algorithm ( const struct asn1_cursor *cursor,
struct asn1_algorithm **algorithm );
extern int asn1_check_algorithm ( const struct asn1_cursor *cursor,
struct asn1_algorithm *expected );
+extern int asn1_parse_cbc ( struct asn1_algorithm *algorithm,
+ struct asn1_cursor *params );
+extern int asn1_parse_gcm ( struct asn1_algorithm *algorithm,
+ struct asn1_cursor *params );
extern int asn1_generalized_time ( const struct asn1_cursor *cursor,
time_t *time );
extern int asn1_grow ( struct asn1_builder *builder, size_t extra );