/
githubmirror
/
ipxe
Обзор
Документация
Войти
/
githubmirror
/
ipxe
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/tests/pubkey_test.c
204 строки
6 KB
Michael Brown
[test] Use mock random data for public key self-tests
06 май 2026, 23:43
06 май 2026, 23:43
7fe8b7f
Код
Авторство
О чём код?
/* * Copyright (C) 2024 Michael Brown <mbrown@fensystems.co.uk>. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. * * You can also choose to distribute this program under the terms of * the Unmodified Binary Distribution Licence (as given in the file * COPYING.UBDL), provided that you have satisfied its requirements. */ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); /** @file * * Public key self-tests * */ /* Forcibly enable assertions */ #undef NDEBUG #include <stdint.h> #include <stdlib.h> #include <string.h> #include <assert.h> #include <ipxe/crypto.h> #include <ipxe/test.h> #include "pubkey_test.h" /** Random data input */ static const uint8_t *pubkey_random; /** Length of random data input */ static size_t pubkey_random_len; /** * Get random data input * * @v data Output buffer * @v len Length of output buffer * @ret rc Return status code */ int pubkey_test_get_random ( void *data, size_t len ) { /* Sanity check */ assert ( len <= pubkey_random_len ); /* Return random data */ memcpy ( data, pubkey_random, len ); /* Consume random data */ pubkey_random += len; pubkey_random_len -= len; return 0; } /** * Report public key encryption and decryption test result * * @v test Public key encryption and decryption test * @v file Test code file * @v line Test code line */ void pubkey_okx ( struct pubkey_test *test, const char *file, unsigned int line ) { struct pubkey_algorithm *pubkey = test->pubkey; struct asn1_builder plaintext; struct asn1_builder ciphertext; /* Test key matching */ okx ( pubkey_match ( pubkey, &test->private, &test->public ) == 0, file, line ); /* Test encrypting with public key to obtain known ciphertext */ ciphertext.data = NULL; ciphertext.len = 0; pubkey_random = test->random; pubkey_random_len = test->random_len; okx ( pubkey_encrypt ( pubkey, &test->public, &test->plaintext, &ciphertext ) == 0, file, line ); okx ( pubkey_random_len == 0, file, line ); okx ( asn1_compare ( asn1_built ( &ciphertext ), &test->ciphertext ) == 0, file, line ); free ( ciphertext.data ); /* Test decrypting with private key to obtain known plaintext */ plaintext.data = NULL; plaintext.len = 0; okx ( pubkey_decrypt ( pubkey, &test->private, &test->ciphertext, &plaintext ) == 0, file, line ); okx ( asn1_compare ( asn1_built ( &plaintext ), &test->plaintext ) == 0, file, line ); free ( plaintext.data ); /* Test encrypting with private key and decrypting with public key */ ciphertext.data = NULL; ciphertext.len = 0; plaintext.data = NULL; plaintext.len = 0; pubkey_random = test->random; pubkey_random_len = test->random_len; okx ( pubkey_encrypt ( pubkey, &test->private, &test->plaintext, &ciphertext ) == 0, file, line ); okx ( pubkey_random_len == 0, file, line ); okx ( pubkey_decrypt ( pubkey, &test->public, asn1_built ( &ciphertext ), &plaintext ) == 0, file, line ); okx ( asn1_compare ( asn1_built ( &plaintext ), &test->plaintext ) == 0, file, line ); free ( ciphertext.data ); free ( plaintext.data ); /* Test encrypting with public key and decrypting with private key */ ciphertext.data = NULL; ciphertext.len = 0; plaintext.data = NULL; plaintext.len = 0; pubkey_random = test->random; pubkey_random_len = test->random_len; okx ( pubkey_encrypt ( pubkey, &test->public, &test->plaintext, &ciphertext ) == 0, file, line ); okx ( pubkey_random_len == 0, file, line ); okx ( pubkey_decrypt ( pubkey, &test->private, asn1_built ( &ciphertext ), &plaintext ) == 0, file, line ); okx ( asn1_compare ( asn1_built ( &plaintext ), &test->plaintext ) == 0, file, line ); free ( ciphertext.data ); free ( plaintext.data ); } /** * Report public key signature test result * * @v test Public key signature test * @v file Test code file * @v line Test code line */ void pubkey_sign_okx ( struct pubkey_sign_test *test, const char *file, unsigned int line ) { struct pubkey_algorithm *pubkey = test->pubkey; struct digest_algorithm *digest = test->digest; uint8_t digestctx[digest->ctxsize]; uint8_t digestout[digest->digestsize]; uint8_t signature[test->signature.len]; struct asn1_cursor cursor = { signature, sizeof ( signature ) }; struct asn1_builder builder = { NULL, 0 }; uint8_t *bad; /* Test key matching */ okx ( pubkey_match ( pubkey, &test->private, &test->public ) == 0, file, line ); /* Construct digest over plaintext */ digest_init ( digest, digestctx ); digest_update ( digest, digestctx, test->plaintext, test->plaintext_len ); digest_final ( digest, digestctx, digestout ); /* Test verification using public key */ okx ( pubkey_verify ( pubkey, &test->public, digest, digestout, &test->signature ) == 0, file, line ); /* Test verification failure of modified signature */ memcpy ( signature, test->signature.data, sizeof ( signature ) ); bad = ( signature + ( sizeof ( signature ) / 2 ) ); *bad ^= 0x40; okx ( pubkey_verify ( pubkey, &test->public, digest, digestout, &cursor ) != 0, file, line ); *bad ^= 0x40; okx ( pubkey_verify ( pubkey, &test->public, digest, digestout, &cursor ) == 0, file, line ); /* Test signing using private key */ pubkey_random = test->random; pubkey_random_len = test->random_len; okx ( pubkey_sign ( pubkey, &test->private, digest, digestout, &builder ) == 0, file, line ); okx ( pubkey_random_len == 0, file, line ); okx ( builder.len != 0, file, line ); okx ( asn1_compare ( asn1_built ( &builder ), &test->signature ) == 0, file, line ); /* Test verification of constructed signature */ okx ( pubkey_verify ( pubkey, &test->public, digest, digestout, asn1_built ( &builder ) ) == 0, file, line ); /* Free signature */ free ( builder.data ); }