1 /* $OpenBSD: test_sshbuf_getput_crypto.c,v 1.3 2021/12/14 21:25:27 deraadt Exp $ */ 2 /* 3 * Regress test for sshbuf.h buffer API 4 * 5 * Placed in the public domain 6 */ 7 8 #include "includes.h" 9 10 #ifdef WITH_OPENSSL 11 12 #include <sys/types.h> 13 #include <stdio.h> 14 #ifdef HAVE_STDINT_H 15 # include <stdint.h> 16 #endif 17 #include <stdlib.h> 18 #include <string.h> 19 20 #include <openssl/bn.h> 21 #include <openssl/objects.h> 22 #ifdef OPENSSL_HAS_NISTP256 23 # include <openssl/ec.h> 24 #endif 25 26 #include "../test_helper/test_helper.h" 27 #include "ssherr.h" 28 #include "sshbuf.h" 29 30 void sshbuf_getput_crypto_tests(void); 31 32 void 33 sshbuf_getput_crypto_tests(void) 34 { 35 struct sshbuf *p1; 36 BIGNUM *bn, *bn2; 37 const char *hexbn1 = "0102030405060708090a0b0c0d0e0f10"; 38 /* This one has MSB set to test bignum2 encoding negative-avoidance */ 39 const char *hexbn2 = "f0e0d0c0b0a0908070605040302010007fff11"; 40 u_char expbn1[] = { 41 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 42 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 43 }; 44 u_char expbn2[] = { 45 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, 0x90, 0x80, 46 0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10, 0x00, 47 0x7f, 0xff, 0x11 48 }; 49 #if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256) 50 const u_char *d; 51 size_t s; 52 BIGNUM *bn_x, *bn_y; 53 int ec256_nid = NID_X9_62_prime256v1; 54 char *ec256_x = "0C828004839D0106AA59575216191357" 55 "34B451459DADB586677EF9DF55784999"; 56 char *ec256_y = "4D196B50F0B4E94B3C73E3A9D4CD9DF2" 57 "C8F9A35E42BDD047550F69D80EC23CD4"; 58 u_char expec256[] = { 59 0x04, 60 0x0c, 0x82, 0x80, 0x04, 0x83, 0x9d, 0x01, 0x06, 61 0xaa, 0x59, 0x57, 0x52, 0x16, 0x19, 0x13, 0x57, 62 0x34, 0xb4, 0x51, 0x45, 0x9d, 0xad, 0xb5, 0x86, 63 0x67, 0x7e, 0xf9, 0xdf, 0x55, 0x78, 0x49, 0x99, 64 0x4d, 0x19, 0x6b, 0x50, 0xf0, 0xb4, 0xe9, 0x4b, 65 0x3c, 0x73, 0xe3, 0xa9, 0xd4, 0xcd, 0x9d, 0xf2, 66 0xc8, 0xf9, 0xa3, 0x5e, 0x42, 0xbd, 0xd0, 0x47, 67 0x55, 0x0f, 0x69, 0xd8, 0x0e, 0xc2, 0x3c, 0xd4 68 }; 69 EC_KEY *eck; 70 EC_POINT *ecp; 71 #endif 72 int r; 73 74 #define MKBN(b, bnn) \ 75 do { \ 76 bnn = NULL; \ 77 ASSERT_INT_GT(BN_hex2bn(&bnn, b), 0); \ 78 } while (0) 79 80 TEST_START("sshbuf_put_bignum2"); 81 MKBN(hexbn1, bn); 82 p1 = sshbuf_new(); 83 ASSERT_PTR_NE(p1, NULL); 84 ASSERT_INT_EQ(sshbuf_put_bignum2(p1, bn), 0); 85 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn1) + 4); 86 ASSERT_U32_EQ(PEEK_U32(sshbuf_ptr(p1)), (u_int32_t)BN_num_bytes(bn)); 87 ASSERT_MEM_EQ(sshbuf_ptr(p1) + 4, expbn1, sizeof(expbn1)); 88 BN_free(bn); 89 sshbuf_free(p1); 90 TEST_DONE(); 91 92 TEST_START("sshbuf_put_bignum2 limited"); 93 MKBN(hexbn1, bn); 94 p1 = sshbuf_new(); 95 ASSERT_PTR_NE(p1, NULL); 96 ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(expbn1) + 3), 0); 97 r = sshbuf_put_bignum2(p1, bn); 98 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE); 99 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); 100 BN_free(bn); 101 sshbuf_free(p1); 102 TEST_DONE(); 103 104 TEST_START("sshbuf_put_bignum2 bn2"); 105 MKBN(hexbn2, bn); 106 p1 = sshbuf_new(); 107 ASSERT_PTR_NE(p1, NULL); 108 ASSERT_INT_EQ(sshbuf_put_bignum2(p1, bn), 0); 109 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn2) + 4 + 1); /* MSB */ 110 ASSERT_U32_EQ(PEEK_U32(sshbuf_ptr(p1)), (u_int32_t)BN_num_bytes(bn) + 1); 111 ASSERT_U8_EQ(*(sshbuf_ptr(p1) + 4), 0x00); 112 ASSERT_MEM_EQ(sshbuf_ptr(p1) + 5, expbn2, sizeof(expbn2)); 113 BN_free(bn); 114 sshbuf_free(p1); 115 TEST_DONE(); 116 117 TEST_START("sshbuf_put_bignum2 bn2 limited"); 118 MKBN(hexbn2, bn); 119 p1 = sshbuf_new(); 120 ASSERT_PTR_NE(p1, NULL); 121 ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(expbn2) + 3), 0); 122 r = sshbuf_put_bignum2(p1, bn); 123 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE); 124 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); 125 BN_free(bn); 126 sshbuf_free(p1); 127 TEST_DONE(); 128 129 TEST_START("sshbuf_get_bignum2"); 130 MKBN(hexbn1, bn); 131 p1 = sshbuf_new(); 132 ASSERT_PTR_NE(p1, NULL); 133 ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn)), 0); 134 ASSERT_INT_EQ(sshbuf_put(p1, expbn1, sizeof(expbn1)), 0); 135 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4 + sizeof(expbn1)); 136 ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xd00f), 0); 137 bn2 = NULL; 138 ASSERT_INT_EQ(sshbuf_get_bignum2(p1, &bn2), 0); 139 ASSERT_BIGNUM_EQ(bn, bn2); 140 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2); 141 BN_free(bn); 142 BN_free(bn2); 143 sshbuf_free(p1); 144 TEST_DONE(); 145 146 TEST_START("sshbuf_get_bignum2 truncated"); 147 MKBN(hexbn1, bn); 148 p1 = sshbuf_new(); 149 ASSERT_PTR_NE(p1, NULL); 150 ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn)), 0); 151 ASSERT_INT_EQ(sshbuf_put(p1, expbn1, sizeof(expbn1) - 1), 0); 152 bn2 = NULL; 153 r = sshbuf_get_bignum2(p1, &bn2); 154 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); 155 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn1) + 3); 156 BN_free(bn); 157 BN_free(bn2); 158 sshbuf_free(p1); 159 TEST_DONE(); 160 161 TEST_START("sshbuf_get_bignum2 giant"); 162 MKBN(hexbn1, bn); 163 p1 = sshbuf_new(); 164 ASSERT_PTR_NE(p1, NULL); 165 ASSERT_INT_EQ(sshbuf_put_u32(p1, 65536), 0); 166 ASSERT_INT_EQ(sshbuf_reserve(p1, 65536, NULL), 0); 167 bn2 = NULL; 168 r = sshbuf_get_bignum2(p1, &bn2); 169 ASSERT_INT_EQ(r, SSH_ERR_BIGNUM_TOO_LARGE); 170 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 65536 + 4); 171 BN_free(bn); 172 BN_free(bn2); 173 sshbuf_free(p1); 174 TEST_DONE(); 175 176 TEST_START("sshbuf_get_bignum2 bn2"); 177 MKBN(hexbn2, bn); 178 p1 = sshbuf_new(); 179 ASSERT_PTR_NE(p1, NULL); 180 ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn) + 1), 0); /* MSB */ 181 ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x00), 0); 182 ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2)), 0); 183 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4 + 1 + sizeof(expbn2)); 184 ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xd00f), 0); 185 bn2 = NULL; 186 ASSERT_INT_EQ(sshbuf_get_bignum2(p1, &bn2), 0); 187 ASSERT_BIGNUM_EQ(bn, bn2); 188 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2); 189 BN_free(bn); 190 BN_free(bn2); 191 sshbuf_free(p1); 192 TEST_DONE(); 193 194 TEST_START("sshbuf_get_bignum2 bn2 truncated"); 195 MKBN(hexbn2, bn); 196 p1 = sshbuf_new(); 197 ASSERT_PTR_NE(p1, NULL); 198 ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn) + 1), 0); 199 ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x00), 0); 200 ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2) - 1), 0); 201 bn2 = NULL; 202 r = sshbuf_get_bignum2(p1, &bn2); 203 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); 204 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn2) + 1 + 4 - 1); 205 BN_free(bn); 206 BN_free(bn2); 207 sshbuf_free(p1); 208 TEST_DONE(); 209 210 TEST_START("sshbuf_get_bignum2 bn2 negative"); 211 MKBN(hexbn2, bn); 212 p1 = sshbuf_new(); 213 ASSERT_PTR_NE(p1, NULL); 214 ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn)), 0); 215 ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2)), 0); 216 bn2 = NULL; 217 r = sshbuf_get_bignum2(p1, &bn2); 218 ASSERT_INT_EQ(r, SSH_ERR_BIGNUM_IS_NEGATIVE); 219 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn2) + 4); 220 BN_free(bn); 221 BN_free(bn2); 222 sshbuf_free(p1); 223 TEST_DONE(); 224 225 #if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256) 226 TEST_START("sshbuf_put_ec"); 227 eck = EC_KEY_new_by_curve_name(ec256_nid); 228 ASSERT_PTR_NE(eck, NULL); 229 ecp = EC_POINT_new(EC_KEY_get0_group(eck)); 230 ASSERT_PTR_NE(ecp, NULL); 231 MKBN(ec256_x, bn_x); 232 MKBN(ec256_y, bn_y); 233 ASSERT_INT_EQ(EC_POINT_set_affine_coordinates_GFp( 234 EC_KEY_get0_group(eck), ecp, bn_x, bn_y, NULL), 1); 235 ASSERT_INT_EQ(EC_KEY_set_public_key(eck, ecp), 1); 236 BN_free(bn_x); 237 BN_free(bn_y); 238 EC_POINT_free(ecp); 239 p1 = sshbuf_new(); 240 ASSERT_PTR_NE(p1, NULL); 241 ASSERT_INT_EQ(sshbuf_put_eckey(p1, eck), 0); 242 ASSERT_INT_EQ(sshbuf_get_string_direct(p1, &d, &s), 0); 243 ASSERT_SIZE_T_EQ(s, sizeof(expec256)); 244 ASSERT_MEM_EQ(d, expec256, sizeof(expec256)); 245 sshbuf_free(p1); 246 EC_KEY_free(eck); 247 TEST_DONE(); 248 249 TEST_START("sshbuf_get_ec"); 250 eck = EC_KEY_new_by_curve_name(ec256_nid); 251 ASSERT_PTR_NE(eck, NULL); 252 p1 = sshbuf_new(); 253 ASSERT_PTR_NE(p1, NULL); 254 ASSERT_INT_EQ(sshbuf_put_string(p1, expec256, sizeof(expec256)), 0); 255 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expec256) + 4); 256 ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x00), 0); 257 ASSERT_INT_EQ(sshbuf_get_eckey(p1, eck), 0); 258 bn_x = BN_new(); 259 bn_y = BN_new(); 260 ASSERT_PTR_NE(bn_x, NULL); 261 ASSERT_PTR_NE(bn_y, NULL); 262 ASSERT_INT_EQ(EC_POINT_get_affine_coordinates_GFp( 263 EC_KEY_get0_group(eck), EC_KEY_get0_public_key(eck), 264 bn_x, bn_y, NULL), 1); 265 MKBN(ec256_x, bn); 266 MKBN(ec256_y, bn2); 267 ASSERT_INT_EQ(BN_cmp(bn_x, bn), 0); 268 ASSERT_INT_EQ(BN_cmp(bn_y, bn2), 0); 269 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1); 270 sshbuf_free(p1); 271 EC_KEY_free(eck); 272 BN_free(bn_x); 273 BN_free(bn_y); 274 BN_free(bn); 275 BN_free(bn2); 276 TEST_DONE(); 277 #endif 278 } 279 280 #endif /* WITH_OPENSSL */ 281