#include <time.h>
#include <ipxe/tables.h>
#include <ipxe/image.h>
+#include <ipxe/crypto.h>
#include <ipxe/asn1.h>
/** @file
*
* @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 );
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;
}
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 */
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 */
*
* @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 */
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 */
int rc;
/* Parse algorithm */
- if ( ( rc = asn1_algorithm ( cursor, &actual ) ) != 0 )
+ if ( ( rc = asn1_algorithm ( cursor, &actual, NULL ) ) != 0 )
return rc;
/* Check algorithm matches */
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
*
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 */
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 );