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 
24 FILE_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  */
50 void 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  */
107 void 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  struct asn1_builder signature = { NULL, 0 };
114  uint8_t *bad;
115 
116  /* Test key matching */
117  okx ( pubkey_match ( pubkey, &test->private, &test->public ) == 0,
118  file, line );
119 
120  /* Construct digest over plaintext */
121  digest_init ( digest, digestctx );
122  digest_update ( digest, digestctx, test->plaintext,
123  test->plaintext_len );
124  digest_final ( digest, digestctx, digestout );
125 
126  /* Test signing using private key */
127  okx ( pubkey_sign ( pubkey, &test->private, digest, digestout,
128  &signature ) == 0, file, line );
129  okx ( signature.len != 0, file, line );
131  &test->signature ) == 0, file, line );
132 
133  /* Test verification using public key */
134  okx ( pubkey_verify ( pubkey, &test->public, digest, digestout,
135  &test->signature ) == 0, file, line );
136 
137  /* Test verification failure of modified signature */
138  bad = ( signature.data + ( test->signature.len / 2 ) );
139  okx ( pubkey_verify ( pubkey, &test->public, digest, digestout,
140  asn1_built ( &signature ) ) == 0, file, line );
141  *bad ^= 0x40;
142  okx ( pubkey_verify ( pubkey, &test->public, digest, digestout,
143  asn1_built ( &signature ) ) != 0, file, line );
144 
145  /* Free signature */
146  free ( signature.data );
147 }
static void digest_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Definition: crypto.h:201
void * data
Data.
Definition: asn1.h:35
int asn1_compare(const struct asn1_cursor *cursor1, const struct asn1_cursor *cursor2)
Compare two ASN.1 objects.
Definition: asn1.c:447
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
static void digest_final(struct digest_algorithm *digest, void *ctx, void *out)
Definition: crypto.h:207
A public-key encryption and decryption test.
Definition: pubkey_test.h:11
Self-test infrastructure.
Cryptographic API.
void pubkey_sign_okx(struct pubkey_sign_test *test, const char *file, unsigned int line)
Report public key signature test result.
Definition: pubkey_test.c:107
static int pubkey_match(struct pubkey_algorithm *pubkey, const struct asn1_cursor *private_key, const struct asn1_cursor *public_key)
Definition: crypto.h:292
A public-key signature test.
Definition: pubkey_test.h:30
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:278
#define okx(success, file, line)
Report test result.
Definition: test.h:44
Assertions.
static void digest_init(struct digest_algorithm *digest, void *ctx)
Definition: crypto.h:196
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
An ASN.1 object builder.
Definition: asn1.h:28
unsigned char uint8_t
Definition: stdint.h:10
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
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:285
size_t ctxsize
Context size.
Definition: crypto.h:22
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:264
size_t digestsize
Digest size.
Definition: crypto.h:26
A message digest algorithm.
Definition: crypto.h:18
static struct asn1_cursor * asn1_built(struct asn1_builder *builder)
Get cursor for built object.
Definition: asn1.h:467
u8 signature
CPU signature.
Definition: CIB_PRM.h:35
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
size_t len
Length of data.
Definition: asn1.h:37
String functions.
A public key algorithm.
Definition: crypto.h:121
static int test
Definition: epic100.c:73
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:271