]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[crypto] Allow for extraction of ASN.1 algorithm parameters
authorMichael Brown <mcb30@ipxe.org>
Mon, 26 Aug 2024 22:36:06 +0000 (23:36 +0100)
committerMichael Brown <mcb30@ipxe.org>
Wed, 28 Aug 2024 12:03:55 +0000 (13:03 +0100)
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>
src/crypto/asn1.c
src/crypto/mishmash/oid_aes_cbc.c
src/crypto/mishmash/oid_aes_gcm.c
src/include/ipxe/asn1.h

index 0e5b1a9dd05e852e38b5f3be764e1fa43be262a8..aa57c6a8bd8e68e58ca52b46e2ebea48a3e67ce2 100644 (file)
@@ -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 */
@@ -677,6 +696,47 @@ int asn1_check_algorithm ( const struct asn1_cursor *cursor,
        return 0;
 }
 
+/**
+ * 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
  *
index 0a7951c634e8d08b02d3836df84507e3754dffc3..b5f7165746d1c76736f7d50775071a8f48b4af3a 100644 (file)
@@ -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,
 };
index 0f94d5323897ef586f4d4217f0879f180268d43c..af1432d8ee01fbd96b6af9889bbf0e3a8d4767af 100644 (file)
@@ -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,
 };
index 26dc479921bf4a515976a777402175cb03a67caa..fac94c52e3a431ca4aedf55d147aa295247b2fcb 100644 (file)
@@ -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 );