iPXE
pubkey_test.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2024 Michael Brown <mbrown@fensystems.co.uk>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
22 */
23
24FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25
26/** @file
27 *
28 * Public key self-tests
29 *
30 */
31
32/* Forcibly enable assertions */
33#undef NDEBUG
34
35#include <stdint.h>
36#include <stdlib.h>
37#include <string.h>
38#include <assert.h>
39#include <ipxe/crypto.h>
40#include <ipxe/test.h>
41#include "pubkey_test.h"
42
43/**
44 * Report public key encryption and decryption test result
45 *
46 * @v test Public key encryption and decryption test
47 * @v file Test code file
48 * @v line Test code line
49 */
50void pubkey_okx ( struct pubkey_test *test, const char *file,
51 unsigned int line ) {
52 struct pubkey_algorithm *pubkey = test->pubkey;
53 struct asn1_builder plaintext;
54 struct asn1_builder ciphertext;
55
56 /* Test key matching */
57 okx ( pubkey_match ( pubkey, &test->private, &test->public ) == 0,
58 file, line );
59
60 /* Test decrypting with private key to obtain known plaintext */
61 plaintext.data = NULL;
62 plaintext.len = 0;
63 okx ( pubkey_decrypt ( pubkey, &test->private, &test->ciphertext,
64 &plaintext ) == 0, file, line );
65 okx ( asn1_compare ( asn1_built ( &plaintext ),
66 &test->plaintext ) == 0, file, line );
67 free ( plaintext.data );
68
69 /* Test encrypting with private key and decrypting with public key */
70 ciphertext.data = NULL;
71 ciphertext.len = 0;
72 plaintext.data = NULL;
73 plaintext.len = 0;
74 okx ( pubkey_encrypt ( pubkey, &test->private, &test->plaintext,
75 &ciphertext ) == 0, file, line );
76 okx ( pubkey_decrypt ( pubkey, &test->public,
77 asn1_built ( &ciphertext ),
78 &plaintext ) == 0, file, line );
79 okx ( asn1_compare ( asn1_built ( &plaintext ),
80 &test->plaintext ) == 0, file, line );
81 free ( ciphertext.data );
82 free ( plaintext.data );
83
84 /* Test encrypting with public key and decrypting with private key */
85 ciphertext.data = NULL;
86 ciphertext.len = 0;
87 plaintext.data = NULL;
88 plaintext.len = 0;
89 okx ( pubkey_encrypt ( pubkey, &test->public, &test->plaintext,
90 &ciphertext ) == 0, file, line );
91 okx ( pubkey_decrypt ( pubkey, &test->private,
92 asn1_built ( &ciphertext ),
93 &plaintext ) == 0, file, line );
94 okx ( asn1_compare ( asn1_built ( &plaintext ),
95 &test->plaintext ) == 0, file, line );
96 free ( ciphertext.data );
97 free ( plaintext.data );
98}
99
100/**
101 * Report public key signature test result
102 *
103 * @v test Public key signature test
104 * @v file Test code file
105 * @v line Test code line
106 */
107void pubkey_sign_okx ( struct pubkey_sign_test *test, const char *file,
108 unsigned int line ) {
109 struct pubkey_algorithm *pubkey = test->pubkey;
110 struct digest_algorithm *digest = test->digest;
111 uint8_t digestctx[digest->ctxsize];
112 uint8_t digestout[digest->digestsize];
113 uint8_t signature[test->signature.len];
114 struct asn1_cursor cursor = { signature, sizeof ( signature ) };
115 struct asn1_builder builder = { NULL, 0 };
116 uint8_t *bad;
117
118 /* Test key matching */
119 okx ( pubkey_match ( pubkey, &test->private, &test->public ) == 0,
120 file, line );
121
122 /* Construct digest over plaintext */
123 digest_init ( digest, digestctx );
124 digest_update ( digest, digestctx, test->plaintext,
125 test->plaintext_len );
126 digest_final ( digest, digestctx, digestout );
127
128 /* Test verification using public key */
129 okx ( pubkey_verify ( pubkey, &test->public, digest, digestout,
130 &test->signature ) == 0, file, line );
131
132 /* Test verification failure of modified signature */
133 memcpy ( signature, test->signature.data, sizeof ( signature ) );
134 bad = ( signature + ( sizeof ( signature ) / 2 ) );
135 *bad ^= 0x40;
136 okx ( pubkey_verify ( pubkey, &test->public, digest, digestout,
137 &cursor ) != 0, file, line );
138 *bad ^= 0x40;
139 okx ( pubkey_verify ( pubkey, &test->public, digest, digestout,
140 &cursor ) == 0, file, line );
141
142 /* Test signing using private key */
143 okx ( pubkey_sign ( pubkey, &test->private, digest, digestout,
144 &builder ) == 0, file, line );
145 okx ( builder.len != 0, file, line );
146 okx ( asn1_compare ( asn1_built ( &builder ), &test->signature ) == 0,
147 file, line );
148
149 /* Test verification of constructed signature */
150 okx ( pubkey_verify ( pubkey, &test->public, digest, digestout,
151 asn1_built ( &builder ) ) == 0, file, line );
152
153 /* Free signature */
154 free ( builder.data );
155}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
u8 signature
CPU signature.
Definition CIB_PRM.h:7
unsigned char uint8_t
Definition stdint.h:10
int asn1_compare(const struct asn1_cursor *cursor1, const struct asn1_cursor *cursor2)
Compare two ASN.1 objects.
Definition asn1.c:458
static struct asn1_cursor * asn1_built(struct asn1_builder *builder)
Get cursor for built object.
Definition asn1.h:492
Assertions.
static int test
Definition epic100.c:73
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
Cryptographic API.
static int pubkey_match(struct pubkey_algorithm *pubkey, const struct asn1_cursor *private_key, const struct asn1_cursor *public_key)
Definition crypto.h:315
static void digest_init(struct digest_algorithm *digest, void *ctx)
Definition crypto.h:219
static void digest_final(struct digest_algorithm *digest, void *ctx, void *out)
Definition crypto.h:230
static int pubkey_encrypt(struct pubkey_algorithm *pubkey, const struct asn1_cursor *key, const struct asn1_cursor *plaintext, struct asn1_builder *ciphertext)
Definition crypto.h:287
static int pubkey_verify(struct pubkey_algorithm *pubkey, const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value, const struct asn1_cursor *signature)
Definition crypto.h:308
static void digest_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Definition crypto.h:224
static int pubkey_decrypt(struct pubkey_algorithm *pubkey, const struct asn1_cursor *key, const struct asn1_cursor *ciphertext, struct asn1_builder *plaintext)
Definition crypto.h:294
static int pubkey_sign(struct pubkey_algorithm *pubkey, const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value, struct asn1_builder *signature)
Definition crypto.h:301
String functions.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void pubkey_okx(struct pubkey_test *test, const char *file, unsigned int line)
Report public key encryption and decryption test result.
Definition pubkey_test.c:50
void pubkey_sign_okx(struct pubkey_sign_test *test, const char *file, unsigned int line)
Report public key signature test result.
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
An ASN.1 object builder.
Definition asn1.h:29
void * data
Data.
Definition asn1.h:36
size_t len
Length of data.
Definition asn1.h:38
An ASN.1 object cursor.
Definition asn1.h:21
A message digest algorithm.
Definition crypto.h:19
size_t digestsize
Digest size.
Definition crypto.h:27
size_t ctxsize
Context size.
Definition crypto.h:23
A public key algorithm.
Definition crypto.h:122
A public-key signature test.
Definition pubkey_test.h:30
A public-key encryption and decryption test.
Definition pubkey_test.h:11
Self-test infrastructure.
#define okx(success, file, line)
Report test result.
Definition test.h:44