// SPDX-License-Identifier: GPL-2.0 // // In Samsung R&D Institute Ukraine, LLC (SRUKR) under a contract between // Samsung R&D Institute Ukraine, LLC (Kyiv, Ukraine) // and "Samsung Electronics Co", Ltd (Seoul, Republic of Korea) // Copyright: (c) Samsung Electronics Co, Ltd 2024. All rights reserved. // #include #include #include #define TEST_MAX_LEN_DATA 48 #define TEST_MAX_LEN_ENTROPY 48 #define TEST_MAX_LEN_STR 128 struct drbg_testvec { const unsigned char entropy[TEST_MAX_LEN_ENTROPY]; size_t entropylen; const unsigned char entpra[TEST_MAX_LEN_ENTROPY]; const unsigned char entprb[TEST_MAX_LEN_ENTROPY]; size_t entprlen; const unsigned char addtla[TEST_MAX_LEN_DATA]; const unsigned char addtlb[TEST_MAX_LEN_DATA]; size_t addtllen; const unsigned char pers[TEST_MAX_LEN_STR]; size_t perslen; const unsigned char expected[TEST_MAX_LEN_STR]; size_t expectedlen; }; struct drbg_test_suite { const struct drbg_testvec *vecs; size_t tv_count; }; static const struct drbg_testvec drbg_pr_hmac_sha256_tv_template[] = { { .entropy = "\x99\x69\xe5\x4b\x47\x03\xff\x31\x78\x5b\x87\x9a" "\x7e\x5c\x0e\xae\x0d\x3e\x30\x95\x59\xe9\xfe\x96" "\xb0\x67\x6d\x49\xd5\x91\xea\x4d\x07\xd2\x0d\x46" "\xd0\x64\x75\x7d\x30\x23\xca\xc2\x37\x61\x27\xab", .entropylen = 48, .entpra = "\xc6\x0f\x29\x99\x10\x0f\x73\x8c\x10\xf7\x47\x92" "\x67\x6a\x3f\xc4\xa2\x62\xd1\x37\x21\x79\x80\x46" "\xe2\x9a\x29\x51\x81\x56\x9f\x54", .entprb = "\xc1\x1d\x45\x24\xc9\x07\x1b\xd3\x09\x60\x15\xfc" "\xf7\xbc\x24\xa6\x07\xf2\x2f\xa0\x65\xc9\x37\x65" "\x8a\x2a\x77\xa8\x69\x90\x89\xf4", .entprlen = 32, .expected = "\xab\xc0\x15\x85\x60\x94\x80\x3a\x93\x8d\xff\xd2" "\x0d\xa9\x48\x43\x87\x0e\xf9\x35\xb8\x2c\xfe\xc1" "\x77\x06\xb8\xf5\x51\xb8\x38\x50\x44\x23\x5d\xd4" "\x4b\x59\x9f\x94\xb3\x9b\xe7\x8d\xd4\x76\xe0\xcf" "\x11\x30\x9c\x99\x5a\x73\x34\xe0\xa7\x8b\x37\xbc" "\x95\x86\x23\x50\x86\xfa\x3b\x63\x7b\xa9\x1c\xf8" "\xfb\x65\xef\xa2\x2a\x58\x9c\x13\x75\x31\xaa\x7b" "\x2d\x4e\x26\x07\xaa\xc2\x72\x92\xb0\x1c\x69\x8e" "\x6e\x01\xae\x67\x9e\xb8\x7c\x01\xa8\x9c\x74\x22" "\xd4\x37\x2d\x6d\x75\x4a\xba\xbb\x4b\xf8\x96\xfc" "\xb1\xcd\x09\xd6\x92\xd0\x28\x3f", .expectedlen = 128, .addtla = "\x00", .addtlb = "\x00", .addtllen = 0, .pers = "\x00", .perslen = 0, }, { .entropy = "\xb9\x1f\xe9\xef\xdd\x9b\x7d\x20\xb6\xec\xe0\x2f" "\xdb\x76\x24\xce\x41\xc8\x3a\x4a\x12\x7f\x3e\x2f" "\xae\x05\x99\xea\xb5\x06\x71\x0d\x0c\x4c\xb4\x05" "\x26\xc6\xbd\xf5\x7f\x2a\x3d\xf2\xb5\x49\x7b\xda", .entropylen = 48, .entpra = "\xef\x67\x50\x9c\xa7\x7d\xdf\xb7\x2d\x81\x01\xa4" "\x62\x81\x6a\x69\x5b\xb3\x37\x45\xa7\x34\x8e\x26" "\x46\xd9\x26\xa2\x19\xd4\x94\x43", .entprb = "\x97\x75\x53\x53\xba\xb4\xa6\xb2\x91\x60\x71\x79" "\xd1\x6b\x4a\x24\x9a\x34\x66\xcc\x33\xab\x07\x98" "\x51\x78\x72\xb2\x79\xfd\x2c\xff", .entprlen = 32, .expected = "\x9c\xdc\x63\x8a\x19\x23\x22\x66\x0c\xc5\xb9\xd7" "\xfb\x2a\xb0\x31\xe3\x8a\x36\xa8\x5a\xa8\x14\xda" "\x1e\xa9\xcc\xfe\xb8\x26\x44\x83\x9f\xf6\xff\xaa" "\xc8\x98\xb8\x30\x35\x3b\x3d\x36\xd2\x49\xd4\x40" "\x62\x0a\x65\x10\x76\x55\xef\xc0\x95\x9c\xa7\xda" "\x3f\xcf\xb7\x7b\xc6\xe1\x28\x52\xfc\x0c\xe2\x37" "\x0d\x83\xa7\x51\x4b\x31\x47\x3c\xe1\x3c\xae\x70" "\x01\xc8\xa3\xd3\xc2\xac\x77\x9c\xd1\x68\x77\x9b" "\x58\x27\x3b\xa5\x0f\xc2\x7a\x8b\x04\x65\x62\xd5" "\xe8\xd6\xfe\x2a\xaf\xd3\xd3\xfe\xbd\x18\xfb\xcd" "\xcd\x66\xb5\x01\x69\x66\xa0\x3c", .expectedlen = 128, .addtla = "\x17\xc1\x56\xcb\xcc\x50\xd6\x03\x7d\x45\x76\xa3" "\x75\x76\xc1\x4a\x66\x1b\x2e\xdf\xb0\x2e\x7d\x56" "\x6d\x99\x3b\xc6\x58\xda\x03\xf6", .addtlb = "\x7c\x7b\x4a\x4b\x32\x5e\x6f\x67\x34\xf5\x21\x4c" "\xf9\x96\xf9\xbf\x1c\x8c\x81\xd3\x9b\x60\x6a\x44" "\xc6\x03\xa2\xfb\x13\x20\x19\xb7", .addtllen = 32, .pers = "\x00", .perslen = 0, }, { .entropy = "\x13\x54\x96\xfc\x1b\x7d\x28\xf3\x18\xc9\xa7\x89" "\xb6\xb3\xc8\x72\xac\x00\xd4\x59\x36\x25\x05\xaf" "\xa5\xdb\x96\xcb\x3c\x58\x46\x87\xa5\xaa\xbf\x20" "\x3b\xfe\x23\x0e\xd1\xc7\x41\x0f\x3f\xc9\xb3\x67", .entropylen = 48, .entpra = "\xe2\xbd\xb7\x48\x08\x06\xf3\xe1\x93\x3c\xac\x79" "\xa7\x2b\x11\xda\xe3\x2e\xe1\x91\xa5\x02\x19\x57" "\x20\x28\xad\xf2\x60\xd7\xcd\x45", .entprb = "\x8b\xd4\x69\xfc\xff\x59\x95\x95\xc6\x51\xde\x71" "\x68\x5f\xfc\xf9\x4a\xab\xec\x5a\xcb\xbe\xd3\x66" "\x1f\xfa\x74\xd3\xac\xa6\x74\x60", .entprlen = 32, .expected = "\x1f\x9e\xaf\xe4\xd2\x46\xb7\x47\x41\x4c\x65\x99" "\x01\xe9\x3b\xbb\x83\x0c\x0a\xb0\xc1\x3a\xe2\xb3" "\x31\x4e\xeb\x93\x73\xee\x0b\x26\xc2\x63\xa5\x75" "\x45\x99\xd4\x5c\x9f\xa1\xd4\x45\x87\x6b\x20\x61" "\x40\xea\x78\xa5\x32\xdf\x9e\x66\x17\xaf\xb1\x88" "\x9e\x2e\x23\xdd\xc1\xda\x13\x97\x88\xa5\xb6\x5e" "\x90\x14\x4e\xef\x13\xab\x5c\xd9\x2c\x97\x9e\x7c" "\xd7\xf8\xce\xea\x81\xf5\xcd\x71\x15\x49\x44\xce" "\x83\xb6\x05\xfb\x7d\x30\xb5\x57\x2c\x31\x4f\xfc" "\xfe\x80\xb6\xc0\x13\x0c\x5b\x9b\x2e\x8f\x3d\xfc" "\xc2\xa3\x0c\x11\x1b\x80\x5f\xf3", .expectedlen = 128, .addtla = "\x00", .addtlb = "\x00", .addtllen = 0, .pers = "\x64\xb6\xfc\x60\xbc\x61\x76\x23\x6d\x3f\x4a\x0f" "\xe1\xb4\xd5\x20\x9e\x70\xdd\x03\x53\x6d\xbf\xce" "\xcd\x56\x80\xbc\xb8\x15\xc8\xaa", .perslen = 32, }, { .entropy = "\xc7\xcc\xbc\x67\x7e\x21\x66\x1e\x27\x2b\x63\xdd" "\x3a\x78\xdc\xdf\x66\x6d\x3f\x24\xae\xcf\x37\x01" "\xa9\x0d\x89\x8a\xa7\xdc\x81\x58\xae\xb2\x10\x15" "\x7e\x18\x44\x6d\x13\xea\xdf\x37\x85\xfe\x81\xfb", .entropylen = 48, .entpra = "\x7b\xa1\x91\x5b\x3c\x04\xc4\x1b\x1d\x19\x2f\x1a" "\x18\x81\x60\x3c\x6c\x62\x91\xb7\xe9\xf5\xcb\x96" "\xbb\x81\x6a\xcc\xb5\xae\x55\xb6", .entprb = "\x99\x2c\xc7\x78\x7e\x3b\x88\x12\xef\xbe\xd3\xd2" "\x7d\x2a\xa5\x86\xda\x8d\x58\x73\x4a\x0a\xb2\x2e" "\xbb\x4c\x7e\xe3\x9a\xb6\x81\xc1", .entprlen = 32, .expected = "\x95\x6f\x95\xfc\x3b\xb7\xfe\x3e\xd0\x4e\x1a\x14" "\x6c\x34\x7f\x7b\x1d\x0d\x63\x5e\x48\x9c\x69\xe6" "\x46\x07\xd2\x87\xf3\x86\x52\x3d\x98\x27\x5e\xd7" "\x54\xe7\x75\x50\x4f\xfb\x4d\xfd\xac\x2f\x4b\x77" "\xcf\x9e\x8e\xcc\x16\xa2\x24\xcd\x53\xde\x3e\xc5" "\x55\x5d\xd5\x26\x3f\x89\xdf\xca\x8b\x4e\x1e\xb6" "\x88\x78\x63\x5c\xa2\x63\x98\x4e\x6f\x25\x59\xb1" "\x5f\x2b\x23\xb0\x4b\xa5\x18\x5d\xc2\x15\x74\x40" "\x59\x4c\xb4\x1e\xcf\x9a\x36\xfd\x43\xe2\x03\xb8" "\x59\x91\x30\x89\x2a\xc8\x5a\x43\x23\x7c\x73\x72" "\xda\x3f\xad\x2b\xba\x00\x6b\xd1", .expectedlen = 128, .addtla = "\x18\xe8\x17\xff\xef\x39\xc7\x41\x5c\x73\x03\x03" "\xf6\x3d\xe8\x5f\xc8\xab\xe4\xab\x0f\xad\xe8\xd6" "\x86\x88\x55\x28\xc1\x69\xdd\x76", .addtlb = "\xac\x07\xfc\xbe\x87\x0e\xd3\xea\x1f\x7e\xb8\xe7" "\x9d\xec\xe8\xe7\xbc\xf3\x18\x25\x77\x35\x4a\xaa" "\x00\x99\x2a\xdd\x0a\x00\x50\x82", .addtllen = 32, .pers = "\xbc\x55\xab\x3c\xf6\x52\xb0\x11\x3d\x7b\x90\xb8" "\x24\xc9\x26\x4e\x5a\x1e\x77\x0d\x3d\x58\x4a\xda" "\xd1\x81\xe9\xf8\xeb\x30\x8f\x6f", .perslen = 32, }, }; static const struct drbg_testvec drbg_nopr_hmac_sha256_tv_template[] = { { .entropy = "\xca\x85\x19\x11\x34\x93\x84\xbf\xfe\x89\xde\x1c" "\xbd\xc4\x6e\x68\x31\xe4\x4d\x34\xa4\xfb\x93\x5e" "\xe2\x85\xdd\x14\xb7\x1a\x74\x88\x65\x9b\xa9\x6c" "\x60\x1d\xc6\x9f\xc9\x02\x94\x08\x05\xec\x0c\xa8", .entropylen = 48, .expected = "\xe5\x28\xe9\xab\xf2\xde\xce\x54\xd4\x7c\x7e\x75" "\xe5\xfe\x30\x21\x49\xf8\x17\xea\x9f\xb4\xbe\xe6" "\xf4\x19\x96\x97\xd0\x4d\x5b\x89\xd5\x4f\xbb\x97" "\x8a\x15\xb5\xc4\x43\xc9\xec\x21\x03\x6d\x24\x60" "\xb6\xf7\x3e\xba\xd0\xdc\x2a\xba\x6e\x62\x4a\xbf" "\x07\x74\x5b\xc1\x07\x69\x4b\xb7\x54\x7b\xb0\x99" "\x5f\x70\xde\x25\xd6\xb2\x9e\x2d\x30\x11\xbb\x19" "\xd2\x76\x76\xc0\x71\x62\xc8\xb5\xcc\xde\x06\x68" "\x96\x1d\xf8\x68\x03\x48\x2c\xb3\x7e\xd6\xd5\xc0" "\xbb\x8d\x50\xcf\x1f\x50\xd4\x76\xaa\x04\x58\xbd" "\xab\xa8\x06\xf4\x8b\xe9\xdc\xb8", .expectedlen = 128, .addtla = "\0x00", .addtlb = "\0x00", .addtllen = 0, .pers = "\0x00", .perslen = 0, }, { .entropy = "\xf9\x7a\x3c\xfd\x91\xfa\xa0\x46\xb9\xe6\x1b\x94" "\x93\xd4\x36\xc4\x93\x1f\x60\x4b\x22\xf1\x08\x15" "\x21\xb3\x41\x91\x51\xe8\xff\x06\x11\xf3\xa7\xd4" "\x35\x95\x35\x7d\x58\x12\x0b\xd1\xe2\xdd\x8a\xed", .entropylen = 48, .expected = "\xc6\x87\x1c\xff\x08\x24\xfe\x55\xea\x76\x89\xa5" "\x22\x29\x88\x67\x30\x45\x0e\x5d\x36\x2d\xa5\xbf" "\x59\x0d\xcf\x9a\xcd\x67\xfe\xd4\xcb\x32\x10\x7d" "\xf5\xd0\x39\x69\xa6\x6b\x1f\x64\x94\xfd\xf5\xd6" "\x3d\x5b\x4d\x0d\x34\xea\x73\x99\xa0\x7d\x01\x16" "\x12\x6d\x0d\x51\x8c\x7c\x55\xba\x46\xe1\x2f\x62" "\xef\xc8\xfe\x28\xa5\x1c\x9d\x42\x8e\x6d\x37\x1d" "\x73\x97\xab\x31\x9f\xc7\x3d\xed\x47\x22\xe5\xb4" "\xf3\x00\x04\x03\x2a\x61\x28\xdf\x5e\x74\x97\xec" "\xf8\x2c\xa7\xb0\xa5\x0e\x86\x7e\xf6\x72\x8a\x4f" "\x50\x9a\x8c\x85\x90\x87\x03\x9c", .expectedlen = 128, .addtla = "\x51\x72\x89\xaf\xe4\x44\xa0\xfe\x5e\xd1\xa4\x1d" "\xbb\xb5\xeb\x17\x15\x00\x79\xbd\xd3\x1e\x29\xcf" "\x2f\xf3\x00\x34\xd8\x26\x8e\x3b", .addtlb = "\x88\x02\x8d\x29\xef\x80\xb4\xe6\xf0\xfe\x12\xf9" "\x1d\x74\x49\xfe\x75\x06\x26\x82\xe8\x9c\x57\x14" "\x40\xc0\xc9\xb5\x2c\x42\xa6\xe0", .addtllen = 32, .pers = "\0x00", .perslen = 0, }, { .entropy = "\x8d\xf0\x13\xb4\xd1\x03\x52\x30\x73\x91\x7d\xdf" "\x6a\x86\x97\x93\x05\x9e\x99\x43\xfc\x86\x54\x54" "\x9e\x7a\xb2\x2f\x7c\x29\xf1\x22\xda\x26\x25\xaf" "\x2d\xdd\x4a\xbc\xce\x3c\xf4\xfa\x46\x59\xd8\x4e", .entropylen = 48, .expected = "\xb9\x1c\xba\x4c\xc8\x4f\xa2\x5d\xf8\x61\x0b\x81" "\xb6\x41\x40\x27\x68\xa2\x09\x72\x34\x93\x2e\x37" "\xd5\x90\xb1\x15\x4c\xbd\x23\xf9\x74\x52\xe3\x10" "\xe2\x91\xc4\x51\x46\x14\x7f\x0d\xa2\xd8\x17\x61" "\xfe\x90\xfb\xa6\x4f\x94\x41\x9c\x0f\x66\x2b\x28" "\xc1\xed\x94\xda\x48\x7b\xb7\xe7\x3e\xec\x79\x8f" "\xbc\xf9\x81\xb7\x91\xd1\xbe\x4f\x17\x7a\x89\x07" "\xaa\x3c\x40\x16\x43\xa5\xb6\x2b\x87\xb8\x9d\x66" "\xb3\xa6\x0e\x40\xd4\xa8\xe4\xe9\xd8\x2a\xf6\xd2" "\x70\x0e\x6f\x53\x5c\xdb\x51\xf7\x5c\x32\x17\x29" "\x10\x37\x41\x03\x0c\xcc\x3a\x56", .expectedlen = 128, .addtla = "\0x00", .addtlb = "\0x00", .addtllen = 0, .pers = "\xb5\x71\xe6\x6d\x7c\x33\x8b\xc0\x7b\x76\xad\x37" "\x57\xbb\x2f\x94\x52\xbf\x7e\x07\x43\x7a\xe8\x58" "\x1c\xe7\xbc\x7c\x3a\xc6\x51\xa9", .perslen = 32, }, { .entropy = "\xc2\xa5\x66\xa9\xa1\x81\x7b\x15\xc5\xc3\xb7\x78" "\x17\x7a\xc8\x7c\x24\xe7\x97\xbe\x0a\x84\x5f\x11" "\xc2\xfe\x39\x9d\xd3\x77\x32\xf2\xcb\x18\x94\xeb" "\x2b\x97\xb3\xc5\x6e\x62\x83\x29\x51\x6f\x86\xec", .entropylen = 48, .expected = "\xb3\xa3\x69\x8d\x77\x76\x99\xa0\xdd\x9f\xa3\xf0" "\xa9\xfa\x57\x83\x2d\x3c\xef\xac\x5d\xf2\x44\x37" "\xc6\xd7\x3a\x0f\xe4\x10\x40\xf1\x72\x90\x38\xae" "\xf1\xe9\x26\x35\x2e\xa5\x9d\xe1\x20\xbf\xb7\xb0" "\x73\x18\x3a\x34\x10\x6e\xfe\xd6\x27\x8f\xf8\xad" "\x84\x4b\xa0\x44\x81\x15\xdf\xdd\xf3\x31\x9a\x82" "\xde\x6b\xb1\x1d\x80\xbd\x87\x1a\x9a\xcd\x35\xc7" "\x36\x45\xe1\x27\x0f\xb9\xfe\x4f\xa8\x8e\xc0\xe4" "\x65\x40\x9e\xa0\xcb\xa8\x09\xfe\x2f\x45\xe0\x49" "\x43\xa2\xe3\x96\xbb\xb7\xdd\x2f\x4e\x07\x95\x30" "\x35\x24\xcc\x9c\xc5\xea\x54\xa1", .expectedlen = 128, .addtla = "\x41\x3d\xd8\x3f\xe5\x68\x35\xab\xd4\x78\xcb\x96" "\x93\xd6\x76\x35\x90\x1c\x40\x23\x9a\x26\x64\x62" "\xd3\x13\x3b\x83\xe4\x9c\x82\x0b", .addtlb = "\xd5\xc4\xa7\x1f\x9d\x6d\x95\xa1\xbe\xdf\x0b\xd2" "\x24\x7c\x27\x7d\x1f\x84\xa4\xe5\x7a\x4a\x88\x25" "\xb8\x2a\x2d\x09\x7d\xe6\x3e\xf1", .addtllen = 32, .pers = "\x13\xce\x4d\x8d\xd2\xdb\x97\x96\xf9\x41\x56\xc8" "\xe8\xf0\x76\x9b\x0a\xa1\xc8\x2c\x13\x23\xb6\x15" "\x36\x60\x3b\xca\x37\xc9\xee\x29", .perslen = 32, }, }; static const struct drbg_test_suite drbg_pr_hmac_sha256_tv = { drbg_pr_hmac_sha256_tv_template, ARRAY_SIZE(drbg_pr_hmac_sha256_tv_template), }; static const struct drbg_test_suite drbg_nopr_hmac_sha256_tv = { drbg_nopr_hmac_sha256_tv_template, ARRAY_SIZE(drbg_nopr_hmac_sha256_tv_template), }; static int __test_drbg(const struct drbg_testvec *tv, int pr, const char *driver, u32 type, u32 mask) { int ret = -EAGAIN; struct crypto_rng *drng; struct drbg_test_data test_data; struct drbg_string addtl, pers, testentropy; unsigned char *buf = kvmalloc(tv->expectedlen, GFP_KERNEL); if (!buf) return -ENOMEM; drng = crypto_alloc_rng(driver, type, mask); if (IS_ERR(drng)) { kfree_sensitive(buf); return -ENOMEM; } test_data.testentropy = &testentropy; drbg_string_fill(&testentropy, tv->entropy, tv->entropylen); drbg_string_fill(&pers, tv->pers, tv->perslen); ret = crypto_drbg_reset_test(drng, &pers, &test_data); if (ret) goto outbuf; drbg_string_fill(&addtl, tv->addtla, tv->addtllen); if (pr) { drbg_string_fill(&testentropy, tv->entpra, tv->entprlen); ret = crypto_drbg_get_bytes_addtl_test(drng, buf, tv->expectedlen, &addtl, &test_data); } else { ret = crypto_drbg_get_bytes_addtl(drng, buf, tv->expectedlen, &addtl); } if (ret < 0) goto outbuf; drbg_string_fill(&addtl, tv->addtlb, tv->addtllen); if (pr) { drbg_string_fill(&testentropy, tv->entprb, tv->entprlen); ret = crypto_drbg_get_bytes_addtl_test(drng, buf, tv->expectedlen, &addtl, &test_data); } else { ret = crypto_drbg_get_bytes_addtl(drng, buf, tv->expectedlen, &addtl); } if (ret < 0) goto outbuf; ret = memcmp(tv->expected, buf, tv->expectedlen); outbuf: crypto_free_rng(drng); kfree_sensitive(buf); return ret; } static int test_drbg(const struct drbg_test_suite *desc, const char *driver, u32 type, u32 mask) { int err = 0; int pr = 0; size_t i = 0; const struct drbg_testvec *template = desc->vecs; size_t tcount = desc->tv_count; if (memcmp(driver, "drbg_pr_", 8) == 0) pr = 1; for (i = 0; i < tcount; i++) { err = __test_drbg(&template[i], pr, driver, type, mask); if (err) { pr_err("MDFPP CAST : %s, test %zu failed, err=%d\n", driver, i, err); err = -EINVAL; break; } } if (!err) pr_err("MDFPP CAST : tests for %s passed\n", driver); return err; } void drbg_mdfpp_cast(void) { int ret = 0; #if defined CONFIG_CRYPTO_DRBG_HMAC ret |= test_drbg(&drbg_nopr_hmac_sha256_tv, "drbg_nopr_hmac_sha256", 0, 0); ret |= test_drbg(&drbg_pr_hmac_sha256_tv, "drbg_pr_hmac_sha256", 0, 0); #endif if (ret) panic("MDFPP CAST : one or more tests failed\n"); }