diff options
Diffstat (limited to '')
| -rw-r--r-- | src/regress/lib/libcrypto/rsa/Makefile | 5 | ||||
| -rw-r--r-- | src/regress/lib/libcrypto/rsa/rsa_padding_test.c | 325 |
2 files changed, 328 insertions, 2 deletions
diff --git a/src/regress/lib/libcrypto/rsa/Makefile b/src/regress/lib/libcrypto/rsa/Makefile index 53065e6408..494d40d867 100644 --- a/src/regress/lib/libcrypto/rsa/Makefile +++ b/src/regress/lib/libcrypto/rsa/Makefile | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | # $OpenBSD: Makefile,v 1.3 2024/03/30 00:34:40 jsing Exp $ | 1 | # $OpenBSD: Makefile,v 1.4 2024/03/30 00:36:14 jsing Exp $ |
| 2 | 2 | ||
| 3 | PROG= rsa_test | 3 | PROGS= rsa_test \ |
| 4 | rsa_padding_test | ||
| 4 | LDADD= -lcrypto | 5 | LDADD= -lcrypto |
| 5 | DPADD= ${LIBCRYPTO} | 6 | DPADD= ${LIBCRYPTO} |
| 6 | WARNINGS= Yes | 7 | WARNINGS= Yes |
diff --git a/src/regress/lib/libcrypto/rsa/rsa_padding_test.c b/src/regress/lib/libcrypto/rsa/rsa_padding_test.c new file mode 100644 index 0000000000..64357bf405 --- /dev/null +++ b/src/regress/lib/libcrypto/rsa/rsa_padding_test.c | |||
| @@ -0,0 +1,325 @@ | |||
| 1 | /* $OpenBSD: rsa_padding_test.c,v 1.1 2024/03/30 00:36:14 jsing Exp $ */ | ||
| 2 | /* | ||
| 3 | * Copyright (c) 2024 Joel Sing <jsing@openbsd.org> | ||
| 4 | * | ||
| 5 | * Permission to use, copy, modify, and distribute this software for any | ||
| 6 | * purpose with or without fee is hereby granted, provided that the above | ||
| 7 | * copyright notice and this permission notice appear in all copies. | ||
| 8 | * | ||
| 9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include <stdint.h> | ||
| 19 | #include <string.h> | ||
| 20 | |||
| 21 | #include <openssl/err.h> | ||
| 22 | #include <openssl/rsa.h> | ||
| 23 | |||
| 24 | #if 0 | ||
| 25 | static void | ||
| 26 | hexdump(const unsigned char *buf, size_t len) | ||
| 27 | { | ||
| 28 | size_t i; | ||
| 29 | |||
| 30 | for (i = 1; i <= len; i++) | ||
| 31 | fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n"); | ||
| 32 | |||
| 33 | fprintf(stderr, "\n"); | ||
| 34 | } | ||
| 35 | #endif | ||
| 36 | |||
| 37 | struct pkcs1_test { | ||
| 38 | uint8_t in[128]; | ||
| 39 | size_t in_len; | ||
| 40 | int want; | ||
| 41 | int want_error; | ||
| 42 | }; | ||
| 43 | |||
| 44 | static const struct pkcs1_test pkcs1_type1_tests[] = { | ||
| 45 | { | ||
| 46 | .in = { | ||
| 47 | 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 48 | 0xff, 0xff, 0xff, 0xff, 0x00, 0x6f, 0x6f, 0x6f, | ||
| 49 | 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, | ||
| 50 | 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, | ||
| 51 | }, | ||
| 52 | .in_len = 32, | ||
| 53 | .want = 19, | ||
| 54 | }, | ||
| 55 | { | ||
| 56 | .in = { | ||
| 57 | 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 58 | 0xff, 0xff, 0x00, | ||
| 59 | }, | ||
| 60 | .in_len = 11, | ||
| 61 | .want = 0, | ||
| 62 | }, | ||
| 63 | { | ||
| 64 | .in = { | ||
| 65 | 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 66 | 0xff, 0xff, 0x00, 0xff, | ||
| 67 | }, | ||
| 68 | .in_len = 12, | ||
| 69 | .want = 1, | ||
| 70 | }, | ||
| 71 | { | ||
| 72 | /* Insufficient padding bytes (< 8). */ | ||
| 73 | .in = { | ||
| 74 | 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 75 | 0xff, 0x00, 0xff, 0xff, | ||
| 76 | }, | ||
| 77 | .in_len = 12, | ||
| 78 | .want = -1, | ||
| 79 | .want_error = RSA_R_BAD_PAD_BYTE_COUNT, | ||
| 80 | }, | ||
| 81 | { | ||
| 82 | /* Incorrect padding type (0x00). */ | ||
| 83 | .in = { | ||
| 84 | 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 85 | 0xff, 0xff, 0x00, 0xff, | ||
| 86 | }, | ||
| 87 | .in_len = 12, | ||
| 88 | .want = -1, | ||
| 89 | .want_error = RSA_R_BLOCK_TYPE_IS_NOT_01, | ||
| 90 | }, | ||
| 91 | { | ||
| 92 | /* Incorrect padding type (0x02). */ | ||
| 93 | .in = { | ||
| 94 | 0x00, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 95 | 0xff, 0xff, 0x00, 0xff, | ||
| 96 | }, | ||
| 97 | .in_len = 12, | ||
| 98 | .want = -1, | ||
| 99 | .want_error = RSA_R_BLOCK_TYPE_IS_NOT_01, | ||
| 100 | }, | ||
| 101 | { | ||
| 102 | /* Non-padding byte before end of padding marker. */ | ||
| 103 | .in = { | ||
| 104 | 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 105 | 0xff, 0xfe, 0x00, 0xff, | ||
| 106 | }, | ||
| 107 | .in_len = 12, | ||
| 108 | .want = -1, | ||
| 109 | .want_error = RSA_R_BAD_FIXED_HEADER_DECRYPT, | ||
| 110 | }, | ||
| 111 | { | ||
| 112 | /* No end of padding marker. */ | ||
| 113 | .in = { | ||
| 114 | 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 115 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 116 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 117 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 118 | }, | ||
| 119 | .in_len = 32, | ||
| 120 | .want = -1, | ||
| 121 | .want_error = RSA_R_NULL_BEFORE_BLOCK_MISSING, | ||
| 122 | }, | ||
| 123 | }; | ||
| 124 | |||
| 125 | #define N_PKCS1_TYPE1_TESTS \ | ||
| 126 | (sizeof(pkcs1_type1_tests) / sizeof(pkcs1_type1_tests[0])) | ||
| 127 | |||
| 128 | static int | ||
| 129 | test_pkcs1_type1(void) | ||
| 130 | { | ||
| 131 | const struct pkcs1_test *pt; | ||
| 132 | uint8_t buf[32], in[19], out[512]; | ||
| 133 | int pad_len; | ||
| 134 | long err; | ||
| 135 | size_t i; | ||
| 136 | int failed = 1; | ||
| 137 | |||
| 138 | memset(in, 0x6f, sizeof(in)); | ||
| 139 | |||
| 140 | if (!RSA_padding_add_PKCS1_type_1(buf, sizeof(buf), in, sizeof(in))) { | ||
| 141 | fprintf(stderr, "FAIL: failed to add PKCS1 type 1 padding\n"); | ||
| 142 | goto failed; | ||
| 143 | } | ||
| 144 | |||
| 145 | pad_len = RSA_padding_check_PKCS1_type_1(out, sizeof(out) - 1, | ||
| 146 | buf + 1, sizeof(buf) - 1, sizeof(buf)); | ||
| 147 | if (pad_len != sizeof(in)) { | ||
| 148 | fprintf(stderr, "FAIL: failed to check PKCS1 type 1 padding\n"); | ||
| 149 | ERR_print_errors_fp(stderr); | ||
| 150 | goto failed; | ||
| 151 | } | ||
| 152 | |||
| 153 | for (i = 0; i < N_PKCS1_TYPE1_TESTS; i++) { | ||
| 154 | pt = &pkcs1_type1_tests[i]; | ||
| 155 | |||
| 156 | ERR_clear_error(); | ||
| 157 | |||
| 158 | pad_len = RSA_padding_check_PKCS1_type_1(out, sizeof(out) - 1, | ||
| 159 | pt->in + 1, pt->in_len - 1, pt->in_len); | ||
| 160 | |||
| 161 | if (pad_len != pt->want) { | ||
| 162 | fprintf(stderr, "FAIL: test %zu - failed to check " | ||
| 163 | "PKCS1 type 1 padding (%d != %d)\n", i, pad_len, | ||
| 164 | pt->want); | ||
| 165 | ERR_print_errors_fp(stderr); | ||
| 166 | goto failed; | ||
| 167 | } | ||
| 168 | |||
| 169 | err = ERR_peek_error(); | ||
| 170 | if (pt->want == -1 && ERR_GET_REASON(err) != pt->want_error) { | ||
| 171 | fprintf(stderr, "FAIL: test %zu - PKCS1 type 1 padding " | ||
| 172 | "check failed with error reason %i, want %i\n", | ||
| 173 | i, ERR_GET_REASON(err), pt->want_error); | ||
| 174 | ERR_print_errors_fp(stderr); | ||
| 175 | goto failed; | ||
| 176 | } | ||
| 177 | } | ||
| 178 | |||
| 179 | failed = 0; | ||
| 180 | |||
| 181 | failed: | ||
| 182 | return failed; | ||
| 183 | } | ||
| 184 | |||
| 185 | static const struct pkcs1_test pkcs1_type2_tests[] = { | ||
| 186 | { | ||
| 187 | .in = { | ||
| 188 | 0x00, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 189 | 0xff, 0xff, 0xff, 0xff, 0x00, 0x6f, 0x6f, 0x6f, | ||
| 190 | 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, | ||
| 191 | 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, | ||
| 192 | }, | ||
| 193 | .in_len = 32, | ||
| 194 | .want = 19, | ||
| 195 | }, | ||
| 196 | { | ||
| 197 | .in = { | ||
| 198 | 0x00, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 199 | 0xff, 0xff, 0x00, | ||
| 200 | }, | ||
| 201 | .in_len = 11, | ||
| 202 | .want = 0, | ||
| 203 | }, | ||
| 204 | { | ||
| 205 | .in = { | ||
| 206 | 0x00, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 207 | 0xff, 0xff, 0x00, 0xff, | ||
| 208 | }, | ||
| 209 | .in_len = 12, | ||
| 210 | .want = 1, | ||
| 211 | }, | ||
| 212 | { | ||
| 213 | /* Insufficient padding bytes (< 8). */ | ||
| 214 | .in = { | ||
| 215 | 0x00, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 216 | 0xff, 0x00, 0xff, 0xff, | ||
| 217 | }, | ||
| 218 | .in_len = 12, | ||
| 219 | .want = -1, | ||
| 220 | .want_error = RSA_R_BAD_PAD_BYTE_COUNT, | ||
| 221 | }, | ||
| 222 | { | ||
| 223 | /* Incorrect padding type (0x00). */ | ||
| 224 | .in = { | ||
| 225 | 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 226 | 0xff, 0xff, 0x00, 0xff, | ||
| 227 | }, | ||
| 228 | .in_len = 12, | ||
| 229 | .want = -1, | ||
| 230 | .want_error = RSA_R_BLOCK_TYPE_IS_NOT_02, | ||
| 231 | }, | ||
| 232 | { | ||
| 233 | /* Incorrect padding type (0x01). */ | ||
| 234 | .in = { | ||
| 235 | 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 236 | 0xff, 0xff, 0x00, 0xff, | ||
| 237 | }, | ||
| 238 | .in_len = 12, | ||
| 239 | .want = -1, | ||
| 240 | .want_error = RSA_R_BLOCK_TYPE_IS_NOT_02, | ||
| 241 | }, | ||
| 242 | { | ||
| 243 | /* No end of padding marker. */ | ||
| 244 | .in = { | ||
| 245 | 0x00, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 246 | 0xff, 0xff, 0xff, 0xff, 0xff, 0x6f, 0x6f, 0x6f, | ||
| 247 | 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, | ||
| 248 | 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, | ||
| 249 | }, | ||
| 250 | .in_len = 32, | ||
| 251 | .want = -1, | ||
| 252 | .want_error = RSA_R_NULL_BEFORE_BLOCK_MISSING, | ||
| 253 | }, | ||
| 254 | }; | ||
| 255 | |||
| 256 | #define N_PKCS1_TYPE2_TESTS \ | ||
| 257 | (sizeof(pkcs1_type2_tests) / sizeof(pkcs1_type2_tests[0])) | ||
| 258 | |||
| 259 | static int | ||
| 260 | test_pkcs1_type2(void) | ||
| 261 | { | ||
| 262 | const struct pkcs1_test *pt; | ||
| 263 | uint8_t buf[32], in[19], out[32]; | ||
| 264 | int pad_len; | ||
| 265 | long err; | ||
| 266 | size_t i; | ||
| 267 | int failed = 1; | ||
| 268 | |||
| 269 | memset(in, 0x6f, sizeof(in)); | ||
| 270 | |||
| 271 | if (!RSA_padding_add_PKCS1_type_2(buf, sizeof(buf), in, sizeof(in))) { | ||
| 272 | fprintf(stderr, "FAIL: failed to add PKCS1 type 2 padding\n"); | ||
| 273 | goto failed; | ||
| 274 | } | ||
| 275 | |||
| 276 | pad_len = RSA_padding_check_PKCS1_type_2(out, sizeof(out) - 1, | ||
| 277 | buf + 1, sizeof(buf) - 1, sizeof(out)); | ||
| 278 | if (pad_len != sizeof(in)) { | ||
| 279 | fprintf(stderr, "FAIL: failed to check PKCS1 type 2 padding\n"); | ||
| 280 | ERR_print_errors_fp(stderr); | ||
| 281 | goto failed; | ||
| 282 | } | ||
| 283 | |||
| 284 | for (i = 0; i < N_PKCS1_TYPE2_TESTS; i++) { | ||
| 285 | pt = &pkcs1_type2_tests[i]; | ||
| 286 | |||
| 287 | ERR_clear_error(); | ||
| 288 | |||
| 289 | pad_len = RSA_padding_check_PKCS1_type_2(out, sizeof(out) - 1, | ||
| 290 | pt->in + 1, pt->in_len - 1, pt->in_len); | ||
| 291 | |||
| 292 | if (pad_len != pt->want) { | ||
| 293 | fprintf(stderr, "FAIL: test %zu - failed to check " | ||
| 294 | "PKCS1 type 2 padding (%d != %d)\n", i, pad_len, | ||
| 295 | pt->want); | ||
| 296 | ERR_print_errors_fp(stderr); | ||
| 297 | goto failed; | ||
| 298 | } | ||
| 299 | |||
| 300 | err = ERR_peek_error(); | ||
| 301 | if (pt->want == -1 && ERR_GET_REASON(err) != pt->want_error) { | ||
| 302 | fprintf(stderr, "FAIL: test %zu - PKCS1 type 2 padding " | ||
| 303 | "check failed with error reason %i, want %i\n", | ||
| 304 | i, ERR_GET_REASON(err), pt->want_error); | ||
| 305 | ERR_print_errors_fp(stderr); | ||
| 306 | goto failed; | ||
| 307 | } | ||
| 308 | } | ||
| 309 | |||
| 310 | failed = 0; | ||
| 311 | |||
| 312 | failed: | ||
| 313 | return failed; | ||
| 314 | } | ||
| 315 | |||
| 316 | int | ||
| 317 | main(int argc, char **argv) | ||
| 318 | { | ||
| 319 | int failed = 0; | ||
| 320 | |||
| 321 | failed |= test_pkcs1_type1(); | ||
| 322 | failed |= test_pkcs1_type2(); | ||
| 323 | |||
| 324 | return failed; | ||
| 325 | } | ||
