testcrypt.c 53 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715
  1. /*
  2. * testcrypt: a standalone test program that provides direct access to
  3. * PuTTY's cryptography and mp_int code.
  4. */
  5. /*
  6. * This program speaks a line-oriented protocol on standard input and
  7. * standard output. It's a half-duplex protocol: it expects to read
  8. * one line of command, and then produce a fixed amount of output
  9. * (namely a line containing a decimal integer, followed by that many
  10. * lines each containing one return value).
  11. *
  12. * The protocol is human-readable enough to make it debuggable, but
  13. * verbose enough that you probably wouldn't want to speak it by hand
  14. * at any great length. The Python program test/testcrypt.py wraps it
  15. * to give a more useful user-facing API, by invoking this binary as a
  16. * subprocess.
  17. *
  18. * (I decided that was a better idea than making this program an
  19. * actual Python module, partly because you can rewrap the same binary
  20. * in another scripting language if you prefer, but mostly because
  21. * it's easy to attach a debugger to testcrypt or to run it under
  22. * sanitisers or valgrind or what have you.)
  23. */
  24. #include <assert.h>
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28. #include <errno.h>
  29. #include "defs.h"
  30. #include "ssh.h"
  31. #include "sshkeygen.h"
  32. #include "misc.h"
  33. #include "mpint.h"
  34. #include "crypto/ecc.h"
  35. #include "crypto/ntru.h"
  36. #include "proxy/cproxy.h"
  37. static NORETURN PRINTF_LIKE(1, 2) void fatal_error(const char *p, ...)
  38. {
  39. va_list ap;
  40. fprintf(stderr, "testcrypt: ");
  41. va_start(ap, p);
  42. vfprintf(stderr, p, ap);
  43. va_end(ap);
  44. fputc('\n', stderr);
  45. exit(1);
  46. }
  47. void out_of_memory(void) { fatal_error("out of memory"); }
  48. static bool old_keyfile_warning_given;
  49. void old_keyfile_warning(void) { old_keyfile_warning_given = true; }
  50. static bufchain random_data_queue;
  51. static prng *test_prng;
  52. void random_read(void *buf, size_t size)
  53. {
  54. if (test_prng) {
  55. prng_read(test_prng, buf, size);
  56. } else {
  57. if (!bufchain_try_fetch_consume(&random_data_queue, buf, size))
  58. fatal_error("No random data in queue");
  59. }
  60. }
  61. uint64_t prng_reseed_time_ms(void)
  62. {
  63. static uint64_t previous_time = 0;
  64. return previous_time += 200;
  65. }
  66. #define VALUE_TYPES(X) \
  67. X(string, strbuf *, strbuf_free(v)) \
  68. X(mpint, mp_int *, mp_free(v)) \
  69. X(modsqrt, ModsqrtContext *, modsqrt_free(v)) \
  70. X(monty, MontyContext *, monty_free(v)) \
  71. X(wcurve, WeierstrassCurve *, ecc_weierstrass_curve_free(v)) \
  72. X(wpoint, WeierstrassPoint *, ecc_weierstrass_point_free(v)) \
  73. X(mcurve, MontgomeryCurve *, ecc_montgomery_curve_free(v)) \
  74. X(mpoint, MontgomeryPoint *, ecc_montgomery_point_free(v)) \
  75. X(ecurve, EdwardsCurve *, ecc_edwards_curve_free(v)) \
  76. X(epoint, EdwardsPoint *, ecc_edwards_point_free(v)) \
  77. X(hash, ssh_hash *, ssh_hash_free(v)) \
  78. X(key, ssh_key *, ssh_key_free(v)) \
  79. X(cipher, ssh_cipher *, ssh_cipher_free(v)) \
  80. X(mac, ssh2_mac *, ssh2_mac_free(v)) \
  81. X(dh, dh_ctx *, dh_cleanup(v)) \
  82. X(ecdh, ecdh_key *, ecdh_key_free(v)) \
  83. X(rsakex, RSAKey *, ssh_rsakex_freekey(v)) \
  84. X(rsa, RSAKey *, rsa_free(v)) \
  85. X(prng, prng *, prng_free(v)) \
  86. X(keycomponents, key_components *, key_components_free(v)) \
  87. X(pcs, PrimeCandidateSource *, pcs_free(v)) \
  88. X(pgc, PrimeGenerationContext *, primegen_free_context(v)) \
  89. X(pockle, Pockle *, pockle_free(v)) \
  90. X(millerrabin, MillerRabin *, miller_rabin_free(v)) \
  91. X(ntrukeypair, NTRUKeyPair *, ntru_keypair_free(v)) \
  92. X(ntruencodeschedule, NTRUEncodeSchedule *, ntru_encode_schedule_free(v)) \
  93. /* end of list */
  94. typedef struct Value Value;
  95. enum ValueType {
  96. #define VALTYPE_ENUM(n,t,f) VT_##n,
  97. VALUE_TYPES(VALTYPE_ENUM)
  98. #undef VALTYPE_ENUM
  99. };
  100. typedef enum ValueType ValueType;
  101. static const char *const type_names[] = {
  102. #define VALTYPE_NAME(n,t,f) #n,
  103. VALUE_TYPES(VALTYPE_NAME)
  104. #undef VALTYPE_NAME
  105. };
  106. #define VALTYPE_TYPEDEF(n,t,f) \
  107. typedef t TD_val_##n; \
  108. typedef t *TD_out_val_##n;
  109. VALUE_TYPES(VALTYPE_TYPEDEF)
  110. #undef VALTYPE_TYPEDEF
  111. struct Value {
  112. /*
  113. * Protocol identifier assigned to this value when it was created.
  114. * Lives in the same malloced block as this Value object itself.
  115. */
  116. ptrlen id;
  117. /*
  118. * Type of the value.
  119. */
  120. ValueType type;
  121. /*
  122. * Union of all the things it could hold.
  123. */
  124. union {
  125. #define VALTYPE_UNION(n,t,f) t vu_##n;
  126. VALUE_TYPES(VALTYPE_UNION)
  127. #undef VALTYPE_UNION
  128. char *bare_string;
  129. };
  130. };
  131. static int valuecmp(void *av, void *bv)
  132. {
  133. Value *a = (Value *)av, *b = (Value *)bv;
  134. return ptrlen_strcmp(a->id, b->id);
  135. }
  136. static int valuefind(void *av, void *bv)
  137. {
  138. ptrlen *a = (ptrlen *)av;
  139. Value *b = (Value *)bv;
  140. return ptrlen_strcmp(*a, b->id);
  141. }
  142. static tree234 *values;
  143. static Value *value_new(ValueType vt)
  144. {
  145. static uint64_t next_index = 0;
  146. char *name = dupprintf("%s%"PRIu64, type_names[vt], next_index++);
  147. size_t namelen = strlen(name);
  148. Value *val = snew_plus(Value, namelen+1);
  149. memcpy(snew_plus_get_aux(val), name, namelen+1);
  150. val->id.ptr = snew_plus_get_aux(val);
  151. val->id.len = namelen;
  152. val->type = vt;
  153. Value *added = add234(values, val);
  154. assert(added == val);
  155. sfree(name);
  156. return val;
  157. }
  158. #define VALTYPE_RETURNFN(n,t,f) \
  159. void return_val_##n(strbuf *out, t v) { \
  160. Value *val = value_new(VT_##n); \
  161. val->vu_##n = v; \
  162. put_datapl(out, val->id); \
  163. put_byte(out, '\n'); \
  164. }
  165. VALUE_TYPES(VALTYPE_RETURNFN)
  166. #undef VALTYPE_RETURNFN
  167. static ptrlen get_word(BinarySource *in)
  168. {
  169. ptrlen toret;
  170. toret.ptr = get_ptr(in);
  171. toret.len = 0;
  172. while (get_avail(in) && get_byte(in) != ' ')
  173. toret.len++;
  174. return toret;
  175. }
  176. typedef uintmax_t TD_uint;
  177. typedef bool TD_boolean;
  178. typedef ptrlen TD_val_string_ptrlen;
  179. typedef char *TD_val_string_asciz;
  180. typedef BinarySource *TD_val_string_binarysource;
  181. typedef unsigned *TD_out_uint;
  182. typedef BinarySink *TD_out_val_string_binarysink;
  183. typedef const char *TD_opt_val_string_asciz;
  184. typedef char **TD_out_val_string_asciz;
  185. typedef char **TD_out_opt_val_string_asciz;
  186. typedef const char **TD_out_opt_val_string_asciz_const;
  187. typedef const ssh_hashalg *TD_hashalg;
  188. typedef const ssh2_macalg *TD_macalg;
  189. typedef const ssh_keyalg *TD_keyalg;
  190. typedef const ssh_cipheralg *TD_cipheralg;
  191. typedef const ssh_kex *TD_dh_group;
  192. typedef const ssh_kex *TD_ecdh_alg;
  193. typedef RsaSsh1Order TD_rsaorder;
  194. typedef key_components *TD_keycomponents;
  195. typedef const PrimeGenerationPolicy *TD_primegenpolicy;
  196. typedef struct mpint_list TD_mpint_list;
  197. typedef struct int16_list *TD_int16_list;
  198. typedef PockleStatus TD_pocklestatus;
  199. typedef struct mr_result TD_mr_result;
  200. typedef Argon2Flavour TD_argon2flavour;
  201. typedef FingerprintType TD_fptype;
  202. typedef HttpDigestHash TD_httpdigesthash;
  203. #define BEGIN_ENUM_TYPE(name) \
  204. static bool enum_translate_##name(ptrlen valname, TD_##name *out) { \
  205. static const struct { \
  206. const char *key; \
  207. TD_##name value; \
  208. } mapping[] = {
  209. #define ENUM_VALUE(name, value) {name, value},
  210. #define END_ENUM_TYPE(name) \
  211. }; \
  212. for (size_t i = 0; i < lenof(mapping); i++) \
  213. if (ptrlen_eq_string(valname, mapping[i].key)) { \
  214. if (out) \
  215. *out = mapping[i].value; \
  216. return true; \
  217. } \
  218. return false; \
  219. } \
  220. \
  221. static TD_##name get_##name(BinarySource *in) { \
  222. ptrlen valname = get_word(in); \
  223. TD_##name out; \
  224. if (enum_translate_##name(valname, &out)) \
  225. return out; \
  226. else \
  227. fatal_error("%s '%.*s': not found", \
  228. #name, PTRLEN_PRINTF(valname)); \
  229. }
  230. #include "testcrypt-enum.h"
  231. #undef BEGIN_ENUM_TYPE
  232. #undef ENUM_VALUE
  233. #undef END_ENUM_TYPE
  234. static uintmax_t get_uint(BinarySource *in)
  235. {
  236. ptrlen word = get_word(in);
  237. char *string = mkstr(word);
  238. uintmax_t toret = strtoumax(string, NULL, 0);
  239. sfree(string);
  240. return toret;
  241. }
  242. static bool get_boolean(BinarySource *in)
  243. {
  244. return ptrlen_eq_string(get_word(in), "true");
  245. }
  246. static Value *lookup_value(ptrlen word)
  247. {
  248. Value *val = find234(values, &word, valuefind);
  249. if (!val)
  250. fatal_error("id '%.*s': not found", PTRLEN_PRINTF(word));
  251. return val;
  252. }
  253. static Value *get_value(BinarySource *in)
  254. {
  255. return lookup_value(get_word(in));
  256. }
  257. typedef void (*finaliser_fn_t)(strbuf *out, void *ctx);
  258. struct finaliser {
  259. finaliser_fn_t fn;
  260. void *ctx;
  261. };
  262. static struct finaliser *finalisers;
  263. static size_t nfinalisers, finalisersize;
  264. static void add_finaliser(finaliser_fn_t fn, void *ctx)
  265. {
  266. sgrowarray(finalisers, finalisersize, nfinalisers);
  267. finalisers[nfinalisers].fn = fn;
  268. finalisers[nfinalisers].ctx = ctx;
  269. nfinalisers++;
  270. }
  271. static void run_finalisers(strbuf *out)
  272. {
  273. for (size_t i = 0; i < nfinalisers; i++)
  274. finalisers[i].fn(out, finalisers[i].ctx);
  275. nfinalisers = 0;
  276. }
  277. static void finaliser_return_value(strbuf *out, void *ctx)
  278. {
  279. Value *val = (Value *)ctx;
  280. put_datapl(out, val->id);
  281. put_byte(out, '\n');
  282. }
  283. static void finaliser_sfree(strbuf *out, void *ctx)
  284. {
  285. sfree(ctx);
  286. }
  287. #define VALTYPE_GETFN(n,t,f) \
  288. static Value *unwrap_value_##n(Value *val) { \
  289. ValueType expected = VT_##n; \
  290. if (expected != val->type) \
  291. fatal_error("id '%.*s': expected %s, got %s", \
  292. PTRLEN_PRINTF(val->id), \
  293. type_names[expected], type_names[val->type]); \
  294. return val; \
  295. } \
  296. static Value *get_value_##n(BinarySource *in) { \
  297. return unwrap_value_##n(get_value(in)); \
  298. } \
  299. static t get_val_##n(BinarySource *in) { \
  300. return get_value_##n(in)->vu_##n; \
  301. }
  302. VALUE_TYPES(VALTYPE_GETFN)
  303. #undef VALTYPE_GETFN
  304. static ptrlen get_val_string_ptrlen(BinarySource *in)
  305. {
  306. return ptrlen_from_strbuf(get_val_string(in));
  307. }
  308. static char *get_val_string_asciz(BinarySource *in)
  309. {
  310. return get_val_string(in)->s;
  311. }
  312. static strbuf *get_opt_val_string(BinarySource *in);
  313. static char *get_opt_val_string_asciz(BinarySource *in)
  314. {
  315. strbuf *sb = get_opt_val_string(in);
  316. return sb ? sb->s : NULL;
  317. }
  318. static mp_int **get_out_val_mpint(BinarySource *in)
  319. {
  320. Value *val = value_new(VT_mpint);
  321. add_finaliser(finaliser_return_value, val);
  322. return &val->vu_mpint;
  323. }
  324. struct mpint_list {
  325. size_t n;
  326. mp_int **integers;
  327. };
  328. static struct mpint_list get_mpint_list(BinarySource *in)
  329. {
  330. size_t n = get_uint(in);
  331. struct mpint_list mpl;
  332. mpl.n = n;
  333. mpl.integers = snewn(n, mp_int *);
  334. for (size_t i = 0; i < n; i++)
  335. mpl.integers[i] = get_val_mpint(in);
  336. add_finaliser(finaliser_sfree, mpl.integers);
  337. return mpl;
  338. }
  339. typedef struct int16_list {
  340. size_t n;
  341. uint16_t *integers;
  342. } int16_list;
  343. static void finaliser_int16_list_free(strbuf *out, void *vlist)
  344. {
  345. int16_list *list = (int16_list *)vlist;
  346. sfree(list->integers);
  347. sfree(list);
  348. }
  349. static int16_list *make_int16_list(size_t n)
  350. {
  351. int16_list *list = snew(int16_list);
  352. list->n = n;
  353. list->integers = snewn(n, uint16_t);
  354. add_finaliser(finaliser_int16_list_free, list);
  355. return list;
  356. }
  357. static int16_list *get_int16_list(BinarySource *in)
  358. {
  359. size_t n = get_uint(in);
  360. int16_list *list = make_int16_list(n);
  361. for (size_t i = 0; i < n; i++)
  362. list->integers[i] = get_uint(in);
  363. return list;
  364. }
  365. static void return_int16_list(strbuf *out, int16_list *list)
  366. {
  367. for (size_t i = 0; i < list->n; i++) {
  368. if (i > 0)
  369. put_byte(out, ',');
  370. put_fmt(out, "%d", (int)(int16_t)list->integers[i]);
  371. }
  372. put_byte(out, '\n');
  373. }
  374. static void finaliser_return_uint(strbuf *out, void *ctx)
  375. {
  376. unsigned *uval = (unsigned *)ctx;
  377. put_fmt(out, "%u\n", *uval);
  378. sfree(uval);
  379. }
  380. static unsigned *get_out_uint(BinarySource *in)
  381. {
  382. unsigned *uval = snew(unsigned);
  383. add_finaliser(finaliser_return_uint, uval);
  384. return uval;
  385. }
  386. static BinarySink *get_out_val_string_binarysink(BinarySource *in)
  387. {
  388. Value *val = value_new(VT_string);
  389. val->vu_string = strbuf_new();
  390. add_finaliser(finaliser_return_value, val);
  391. return BinarySink_UPCAST(val->vu_string);
  392. }
  393. static void return_val_string_asciz_const(strbuf *out, const char *s);
  394. static void return_val_string_asciz(strbuf *out, char *s);
  395. static void finaliser_return_opt_string_asciz(strbuf *out, void *ctx)
  396. {
  397. char **valp = (char **)ctx;
  398. char *val = *valp;
  399. sfree(valp);
  400. if (!val)
  401. put_fmt(out, "NULL\n");
  402. else
  403. return_val_string_asciz(out, val);
  404. }
  405. static char **get_out_opt_val_string_asciz(BinarySource *in)
  406. {
  407. char **valp = snew(char *);
  408. *valp = NULL;
  409. add_finaliser(finaliser_return_opt_string_asciz, valp);
  410. return valp;
  411. }
  412. static void finaliser_return_opt_string_asciz_const(strbuf *out, void *ctx)
  413. {
  414. const char **valp = (const char **)ctx;
  415. const char *val = *valp;
  416. sfree(valp);
  417. if (!val)
  418. put_fmt(out, "NULL\n");
  419. else
  420. return_val_string_asciz_const(out, val);
  421. }
  422. static const char **get_out_opt_val_string_asciz_const(BinarySource *in)
  423. {
  424. const char **valp = snew(const char *);
  425. *valp = NULL;
  426. add_finaliser(finaliser_return_opt_string_asciz_const, valp);
  427. return valp;
  428. }
  429. static BinarySource *get_val_string_binarysource(BinarySource *in)
  430. {
  431. strbuf *sb = get_val_string(in);
  432. BinarySource *src = snew(BinarySource);
  433. BinarySource_BARE_INIT(src, sb->u, sb->len);
  434. add_finaliser(finaliser_sfree, src);
  435. return src;
  436. }
  437. #define GET_CONSUMED_FN(type) \
  438. typedef TD_val_##type TD_consumed_val_##type; \
  439. static TD_val_##type get_consumed_val_##type(BinarySource *in) \
  440. { \
  441. Value *val = get_value_##type(in); \
  442. TD_val_##type toret = val->vu_##type; \
  443. del234(values, val); \
  444. sfree(val); \
  445. return toret; \
  446. }
  447. GET_CONSUMED_FN(hash)
  448. GET_CONSUMED_FN(pcs)
  449. static void return_int(strbuf *out, intmax_t u)
  450. {
  451. put_fmt(out, "%"PRIdMAX"\n", u);
  452. }
  453. static void return_uint(strbuf *out, uintmax_t u)
  454. {
  455. put_fmt(out, "0x%"PRIXMAX"\n", u);
  456. }
  457. static void return_boolean(strbuf *out, bool b)
  458. {
  459. put_fmt(out, "%s\n", b ? "true" : "false");
  460. }
  461. static void return_pocklestatus(strbuf *out, PockleStatus status)
  462. {
  463. switch (status) {
  464. default:
  465. put_fmt(out, "POCKLE_BAD_STATUS_VALUE\n");
  466. break;
  467. #define STATUS_CASE(id) \
  468. case id: \
  469. put_fmt(out, "%s\n", #id); \
  470. break;
  471. POCKLE_STATUSES(STATUS_CASE);
  472. #undef STATUS_CASE
  473. }
  474. }
  475. static void return_mr_result(strbuf *out, struct mr_result result)
  476. {
  477. if (!result.passed)
  478. put_fmt(out, "failed\n");
  479. else if (!result.potential_primitive_root)
  480. put_fmt(out, "passed\n");
  481. else
  482. put_fmt(out, "passed+ppr\n");
  483. }
  484. static void return_val_string_asciz_const(strbuf *out, const char *s)
  485. {
  486. strbuf *sb = strbuf_new();
  487. put_data(sb, s, strlen(s));
  488. return_val_string(out, sb);
  489. }
  490. static void return_val_string_asciz(strbuf *out, char *s)
  491. {
  492. return_val_string_asciz_const(out, s);
  493. sfree(s);
  494. }
  495. #define NULLABLE_RETURN_WRAPPER(type_name, c_type) \
  496. static void return_opt_##type_name(strbuf *out, c_type ptr) \
  497. { \
  498. if (!ptr) \
  499. put_fmt(out, "NULL\n"); \
  500. else \
  501. return_##type_name(out, ptr); \
  502. }
  503. NULLABLE_RETURN_WRAPPER(val_string, strbuf *)
  504. NULLABLE_RETURN_WRAPPER(val_string_asciz, char *)
  505. NULLABLE_RETURN_WRAPPER(val_string_asciz_const, const char *)
  506. NULLABLE_RETURN_WRAPPER(val_cipher, ssh_cipher *)
  507. NULLABLE_RETURN_WRAPPER(val_mac, ssh2_mac *)
  508. NULLABLE_RETURN_WRAPPER(val_hash, ssh_hash *)
  509. NULLABLE_RETURN_WRAPPER(val_key, ssh_key *)
  510. NULLABLE_RETURN_WRAPPER(val_mpint, mp_int *)
  511. NULLABLE_RETURN_WRAPPER(int16_list, int16_list *)
  512. static void handle_hello(BinarySource *in, strbuf *out)
  513. {
  514. put_fmt(out, "hello, world\n");
  515. }
  516. static void rsa_free(RSAKey *rsa)
  517. {
  518. freersakey(rsa);
  519. sfree(rsa);
  520. }
  521. static void free_value(Value *val)
  522. {
  523. switch (val->type) {
  524. #define VALTYPE_FREE(n,t,f) case VT_##n: { t v = val->vu_##n; (f); break; }
  525. VALUE_TYPES(VALTYPE_FREE)
  526. #undef VALTYPE_FREE
  527. }
  528. sfree(val);
  529. }
  530. static void handle_free(BinarySource *in, strbuf *out)
  531. {
  532. Value *val = get_value(in);
  533. del234(values, val);
  534. free_value(val);
  535. }
  536. static void handle_newstring(BinarySource *in, strbuf *out)
  537. {
  538. strbuf *sb = strbuf_new();
  539. while (get_avail(in)) {
  540. char c = get_byte(in);
  541. if (c == '%') {
  542. char hex[3];
  543. hex[0] = get_byte(in);
  544. if (hex[0] != '%') {
  545. hex[1] = get_byte(in);
  546. hex[2] = '\0';
  547. c = strtoul(hex, NULL, 16);
  548. }
  549. }
  550. put_byte(sb, c);
  551. }
  552. return_val_string(out, sb);
  553. }
  554. static void handle_getstring(BinarySource *in, strbuf *out)
  555. {
  556. strbuf *sb = get_val_string(in);
  557. for (size_t i = 0; i < sb->len; i++) {
  558. char c = sb->s[i];
  559. if (c > ' ' && c < 0x7F && c != '%') {
  560. put_byte(out, c);
  561. } else {
  562. put_fmt(out, "%%%02X", 0xFFU & (unsigned)c);
  563. }
  564. }
  565. put_byte(out, '\n');
  566. }
  567. static void handle_mp_literal(BinarySource *in, strbuf *out)
  568. {
  569. ptrlen pl = get_word(in);
  570. char *str = mkstr(pl);
  571. mp_int *mp = mp__from_string_literal(str);
  572. sfree(str);
  573. return_val_mpint(out, mp);
  574. }
  575. static void handle_mp_dump(BinarySource *in, strbuf *out)
  576. {
  577. mp_int *mp = get_val_mpint(in);
  578. for (size_t i = mp_max_bytes(mp); i-- > 0 ;)
  579. put_fmt(out, "%02X", mp_get_byte(mp, i));
  580. put_byte(out, '\n');
  581. }
  582. static void handle_checkenum(BinarySource *in, strbuf *out)
  583. {
  584. ptrlen type = get_word(in);
  585. ptrlen value = get_word(in);
  586. bool ok = false;
  587. #define BEGIN_ENUM_TYPE(name) \
  588. if (ptrlen_eq_string(type, #name)) \
  589. ok = enum_translate_##name(value, NULL);
  590. #define ENUM_VALUE(name, value)
  591. #define END_ENUM_TYPE(name)
  592. #include "testcrypt-enum.h"
  593. #undef BEGIN_ENUM_TYPE
  594. #undef ENUM_VALUE
  595. #undef END_ENUM_TYPE
  596. put_dataz(out, ok ? "ok\n" : "bad\n");
  597. }
  598. static void random_queue(ptrlen pl)
  599. {
  600. bufchain_add(&random_data_queue, pl.ptr, pl.len);
  601. }
  602. static size_t random_queue_len(void)
  603. {
  604. return bufchain_size(&random_data_queue);
  605. }
  606. static void random_clear(void)
  607. {
  608. if (test_prng) {
  609. prng_free(test_prng);
  610. test_prng = NULL;
  611. }
  612. bufchain_clear(&random_data_queue);
  613. }
  614. static void random_make_prng(const ssh_hashalg *hashalg, ptrlen seed)
  615. {
  616. random_clear();
  617. test_prng = prng_new(hashalg);
  618. prng_seed_begin(test_prng);
  619. put_datapl(test_prng, seed);
  620. prng_seed_finish(test_prng);
  621. }
  622. mp_int *monty_identity_wrapper(MontyContext *mc)
  623. {
  624. return mp_copy(monty_identity(mc));
  625. }
  626. mp_int *monty_modulus_wrapper(MontyContext *mc)
  627. {
  628. return mp_copy(monty_modulus(mc));
  629. }
  630. strbuf *ssh_hash_digest_wrapper(ssh_hash *h)
  631. {
  632. strbuf *sb = strbuf_new();
  633. void *p = strbuf_append(sb, ssh_hash_alg(h)->hlen);
  634. ssh_hash_digest(h, p);
  635. return sb;
  636. }
  637. strbuf *ssh_hash_final_wrapper(ssh_hash *h)
  638. {
  639. strbuf *sb = strbuf_new();
  640. void *p = strbuf_append(sb, ssh_hash_alg(h)->hlen);
  641. ssh_hash_final(h, p);
  642. return sb;
  643. }
  644. void ssh_cipher_setiv_wrapper(ssh_cipher *c, ptrlen iv)
  645. {
  646. if (iv.len != ssh_cipher_alg(c)->blksize)
  647. fatal_error("ssh_cipher_setiv: needs exactly %d bytes",
  648. ssh_cipher_alg(c)->blksize);
  649. ssh_cipher_setiv(c, iv.ptr);
  650. }
  651. void ssh_cipher_setkey_wrapper(ssh_cipher *c, ptrlen key)
  652. {
  653. if (key.len != ssh_cipher_alg(c)->padded_keybytes)
  654. fatal_error("ssh_cipher_setkey: needs exactly %d bytes",
  655. ssh_cipher_alg(c)->padded_keybytes);
  656. ssh_cipher_setkey(c, key.ptr);
  657. }
  658. strbuf *ssh_cipher_encrypt_wrapper(ssh_cipher *c, ptrlen input)
  659. {
  660. if (input.len % ssh_cipher_alg(c)->blksize)
  661. fatal_error("ssh_cipher_encrypt: needs a multiple of %d bytes",
  662. ssh_cipher_alg(c)->blksize);
  663. strbuf *sb = strbuf_dup(input);
  664. ssh_cipher_encrypt(c, sb->u, sb->len);
  665. return sb;
  666. }
  667. strbuf *ssh_cipher_decrypt_wrapper(ssh_cipher *c, ptrlen input)
  668. {
  669. if (input.len % ssh_cipher_alg(c)->blksize)
  670. fatal_error("ssh_cipher_decrypt: needs a multiple of %d bytes",
  671. ssh_cipher_alg(c)->blksize);
  672. strbuf *sb = strbuf_dup(input);
  673. ssh_cipher_decrypt(c, sb->u, sb->len);
  674. return sb;
  675. }
  676. strbuf *ssh_cipher_encrypt_length_wrapper(ssh_cipher *c, ptrlen input,
  677. unsigned long seq)
  678. {
  679. if (input.len != 4)
  680. fatal_error("ssh_cipher_encrypt_length: needs exactly 4 bytes");
  681. strbuf *sb = strbuf_dup(input);
  682. ssh_cipher_encrypt_length(c, sb->u, sb->len, seq);
  683. return sb;
  684. }
  685. strbuf *ssh_cipher_decrypt_length_wrapper(ssh_cipher *c, ptrlen input,
  686. unsigned long seq)
  687. {
  688. if (input.len != 4)
  689. fatal_error("ssh_cipher_decrypt_length: needs exactly 4 bytes");
  690. strbuf *sb = strbuf_dup(input);
  691. ssh_cipher_decrypt_length(c, sb->u, sb->len, seq);
  692. return sb;
  693. }
  694. strbuf *ssh2_mac_genresult_wrapper(ssh2_mac *m)
  695. {
  696. strbuf *sb = strbuf_new();
  697. void *u = strbuf_append(sb, ssh2_mac_alg(m)->len);
  698. ssh2_mac_genresult(m, u);
  699. return sb;
  700. }
  701. ssh_key *ssh_key_base_key_wrapper(ssh_key *key)
  702. {
  703. /* To avoid having to explain the borrowed reference to Python,
  704. * just clone the key unconditionally */
  705. return ssh_key_clone(ssh_key_base_key(key));
  706. }
  707. void ssh_key_ca_public_blob_wrapper(ssh_key *key, BinarySink *out)
  708. {
  709. /* Wrap to avoid null-pointer dereference */
  710. if (!key->vt->is_certificate)
  711. fatal_error("ssh_key_ca_public_blob: needs a certificate");
  712. ssh_key_ca_public_blob(key, out);
  713. }
  714. void ssh_key_cert_id_string_wrapper(ssh_key *key, BinarySink *out)
  715. {
  716. /* Wrap to avoid null-pointer dereference */
  717. if (!key->vt->is_certificate)
  718. fatal_error("ssh_key_cert_id_string: needs a certificate");
  719. ssh_key_cert_id_string(key, out);
  720. }
  721. static bool ssh_key_check_cert_wrapper(
  722. ssh_key *key, bool host, ptrlen principal, uint64_t time, ptrlen optstr,
  723. BinarySink *error)
  724. {
  725. /* Wrap to avoid null-pointer dereference */
  726. if (!key->vt->is_certificate)
  727. fatal_error("ssh_key_cert_id_string: needs a certificate");
  728. ca_options opts;
  729. opts.permit_rsa_sha1 = true;
  730. opts.permit_rsa_sha256 = true;
  731. opts.permit_rsa_sha512 = true;
  732. while (optstr.len) {
  733. ptrlen word = ptrlen_get_word(&optstr, ",");
  734. ptrlen key = word, value = PTRLEN_LITERAL("");
  735. const char *comma = memchr(word.ptr, '=', word.len);
  736. if (comma) {
  737. key.len = comma - (const char *)word.ptr;
  738. value.ptr = comma + 1;
  739. value.len = word.len - key.len - 1;
  740. }
  741. if (ptrlen_eq_string(key, "permit_rsa_sha1"))
  742. opts.permit_rsa_sha1 = ptrlen_eq_string(value, "true");
  743. if (ptrlen_eq_string(key, "permit_rsa_sha256"))
  744. opts.permit_rsa_sha256 = ptrlen_eq_string(value, "true");
  745. if (ptrlen_eq_string(key, "permit_rsa_sha512"))
  746. opts.permit_rsa_sha512 = ptrlen_eq_string(value, "true");
  747. }
  748. return ssh_key_check_cert(key, host, principal, time, &opts, error);
  749. }
  750. bool dh_validate_f_wrapper(dh_ctx *dh, mp_int *f)
  751. {
  752. return dh_validate_f(dh, f) == NULL;
  753. }
  754. void ssh_hash_update(ssh_hash *h, ptrlen pl)
  755. {
  756. put_datapl(h, pl);
  757. }
  758. void ssh2_mac_update(ssh2_mac *m, ptrlen pl)
  759. {
  760. put_datapl(m, pl);
  761. }
  762. static RSAKey *rsa_new(void)
  763. {
  764. RSAKey *rsa = snew(RSAKey);
  765. memset(rsa, 0, sizeof(RSAKey));
  766. return rsa;
  767. }
  768. strbuf *ecdh_key_getkey_wrapper(ecdh_key *ek, ptrlen remoteKey)
  769. {
  770. /* Fold the boolean return value in C into the string return value
  771. * for this purpose, by returning NULL on failure */
  772. strbuf *sb = strbuf_new();
  773. if (!ecdh_key_getkey(ek, remoteKey, BinarySink_UPCAST(sb))) {
  774. strbuf_free(sb);
  775. return NULL;
  776. }
  777. return sb;
  778. }
  779. static void int16_list_resize(int16_list *list, unsigned p)
  780. {
  781. list->integers = sresize(list->integers, p, uint16_t);
  782. for (size_t i = list->n; i < p; i++)
  783. list->integers[i] = 0;
  784. }
  785. #if 0
  786. static int16_list ntru_ring_to_list_and_free(uint16_t *out, unsigned p)
  787. {
  788. struct mpint_list mpl;
  789. mpl.n = p;
  790. mpl->integers = snewn(p, mp_int *);
  791. for (unsigned i = 0; i < p; i++)
  792. mpl->integers[i] = mp_from_integer((int16_t)out[i]);
  793. sfree(out);
  794. add_finaliser(finaliser_sfree, mpl->integers);
  795. return mpl;
  796. }
  797. #endif
  798. int16_list *ntru_ring_multiply_wrapper(
  799. int16_list *a, int16_list *b, unsigned p, unsigned q)
  800. {
  801. int16_list_resize(a, p);
  802. int16_list_resize(b, p);
  803. int16_list *out = make_int16_list(p);
  804. ntru_ring_multiply(out->integers, a->integers, b->integers, p, q);
  805. return out;
  806. }
  807. int16_list *ntru_ring_invert_wrapper(int16_list *in, unsigned p, unsigned q)
  808. {
  809. int16_list_resize(in, p);
  810. int16_list *out = make_int16_list(p);
  811. unsigned success = ntru_ring_invert(out->integers, in->integers, p, q);
  812. if (!success)
  813. return NULL;
  814. return out;
  815. }
  816. int16_list *ntru_mod3_wrapper(int16_list *in, unsigned p, unsigned q)
  817. {
  818. int16_list_resize(in, p);
  819. int16_list *out = make_int16_list(p);
  820. ntru_mod3(out->integers, in->integers, p, q);
  821. return out;
  822. }
  823. int16_list *ntru_round3_wrapper(int16_list *in, unsigned p, unsigned q)
  824. {
  825. int16_list_resize(in, p);
  826. int16_list *out = make_int16_list(p);
  827. ntru_round3(out->integers, in->integers, p, q);
  828. return out;
  829. }
  830. int16_list *ntru_bias_wrapper(int16_list *in, unsigned bias,
  831. unsigned p, unsigned q)
  832. {
  833. int16_list_resize(in, p);
  834. int16_list *out = make_int16_list(p);
  835. ntru_bias(out->integers, in->integers, bias, p, q);
  836. return out;
  837. }
  838. int16_list *ntru_scale_wrapper(int16_list *in, unsigned scale,
  839. unsigned p, unsigned q)
  840. {
  841. int16_list_resize(in, p);
  842. int16_list *out = make_int16_list(p);
  843. ntru_scale(out->integers, in->integers, scale, p, q);
  844. return out;
  845. }
  846. NTRUEncodeSchedule *ntru_encode_schedule_wrapper(int16_list *in)
  847. {
  848. return ntru_encode_schedule(in->integers, in->n);
  849. }
  850. void ntru_encode_wrapper(NTRUEncodeSchedule *sched, int16_list *rs,
  851. BinarySink *bs)
  852. {
  853. ntru_encode(sched, rs->integers, bs);
  854. }
  855. int16_list *ntru_decode_wrapper(NTRUEncodeSchedule *sched, ptrlen data)
  856. {
  857. int16_list *out = make_int16_list(ntru_encode_schedule_nvals(sched));
  858. ntru_decode(sched, out->integers, data);
  859. return out;
  860. }
  861. int16_list *ntru_gen_short_wrapper(unsigned p, unsigned w)
  862. {
  863. int16_list *out = make_int16_list(p);
  864. ntru_gen_short(out->integers, p, w);
  865. return out;
  866. }
  867. int16_list *ntru_pubkey_wrapper(NTRUKeyPair *keypair)
  868. {
  869. unsigned p = ntru_keypair_p(keypair);
  870. int16_list *out = make_int16_list(p);
  871. memcpy(out->integers, ntru_pubkey(keypair), p*sizeof(uint16_t));
  872. return out;
  873. }
  874. int16_list *ntru_encrypt_wrapper(int16_list *plaintext, int16_list *pubkey,
  875. unsigned p, unsigned q)
  876. {
  877. int16_list *out = make_int16_list(p);
  878. ntru_encrypt(out->integers, plaintext->integers, pubkey->integers, p, q);
  879. return out;
  880. }
  881. int16_list *ntru_decrypt_wrapper(int16_list *ciphertext, NTRUKeyPair *keypair)
  882. {
  883. unsigned p = ntru_keypair_p(keypair);
  884. int16_list *out = make_int16_list(p);
  885. ntru_decrypt(out->integers, ciphertext->integers, keypair);
  886. return out;
  887. }
  888. strbuf *rsa_ssh1_encrypt_wrapper(ptrlen input, RSAKey *key)
  889. {
  890. /* Fold the boolean return value in C into the string return value
  891. * for this purpose, by returning NULL on failure */
  892. strbuf *sb = strbuf_new();
  893. put_datapl(sb, input);
  894. put_padding(sb, key->bytes - input.len, 0);
  895. if (!rsa_ssh1_encrypt(sb->u, input.len, key)) {
  896. strbuf_free(sb);
  897. return NULL;
  898. }
  899. return sb;
  900. }
  901. strbuf *rsa_ssh1_decrypt_pkcs1_wrapper(mp_int *input, RSAKey *key)
  902. {
  903. /* Again, return "" on failure */
  904. strbuf *sb = strbuf_new();
  905. if (!rsa_ssh1_decrypt_pkcs1(input, key, sb))
  906. strbuf_clear(sb);
  907. return sb;
  908. }
  909. strbuf *des_encrypt_xdmauth_wrapper(ptrlen key, ptrlen data)
  910. {
  911. if (key.len != 7)
  912. fatal_error("des_encrypt_xdmauth: key must be 7 bytes long");
  913. if (data.len % 8 != 0)
  914. fatal_error("des_encrypt_xdmauth: data must be a multiple of 8 bytes");
  915. strbuf *sb = strbuf_dup(data);
  916. des_encrypt_xdmauth(key.ptr, sb->u, sb->len);
  917. return sb;
  918. }
  919. strbuf *des_decrypt_xdmauth_wrapper(ptrlen key, ptrlen data)
  920. {
  921. if (key.len != 7)
  922. fatal_error("des_decrypt_xdmauth: key must be 7 bytes long");
  923. if (data.len % 8 != 0)
  924. fatal_error("des_decrypt_xdmauth: data must be a multiple of 8 bytes");
  925. strbuf *sb = strbuf_dup(data);
  926. des_decrypt_xdmauth(key.ptr, sb->u, sb->len);
  927. return sb;
  928. }
  929. strbuf *des3_encrypt_pubkey_wrapper(ptrlen key, ptrlen data)
  930. {
  931. if (key.len != 16)
  932. fatal_error("des3_encrypt_pubkey: key must be 16 bytes long");
  933. if (data.len % 8 != 0)
  934. fatal_error("des3_encrypt_pubkey: data must be a multiple of 8 bytes");
  935. strbuf *sb = strbuf_dup(data);
  936. des3_encrypt_pubkey(key.ptr, sb->u, sb->len);
  937. return sb;
  938. }
  939. strbuf *des3_decrypt_pubkey_wrapper(ptrlen key, ptrlen data)
  940. {
  941. if (key.len != 16)
  942. fatal_error("des3_decrypt_pubkey: key must be 16 bytes long");
  943. if (data.len % 8 != 0)
  944. fatal_error("des3_decrypt_pubkey: data must be a multiple of 8 bytes");
  945. strbuf *sb = strbuf_dup(data);
  946. des3_decrypt_pubkey(key.ptr, sb->u, sb->len);
  947. return sb;
  948. }
  949. strbuf *des3_encrypt_pubkey_ossh_wrapper(ptrlen key, ptrlen iv, ptrlen data)
  950. {
  951. if (key.len != 24)
  952. fatal_error("des3_encrypt_pubkey_ossh: key must be 24 bytes long");
  953. if (iv.len != 8)
  954. fatal_error("des3_encrypt_pubkey_ossh: iv must be 8 bytes long");
  955. if (data.len % 8 != 0)
  956. fatal_error("des3_encrypt_pubkey_ossh: data must be a multiple of 8 bytes");
  957. strbuf *sb = strbuf_dup(data);
  958. des3_encrypt_pubkey_ossh(key.ptr, iv.ptr, sb->u, sb->len);
  959. return sb;
  960. }
  961. strbuf *des3_decrypt_pubkey_ossh_wrapper(ptrlen key, ptrlen iv, ptrlen data)
  962. {
  963. if (key.len != 24)
  964. fatal_error("des3_decrypt_pubkey_ossh: key must be 24 bytes long");
  965. if (iv.len != 8)
  966. fatal_error("des3_encrypt_pubkey_ossh: iv must be 8 bytes long");
  967. if (data.len % 8 != 0)
  968. fatal_error("des3_decrypt_pubkey_ossh: data must be a multiple of 8 bytes");
  969. strbuf *sb = strbuf_dup(data);
  970. des3_decrypt_pubkey_ossh(key.ptr, iv.ptr, sb->u, sb->len);
  971. return sb;
  972. }
  973. strbuf *aes256_encrypt_pubkey_wrapper(ptrlen key, ptrlen iv, ptrlen data)
  974. {
  975. if (key.len != 32)
  976. fatal_error("aes256_encrypt_pubkey: key must be 32 bytes long");
  977. if (iv.len != 16)
  978. fatal_error("aes256_encrypt_pubkey: iv must be 16 bytes long");
  979. if (data.len % 16 != 0)
  980. fatal_error("aes256_encrypt_pubkey: data must be a multiple of 16 bytes");
  981. strbuf *sb = strbuf_dup(data);
  982. aes256_encrypt_pubkey(key.ptr, iv.ptr, sb->u, sb->len);
  983. return sb;
  984. }
  985. strbuf *aes256_decrypt_pubkey_wrapper(ptrlen key, ptrlen iv, ptrlen data)
  986. {
  987. if (key.len != 32)
  988. fatal_error("aes256_decrypt_pubkey: key must be 32 bytes long");
  989. if (iv.len != 16)
  990. fatal_error("aes256_encrypt_pubkey: iv must be 16 bytes long");
  991. if (data.len % 16 != 0)
  992. fatal_error("aes256_decrypt_pubkey: data must be a multiple of 16 bytes");
  993. strbuf *sb = strbuf_dup(data);
  994. aes256_decrypt_pubkey(key.ptr, iv.ptr, sb->u, sb->len);
  995. return sb;
  996. }
  997. strbuf *prng_read_wrapper(prng *pr, size_t size)
  998. {
  999. strbuf *sb = strbuf_new();
  1000. prng_read(pr, strbuf_append(sb, size), size);
  1001. return sb;
  1002. }
  1003. void prng_seed_update(prng *pr, ptrlen data)
  1004. {
  1005. put_datapl(pr, data);
  1006. }
  1007. bool crcda_detect(ptrlen packet, ptrlen iv)
  1008. {
  1009. if (iv.len != 0 && iv.len != 8)
  1010. fatal_error("crcda_detect: iv must be empty or 8 bytes long");
  1011. if (packet.len % 8 != 0)
  1012. fatal_error("crcda_detect: packet must be a multiple of 8 bytes");
  1013. struct crcda_ctx *ctx = crcda_make_context();
  1014. bool toret = detect_attack(ctx, packet.ptr, packet.len,
  1015. iv.len ? iv.ptr : NULL);
  1016. crcda_free_context(ctx);
  1017. return toret;
  1018. }
  1019. ssh_key *ppk_load_s_wrapper(BinarySource *src, char **comment,
  1020. const char *passphrase, const char **errorstr)
  1021. {
  1022. ssh2_userkey *uk = ppk_load_s(src, passphrase, errorstr);
  1023. if (uk == SSH2_WRONG_PASSPHRASE) {
  1024. /* Fudge this special return value */
  1025. *errorstr = "SSH2_WRONG_PASSPHRASE";
  1026. return NULL;
  1027. }
  1028. if (uk == NULL)
  1029. return NULL;
  1030. ssh_key *toret = uk->key;
  1031. *comment = uk->comment;
  1032. sfree(uk);
  1033. return toret;
  1034. }
  1035. int rsa1_load_s_wrapper(BinarySource *src, RSAKey *rsa, char **comment,
  1036. const char *passphrase, const char **errorstr)
  1037. {
  1038. int toret = rsa1_load_s(src, rsa, passphrase, errorstr);
  1039. *comment = rsa->comment;
  1040. rsa->comment = NULL;
  1041. return toret;
  1042. }
  1043. strbuf *ppk_save_sb_wrapper(
  1044. ssh_key *key, const char *comment, const char *passphrase,
  1045. unsigned fmt_version, Argon2Flavour flavour,
  1046. uint32_t mem, uint32_t passes, uint32_t parallel)
  1047. {
  1048. /*
  1049. * For repeatable testing purposes, we never want a timing-dependent
  1050. * choice of password hashing parameters, so this is easy.
  1051. */
  1052. ppk_save_parameters save_params;
  1053. memset(&save_params, 0, sizeof(save_params));
  1054. save_params.fmt_version = fmt_version;
  1055. save_params.argon2_flavour = flavour;
  1056. save_params.argon2_mem = mem;
  1057. save_params.argon2_passes_auto = false;
  1058. save_params.argon2_passes = passes;
  1059. save_params.argon2_parallelism = parallel;
  1060. ssh2_userkey uk;
  1061. uk.key = key;
  1062. uk.comment = dupstr(comment);
  1063. strbuf *toret = ppk_save_sb(&uk, passphrase, &save_params);
  1064. sfree(uk.comment);
  1065. return toret;
  1066. }
  1067. strbuf *rsa1_save_sb_wrapper(RSAKey *key, const char *comment,
  1068. const char *passphrase)
  1069. {
  1070. key->comment = dupstr(comment);
  1071. strbuf *toret = rsa1_save_sb(key, passphrase);
  1072. sfree(key->comment);
  1073. key->comment = NULL;
  1074. return toret;
  1075. }
  1076. #define return_void(out, expression) (expression)
  1077. static ProgressReceiver null_progress = { .vt = &null_progress_vt };
  1078. mp_int *primegen_generate_wrapper(
  1079. PrimeGenerationContext *ctx, PrimeCandidateSource *pcs)
  1080. {
  1081. return primegen_generate(ctx, pcs, &null_progress);
  1082. }
  1083. RSAKey *rsa1_generate(int bits, bool strong, PrimeGenerationContext *pgc)
  1084. {
  1085. RSAKey *rsakey = snew(RSAKey);
  1086. rsa_generate(rsakey, bits, strong, pgc, &null_progress);
  1087. rsakey->comment = NULL;
  1088. return rsakey;
  1089. }
  1090. ssh_key *rsa_generate_wrapper(int bits, bool strong,
  1091. PrimeGenerationContext *pgc)
  1092. {
  1093. return &rsa1_generate(bits, strong, pgc)->sshk;
  1094. }
  1095. ssh_key *dsa_generate_wrapper(int bits, PrimeGenerationContext *pgc)
  1096. {
  1097. struct dsa_key *dsakey = snew(struct dsa_key);
  1098. dsa_generate(dsakey, bits, pgc, &null_progress);
  1099. return &dsakey->sshk;
  1100. }
  1101. ssh_key *ecdsa_generate_wrapper(int bits)
  1102. {
  1103. struct ecdsa_key *ek = snew(struct ecdsa_key);
  1104. if (!ecdsa_generate(ek, bits)) {
  1105. sfree(ek);
  1106. return NULL;
  1107. }
  1108. return &ek->sshk;
  1109. }
  1110. ssh_key *eddsa_generate_wrapper(int bits)
  1111. {
  1112. struct eddsa_key *ek = snew(struct eddsa_key);
  1113. if (!eddsa_generate(ek, bits)) {
  1114. sfree(ek);
  1115. return NULL;
  1116. }
  1117. return &ek->sshk;
  1118. }
  1119. size_t key_components_count(key_components *kc) { return kc->ncomponents; }
  1120. const char *key_components_nth_name(key_components *kc, size_t n)
  1121. {
  1122. return (n >= kc->ncomponents ? NULL :
  1123. kc->components[n].name);
  1124. }
  1125. strbuf *key_components_nth_str(key_components *kc, size_t n)
  1126. {
  1127. if (n >= kc->ncomponents)
  1128. return NULL;
  1129. if (kc->components[n].type != KCT_TEXT &&
  1130. kc->components[n].type != KCT_BINARY)
  1131. return NULL;
  1132. return strbuf_dup(ptrlen_from_strbuf(kc->components[n].str));
  1133. }
  1134. mp_int *key_components_nth_mp(key_components *kc, size_t n)
  1135. {
  1136. return (n >= kc->ncomponents ? NULL :
  1137. kc->components[n].type != KCT_MPINT ? NULL :
  1138. mp_copy(kc->components[n].mp));
  1139. }
  1140. PockleStatus pockle_add_prime_wrapper(Pockle *pockle, mp_int *p,
  1141. struct mpint_list mpl, mp_int *witness)
  1142. {
  1143. return pockle_add_prime(pockle, p, mpl.integers, mpl.n, witness);
  1144. }
  1145. strbuf *argon2_wrapper(Argon2Flavour flavour, uint32_t mem, uint32_t passes,
  1146. uint32_t parallel, uint32_t taglen,
  1147. ptrlen P, ptrlen S, ptrlen K, ptrlen X)
  1148. {
  1149. strbuf *out = strbuf_new();
  1150. argon2(flavour, mem, passes, parallel, taglen, P, S, K, X, out);
  1151. return out;
  1152. }
  1153. strbuf *openssh_bcrypt_wrapper(ptrlen passphrase, ptrlen salt,
  1154. unsigned rounds, unsigned outbytes)
  1155. {
  1156. strbuf *out = strbuf_new();
  1157. openssh_bcrypt(passphrase, salt, rounds,
  1158. strbuf_append(out, outbytes), outbytes);
  1159. return out;
  1160. }
  1161. strbuf *get_implementations_commasep(ptrlen alg)
  1162. {
  1163. strbuf *out = strbuf_new();
  1164. put_datapl(out, alg);
  1165. if (ptrlen_startswith(alg, PTRLEN_LITERAL("aesgcm"), NULL)) {
  1166. put_fmt(out, ",%.*s_sw", PTRLEN_PRINTF(alg));
  1167. put_fmt(out, ",%.*s_ref_poly", PTRLEN_PRINTF(alg));
  1168. #if HAVE_CLMUL
  1169. put_fmt(out, ",%.*s_clmul", PTRLEN_PRINTF(alg));
  1170. #endif
  1171. #if HAVE_NEON_PMULL
  1172. put_fmt(out, ",%.*s_neon", PTRLEN_PRINTF(alg));
  1173. #endif
  1174. } else if (ptrlen_startswith(alg, PTRLEN_LITERAL("aes"), NULL)) {
  1175. put_fmt(out, ",%.*s_sw", PTRLEN_PRINTF(alg));
  1176. #if HAVE_AES_NI
  1177. put_fmt(out, ",%.*s_ni", PTRLEN_PRINTF(alg));
  1178. #endif
  1179. #if HAVE_NEON_CRYPTO
  1180. put_fmt(out, ",%.*s_neon", PTRLEN_PRINTF(alg));
  1181. #endif
  1182. } else if (ptrlen_startswith(alg, PTRLEN_LITERAL("sha256"), NULL) ||
  1183. ptrlen_startswith(alg, PTRLEN_LITERAL("sha1"), NULL)) {
  1184. put_fmt(out, ",%.*s_sw", PTRLEN_PRINTF(alg));
  1185. #if HAVE_SHA_NI
  1186. put_fmt(out, ",%.*s_ni", PTRLEN_PRINTF(alg));
  1187. #endif
  1188. #if HAVE_NEON_CRYPTO
  1189. put_fmt(out, ",%.*s_neon", PTRLEN_PRINTF(alg));
  1190. #endif
  1191. } else if (ptrlen_startswith(alg, PTRLEN_LITERAL("sha512"), NULL)) {
  1192. put_fmt(out, ",%.*s_sw", PTRLEN_PRINTF(alg));
  1193. #if HAVE_NEON_SHA512
  1194. put_fmt(out, ",%.*s_neon", PTRLEN_PRINTF(alg));
  1195. #endif
  1196. }
  1197. return out;
  1198. }
  1199. #define OPTIONAL_PTR_FUNC(type) \
  1200. typedef TD_val_##type TD_opt_val_##type; \
  1201. static TD_opt_val_##type get_opt_val_##type(BinarySource *in) { \
  1202. ptrlen word = get_word(in); \
  1203. if (ptrlen_eq_string(word, "NULL")) \
  1204. return NULL; \
  1205. return unwrap_value_##type(lookup_value(word))->vu_##type; \
  1206. }
  1207. OPTIONAL_PTR_FUNC(cipher)
  1208. OPTIONAL_PTR_FUNC(mpint)
  1209. OPTIONAL_PTR_FUNC(string)
  1210. /*
  1211. * HERE BE DRAGONS: the horrible C preprocessor business that reads
  1212. * testcrypt-func.h and generates a marshalling wrapper for each
  1213. * exported function.
  1214. *
  1215. * In an ideal world, we would start from a specification like this in
  1216. * testcrypt-func.h
  1217. *
  1218. * FUNC(val_foo, example, ARG(val_bar, bar), ARG(uint, n))
  1219. *
  1220. * and generate a wrapper function looking like this:
  1221. *
  1222. * static void handle_example(BinarySource *in, strbuf *out) {
  1223. * TD_val_bar bar = get_val_bar(in);
  1224. * TD_uint n = get_uint(in);
  1225. * return_val_foo(out, example(bar, n));
  1226. * }
  1227. *
  1228. * which would read the marshalled form of each function argument in
  1229. * turn from the input BinarySource via the get_<type>() function
  1230. * family defined in this file; assign each argument to a local
  1231. * variable; call the underlying C function with all those arguments;
  1232. * and then call a function of the return_<type>() family to marshal
  1233. * the output value into the output strbuf to be sent to standard
  1234. * output.
  1235. *
  1236. * With a more general macro processor such as m4, or custom code in
  1237. * Perl or Python, or a helper program like llvm-tblgen, we could just
  1238. * do that directly, reading function specifications from
  1239. * testcrypt-func.h and writing out exactly the above. But we don't
  1240. * have a fully general macro processor (since everything in that
  1241. * category introduces an extra build dependency that's awkward on
  1242. * plain Windows, or requires compiling and running a helper program
  1243. * which is awkward in a cross-compile). We only have cpp. And in cpp,
  1244. * a macro can't expand one of its arguments differently in two parts
  1245. * of its own expansion. So we have to be more clever.
  1246. *
  1247. * In place of the above code, I instead generate three successive
  1248. * declarations for each function. In simplified form they would look
  1249. * like this:
  1250. *
  1251. * typedef struct ARGS_example {
  1252. * TD_val_bar bar;
  1253. * TD_uint n;
  1254. * } ARGS_example;
  1255. *
  1256. * static inline ARGS_example get_args_example(BinarySource *in) {
  1257. * ARGS_example args;
  1258. * args.bar = get_val_bar(in);
  1259. * args.n = get_uint(in);
  1260. * return args;
  1261. * }
  1262. *
  1263. * static void handle_example(BinarySource *in, strbuf *out) {
  1264. * ARGS_example args = get_args_example(in);
  1265. * return_val_foo(out, example(args.bar, args.n));
  1266. * }
  1267. *
  1268. * Each of these mentions the arguments and their types just _once_,
  1269. * so each one can be generated by a single expansion of the FUNC(...)
  1270. * specification in testcrypt-func.h, with FUNC and ARG and VOID
  1271. * defined to appropriate values.
  1272. *
  1273. * Or ... *nearly*. In fact, I left out several details there, but
  1274. * it's a good starting point to understand the full version.
  1275. *
  1276. * To begin with, several of the variable names shown above are
  1277. * actually named with an ugly leading underscore, to minimise the
  1278. * chance of them colliding with real parameter names. (You could
  1279. * easily imagine 'out' being the name of a parameter to one of the
  1280. * wrapped functions.) Also, we memset the whole structure to zero at
  1281. * the start of get_args_example() to avoid compiler warnings about
  1282. * uninitialised stuff, and insert a precautionary '(void)args;' in
  1283. * handle_example to avoid a similar warning about _unused_ stuff.
  1284. *
  1285. * The big problem is the commas that have to appear between arguments
  1286. * in the final call to the actual C function. Those can't be
  1287. * generated by expanding the ARG macro itself, or you'd get one too
  1288. * many - either a leading comma or a trailing comma. Trailing commas
  1289. * are legal in a Python function call, but unfortunately C is not yet
  1290. * so enlightened. (C permits a trailing comma in a struct or array
  1291. * initialiser, and is coming round to it in enums, but hasn't yet
  1292. * seen the light about function calls or function prototypes.)
  1293. *
  1294. * So the commas must appear _between_ ARG(...) specifiers. And that
  1295. * means they unavoidably appear in _every_ expansion of FUNC() (or
  1296. * rather, every expansion that uses the variadic argument list at
  1297. * all). Therefore, we need to ensure they're harmless in the other
  1298. * two functions as well.
  1299. *
  1300. * In the get_args_example() function above, there's no real problem.
  1301. * The list of assignments can perfectly well be separated by commas
  1302. * instead of semicolons, so that it becomes a single expression-
  1303. * statement instead of a sequence of them; the comma operator still
  1304. * defines a sequence point, so it's fine.
  1305. *
  1306. * But what about the structure definition of ARGS_example?
  1307. *
  1308. * To get round that, we fill the structure with pointless extra
  1309. * cruft, in the form of an extra 'int' field before and after each
  1310. * actually useful argument field. So the real structure definition
  1311. * ends up looking more like this:
  1312. *
  1313. * typedef struct ARGS_example {
  1314. * int _predummy_bar;
  1315. * TD_val_bar bar;
  1316. * int _postdummy_bar, _predummy_n;
  1317. * TD_uint n;
  1318. * int _postdummy_n;
  1319. * } ARGS_example;
  1320. *
  1321. * Those extra 'int' fields are ignored completely at run time. They
  1322. * might cause a runtime space cost if the struct doesn't get
  1323. * completely optimised away when get_args_example is inlined into
  1324. * handle_example, but even if so, that's OK, this is a test program
  1325. * whose memory usage isn't critical. The real point is that, in
  1326. * between each pair of real arguments, there's a declaration
  1327. * containing *two* int variables, and in between them is the vital
  1328. * comma that we need!
  1329. *
  1330. * So in that pass through testcrypt-func.h, the ARG(type, name) macro
  1331. * has to expand to the weird piece of text
  1332. *
  1333. * _predummy_name; // terminating the previous int declaration
  1334. * TD_type name; // declaring the thing we actually wanted
  1335. * int _postdummy_name // new declaration ready to see a comma
  1336. *
  1337. * so that a comma-separated list of pieces of expansion like that
  1338. * will fall into just the right form to be the core of the above
  1339. * expanded structure definition. Then we just need to put in the
  1340. * 'int' after the open brace, and the ';' before the closing brace,
  1341. * and we've got everything we need to make it all syntactically legal.
  1342. *
  1343. * Finally, what if a wrapped function has _no_ arguments? Two out of
  1344. * three uses of the argument list here need some kind of special case
  1345. * for that. That's why you have to write 'VOID' explicitly in an
  1346. * empty argument list in testcrypt-func.h: we make VOID expand to
  1347. * whatever is needed to avoid a syntax error in that special case.
  1348. */
  1349. /*
  1350. * Workarounds for an awkwardness in Visual Studio's preprocessor,
  1351. * which disagrees with everyone else about what happens if you expand
  1352. * __VA_ARGS__ into the argument list of another macro. gcc and clang
  1353. * will treat the commas expanding from __VA_ARGS__ as argument
  1354. * separators, whereas VS will make them all part of a single argument
  1355. * to the secondary macro. We want the former behaviour, so we use
  1356. * the following workaround to enforce it.
  1357. *
  1358. * Each of these JUXTAPOSE macros simply places its arguments side by
  1359. * side. But the arguments are macro-expanded before JUXTAPOSE is
  1360. * called at all, so we can do this:
  1361. *
  1362. * JUXTAPOSE(macroname, (__VA_ARGS__))
  1363. * -> JUXTAPOSE(macroname, (foo, bar, baz))
  1364. * -> macroname (foo, bar, baz)
  1365. *
  1366. * and this preliminary expansion causes the commas to be treated
  1367. * normally by the time VS gets round to expanding the inner macro.
  1368. *
  1369. * We need two differently named JUXTAPOSE macros, because we have to
  1370. * do this trick twice: once to turn FUNC and FUNC_WRAPPED in
  1371. * testcrypt-funcs.h into the underlying common FUNC_INNER, and again
  1372. * to expand the final function call. And you can't expand a macro
  1373. * inside text expanded from the _same_ macro, so we have to do the
  1374. * outer and inner instances of this trick using macros of different
  1375. * names.
  1376. */
  1377. #define JUXTAPOSE1(first, second) first second
  1378. #define JUXTAPOSE2(first, second) first second
  1379. #define FUNC(outtype, fname, ...) \
  1380. JUXTAPOSE1(FUNC_INNER, (outtype, fname, fname, __VA_ARGS__))
  1381. #define FUNC_WRAPPED(outtype, fname, ...) \
  1382. JUXTAPOSE1(FUNC_INNER, (outtype, fname, fname##_wrapper, __VA_ARGS__))
  1383. #define ARG(type, arg) _predummy_##arg; TD_##type arg; int _postdummy_##arg
  1384. #define VOID _voiddummy
  1385. #define FUNC_INNER(outtype, fname, realname, ...) \
  1386. typedef struct ARGS_##fname { \
  1387. int __VA_ARGS__; \
  1388. } ARGS_##fname;
  1389. #include "testcrypt-func.h"
  1390. #undef FUNC_INNER
  1391. #undef ARG
  1392. #undef VOID
  1393. #define ARG(type, arg) _args.arg = get_##type(_in)
  1394. #define VOID ((void)0)
  1395. #define FUNC_INNER(outtype, fname, realname, ...) \
  1396. static inline ARGS_##fname get_args_##fname(BinarySource *_in) { \
  1397. ARGS_##fname _args; \
  1398. memset(&_args, 0, sizeof(_args)); \
  1399. __VA_ARGS__; \
  1400. return _args; \
  1401. }
  1402. #include "testcrypt-func.h"
  1403. #undef FUNC_INNER
  1404. #undef ARG
  1405. #undef VOID
  1406. #define ARG(type, arg) _args.arg
  1407. #define VOID
  1408. #define FUNC_INNER(outtype, fname, realname, ...) \
  1409. static void handle_##fname(BinarySource *_in, strbuf *_out) { \
  1410. ARGS_##fname _args = get_args_##fname(_in); \
  1411. (void)_args; /* suppress warning if no actual arguments */ \
  1412. return_##outtype(_out, JUXTAPOSE2(realname, (__VA_ARGS__))); \
  1413. }
  1414. #include "testcrypt-func.h"
  1415. #undef FUNC_INNER
  1416. #undef ARG
  1417. static void process_line(BinarySource *in, strbuf *out)
  1418. {
  1419. ptrlen id = get_word(in);
  1420. #define DISPATCH_INTERNAL(cmdname, handler) do { \
  1421. if (ptrlen_eq_string(id, cmdname)) { \
  1422. handler(in, out); \
  1423. return; \
  1424. } \
  1425. } while (0)
  1426. #define DISPATCH_COMMAND(cmd) DISPATCH_INTERNAL(#cmd, handle_##cmd)
  1427. DISPATCH_COMMAND(hello);
  1428. DISPATCH_COMMAND(free);
  1429. DISPATCH_COMMAND(newstring);
  1430. DISPATCH_COMMAND(getstring);
  1431. DISPATCH_COMMAND(mp_literal);
  1432. DISPATCH_COMMAND(mp_dump);
  1433. DISPATCH_COMMAND(checkenum);
  1434. #undef DISPATCH_COMMAND
  1435. #define FUNC_INNER(outtype, fname, realname, ...) \
  1436. DISPATCH_INTERNAL(#fname,handle_##fname);
  1437. #include "testcrypt-func.h"
  1438. #undef FUNC_INNER
  1439. #undef DISPATCH_INTERNAL
  1440. fatal_error("command '%.*s': unrecognised", PTRLEN_PRINTF(id));
  1441. }
  1442. static void free_all_values(void)
  1443. {
  1444. for (Value *val; (val = delpos234(values, 0)) != NULL ;)
  1445. free_value(val);
  1446. freetree234(values);
  1447. }
  1448. void dputs(const char *buf)
  1449. {
  1450. fputs(buf, stderr);
  1451. }
  1452. int main(int argc, char **argv)
  1453. {
  1454. const char *infile = NULL, *outfile = NULL;
  1455. bool doing_opts = true;
  1456. while (--argc > 0) {
  1457. char *p = *++argv;
  1458. if (p[0] == '-' && doing_opts) {
  1459. if (!strcmp(p, "-o")) {
  1460. if (--argc <= 0) {
  1461. fprintf(stderr, "'-o' expects a filename\n");
  1462. return 1;
  1463. }
  1464. outfile = *++argv;
  1465. } else if (!strcmp(p, "--")) {
  1466. doing_opts = false;
  1467. } else if (!strcmp(p, "--help")) {
  1468. printf("usage: testcrypt [INFILE] [-o OUTFILE]\n");
  1469. printf(" also: testcrypt --help display this text\n");
  1470. return 0;
  1471. } else {
  1472. fprintf(stderr, "unknown command line option '%s'\n", p);
  1473. return 1;
  1474. }
  1475. } else if (!infile) {
  1476. infile = p;
  1477. } else {
  1478. fprintf(stderr, "can only handle one input file name\n");
  1479. return 1;
  1480. }
  1481. }
  1482. FILE *infp = stdin;
  1483. if (infile) {
  1484. infp = fopen(infile, "r");
  1485. if (!infp) {
  1486. fprintf(stderr, "%s: open: %s\n", infile, strerror(errno));
  1487. return 1;
  1488. }
  1489. }
  1490. FILE *outfp = stdout;
  1491. if (outfile) {
  1492. outfp = fopen(outfile, "w");
  1493. if (!outfp) {
  1494. fprintf(stderr, "%s: open: %s\n", outfile, strerror(errno));
  1495. return 1;
  1496. }
  1497. }
  1498. values = newtree234(valuecmp);
  1499. atexit(free_all_values);
  1500. for (char *line; (line = chomp(fgetline(infp))) != NULL ;) {
  1501. BinarySource src[1];
  1502. BinarySource_BARE_INIT(src, line, strlen(line));
  1503. strbuf *sb = strbuf_new();
  1504. process_line(src, sb);
  1505. run_finalisers(sb);
  1506. size_t lines = 0;
  1507. for (size_t i = 0; i < sb->len; i++)
  1508. if (sb->s[i] == '\n')
  1509. lines++;
  1510. fprintf(outfp, "%"SIZEu"\n%s", lines, sb->s);
  1511. fflush(outfp);
  1512. strbuf_free(sb);
  1513. sfree(line);
  1514. }
  1515. if (infp != stdin)
  1516. fclose(infp);
  1517. if (outfp != stdin)
  1518. fclose(outfp);
  1519. return 0;
  1520. }