ssh_test.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
  2. /* SPDX-License-Identifier: Unlicense */
  3. #include "tomcrypt_test.h"
  4. /**
  5. @file ssh_test.c
  6. Support for SSH data formats (RFC4251), Russ Williams
  7. */
  8. #ifdef LTC_SSH
  9. #define BUFSIZE 64
  10. /**
  11. Test vectors from from RFC4251, section 5
  12. uint32: "the value 699921578 (0x29b7f4aa) is stored as 29 b7 f4 aa"
  13. string: "the US-ASCII string "testing" is represented as 00 00 00 07 t e s t i n g"
  14. mpint:
  15. value (hex) representation (hex)
  16. ----------- --------------------
  17. 0 00 00 00 00
  18. 9a378f9b2e332a7 00 00 00 08 09 a3 78 f9 b2 e3 32 a7
  19. 80 00 00 00 02 00 80
  20. -1234 00 00 00 02 ed cc
  21. -deadbeef 00 00 00 05 ff 21 52 41 11
  22. name-list:
  23. value representation (hex)
  24. ----- --------------------
  25. (), the empty name-list 00 00 00 00
  26. ("zlib") 00 00 00 04 7a 6c 69 62
  27. ("zlib,none") 00 00 00 09 7a 6c 69 62 2c 6e 6f 6e 65
  28. */
  29. static const unsigned char byte1[] = {0x01};
  30. static const unsigned char byte2[] = {0x71};
  31. static const unsigned char uint32[] = {0x29, 0xb7, 0xf4, 0xaa};
  32. static const unsigned char uint64[] = {0x09, 0xa3, 0x78, 0xf9, 0xb2, 0xe3, 0x32, 0xa7};
  33. static const unsigned char string[] = {0x00, 0x00, 0x00, 0x07, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67};
  34. static const unsigned char mpint1[] = {0x00, 0x00, 0x00, 0x00};
  35. static const unsigned char mpint2[] = {0x00, 0x00, 0x00, 0x08, 0x09, 0xa3, 0x78, 0xf9, 0xb2, 0xe3, 0x32, 0xa7};
  36. static const unsigned char mpint3[] = {0x00, 0x00, 0x00, 0x02, 0x00, 0x80};
  37. static const unsigned char nlist1[] = {0x00, 0x00, 0x00, 0x00};
  38. static const unsigned char nlist2[] = {0x00, 0x00, 0x00, 0x04, 0x7a, 0x6c, 0x69, 0x62};
  39. static const unsigned char nlist3[] = {0x00, 0x00, 0x00, 0x09, 0x7a, 0x6c, 0x69, 0x62, 0x2c, 0x6e, 0x6f, 0x6e, 0x65};
  40. /**
  41. LTC_SSH encoding test
  42. @return CRYPT_OK if successful
  43. */
  44. static int s_ssh_encoding_test(void)
  45. {
  46. unsigned char buffer[BUFSIZE];
  47. unsigned long buflen;
  48. unsigned long len;
  49. void *v, *zero;
  50. int err;
  51. /* Buffer too short */
  52. buflen = 3;
  53. zeromem(buffer, BUFSIZE);
  54. SHOULD_FAIL(ssh_encode_sequence_multi(buffer, &buflen,
  55. LTC_SSHDATA_UINT32, 0x29b7f4aa,
  56. LTC_SSHDATA_EOL, NULL));
  57. /* byte */
  58. buflen = BUFSIZE;
  59. zeromem(buffer, BUFSIZE);
  60. DO(ssh_encode_sequence_multi(buffer, &buflen,
  61. LTC_SSHDATA_BYTE, 0x01,
  62. LTC_SSHDATA_EOL, NULL));
  63. COMPARE_TESTVECTOR(buffer, buflen, byte1, sizeof(byte1), "enc-byte", 1);
  64. buflen = BUFSIZE;
  65. zeromem(buffer, BUFSIZE);
  66. DO(ssh_encode_sequence_multi(buffer, &buflen,
  67. LTC_SSHDATA_BYTE, 0x71,
  68. LTC_SSHDATA_EOL, NULL));
  69. COMPARE_TESTVECTOR(buffer, buflen, byte2, sizeof(byte2), "enc-byte", 2);
  70. if (XMEMCMP(buffer, byte2, buflen) != 0) return CRYPT_FAIL_TESTVECTOR;
  71. /* boolean */
  72. buflen = BUFSIZE;
  73. zeromem(buffer, BUFSIZE);
  74. DO(ssh_encode_sequence_multi(buffer, &buflen,
  75. LTC_SSHDATA_BOOLEAN, 0x01,
  76. LTC_SSHDATA_EOL, NULL));
  77. COMPARE_TESTVECTOR(buffer, buflen, byte1, sizeof(byte1), "enc-boolean", 1);
  78. buflen = BUFSIZE;
  79. zeromem(buffer, BUFSIZE);
  80. DO(ssh_encode_sequence_multi(buffer, &buflen,
  81. LTC_SSHDATA_BOOLEAN, 0x71,
  82. LTC_SSHDATA_EOL, NULL));
  83. /* Should be written out as 0x01 */
  84. COMPARE_TESTVECTOR(buffer, buflen, byte1, sizeof(byte1), "enc-boolean", 2);
  85. /* uint32 */
  86. buflen = BUFSIZE;
  87. zeromem(buffer, BUFSIZE);
  88. DO(ssh_encode_sequence_multi(buffer, &buflen,
  89. LTC_SSHDATA_UINT32, 0x29b7f4aa,
  90. LTC_SSHDATA_EOL, NULL));
  91. COMPARE_TESTVECTOR(buffer, buflen, uint32, sizeof(uint32), "enc-uint32", 1);
  92. /* uint64 */
  93. buflen = BUFSIZE;
  94. zeromem(buffer, BUFSIZE);
  95. DO(ssh_encode_sequence_multi(buffer, &buflen,
  96. LTC_SSHDATA_UINT64, CONST64(0x09a378f9b2e332a7),
  97. LTC_SSHDATA_EOL, NULL));
  98. COMPARE_TESTVECTOR(buffer, buflen, uint64, sizeof(uint64), "enc-uint64", 1);
  99. /* string */
  100. buflen = BUFSIZE;
  101. zeromem(buffer, BUFSIZE);
  102. len = strlen("testing");
  103. DO(ssh_encode_sequence_multi(buffer, &buflen,
  104. LTC_SSHDATA_STRING, "testing", len,
  105. LTC_SSHDATA_EOL, NULL));
  106. COMPARE_TESTVECTOR(buffer, buflen, string, sizeof(string), "enc-string", 1);
  107. /* mpint */
  108. if ((err = ltc_mp_init_multi(&zero, &v, LTC_NULL)) != CRYPT_OK) {
  109. return err;
  110. }
  111. buflen = BUFSIZE;
  112. zeromem(buffer, BUFSIZE);
  113. DO(ltc_mp_set(zero, 0));
  114. DO(ssh_encode_sequence_multi(buffer, &buflen,
  115. LTC_SSHDATA_MPINT, zero,
  116. LTC_SSHDATA_EOL, NULL));
  117. COMPARE_TESTVECTOR(buffer, buflen, mpint1, sizeof(mpint1), "enc-mpint", 1);
  118. buflen = BUFSIZE;
  119. zeromem(buffer, BUFSIZE);
  120. DO(ltc_mp_read_radix(v, "9a378f9b2e332a7", 16));
  121. DO(ssh_encode_sequence_multi(buffer, &buflen,
  122. LTC_SSHDATA_MPINT, v,
  123. LTC_SSHDATA_EOL, NULL));
  124. COMPARE_TESTVECTOR(buffer, buflen, mpint2, sizeof(mpint2), "enc-mpint", 2);
  125. buflen = BUFSIZE;
  126. zeromem(buffer, BUFSIZE);
  127. DO(ltc_mp_set(v, 0x80));
  128. DO(ssh_encode_sequence_multi(buffer, &buflen,
  129. LTC_SSHDATA_MPINT, v,
  130. LTC_SSHDATA_EOL, NULL));
  131. COMPARE_TESTVECTOR(buffer, buflen, mpint3, sizeof(mpint3), "enc-mpint", 3);
  132. ltc_mp_deinit_multi(v, zero, LTC_NULL);
  133. /* name-list */
  134. buflen = BUFSIZE;
  135. zeromem(buffer, BUFSIZE);
  136. len = strlen("");
  137. DO(ssh_encode_sequence_multi(buffer, &buflen,
  138. LTC_SSHDATA_NAMELIST, "", len,
  139. LTC_SSHDATA_EOL, NULL));
  140. COMPARE_TESTVECTOR(buffer, buflen, nlist1, sizeof(nlist1), "enc-nlist", 1);
  141. buflen = BUFSIZE;
  142. zeromem(buffer, BUFSIZE);
  143. len = strlen("zlib");
  144. DO(ssh_encode_sequence_multi(buffer, &buflen,
  145. LTC_SSHDATA_NAMELIST, "zlib", len,
  146. LTC_SSHDATA_EOL, NULL));
  147. COMPARE_TESTVECTOR(buffer, buflen, nlist2, sizeof(nlist2), "enc-nlist", 2);
  148. buflen = BUFSIZE;
  149. zeromem(buffer, BUFSIZE);
  150. len = strlen("zlib,none");
  151. DO(ssh_encode_sequence_multi(buffer, &buflen,
  152. LTC_SSHDATA_NAMELIST, "zlib,none", len,
  153. LTC_SSHDATA_EOL, NULL));
  154. COMPARE_TESTVECTOR(buffer, buflen, nlist3, sizeof(nlist3), "enc-nlist", 3);
  155. return CRYPT_OK;
  156. }
  157. /**
  158. LTC_SSH decoding test
  159. @return CRYPT_OK if successful
  160. */
  161. static int s_ssh_decoding_test(void)
  162. {
  163. char strbuf[BUFSIZE];
  164. void *u, *v;
  165. unsigned long size;
  166. ulong32 tmp32;
  167. ulong64 tmp64;
  168. unsigned char tmp8;
  169. unsigned long len;
  170. int err;
  171. /* Buffer longer */
  172. len = sizeof(strbuf);
  173. strbuf[0] = 0;
  174. DO(ssh_decode_sequence_multi((unsigned char*)strbuf, &len,
  175. LTC_SSHDATA_BYTE, &tmp8,
  176. LTC_SSHDATA_EOL, NULL));
  177. ENSURE(tmp8 == 0x00);
  178. ENSURE(len == 1);
  179. /* byte */
  180. len = sizeof(byte1);
  181. DO(ssh_decode_sequence_multi(byte1, &len,
  182. LTC_SSHDATA_BYTE, &tmp8,
  183. LTC_SSHDATA_EOL, NULL));
  184. ENSURE(tmp8 == 0x01);
  185. ENSURE(len == 1);
  186. len = sizeof(byte2);
  187. DO(ssh_decode_sequence_multi(byte2, &len,
  188. LTC_SSHDATA_BYTE, &tmp8,
  189. LTC_SSHDATA_EOL, NULL));
  190. ENSURE(tmp8 == 0x71);
  191. ENSURE(len == 1);
  192. /* boolean */
  193. len = sizeof(byte1);
  194. DO(ssh_decode_sequence_multi(byte1, &len,
  195. LTC_SSHDATA_BOOLEAN, &tmp8,
  196. LTC_SSHDATA_EOL, NULL));
  197. ENSURE(tmp8 == 0x01);
  198. ENSURE(len == 1);
  199. len = sizeof(byte2);
  200. DO(ssh_decode_sequence_multi(byte2, &len,
  201. LTC_SSHDATA_BOOLEAN, &tmp8,
  202. LTC_SSHDATA_EOL, NULL));
  203. ENSURE(tmp8 == 0x01);
  204. ENSURE(len == 1);
  205. /* uint32 */
  206. len = sizeof(uint32);
  207. DO(ssh_decode_sequence_multi(uint32, &len,
  208. LTC_SSHDATA_UINT32, &tmp32,
  209. LTC_SSHDATA_EOL, NULL));
  210. ENSURE(tmp32 == 0x29b7f4aa);
  211. ENSURE(len == 4);
  212. /* uint64 */
  213. len = sizeof(uint64);
  214. DO(ssh_decode_sequence_multi(uint64, &len,
  215. LTC_SSHDATA_UINT64, &tmp64,
  216. LTC_SSHDATA_EOL, NULL));
  217. if (tmp64 != CONST64(0x09a378f9b2e332a7)) return CRYPT_FAIL_TESTVECTOR;
  218. ENSURE(len == 8);
  219. /* string */
  220. zeromem(strbuf, BUFSIZE);
  221. size = BUFSIZE;
  222. len = sizeof(string);
  223. DO(ssh_decode_sequence_multi(string, &len,
  224. LTC_SSHDATA_STRING, strbuf, &size,
  225. LTC_SSHDATA_EOL, NULL));
  226. ENSURE(strlen("testing") == size);
  227. ENSURE(XSTRCMP(strbuf, "testing") == 0);
  228. ENSURE(strlen("testing") + 4 == len);
  229. /* mpint */
  230. if ((err = ltc_mp_init_multi(&u, &v, LTC_NULL)) != CRYPT_OK) {
  231. return err;
  232. }
  233. len = sizeof(mpint1);
  234. DO(ssh_decode_sequence_multi(mpint1, &len,
  235. LTC_SSHDATA_MPINT, v,
  236. LTC_SSHDATA_EOL, NULL));
  237. ENSURE(ltc_mp_cmp_d(v, 0) == LTC_MP_EQ);
  238. ENSURE(sizeof(mpint1) == len);
  239. len = sizeof(mpint2);
  240. DO(ssh_decode_sequence_multi(mpint2, &len,
  241. LTC_SSHDATA_MPINT, v,
  242. LTC_SSHDATA_EOL, NULL));
  243. DO(ltc_mp_read_radix(u, "9a378f9b2e332a7", 16));
  244. ENSURE(ltc_mp_cmp(u, v) == LTC_MP_EQ);
  245. ENSURE(sizeof(mpint2) == len);
  246. len = sizeof(mpint3);
  247. DO(ssh_decode_sequence_multi(mpint3, &len,
  248. LTC_SSHDATA_MPINT, v,
  249. LTC_SSHDATA_EOL, NULL));
  250. ENSURE(ltc_mp_cmp_d(v, 0x80) == LTC_MP_EQ);
  251. ENSURE(sizeof(mpint3) == len);
  252. ltc_mp_deinit_multi(v, u, LTC_NULL);
  253. /* name-list */
  254. zeromem(strbuf, BUFSIZE);
  255. size = BUFSIZE;
  256. len = sizeof(nlist1);
  257. DO(ssh_decode_sequence_multi(nlist1, &len,
  258. LTC_SSHDATA_NAMELIST, strbuf, &size,
  259. LTC_SSHDATA_EOL, NULL));
  260. ENSURE(strlen("") == size);
  261. ENSURE(XSTRCMP(strbuf, "") == 0);
  262. zeromem(strbuf, BUFSIZE);
  263. size = BUFSIZE;
  264. len = sizeof(nlist2);
  265. DO(ssh_decode_sequence_multi(nlist2, &len,
  266. LTC_SSHDATA_NAMELIST, strbuf, &size,
  267. LTC_SSHDATA_EOL, NULL));
  268. ENSURE(strlen("zlib") == size);
  269. ENSURE(XSTRCMP(strbuf, "zlib") == 0);
  270. ENSURE(strlen("zlib") + 4 == len);
  271. zeromem(strbuf, BUFSIZE);
  272. size = BUFSIZE;
  273. len = sizeof(nlist3);
  274. DO(ssh_decode_sequence_multi(nlist3, &len,
  275. LTC_SSHDATA_NAMELIST, strbuf, &size,
  276. LTC_SSHDATA_EOL, NULL));
  277. ENSURE(strlen("zlib,none") == size);
  278. ENSURE(XSTRCMP(strbuf, "zlib,none") == 0);
  279. ENSURE(strlen("zlib,none") + 4 == len);
  280. return CRYPT_OK;
  281. }
  282. /**
  283. LTC_SSH self-test
  284. @return CRYPT_OK if successful, CRYPT_NOP if tests have been disabled.
  285. */
  286. int ssh_test(void)
  287. {
  288. if (ltc_mp.name == NULL) return CRYPT_NOP;
  289. DO(s_ssh_encoding_test());
  290. DO(s_ssh_decoding_test());
  291. return CRYPT_OK;
  292. }
  293. #else
  294. int ssh_test(void)
  295. {
  296. return CRYPT_NOP;
  297. }
  298. #endif