diff --git a/test/testcrypt.py b/test/testcrypt.py index 28a00897..170ad3ce 100644 --- a/test/testcrypt.py +++ b/test/testcrypt.py @@ -3,6 +3,7 @@ import os import numbers import subprocess import re +import string import struct from binascii import hexlify @@ -269,10 +270,95 @@ class Function(object): return retvals[0] return tuple(retvals) -def _setup(scope): - header_file = os.path.join(putty_srcdir, "testcrypt.h") +def _lex_testcrypt_header(header): + pat = re.compile( + # Skip any combination of whitespace and comments + '(?:{})*'.format('|'.join(( + '[ \t\n]', # whitespace + '/\\*(?:.|\n)*?\\*/', # C90-style /* ... */ comment, ended eagerly + '//[^\n]*\n', # C99-style comment to end-of-line + ))) + + # And then match a token + '({})'.format('|'.join(( + # Punctuation + '\(', + '\)', + ',', + # Identifier + '[A-Za-z_][A-Za-z0-9_]*', + # End of string + '$', + ))) + ) - linere = re.compile(r'^FUNC\d+\((.*)\)$') + pos = 0 + end = len(header) + while pos < end: + m = pat.match(header, pos) + assert m is not None, ( + "Failed to lex testcrypt.h at byte position {:d}".format(pos)) + + pos = m.end() + tok = m.group(1) + if len(tok) == 0: + assert pos == end, ( + "Empty token should only be returned at end of string") + yield tok, m.start(1) + +def _parse_testcrypt_header(tokens): + def is_id(tok): + return tok[0] in string.ascii_letters+"_" + def expect(what, why, eof_ok=False): + tok, pos = next(tokens) + if tok == '' and eof_ok: + return None + if hasattr(what, '__call__'): + description = lambda: "" + ok = what(tok) + elif isinstance(what, set): + description = lambda: " or ".join("'"+x+"' " for x in sorted(what)) + ok = tok in what + else: + description = lambda: "'"+what+"' " + ok = tok == what + if not ok: + sys.exit("testcrypt.h:{:d}: expected {}{}".format( + pos, description(), why)) + return tok + + while True: + tok = expect("FUNC", "at start of function specification", eof_ok=True) + if tok is None: + break + + expect("(", "after FUNC") + rettype = expect(is_id, "return type") + expect(",", "after return type") + funcname = expect(is_id, "function name") + expect(",", "after function name") + expect("(", "to begin argument list") + args = [] + firstargkind = expect({"ARG", "VOID"}, "at start of argument list") + if firstargkind == "VOID": + expect(")", "after VOID") + else: + while True: + # Every time we come back to the top of this loop, we've + # just seen 'ARG' + expect("(", "after ARG") + argtype = expect(is_id, "argument type") + expect(",", "after argument type") + argname = expect(is_id, "argument name") + args.append((argtype, argname)) + expect(")", "at end of ARG") + punct = expect({",", ")"}, "after argument") + if punct == ")": + break + expect("ARG", "to begin next argument") + expect(")", "at end of FUNC") + yield funcname, rettype, args + +def _setup(scope): valprefix = "val_" outprefix = "out_" optprefix = "opt_" @@ -288,36 +374,34 @@ def _setup(scope): arg = arg[:arg.index("_", len(valprefix))] return arg - with open(header_file) as f: - for line in iter(f.readline, ""): - line = line.rstrip("\r\n").replace(" ", "") - m = linere.match(line) - if m is not None: - words = m.group(1).split(",") - function = words[1] - rettypes = [] - argtypes = [] - argsconsumed = [] - if words[0] != "void": - rettypes.append(trim_argtype(words[0])) - for arg in words[2:]: - if arg.startswith(outprefix): - rettypes.append(trim_argtype(arg[len(outprefix):])) - else: - consumed = False - if arg.startswith(consprefix): - arg = arg[len(consprefix):] - consumed = True - arg = trim_argtype(arg) - argtypes.append((arg, consumed)) - func = Function(function, rettypes, argtypes) - scope[function] = func - if len(argtypes) > 0: - t = argtypes[0][0] - if (t in method_prefixes and - function.startswith(method_prefixes[t])): - methodname = function[len(method_prefixes[t]):] - method_lists[t].append((methodname, func)) + with open(os.path.join(putty_srcdir, "testcrypt.h")) as f: + header = f.read() + tokens = _lex_testcrypt_header(header) + for function, rettype, arglist in _parse_testcrypt_header(tokens): + rettypes = [] + if rettype != "void": + rettypes.append(trim_argtype(rettype)) + + argtypes = [] + argsconsumed = [] + for arg, argname in arglist: + if arg.startswith(outprefix): + rettypes.append(trim_argtype(arg[len(outprefix):])) + else: + consumed = False + if arg.startswith(consprefix): + arg = arg[len(consprefix):] + consumed = True + arg = trim_argtype(arg) + argtypes.append((arg, consumed)) + func = Function(function, rettypes, argtypes) + scope[function] = func + if len(argtypes) > 0: + t = argtypes[0][0] + if (t in method_prefixes and + function.startswith(method_prefixes[t])): + methodname = function[len(method_prefixes[t]):] + method_lists[t].append((methodname, func)) _setup(globals()) del _setup diff --git a/testcrypt.c b/testcrypt.c index 456cd831..bf49af25 100644 --- a/testcrypt.c +++ b/testcrypt.c @@ -1406,180 +1406,226 @@ typedef Argon2Flavour TD_argon2flavour; typedef FingerprintType TD_fptype; typedef HttpDigestHash TD_httpdigesthash; -#define FUNC0(rettype, function) \ - static void handle_##function(BinarySource *in, strbuf *out) { \ - return_##rettype(out, function()); \ - } +/* + * HERE BE DRAGONS: the horrible C preprocessor business that reads + * testcrypt.h and generates a marshalling wrapper for each exported + * function. + * + * In an ideal world, we would start from a specification like this in + * testcrypt.h + * + * FUNC(val_foo, example, (ARG(val_bar, bar), ARG(uint, n))) + * + * and generate a wrapper function looking like this: + * + * static void handle_example(BinarySource *in, strbuf *out) { + * TD_val_bar bar = get_val_bar(in); + * TD_uint n = get_uint(in); + * return_val_foo(out, example(bar, n)); + * } + * + * which would read the marshalled form of each function argument in + * turn from the input BinarySource via the get_() function + * family defined in this file; assign each argument to a local + * variable; call the underlying C function with all those arguments; + * and then call a function of the return_() family to marshal + * the output value into the output strbuf to be sent to standard + * output. + * + * With a more general macro processor such as m4, or custom code in + * Perl or Python, or a helper program like llvm-tblgen, we could just + * do that directly, reading function specifications from testcrypt.h + * and writing out exactly the above. But we don't have a fully + * general macro processor (since everything in that category + * introduces an extra build dependency that's awkward on plain + * Windows, or requires compiling and running a helper program which + * is awkward in a cross-compile). We only have cpp. And in cpp, a + * macro can't expand one of its arguments differently in two parts of + * its own expansion. So we have to be more clever. + * + * In place of the above code, I instead generate three successive + * declarations for each function. In simplified form they would look + * like this: + * + * typedef struct ARGS_example { + * TD_val_bar bar; + * TD_uint n; + * } ARGS_example; + * + * static inline ARGS_example get_args_example(BinarySource *in) { + * ARGS_example args; + * args.bar = get_val_bar(in); + * args.n = get_uint(in); + * return args; + * } + * + * static void handle_example(BinarySource *in, strbuf *out) { + * ARGS_example args = get_args_example(in); + * return_val_foo(out, example(args.bar, args.n)); + * } + * + * Each of these mentions the arguments and their types just _once_, + * so each one can be generated by a single expansion of the FUNC(...) + * specification in testcrypt.h, with FUNC and ARG and VOID defined to + * appropriate values. + * + * Or ... *nearly*. In fact, I left out several details there, but + * it's a good starting point to understand the full version. + * + * To begin with, several of the variable names shown above are + * actually named with an ugly leading underscore, to minimise the + * chance of them colliding with real parameter names. (You could + * easily imagine 'out' being the name of a parameter to one of the + * wrapped functions.) Also, we memset the whole structure to zero at + * the start of get_args_example() to avoid compiler warnings about + * uninitialised stuff, and insert a precautionary '(void)args;' in + * handle_example to avoid a similar warning about _unused_ stuff. + * + * The big problem is the commas that have to appear between arguments + * in the final call to the actual C function. Those can't be + * generated by expanding the ARG macro itself, or you'd get one too + * many - either a leading comma or a trailing comma. Trailing commas + * are legal in a Python function call, but unfortunately C is not yet + * so enlightened. (C permits a trailing comma in a struct or array + * initialiser, and is coming round to it in enums, but hasn't yet + * seen the light about function calls or function prototypes.) + * + * So the commas must appear _between_ ARG(...) specifiers. And that + * means they unavoidably appear in _every_ expansion of FUNC() (or + * rather, every expansion that uses the argument list at all). + * Therefore, we need to ensure they're harmless in the other two + * functions as well. + * + * In the get_args_example() function above, there's no real problem. + * The list of assignments can perfectly well be separated by commas + * instead of semicolons, so that it becomes a single expression- + * statement instead of a sequence of them; the comma operator still + * defines a sequence point, so it's fine. + * + * But what about the structure definition of ARGS_example? + * + * To get round that, we fill the structure with pointless extra + * cruft, in the form of an extra 'int' field before and after each + * actually useful argument field. So the real structure definition + * ends up looking more like this: + * + * typedef struct ARGS_example { + * int _predummy_bar; + * TD_val_bar bar; + * int _postdummy_bar, _predummy_n; + * TD_uint n; + * int _postdummy_n; + * } ARGS_example; + * + * Those extra 'int' fields are ignored completely at run time. They + * might cause a runtime space cost if the struct doesn't get + * completely optimised away when get_args_example is inlined into + * handle_example, but even if so, that's OK, this is a test program + * whose memory usage isn't critical. The real point is that, in + * between each pair of real arguments, there's a declaration + * containing *two* int variables, and in between them is the vital + * comma that we need! + * + * So in that pass through testcrypt.h, the ARG(type, name) macro has + * to expand to the weird piece of text + * + * _predummy_name; // terminating the previous int declaration + * TD_type name; // declaring the thing we actually wanted + * int _postdummy_name // new declaration ready to see a comma + * + * so that a comma-separated list of pieces of expansion like that + * will fall into just the right form to be the core of the above + * expanded structure definition. Then we just need to put in the + * 'int' after the open brace, and the ';' before the closing brace, + * and we've got everything we need to make it all syntactically legal. + * + * Other points of note: + * + * Why the extra pair of parens around the whole argument list? You'd + * like to think that FUNC could be a variadic macro, and just use + * __VA_ARGS__ to expand all the arguments wherever they're needed. + * But unfortunately there's a portability consideration: some of the + * 'functions' wrapped by this system are actually macros in turn, and + * if you use __VA_ARGS__ to expand multiple arguments from one macro + * into the argument list of another macro, compilers disagree on what + * happens: Visual Studio in particular will turn __VA_ARGS__ into + * just one argument instead of multiple ones. That is, if you do this: + * + * #define DESTINATION_MACRO(a, b) ... stuff using a and b ... + * #define WRAPPER(...) DESTINATION_MACRO(__VA_ARGS__) + * WRAPPER(1, 2) + * + * then most compilers will behave as if you'd called + * DESTINATION_MACRO with 'a' expanding to 1 and 'b' expanding to 2. + * But Visual Studio will consider that you called it with 'a' + * expanding to the whole of __VA_ARGS__ - that is, the token sequence + * '1 , 2' - and will expand 'b' to nothing at all! + * + * So we have a constraint that if ARGS is going to be turned into the + * argument list to the actual called function - as it is in the final + * handle_example() expansion shown above - then the commas can't come + * from a variadic expansion of __VA_ARGS__. Hence, FUNC can't _be_ a + * variadic macro. Instead, we wrap all the arguments in an extra pair + * of parens, and generate the final call not by saying function(args) + * but by saying just 'function args', since 'args' contains the + * parens already. + * + * In get_args_example(), that's still fine, because our giant + * comma-separated expression containing multiple assignment + * subexpressions can legally be wrapped in parentheses as well. But + * what do you do in the structure definition? + * + * Answer: _there_ we use a variadic macro to strip off the outer + * parens, by expanding to just __VA_ARGS__. That's OK even in Visual + * Studio, because in this particular context, __VA_ARGS__ is ending + * up in a structure definition and definitely _not_ in the argument + * list of another macro. + * + * Finally, what if a wrapped function has _no_ arguments? Two out of + * three uses of the argument list here need some kind of special case + * for that. That's why you have to write 'VOID' explicitly in an + * empty argument list in testcrypt.h: we make VOID expand to whatever + * is needed to avoid a syntax error in that special case. + */ -#define FUNC1(rettype, function, type1) \ - static void handle_##function(BinarySource *in, strbuf *out) { \ - TD_##type1 arg1 = get_##type1(in); \ - return_##rettype(out, function(arg1)); \ - } - -#define FUNC2(rettype, function, type1, type2) \ - static void handle_##function(BinarySource *in, strbuf *out) { \ - TD_##type1 arg1 = get_##type1(in); \ - TD_##type2 arg2 = get_##type2(in); \ - return_##rettype(out, function(arg1, arg2)); \ - } - -#define FUNC3(rettype, function, type1, type2, type3) \ - static void handle_##function(BinarySource *in, strbuf *out) { \ - TD_##type1 arg1 = get_##type1(in); \ - TD_##type2 arg2 = get_##type2(in); \ - TD_##type3 arg3 = get_##type3(in); \ - return_##rettype(out, function(arg1, arg2, arg3)); \ - } - -#define FUNC4(rettype, function, type1, type2, type3, type4) \ - static void handle_##function(BinarySource *in, strbuf *out) { \ - TD_##type1 arg1 = get_##type1(in); \ - TD_##type2 arg2 = get_##type2(in); \ - TD_##type3 arg3 = get_##type3(in); \ - TD_##type4 arg4 = get_##type4(in); \ - return_##rettype(out, function(arg1, arg2, arg3, arg4)); \ - } - -#define FUNC5(rettype, function, type1, type2, type3, type4, type5) \ - static void handle_##function(BinarySource *in, strbuf *out) { \ - TD_##type1 arg1 = get_##type1(in); \ - TD_##type2 arg2 = get_##type2(in); \ - TD_##type3 arg3 = get_##type3(in); \ - TD_##type4 arg4 = get_##type4(in); \ - TD_##type5 arg5 = get_##type5(in); \ - return_##rettype(out, function(arg1, arg2, arg3, arg4, arg5)); \ - } - -#define FUNC6(rettype, function, type1, type2, type3, type4, type5, \ - type6) \ - static void handle_##function(BinarySource *in, strbuf *out) { \ - TD_##type1 arg1 = get_##type1(in); \ - TD_##type2 arg2 = get_##type2(in); \ - TD_##type3 arg3 = get_##type3(in); \ - TD_##type4 arg4 = get_##type4(in); \ - TD_##type5 arg5 = get_##type5(in); \ - TD_##type6 arg6 = get_##type6(in); \ - return_##rettype(out, function(arg1, arg2, arg3, arg4, arg5, \ - arg6)); \ - } - -#define FUNC7(rettype, function, type1, type2, type3, type4, type5, \ - type6, type7) \ - static void handle_##function(BinarySource *in, strbuf *out) { \ - TD_##type1 arg1 = get_##type1(in); \ - TD_##type2 arg2 = get_##type2(in); \ - TD_##type3 arg3 = get_##type3(in); \ - TD_##type4 arg4 = get_##type4(in); \ - TD_##type5 arg5 = get_##type5(in); \ - TD_##type6 arg6 = get_##type6(in); \ - TD_##type7 arg7 = get_##type7(in); \ - return_##rettype(out, function(arg1, arg2, arg3, arg4, arg5, \ - arg6, arg7)); \ - } - -#define FUNC8(rettype, function, type1, type2, type3, type4, type5, \ - type6, type7, type8) \ - static void handle_##function(BinarySource *in, strbuf *out) { \ - TD_##type1 arg1 = get_##type1(in); \ - TD_##type2 arg2 = get_##type2(in); \ - TD_##type3 arg3 = get_##type3(in); \ - TD_##type4 arg4 = get_##type4(in); \ - TD_##type5 arg5 = get_##type5(in); \ - TD_##type6 arg6 = get_##type6(in); \ - TD_##type7 arg7 = get_##type7(in); \ - TD_##type8 arg8 = get_##type8(in); \ - return_##rettype(out, function(arg1, arg2, arg3, arg4, arg5, \ - arg6, arg7, arg8)); \ - } - -#define FUNC9(rettype, function, type1, type2, type3, type4, type5, \ - type6, type7, type8, type9) \ - static void handle_##function(BinarySource *in, strbuf *out) { \ - TD_##type1 arg1 = get_##type1(in); \ - TD_##type2 arg2 = get_##type2(in); \ - TD_##type3 arg3 = get_##type3(in); \ - TD_##type4 arg4 = get_##type4(in); \ - TD_##type5 arg5 = get_##type5(in); \ - TD_##type6 arg6 = get_##type6(in); \ - TD_##type7 arg7 = get_##type7(in); \ - TD_##type8 arg8 = get_##type8(in); \ - TD_##type9 arg9 = get_##type9(in); \ - return_##rettype(out, function(arg1, arg2, arg3, arg4, arg5, \ - arg6, arg7, arg8, arg9)); \ - } - -#define FUNC10(rettype, function, type1, type2, type3, type4, type5, \ - type6, type7, type8, type9, type10) \ - static void handle_##function(BinarySource *in, strbuf *out) { \ - TD_##type1 arg1 = get_##type1(in); \ - TD_##type2 arg2 = get_##type2(in); \ - TD_##type3 arg3 = get_##type3(in); \ - TD_##type4 arg4 = get_##type4(in); \ - TD_##type5 arg5 = get_##type5(in); \ - TD_##type6 arg6 = get_##type6(in); \ - TD_##type7 arg7 = get_##type7(in); \ - TD_##type8 arg8 = get_##type8(in); \ - TD_##type9 arg9 = get_##type9(in); \ - TD_##type10 arg10 = get_##type10(in); \ - return_##rettype(out, function(arg1, arg2, arg3, arg4, arg5, \ - arg6, arg7, arg8, arg9, arg10)); \ - } - -#define FUNC11(rettype, function, type1, type2, type3, type4, type5, \ - type6, type7, type8, type9, type10, type11) \ - static void handle_##function(BinarySource *in, strbuf *out) { \ - TD_##type1 arg1 = get_##type1(in); \ - TD_##type2 arg2 = get_##type2(in); \ - TD_##type3 arg3 = get_##type3(in); \ - TD_##type4 arg4 = get_##type4(in); \ - TD_##type5 arg5 = get_##type5(in); \ - TD_##type6 arg6 = get_##type6(in); \ - TD_##type7 arg7 = get_##type7(in); \ - TD_##type8 arg8 = get_##type8(in); \ - TD_##type9 arg9 = get_##type9(in); \ - TD_##type10 arg10 = get_##type10(in); \ - TD_##type11 arg11 = get_##type11(in); \ - return_##rettype(out, function(arg1, arg2, arg3, arg4, arg5, \ - arg6, arg7, arg8, arg9, arg10, \ - arg11)); \ - } - -#define FUNC12(rettype, function, type1, type2, type3, type4, type5, \ - type6, type7, type8, type9, type10, type11, type12) \ - static void handle_##function(BinarySource *in, strbuf *out) { \ - TD_##type1 arg1 = get_##type1(in); \ - TD_##type2 arg2 = get_##type2(in); \ - TD_##type3 arg3 = get_##type3(in); \ - TD_##type4 arg4 = get_##type4(in); \ - TD_##type5 arg5 = get_##type5(in); \ - TD_##type6 arg6 = get_##type6(in); \ - TD_##type7 arg7 = get_##type7(in); \ - TD_##type8 arg8 = get_##type8(in); \ - TD_##type9 arg9 = get_##type9(in); \ - TD_##type10 arg10 = get_##type10(in); \ - TD_##type11 arg11 = get_##type11(in); \ - TD_##type12 arg12 = get_##type12(in); \ - return_##rettype(out, function(arg1, arg2, arg3, arg4, arg5, \ - arg6, arg7, arg8, arg9, arg10, \ - arg11, arg12)); \ - } +#define DEPARENTHESISE(...) __VA_ARGS__ +#define ARG(type, arg) _predummy_##arg; TD_##type arg; int _postdummy_##arg +#define VOID _voiddummy +#define FUNC(outtype, fname, args) \ + typedef struct ARGS_##fname { \ + int DEPARENTHESISE args; \ + } ARGS_##fname; #include "testcrypt.h" +#undef FUNC +#undef ARG +#undef VOID -#undef FUNC12 -#undef FUNC11 -#undef FUNC10 -#undef FUNC9 -#undef FUNC8 -#undef FUNC7 -#undef FUNC6 -#undef FUNC5 -#undef FUNC4 -#undef FUNC3 -#undef FUNC2 -#undef FUNC1 -#undef FUNC0 +#define ARG(type, arg) _args.arg = get_##type(_in) +#define VOID ((void)0) +#define FUNC(outtype, fname, args) \ + static inline ARGS_##fname get_args_##fname(BinarySource *_in) { \ + ARGS_##fname _args; \ + memset(&_args, 0, sizeof(_args)); \ + args; \ + return _args; \ + } +#include "testcrypt.h" +#undef FUNC +#undef ARG +#undef VOID + +#define ARG(type, arg) _args.arg +#define VOID +#define FUNC(outtype, fname, args) \ + static void handle_##fname(BinarySource *_in, strbuf *_out) { \ + ARGS_##fname _args = get_args_##fname(_in); \ + (void)_args; /* suppress warning if no actual arguments */ \ + return_##outtype(_out, fname args); \ + } +#include "testcrypt.h" +#undef FUNC +#undef ARG static void process_line(BinarySource *in, strbuf *out) { @@ -1601,35 +1647,14 @@ static void process_line(BinarySource *in, strbuf *out) DISPATCH_COMMAND(mp_dump); #undef DISPATCH_COMMAND -#define FUNC0(ret,fn) DISPATCH_INTERNAL(#fn,handle_##fn); -#define FUNC1(ret,fn,...) DISPATCH_INTERNAL(#fn,handle_##fn); -#define FUNC2(ret,fn,...) DISPATCH_INTERNAL(#fn,handle_##fn); -#define FUNC3(ret,fn,...) DISPATCH_INTERNAL(#fn,handle_##fn); -#define FUNC4(ret,fn,...) DISPATCH_INTERNAL(#fn,handle_##fn); -#define FUNC5(ret,fn,...) DISPATCH_INTERNAL(#fn,handle_##fn); -#define FUNC6(ret,fn,...) DISPATCH_INTERNAL(#fn,handle_##fn); -#define FUNC7(ret,fn,...) DISPATCH_INTERNAL(#fn,handle_##fn); -#define FUNC8(ret,fn,...) DISPATCH_INTERNAL(#fn,handle_##fn); -#define FUNC9(ret,fn,...) DISPATCH_INTERNAL(#fn,handle_##fn); -#define FUNC10(ret,fn,...) DISPATCH_INTERNAL(#fn,handle_##fn); -#define FUNC11(ret,fn,...) DISPATCH_INTERNAL(#fn,handle_##fn); -#define FUNC12(ret,fn,...) DISPATCH_INTERNAL(#fn,handle_##fn); - +#define FUNC(outtype, fname, args) DISPATCH_INTERNAL(#fname,handle_##fname); +#define ARG1(type, arg) +#define ARGN(type, arg) +#define VOID #include "testcrypt.h" - -#undef FUNC12 -#undef FUNC11 -#undef FUNC10 -#undef FUNC9 -#undef FUNC8 -#undef FUNC7 -#undef FUNC6 -#undef FUNC5 -#undef FUNC4 -#undef FUNC3 -#undef FUNC2 -#undef FUNC1 -#undef FUNC0 +#undef FUNC +#undef ARG +#undef VOID #undef DISPATCH_INTERNAL diff --git a/testcrypt.h b/testcrypt.h index d6ac0a2a..0e8f8186 100644 --- a/testcrypt.h +++ b/testcrypt.h @@ -1,126 +1,190 @@ +/* + * List of functions exported by the 'testcrypt' system to provide a + * Python API for running unit tests and auxiliary programs. + * + * Each function definition in this file has the form + * + * FUNC(return-type, function-name, (arguments)) + * + * where 'arguments' in turn is either VOID, or a comma-separated list + * of argument specifications of the form + * + * ARG(argument-type, argument-name) + * + * Type names are always single identifiers, and they have some + * standard prefixes: + * + * 'val_' means that the type refers to something dynamically + * allocated, so that it has a persistent identity, needs to be freed + * when finished with (though this is done automatically by the + * testcrypt.py system via Python's reference counting), and may also + * be mutable. The argument type in C will be a pointer; in Python the + * corresponding argument will be an instance of a 'Value' object + * defined in testcrypt.py. + * + * 'opt_val_' is a modification of 'val_' to indicate that the pointer + * may be NULL. In Python this is translated by accepting (or + * returning) None as an alternative to a Value. + * + * 'out_' on an argument type indicates an additional output + * parameter. The argument type in C has an extra layer of + * indirection, e.g. an 'out_val_mpint' is an 'mpint **' instead of an + * 'mpint *', identifying a pointer variable where the returned + * pointer value will be written. In the Python API, these arguments + * do not appear in the argument list of the Python function; instead + * they cause the return value to become a tuple, with additional + * types appended. For example, a declaration like + * + * FUNC(val_foo, example, (ARG(out_val_bar, bar), ARG(val_baz, baz))) + * + * would identify a function in C with the following prototype, which + * returns a 'foo *' directly and a 'bar *' by writing it through the + * provided 'bar **' pointer argument: + * + * foo *example(bar **extra_output, baz *input); + * + * and in Python this would become a function taking one argument of + * type 'baz' and returning a tuple of the form (foo, bar). + * + * 'out_' and 'opt_' can go together, if a function returns a second + * output value but it may in some cases be NULL. + * + * 'consumed_' on an argument type indicates that the C function + * receiving that argument frees it as a side effect. + * + * Any argument type which does not start 'val_' is plain old data + * with no dynamic allocation requirements. Ordinary C integers are + * sometimes handled this way (e.g. 'uint'). Other plain-data types + * are represented in Python as a string that must be one of a + * recognised set of keywords; in C these variously translate into + * enumeration types (e.g. argon2flavour, rsaorder) or pointers to + * const vtables of one kind or another (e.g. keyalg, hashalg, + * primegenpolicy). + */ + /* * mpint.h functions. */ -FUNC1(val_mpint, mp_new, uint) -FUNC1(void, mp_clear, val_mpint) -FUNC1(val_mpint, mp_from_bytes_le, val_string_ptrlen) -FUNC1(val_mpint, mp_from_bytes_be, val_string_ptrlen) -FUNC1(val_mpint, mp_from_integer, uint) -FUNC1(val_mpint, mp_from_decimal_pl, val_string_ptrlen) -FUNC1(val_mpint, mp_from_decimal, val_string_asciz) -FUNC1(val_mpint, mp_from_hex_pl, val_string_ptrlen) -FUNC1(val_mpint, mp_from_hex, val_string_asciz) -FUNC1(val_mpint, mp_copy, val_mpint) -FUNC1(val_mpint, mp_power_2, uint) -FUNC2(uint, mp_get_byte, val_mpint, uint) -FUNC2(uint, mp_get_bit, val_mpint, uint) -FUNC3(void, mp_set_bit, val_mpint, uint, uint) -FUNC1(uint, mp_max_bytes, val_mpint) -FUNC1(uint, mp_max_bits, val_mpint) -FUNC1(uint, mp_get_nbits, val_mpint) -FUNC1(val_string_asciz, mp_get_decimal, val_mpint) -FUNC1(val_string_asciz, mp_get_hex, val_mpint) -FUNC1(val_string_asciz, mp_get_hex_uppercase, val_mpint) -FUNC2(uint, mp_cmp_hs, val_mpint, val_mpint) -FUNC2(uint, mp_cmp_eq, val_mpint, val_mpint) -FUNC2(uint, mp_hs_integer, val_mpint, uint) -FUNC2(uint, mp_eq_integer, val_mpint, uint) -FUNC3(void, mp_min_into, val_mpint, val_mpint, val_mpint) -FUNC3(void, mp_max_into, val_mpint, val_mpint, val_mpint) -FUNC2(val_mpint, mp_min, val_mpint, val_mpint) -FUNC2(val_mpint, mp_max, val_mpint, val_mpint) -FUNC2(void, mp_copy_into, val_mpint, val_mpint) -FUNC4(void, mp_select_into, val_mpint, val_mpint, val_mpint, uint) -FUNC3(void, mp_add_into, val_mpint, val_mpint, val_mpint) -FUNC3(void, mp_sub_into, val_mpint, val_mpint, val_mpint) -FUNC3(void, mp_mul_into, val_mpint, val_mpint, val_mpint) -FUNC2(val_mpint, mp_add, val_mpint, val_mpint) -FUNC2(val_mpint, mp_sub, val_mpint, val_mpint) -FUNC2(val_mpint, mp_mul, val_mpint, val_mpint) -FUNC3(void, mp_and_into, val_mpint, val_mpint, val_mpint) -FUNC3(void, mp_or_into, val_mpint, val_mpint, val_mpint) -FUNC3(void, mp_xor_into, val_mpint, val_mpint, val_mpint) -FUNC3(void, mp_bic_into, val_mpint, val_mpint, val_mpint) -FUNC2(void, mp_copy_integer_into, val_mpint, uint) -FUNC3(void, mp_add_integer_into, val_mpint, val_mpint, uint) -FUNC3(void, mp_sub_integer_into, val_mpint, val_mpint, uint) -FUNC3(void, mp_mul_integer_into, val_mpint, val_mpint, uint) -FUNC4(void, mp_cond_add_into, val_mpint, val_mpint, val_mpint, uint) -FUNC4(void, mp_cond_sub_into, val_mpint, val_mpint, val_mpint, uint) -FUNC3(void, mp_cond_swap, val_mpint, val_mpint, uint) -FUNC2(void, mp_cond_clear, val_mpint, uint) -FUNC4(void, mp_divmod_into, val_mpint, val_mpint, opt_val_mpint, opt_val_mpint) -FUNC2(val_mpint, mp_div, val_mpint, val_mpint) -FUNC2(val_mpint, mp_mod, val_mpint, val_mpint) -FUNC3(val_mpint, mp_nthroot, val_mpint, uint, opt_val_mpint) -FUNC2(void, mp_reduce_mod_2to, val_mpint, uint) -FUNC2(val_mpint, mp_invert_mod_2to, val_mpint, uint) -FUNC2(val_mpint, mp_invert, val_mpint, val_mpint) -FUNC5(void, mp_gcd_into, val_mpint, val_mpint, opt_val_mpint, opt_val_mpint, opt_val_mpint) -FUNC2(val_mpint, mp_gcd, val_mpint, val_mpint) -FUNC2(uint, mp_coprime, val_mpint, val_mpint) -FUNC2(val_modsqrt, modsqrt_new, val_mpint, val_mpint) +FUNC(val_mpint, mp_new, (ARG(uint, maxbits))) +FUNC(void, mp_clear, (ARG(val_mpint, x))) +FUNC(val_mpint, mp_from_bytes_le, (ARG(val_string_ptrlen, bytes))) +FUNC(val_mpint, mp_from_bytes_be, (ARG(val_string_ptrlen, bytes))) +FUNC(val_mpint, mp_from_integer, (ARG(uint, n))) +FUNC(val_mpint, mp_from_decimal_pl, (ARG(val_string_ptrlen, decimal))) +FUNC(val_mpint, mp_from_decimal, (ARG(val_string_asciz, decimal))) +FUNC(val_mpint, mp_from_hex_pl, (ARG(val_string_ptrlen, hex))) +FUNC(val_mpint, mp_from_hex, (ARG(val_string_asciz, hex))) +FUNC(val_mpint, mp_copy, (ARG(val_mpint, x))) +FUNC(val_mpint, mp_power_2, (ARG(uint, power))) +FUNC(uint, mp_get_byte, (ARG(val_mpint, x), ARG(uint, byte))) +FUNC(uint, mp_get_bit, (ARG(val_mpint, x), ARG(uint, bit))) +FUNC(void, mp_set_bit, (ARG(val_mpint, x), ARG(uint, bit), ARG(uint, val))) +FUNC(uint, mp_max_bytes, (ARG(val_mpint, x))) +FUNC(uint, mp_max_bits, (ARG(val_mpint, x))) +FUNC(uint, mp_get_nbits, (ARG(val_mpint, x))) +FUNC(val_string_asciz, mp_get_decimal, (ARG(val_mpint, x))) +FUNC(val_string_asciz, mp_get_hex, (ARG(val_mpint, x))) +FUNC(val_string_asciz, mp_get_hex_uppercase, (ARG(val_mpint, x))) +FUNC(uint, mp_cmp_hs, (ARG(val_mpint, a), ARG(val_mpint, b))) +FUNC(uint, mp_cmp_eq, (ARG(val_mpint, a), ARG(val_mpint, b))) +FUNC(uint, mp_hs_integer, (ARG(val_mpint, x), ARG(uint, n))) +FUNC(uint, mp_eq_integer, (ARG(val_mpint, x), ARG(uint, n))) +FUNC(void, mp_min_into, (ARG(val_mpint, r), ARG(val_mpint, x), ARG(val_mpint, y))) +FUNC(void, mp_max_into, (ARG(val_mpint, r), ARG(val_mpint, x), ARG(val_mpint, y))) +FUNC(val_mpint, mp_min, (ARG(val_mpint, x), ARG(val_mpint, y))) +FUNC(val_mpint, mp_max, (ARG(val_mpint, x), ARG(val_mpint, y))) +FUNC(void, mp_copy_into, (ARG(val_mpint, dest), ARG(val_mpint, src))) +FUNC(void, mp_select_into, (ARG(val_mpint, dest), ARG(val_mpint, src0), ARG(val_mpint, src1), ARG(uint, choose_src1))) +FUNC(void, mp_add_into, (ARG(val_mpint, r), ARG(val_mpint, a), ARG(val_mpint, b))) +FUNC(void, mp_sub_into, (ARG(val_mpint, r), ARG(val_mpint, a), ARG(val_mpint, b))) +FUNC(void, mp_mul_into, (ARG(val_mpint, r), ARG(val_mpint, a), ARG(val_mpint, b))) +FUNC(val_mpint, mp_add, (ARG(val_mpint, x), ARG(val_mpint, y))) +FUNC(val_mpint, mp_sub, (ARG(val_mpint, x), ARG(val_mpint, y))) +FUNC(val_mpint, mp_mul, (ARG(val_mpint, x), ARG(val_mpint, y))) +FUNC(void, mp_and_into, (ARG(val_mpint, r), ARG(val_mpint, a), ARG(val_mpint, b))) +FUNC(void, mp_or_into, (ARG(val_mpint, r), ARG(val_mpint, a), ARG(val_mpint, b))) +FUNC(void, mp_xor_into, (ARG(val_mpint, r), ARG(val_mpint, a), ARG(val_mpint, b))) +FUNC(void, mp_bic_into, (ARG(val_mpint, r), ARG(val_mpint, a), ARG(val_mpint, b))) +FUNC(void, mp_copy_integer_into, (ARG(val_mpint, dest), ARG(uint, n))) +FUNC(void, mp_add_integer_into, (ARG(val_mpint, r), ARG(val_mpint, a), ARG(uint, n))) +FUNC(void, mp_sub_integer_into, (ARG(val_mpint, r), ARG(val_mpint, a), ARG(uint, n))) +FUNC(void, mp_mul_integer_into, (ARG(val_mpint, r), ARG(val_mpint, a), ARG(uint, n))) +FUNC(void, mp_cond_add_into, (ARG(val_mpint, r), ARG(val_mpint, a), ARG(val_mpint, b), ARG(uint, yes))) +FUNC(void, mp_cond_sub_into, (ARG(val_mpint, r), ARG(val_mpint, a), ARG(val_mpint, b), ARG(uint, yes))) +FUNC(void, mp_cond_swap, (ARG(val_mpint, x0), ARG(val_mpint, x1), ARG(uint, swap))) +FUNC(void, mp_cond_clear, (ARG(val_mpint, x), ARG(uint, clear))) +FUNC(void, mp_divmod_into, (ARG(val_mpint, n), ARG(val_mpint, d), ARG(opt_val_mpint, q), ARG(opt_val_mpint, r))) +FUNC(val_mpint, mp_div, (ARG(val_mpint, n), ARG(val_mpint, d))) +FUNC(val_mpint, mp_mod, (ARG(val_mpint, x), ARG(val_mpint, modulus))) +FUNC(val_mpint, mp_nthroot, (ARG(val_mpint, y), ARG(uint, n), ARG(opt_val_mpint, remainder))) +FUNC(void, mp_reduce_mod_2to, (ARG(val_mpint, x), ARG(uint, p))) +FUNC(val_mpint, mp_invert_mod_2to, (ARG(val_mpint, x), ARG(uint, p))) +FUNC(val_mpint, mp_invert, (ARG(val_mpint, x), ARG(val_mpint, modulus))) +FUNC(void, mp_gcd_into, (ARG(val_mpint, a), ARG(val_mpint, b), ARG(opt_val_mpint, gcd_out), ARG(opt_val_mpint, A_out), ARG(opt_val_mpint, B_out))) +FUNC(val_mpint, mp_gcd, (ARG(val_mpint, a), ARG(val_mpint, b))) +FUNC(uint, mp_coprime, (ARG(val_mpint, a), ARG(val_mpint, b))) +FUNC(val_modsqrt, modsqrt_new, (ARG(val_mpint, p), ARG(val_mpint, any_nonsquare_mod_p))) /* The modsqrt functions' 'success' pointer becomes a second return value */ -FUNC3(val_mpint, mp_modsqrt, val_modsqrt, val_mpint, out_uint) -FUNC1(val_monty, monty_new, val_mpint) -FUNC1(val_mpint, monty_modulus, val_monty) -FUNC1(val_mpint, monty_identity, val_monty) -FUNC3(void, monty_import_into, val_monty, val_mpint, val_mpint) -FUNC2(val_mpint, monty_import, val_monty, val_mpint) -FUNC3(void, monty_export_into, val_monty, val_mpint, val_mpint) -FUNC2(val_mpint, monty_export, val_monty, val_mpint) -FUNC4(void, monty_mul_into, val_monty, val_mpint, val_mpint, val_mpint) -FUNC3(val_mpint, monty_add, val_monty, val_mpint, val_mpint) -FUNC3(val_mpint, monty_sub, val_monty, val_mpint, val_mpint) -FUNC3(val_mpint, monty_mul, val_monty, val_mpint, val_mpint) -FUNC3(val_mpint, monty_pow, val_monty, val_mpint, val_mpint) -FUNC2(val_mpint, monty_invert, val_monty, val_mpint) -FUNC3(val_mpint, monty_modsqrt, val_modsqrt, val_mpint, out_uint) -FUNC3(val_mpint, mp_modpow, val_mpint, val_mpint, val_mpint) -FUNC3(val_mpint, mp_modmul, val_mpint, val_mpint, val_mpint) -FUNC3(val_mpint, mp_modadd, val_mpint, val_mpint, val_mpint) -FUNC3(val_mpint, mp_modsub, val_mpint, val_mpint, val_mpint) -FUNC3(void, mp_lshift_safe_into, val_mpint, val_mpint, uint) -FUNC3(void, mp_rshift_safe_into, val_mpint, val_mpint, uint) -FUNC2(val_mpint, mp_rshift_safe, val_mpint, uint) -FUNC3(void, mp_lshift_fixed_into, val_mpint, val_mpint, uint) -FUNC3(void, mp_rshift_fixed_into, val_mpint, val_mpint, uint) -FUNC2(val_mpint, mp_rshift_fixed, val_mpint, uint) -FUNC1(val_mpint, mp_random_bits, uint) -FUNC2(val_mpint, mp_random_in_range, val_mpint, val_mpint) +FUNC(val_mpint, mp_modsqrt, (ARG(val_modsqrt, sc), ARG(val_mpint, x), ARG(out_uint, success))) +FUNC(val_monty, monty_new, (ARG(val_mpint, modulus))) +FUNC(val_mpint, monty_modulus, (ARG(val_monty, mc))) +FUNC(val_mpint, monty_identity, (ARG(val_monty, mc))) +FUNC(void, monty_import_into, (ARG(val_monty, mc), ARG(val_mpint, r), ARG(val_mpint, x))) +FUNC(val_mpint, monty_import, (ARG(val_monty, mc), ARG(val_mpint, x))) +FUNC(void, monty_export_into, (ARG(val_monty, mc), ARG(val_mpint, r), ARG(val_mpint, x))) +FUNC(val_mpint, monty_export, (ARG(val_monty, mc), ARG(val_mpint, x))) +FUNC(void, monty_mul_into, (ARG(val_monty, mc), ARG(val_mpint, r), ARG(val_mpint, x), ARG(val_mpint, y))) +FUNC(val_mpint, monty_add, (ARG(val_monty, mc), ARG(val_mpint, x), ARG(val_mpint, y))) +FUNC(val_mpint, monty_sub, (ARG(val_monty, mc), ARG(val_mpint, x), ARG(val_mpint, y))) +FUNC(val_mpint, monty_mul, (ARG(val_monty, mc), ARG(val_mpint, x), ARG(val_mpint, y))) +FUNC(val_mpint, monty_pow, (ARG(val_monty, mc), ARG(val_mpint, base), ARG(val_mpint, exponent))) +FUNC(val_mpint, monty_invert, (ARG(val_monty, mc), ARG(val_mpint, x))) +FUNC(val_mpint, monty_modsqrt, (ARG(val_modsqrt, sc), ARG(val_mpint, mx), ARG(out_uint, success))) +FUNC(val_mpint, mp_modpow, (ARG(val_mpint, base), ARG(val_mpint, exponent), ARG(val_mpint, modulus))) +FUNC(val_mpint, mp_modmul, (ARG(val_mpint, x), ARG(val_mpint, y), ARG(val_mpint, modulus))) +FUNC(val_mpint, mp_modadd, (ARG(val_mpint, x), ARG(val_mpint, y), ARG(val_mpint, modulus))) +FUNC(val_mpint, mp_modsub, (ARG(val_mpint, x), ARG(val_mpint, y), ARG(val_mpint, modulus))) +FUNC(void, mp_lshift_safe_into, (ARG(val_mpint, r), ARG(val_mpint, x), ARG(uint, shift))) +FUNC(void, mp_rshift_safe_into, (ARG(val_mpint, r), ARG(val_mpint, x), ARG(uint, shift))) +FUNC(val_mpint, mp_rshift_safe, (ARG(val_mpint, x), ARG(uint, shift))) +FUNC(void, mp_lshift_fixed_into, (ARG(val_mpint, r), ARG(val_mpint, a), ARG(uint, shift))) +FUNC(void, mp_rshift_fixed_into, (ARG(val_mpint, r), ARG(val_mpint, x), ARG(uint, shift))) +FUNC(val_mpint, mp_rshift_fixed, (ARG(val_mpint, x), ARG(uint, shift))) +FUNC(val_mpint, mp_random_bits, (ARG(uint, bits))) +FUNC(val_mpint, mp_random_in_range, (ARG(val_mpint, lo), ARG(val_mpint, hi))) /* * ecc.h functions. */ -FUNC4(val_wcurve, ecc_weierstrass_curve, val_mpint, val_mpint, val_mpint, opt_val_mpint) -FUNC1(val_wpoint, ecc_weierstrass_point_new_identity, val_wcurve) -FUNC3(val_wpoint, ecc_weierstrass_point_new, val_wcurve, val_mpint, val_mpint) -FUNC3(val_wpoint, ecc_weierstrass_point_new_from_x, val_wcurve, val_mpint, uint) -FUNC1(val_wpoint, ecc_weierstrass_point_copy, val_wpoint) -FUNC1(uint, ecc_weierstrass_point_valid, val_wpoint) -FUNC2(val_wpoint, ecc_weierstrass_add_general, val_wpoint, val_wpoint) -FUNC2(val_wpoint, ecc_weierstrass_add, val_wpoint, val_wpoint) -FUNC1(val_wpoint, ecc_weierstrass_double, val_wpoint) -FUNC2(val_wpoint, ecc_weierstrass_multiply, val_wpoint, val_mpint) -FUNC1(uint, ecc_weierstrass_is_identity, val_wpoint) +FUNC(val_wcurve, ecc_weierstrass_curve, (ARG(val_mpint, p), ARG(val_mpint, a), ARG(val_mpint, b), ARG(opt_val_mpint, nonsquare_mod_p))) +FUNC(val_wpoint, ecc_weierstrass_point_new_identity, (ARG(val_wcurve, curve))) +FUNC(val_wpoint, ecc_weierstrass_point_new, (ARG(val_wcurve, curve), ARG(val_mpint, x), ARG(val_mpint, y))) +FUNC(val_wpoint, ecc_weierstrass_point_new_from_x, (ARG(val_wcurve, curve), ARG(val_mpint, x), ARG(uint, desired_y_parity))) +FUNC(val_wpoint, ecc_weierstrass_point_copy, (ARG(val_wpoint, wc))) +FUNC(uint, ecc_weierstrass_point_valid, (ARG(val_wpoint, P))) +FUNC(val_wpoint, ecc_weierstrass_add_general, (ARG(val_wpoint, P), ARG(val_wpoint, Q))) +FUNC(val_wpoint, ecc_weierstrass_add, (ARG(val_wpoint, P), ARG(val_wpoint, Q))) +FUNC(val_wpoint, ecc_weierstrass_double, (ARG(val_wpoint, P))) +FUNC(val_wpoint, ecc_weierstrass_multiply, (ARG(val_wpoint, B), ARG(val_mpint, n))) +FUNC(uint, ecc_weierstrass_is_identity, (ARG(val_wpoint, wp))) /* The output pointers in get_affine all become extra output values */ -FUNC3(void, ecc_weierstrass_get_affine, val_wpoint, out_val_mpint, out_val_mpint) -FUNC3(val_mcurve, ecc_montgomery_curve, val_mpint, val_mpint, val_mpint) -FUNC2(val_mpoint, ecc_montgomery_point_new, val_mcurve, val_mpint) -FUNC1(val_mpoint, ecc_montgomery_point_copy, val_mpoint) -FUNC3(val_mpoint, ecc_montgomery_diff_add, val_mpoint, val_mpoint, val_mpoint) -FUNC1(val_mpoint, ecc_montgomery_double, val_mpoint) -FUNC2(val_mpoint, ecc_montgomery_multiply, val_mpoint, val_mpint) -FUNC2(void, ecc_montgomery_get_affine, val_mpoint, out_val_mpint) -FUNC1(boolean, ecc_montgomery_is_identity, val_mpoint) -FUNC4(val_ecurve, ecc_edwards_curve, val_mpint, val_mpint, val_mpint, opt_val_mpint) -FUNC3(val_epoint, ecc_edwards_point_new, val_ecurve, val_mpint, val_mpint) -FUNC3(val_epoint, ecc_edwards_point_new_from_y, val_ecurve, val_mpint, uint) -FUNC1(val_epoint, ecc_edwards_point_copy, val_epoint) -FUNC2(val_epoint, ecc_edwards_add, val_epoint, val_epoint) -FUNC2(val_epoint, ecc_edwards_multiply, val_epoint, val_mpint) -FUNC2(uint, ecc_edwards_eq, val_epoint, val_epoint) -FUNC3(void, ecc_edwards_get_affine, val_epoint, out_val_mpint, out_val_mpint) +FUNC(void, ecc_weierstrass_get_affine, (ARG(val_wpoint, wp), ARG(out_val_mpint, x), ARG(out_val_mpint, y))) +FUNC(val_mcurve, ecc_montgomery_curve, (ARG(val_mpint, p), ARG(val_mpint, a), ARG(val_mpint, b))) +FUNC(val_mpoint, ecc_montgomery_point_new, (ARG(val_mcurve, mc), ARG(val_mpint, x))) +FUNC(val_mpoint, ecc_montgomery_point_copy, (ARG(val_mpoint, orig))) +FUNC(val_mpoint, ecc_montgomery_diff_add, (ARG(val_mpoint, P), ARG(val_mpoint, Q), ARG(val_mpoint, PminusQ))) +FUNC(val_mpoint, ecc_montgomery_double, (ARG(val_mpoint, P))) +FUNC(val_mpoint, ecc_montgomery_multiply, (ARG(val_mpoint, B), ARG(val_mpint, n))) +FUNC(void, ecc_montgomery_get_affine, (ARG(val_mpoint, mp), ARG(out_val_mpint, x))) +FUNC(boolean, ecc_montgomery_is_identity, (ARG(val_mpoint, mp))) +FUNC(val_ecurve, ecc_edwards_curve, (ARG(val_mpint, p), ARG(val_mpint, d), ARG(val_mpint, a), ARG(opt_val_mpint, nonsquare_mod_p))) +FUNC(val_epoint, ecc_edwards_point_new, (ARG(val_ecurve, curve), ARG(val_mpint, x), ARG(val_mpint, y))) +FUNC(val_epoint, ecc_edwards_point_new_from_y, (ARG(val_ecurve, curve), ARG(val_mpint, y), ARG(uint, desired_x_parity))) +FUNC(val_epoint, ecc_edwards_point_copy, (ARG(val_epoint, ec))) +FUNC(val_epoint, ecc_edwards_add, (ARG(val_epoint, P), ARG(val_epoint, Q))) +FUNC(val_epoint, ecc_edwards_multiply, (ARG(val_epoint, B), ARG(val_mpint, n))) +FUNC(uint, ecc_edwards_eq, (ARG(val_epoint, P), ARG(val_epoint, Q))) +FUNC(void, ecc_edwards_get_affine, (ARG(val_epoint, wp), ARG(out_val_mpint, x), ARG(out_val_mpint, y))) /* * The ssh_hash abstraction. Note the 'consumed', indicating that @@ -129,26 +193,26 @@ FUNC3(void, ecc_edwards_get_affine, val_epoint, out_val_mpint, out_val_mpint) * ssh_hash_update is an invention of testcrypt, handled in the real C * API by the hash object also functioning as a BinarySink. */ -FUNC1(opt_val_hash, ssh_hash_new, hashalg) -FUNC1(void, ssh_hash_reset, val_hash) -FUNC1(val_hash, ssh_hash_copy, val_hash) -FUNC1(val_string, ssh_hash_digest, val_hash) -FUNC1(val_string, ssh_hash_final, consumed_val_hash) -FUNC2(void, ssh_hash_update, val_hash, val_string_ptrlen) +FUNC(opt_val_hash, ssh_hash_new, (ARG(hashalg, alg))) +FUNC(void, ssh_hash_reset, (ARG(val_hash, h))) +FUNC(val_hash, ssh_hash_copy, (ARG(val_hash, orig))) +FUNC(val_string, ssh_hash_digest, (ARG(val_hash, h))) +FUNC(val_string, ssh_hash_final, (ARG(consumed_val_hash, h))) +FUNC(void, ssh_hash_update, (ARG(val_hash, h), ARG(val_string_ptrlen, pl))) -FUNC1(opt_val_hash, blake2b_new_general, uint) +FUNC(opt_val_hash, blake2b_new_general, (ARG(uint, hashlen))) /* * The ssh2_mac abstraction. Note the optional ssh_cipher parameter * to ssh2_mac_new. Also, again, I've invented an ssh2_mac_update so * you can put data into the MAC. */ -FUNC2(val_mac, ssh2_mac_new, macalg, opt_val_cipher) -FUNC2(void, ssh2_mac_setkey, val_mac, val_string_ptrlen) -FUNC1(void, ssh2_mac_start, val_mac) -FUNC2(void, ssh2_mac_update, val_mac, val_string_ptrlen) -FUNC1(val_string, ssh2_mac_genresult, val_mac) -FUNC1(val_string_asciz_const, ssh2_mac_text_name, val_mac) +FUNC(val_mac, ssh2_mac_new, (ARG(macalg, alg), ARG(opt_val_cipher, cipher))) +FUNC(void, ssh2_mac_setkey, (ARG(val_mac, m), ARG(val_string_ptrlen, key))) +FUNC(void, ssh2_mac_start, (ARG(val_mac, m))) +FUNC(void, ssh2_mac_update, (ARG(val_mac, m), ARG(val_string_ptrlen, pl))) +FUNC(val_string, ssh2_mac_genresult, (ARG(val_mac, m))) +FUNC(val_string_asciz_const, ssh2_mac_text_name, (ARG(val_mac, m))) /* * The ssh_key abstraction. All the uses of BinarySink and @@ -157,174 +221,174 @@ FUNC1(val_string_asciz_const, ssh2_mac_text_name, val_mac) * all the functions that output key and signature blobs do it by * returning a string. */ -FUNC2(val_key, ssh_key_new_pub, keyalg, val_string_ptrlen) -FUNC3(opt_val_key, ssh_key_new_priv, keyalg, val_string_ptrlen, val_string_ptrlen) -FUNC2(opt_val_key, ssh_key_new_priv_openssh, keyalg, val_string_binarysource) -FUNC2(opt_val_string_asciz, ssh_key_invalid, val_key, uint) -FUNC4(void, ssh_key_sign, val_key, val_string_ptrlen, uint, out_val_string_binarysink) -FUNC3(boolean, ssh_key_verify, val_key, val_string_ptrlen, val_string_ptrlen) -FUNC2(void, ssh_key_public_blob, val_key, out_val_string_binarysink) -FUNC2(void, ssh_key_private_blob, val_key, out_val_string_binarysink) -FUNC2(void, ssh_key_openssh_blob, val_key, out_val_string_binarysink) -FUNC1(val_string_asciz, ssh_key_cache_str, val_key) -FUNC1(val_keycomponents, ssh_key_components, val_key) -FUNC2(uint, ssh_key_public_bits, keyalg, val_string_ptrlen) +FUNC(val_key, ssh_key_new_pub, (ARG(keyalg, self), ARG(val_string_ptrlen, pub))) +FUNC(opt_val_key, ssh_key_new_priv, (ARG(keyalg, self), ARG(val_string_ptrlen, pub), ARG(val_string_ptrlen, priv))) +FUNC(opt_val_key, ssh_key_new_priv_openssh, (ARG(keyalg, self), ARG(val_string_binarysource, src))) +FUNC(opt_val_string_asciz, ssh_key_invalid, (ARG(val_key, key), ARG(uint, flags))) +FUNC(void, ssh_key_sign, (ARG(val_key, key), ARG(val_string_ptrlen, data), ARG(uint, flags), ARG(out_val_string_binarysink, bs))) +FUNC(boolean, ssh_key_verify, (ARG(val_key, key), ARG(val_string_ptrlen, sig), ARG(val_string_ptrlen, data))) +FUNC(void, ssh_key_public_blob, (ARG(val_key, key), ARG(out_val_string_binarysink, bs))) +FUNC(void, ssh_key_private_blob, (ARG(val_key, key), ARG(out_val_string_binarysink, bs))) +FUNC(void, ssh_key_openssh_blob, (ARG(val_key, key), ARG(out_val_string_binarysink, bs))) +FUNC(val_string_asciz, ssh_key_cache_str, (ARG(val_key, key))) +FUNC(val_keycomponents, ssh_key_components, (ARG(val_key, key))) +FUNC(uint, ssh_key_public_bits, (ARG(keyalg, self), ARG(val_string_ptrlen, blob))) /* * Accessors to retrieve the innards of a 'key_components'. */ -FUNC1(uint, key_components_count, val_keycomponents) -FUNC2(opt_val_string_asciz_const, key_components_nth_name, val_keycomponents, uint) -FUNC2(opt_val_string_asciz_const, key_components_nth_str, val_keycomponents, uint) -FUNC2(opt_val_mpint, key_components_nth_mp, val_keycomponents, uint) +FUNC(uint, key_components_count, (ARG(val_keycomponents, kc))) +FUNC(opt_val_string_asciz_const, key_components_nth_name, (ARG(val_keycomponents, kc), ARG(uint, n))) +FUNC(opt_val_string_asciz_const, key_components_nth_str, (ARG(val_keycomponents, kc), ARG(uint, n))) +FUNC(opt_val_mpint, key_components_nth_mp, (ARG(val_keycomponents, kc), ARG(uint, n))) /* * The ssh_cipher abstraction. The in-place encrypt and decrypt * functions are wrapped to replace them with versions that take one * string and return a separate string. */ -FUNC1(opt_val_cipher, ssh_cipher_new, cipheralg) -FUNC2(void, ssh_cipher_setiv, val_cipher, val_string_ptrlen) -FUNC2(void, ssh_cipher_setkey, val_cipher, val_string_ptrlen) -FUNC2(val_string, ssh_cipher_encrypt, val_cipher, val_string_ptrlen) -FUNC2(val_string, ssh_cipher_decrypt, val_cipher, val_string_ptrlen) -FUNC3(val_string, ssh_cipher_encrypt_length, val_cipher, val_string_ptrlen, uint) -FUNC3(val_string, ssh_cipher_decrypt_length, val_cipher, val_string_ptrlen, uint) +FUNC(opt_val_cipher, ssh_cipher_new, (ARG(cipheralg, alg))) +FUNC(void, ssh_cipher_setiv, (ARG(val_cipher, c), ARG(val_string_ptrlen, iv))) +FUNC(void, ssh_cipher_setkey, (ARG(val_cipher, c), ARG(val_string_ptrlen, key))) +FUNC(val_string, ssh_cipher_encrypt, (ARG(val_cipher, c), ARG(val_string_ptrlen, blk))) +FUNC(val_string, ssh_cipher_decrypt, (ARG(val_cipher, c), ARG(val_string_ptrlen, blk))) +FUNC(val_string, ssh_cipher_encrypt_length, (ARG(val_cipher, c), ARG(val_string_ptrlen, blk), ARG(uint, seq))) +FUNC(val_string, ssh_cipher_decrypt_length, (ARG(val_cipher, c), ARG(val_string_ptrlen, blk), ARG(uint, seq))) /* * Integer Diffie-Hellman. */ -FUNC1(val_dh, dh_setup_group, dh_group) -FUNC2(val_dh, dh_setup_gex, val_mpint, val_mpint) -FUNC1(uint, dh_modulus_bit_size, val_dh) -FUNC2(val_mpint, dh_create_e, val_dh, uint) -FUNC2(boolean, dh_validate_f, val_dh, val_mpint) -FUNC2(val_mpint, dh_find_K, val_dh, val_mpint) +FUNC(val_dh, dh_setup_group, (ARG(dh_group, kex))) +FUNC(val_dh, dh_setup_gex, (ARG(val_mpint, pval), ARG(val_mpint, gval))) +FUNC(uint, dh_modulus_bit_size, (ARG(val_dh, ctx))) +FUNC(val_mpint, dh_create_e, (ARG(val_dh, ctx), ARG(uint, nbits))) +FUNC(boolean, dh_validate_f, (ARG(val_dh, ctx), ARG(val_mpint, f))) +FUNC(val_mpint, dh_find_K, (ARG(val_dh, ctx), ARG(val_mpint, f))) /* * Elliptic-curve Diffie-Hellman. */ -FUNC1(val_ecdh, ssh_ecdhkex_newkey, ecdh_alg) -FUNC2(void, ssh_ecdhkex_getpublic, val_ecdh, out_val_string_binarysink) -FUNC2(opt_val_mpint, ssh_ecdhkex_getkey, val_ecdh, val_string_ptrlen) +FUNC(val_ecdh, ssh_ecdhkex_newkey, (ARG(ecdh_alg, kex))) +FUNC(void, ssh_ecdhkex_getpublic, (ARG(val_ecdh, key), ARG(out_val_string_binarysink, bs))) +FUNC(opt_val_mpint, ssh_ecdhkex_getkey, (ARG(val_ecdh, key), ARG(val_string_ptrlen, remoteKey))) /* * RSA key exchange, and also the BinarySource get function * get_ssh1_rsa_priv_agent, which is a convenient way to make an * RSAKey for RSA kex testing purposes. */ -FUNC1(val_rsakex, ssh_rsakex_newkey, val_string_ptrlen) -FUNC1(uint, ssh_rsakex_klen, val_rsakex) -FUNC3(val_string, ssh_rsakex_encrypt, val_rsakex, hashalg, val_string_ptrlen) -FUNC3(opt_val_mpint, ssh_rsakex_decrypt, val_rsakex, hashalg, val_string_ptrlen) -FUNC1(val_rsakex, get_rsa_ssh1_priv_agent, val_string_binarysource) +FUNC(val_rsakex, ssh_rsakex_newkey, (ARG(val_string_ptrlen, data))) +FUNC(uint, ssh_rsakex_klen, (ARG(val_rsakex, key))) +FUNC(val_string, ssh_rsakex_encrypt, (ARG(val_rsakex, key), ARG(hashalg, h), ARG(val_string_ptrlen, plaintext))) +FUNC(opt_val_mpint, ssh_rsakex_decrypt, (ARG(val_rsakex, key), ARG(hashalg, h), ARG(val_string_ptrlen, ciphertext))) +FUNC(val_rsakex, get_rsa_ssh1_priv_agent, (ARG(val_string_binarysource, src))) /* * Bare RSA keys as used in SSH-1. The construction API functions * write into an existing RSAKey object, so I've invented an 'rsa_new' * function to make one in the first place. */ -FUNC0(val_rsa, rsa_new) -FUNC3(void, get_rsa_ssh1_pub, val_string_binarysource, val_rsa, rsaorder) -FUNC2(void, get_rsa_ssh1_priv, val_string_binarysource, val_rsa) -FUNC2(opt_val_string, rsa_ssh1_encrypt, val_string_ptrlen, val_rsa) -FUNC2(val_mpint, rsa_ssh1_decrypt, val_mpint, val_rsa) -FUNC2(val_string, rsa_ssh1_decrypt_pkcs1, val_mpint, val_rsa) -FUNC1(val_string_asciz, rsastr_fmt, val_rsa) -FUNC1(val_string_asciz, rsa_ssh1_fingerprint, val_rsa) -FUNC3(void, rsa_ssh1_public_blob, out_val_string_binarysink, val_rsa, rsaorder) -FUNC1(int, rsa_ssh1_public_blob_len, val_string_ptrlen) -FUNC2(void, rsa_ssh1_private_blob_agent, out_val_string_binarysink, val_rsa) +FUNC(val_rsa, rsa_new, (VOID)) +FUNC(void, get_rsa_ssh1_pub, (ARG(val_string_binarysource, src), ARG(val_rsa, key), ARG(rsaorder, order))) +FUNC(void, get_rsa_ssh1_priv, (ARG(val_string_binarysource, src), ARG(val_rsa, key))) +FUNC(opt_val_string, rsa_ssh1_encrypt, (ARG(val_string_ptrlen, data), ARG(val_rsa, key))) +FUNC(val_mpint, rsa_ssh1_decrypt, (ARG(val_mpint, input), ARG(val_rsa, key))) +FUNC(val_string, rsa_ssh1_decrypt_pkcs1, (ARG(val_mpint, input), ARG(val_rsa, key))) +FUNC(val_string_asciz, rsastr_fmt, (ARG(val_rsa, key))) +FUNC(val_string_asciz, rsa_ssh1_fingerprint, (ARG(val_rsa, key))) +FUNC(void, rsa_ssh1_public_blob, (ARG(out_val_string_binarysink, bs), ARG(val_rsa, key), ARG(rsaorder, order))) +FUNC(int, rsa_ssh1_public_blob_len, (ARG(val_string_ptrlen, data))) +FUNC(void, rsa_ssh1_private_blob_agent, (ARG(out_val_string_binarysink, bs), ARG(val_rsa, key))) /* * The PRNG type. Similarly to hashes and MACs, I've invented an extra * function prng_seed_update for putting seed data into the PRNG's * exposed BinarySink. */ -FUNC1(val_prng, prng_new, hashalg) -FUNC1(void, prng_seed_begin, val_prng) -FUNC2(void, prng_seed_update, val_prng, val_string_ptrlen) -FUNC1(void, prng_seed_finish, val_prng) -FUNC2(val_string, prng_read, val_prng, uint) -FUNC3(void, prng_add_entropy, val_prng, uint, val_string_ptrlen) +FUNC(val_prng, prng_new, (ARG(hashalg, hashalg))) +FUNC(void, prng_seed_begin, (ARG(val_prng, p))) +FUNC(void, prng_seed_update, (ARG(val_prng, pr), ARG(val_string_ptrlen, data))) +FUNC(void, prng_seed_finish, (ARG(val_prng, p))) +FUNC(val_string, prng_read, (ARG(val_prng, p), ARG(uint, size))) +FUNC(void, prng_add_entropy, (ARG(val_prng, p), ARG(uint, source_id), ARG(val_string_ptrlen, data))) /* * Key load/save functions, or rather, the BinarySource / strbuf API * that sits just inside the file I/O versions. */ -FUNC2(boolean, ppk_encrypted_s, val_string_binarysource, out_opt_val_string_asciz) -FUNC2(boolean, rsa1_encrypted_s, val_string_binarysource, out_opt_val_string_asciz) -FUNC5(boolean, ppk_loadpub_s, val_string_binarysource, out_opt_val_string_asciz, out_val_string_binarysink, out_opt_val_string_asciz, out_opt_val_string_asciz_const) -FUNC4(int, rsa1_loadpub_s, val_string_binarysource, out_val_string_binarysink, out_opt_val_string_asciz, out_opt_val_string_asciz_const) -FUNC4(opt_val_key, ppk_load_s, val_string_binarysource, out_opt_val_string_asciz, opt_val_string_asciz, out_opt_val_string_asciz_const) -FUNC5(int, rsa1_load_s, val_string_binarysource, val_rsa, out_opt_val_string_asciz, opt_val_string_asciz, out_opt_val_string_asciz_const) -FUNC8(val_string, ppk_save_sb, val_key, opt_val_string_asciz, opt_val_string_asciz, uint, argon2flavour, uint, uint, uint) -FUNC3(val_string, rsa1_save_sb, val_rsa, opt_val_string_asciz, opt_val_string_asciz) +FUNC(boolean, ppk_encrypted_s, (ARG(val_string_binarysource, src), ARG(out_opt_val_string_asciz, comment))) +FUNC(boolean, rsa1_encrypted_s, (ARG(val_string_binarysource, src), ARG(out_opt_val_string_asciz, comment))) +FUNC(boolean, ppk_loadpub_s, (ARG(val_string_binarysource, src), ARG(out_opt_val_string_asciz, algorithm), ARG(out_val_string_binarysink, bs), ARG(out_opt_val_string_asciz, commentptr), ARG(out_opt_val_string_asciz_const, errorstr))) +FUNC(int, rsa1_loadpub_s, (ARG(val_string_binarysource, src), ARG(out_val_string_binarysink, bs), ARG(out_opt_val_string_asciz, commentptr), ARG(out_opt_val_string_asciz_const, errorstr))) +FUNC(opt_val_key, ppk_load_s, (ARG(val_string_binarysource, src), ARG(out_opt_val_string_asciz, comment), ARG(opt_val_string_asciz, passphrase), ARG(out_opt_val_string_asciz_const, errorstr))) +FUNC(int, rsa1_load_s, (ARG(val_string_binarysource, src), ARG(val_rsa, key), ARG(out_opt_val_string_asciz, comment), ARG(opt_val_string_asciz, passphrase), ARG(out_opt_val_string_asciz_const, errorstr))) +FUNC(val_string, ppk_save_sb, (ARG(val_key, key), ARG(opt_val_string_asciz, comment), ARG(opt_val_string_asciz, passphrase), ARG(uint, fmt_version), ARG(argon2flavour, flavour), ARG(uint, mem), ARG(uint, passes), ARG(uint, parallel))) +FUNC(val_string, rsa1_save_sb, (ARG(val_rsa, key), ARG(opt_val_string_asciz, comment), ARG(opt_val_string_asciz, passphrase))) -FUNC2(val_string_asciz, ssh2_fingerprint_blob, val_string_ptrlen, fptype) +FUNC(val_string_asciz, ssh2_fingerprint_blob, (ARG(val_string_ptrlen, blob), ARG(fptype, fptype))) /* * Password hashing. */ -FUNC9(val_string, argon2, argon2flavour, uint, uint, uint, uint, val_string_ptrlen, val_string_ptrlen, val_string_ptrlen, val_string_ptrlen) -FUNC2(val_string, argon2_long_hash, uint, val_string_ptrlen) +FUNC(val_string, argon2, (ARG(argon2flavour, flavour), ARG(uint, mem), ARG(uint, passes), ARG(uint, parallel), ARG(uint, taglen), ARG(val_string_ptrlen, P), ARG(val_string_ptrlen, S), ARG(val_string_ptrlen, K), ARG(val_string_ptrlen, X))) +FUNC(val_string, argon2_long_hash, (ARG(uint, length), ARG(val_string_ptrlen, data))) /* * Key generation functions. */ -FUNC3(val_key, rsa_generate, uint, boolean, val_pgc) -FUNC2(val_key, dsa_generate, uint, val_pgc) -FUNC1(opt_val_key, ecdsa_generate, uint) -FUNC1(opt_val_key, eddsa_generate, uint) -FUNC3(val_rsa, rsa1_generate, uint, boolean, val_pgc) -FUNC1(val_pgc, primegen_new_context, primegenpolicy) -FUNC2(opt_val_mpint, primegen_generate, val_pgc, consumed_val_pcs) -FUNC2(val_string, primegen_mpu_certificate, val_pgc, val_mpint) -FUNC1(val_pcs, pcs_new, uint) -FUNC3(val_pcs, pcs_new_with_firstbits, uint, uint, uint) -FUNC3(void, pcs_require_residue, val_pcs, val_mpint, val_mpint) -FUNC2(void, pcs_require_residue_1, val_pcs, val_mpint) -FUNC2(void, pcs_require_residue_1_mod_prime, val_pcs, val_mpint) -FUNC3(void, pcs_avoid_residue_small, val_pcs, uint, uint) -FUNC1(void, pcs_try_sophie_germain, val_pcs) -FUNC1(void, pcs_set_oneshot, val_pcs) -FUNC1(void, pcs_ready, val_pcs) -FUNC4(void, pcs_inspect, val_pcs, out_val_mpint, out_val_mpint, out_val_mpint) -FUNC1(val_mpint, pcs_generate, val_pcs) -FUNC0(val_pockle, pockle_new) -FUNC1(uint, pockle_mark, val_pockle) -FUNC2(void, pockle_release, val_pockle, uint) -FUNC2(pocklestatus, pockle_add_small_prime, val_pockle, val_mpint) -FUNC4(pocklestatus, pockle_add_prime, val_pockle, val_mpint, mpint_list, val_mpint) -FUNC2(val_string, pockle_mpu, val_pockle, val_mpint) -FUNC1(val_millerrabin, miller_rabin_new, val_mpint) -FUNC2(mr_result, miller_rabin_test, val_millerrabin, val_mpint) +FUNC(val_key, rsa_generate, (ARG(uint, bits), ARG(boolean, strong), ARG(val_pgc, pgc))) +FUNC(val_key, dsa_generate, (ARG(uint, bits), ARG(val_pgc, pgc))) +FUNC(opt_val_key, ecdsa_generate, (ARG(uint, bits))) +FUNC(opt_val_key, eddsa_generate, (ARG(uint, bits))) +FUNC(val_rsa, rsa1_generate, (ARG(uint, bits), ARG(boolean, strong), ARG(val_pgc, pgc))) +FUNC(val_pgc, primegen_new_context, (ARG(primegenpolicy, policy))) +FUNC(opt_val_mpint, primegen_generate, (ARG(val_pgc, ctx), ARG(consumed_val_pcs, pcs))) +FUNC(val_string, primegen_mpu_certificate, (ARG(val_pgc, ctx), ARG(val_mpint, p))) +FUNC(val_pcs, pcs_new, (ARG(uint, bits))) +FUNC(val_pcs, pcs_new_with_firstbits, (ARG(uint, bits), ARG(uint, first), ARG(uint, nfirst))) +FUNC(void, pcs_require_residue, (ARG(val_pcs, s), ARG(val_mpint, mod), ARG(val_mpint, res))) +FUNC(void, pcs_require_residue_1, (ARG(val_pcs, s), ARG(val_mpint, mod))) +FUNC(void, pcs_require_residue_1_mod_prime, (ARG(val_pcs, s), ARG(val_mpint, mod))) +FUNC(void, pcs_avoid_residue_small, (ARG(val_pcs, s), ARG(uint, mod), ARG(uint, res))) +FUNC(void, pcs_try_sophie_germain, (ARG(val_pcs, s))) +FUNC(void, pcs_set_oneshot, (ARG(val_pcs, s))) +FUNC(void, pcs_ready, (ARG(val_pcs, s))) +FUNC(void, pcs_inspect, (ARG(val_pcs, pcs), ARG(out_val_mpint, limit_out), ARG(out_val_mpint, factor_out), ARG(out_val_mpint, addend_out))) +FUNC(val_mpint, pcs_generate, (ARG(val_pcs, s))) +FUNC(val_pockle, pockle_new, (VOID)) +FUNC(uint, pockle_mark, (ARG(val_pockle, pockle))) +FUNC(void, pockle_release, (ARG(val_pockle, pockle), ARG(uint, mark))) +FUNC(pocklestatus, pockle_add_small_prime, (ARG(val_pockle, pockle), ARG(val_mpint, p))) +FUNC(pocklestatus, pockle_add_prime, (ARG(val_pockle, pockle), ARG(val_mpint, p), ARG(mpint_list, factors), ARG(val_mpint, witness))) +FUNC(val_string, pockle_mpu, (ARG(val_pockle, pockle), ARG(val_mpint, p))) +FUNC(val_millerrabin, miller_rabin_new, (ARG(val_mpint, p))) +FUNC(mr_result, miller_rabin_test, (ARG(val_millerrabin, mr), ARG(val_mpint, w))) /* * Miscellaneous. */ -FUNC2(val_wpoint, ecdsa_public, val_mpint, keyalg) -FUNC2(val_epoint, eddsa_public, val_mpint, keyalg) -FUNC2(val_string, des_encrypt_xdmauth, val_string_ptrlen, val_string_ptrlen) -FUNC2(val_string, des_decrypt_xdmauth, val_string_ptrlen, val_string_ptrlen) -FUNC2(val_string, des3_encrypt_pubkey, val_string_ptrlen, val_string_ptrlen) -FUNC2(val_string, des3_decrypt_pubkey, val_string_ptrlen, val_string_ptrlen) -FUNC3(val_string, des3_encrypt_pubkey_ossh, val_string_ptrlen, val_string_ptrlen, val_string_ptrlen) -FUNC3(val_string, des3_decrypt_pubkey_ossh, val_string_ptrlen, val_string_ptrlen, val_string_ptrlen) -FUNC3(val_string, aes256_encrypt_pubkey, val_string_ptrlen, val_string_ptrlen, val_string_ptrlen) -FUNC3(val_string, aes256_decrypt_pubkey, val_string_ptrlen, val_string_ptrlen, val_string_ptrlen) -FUNC1(uint, crc32_rfc1662, val_string_ptrlen) -FUNC1(uint, crc32_ssh1, val_string_ptrlen) -FUNC2(uint, crc32_update, uint, val_string_ptrlen) -FUNC2(boolean, crcda_detect, val_string_ptrlen, val_string_ptrlen) -FUNC1(val_string, get_implementations_commasep, val_string_ptrlen) -FUNC12(void, http_digest_response, out_val_string_binarysink, val_string_ptrlen, val_string_ptrlen, val_string_ptrlen, val_string_ptrlen, val_string_ptrlen, val_string_ptrlen, val_string_ptrlen, val_string_ptrlen, uint, httpdigesthash, boolean) +FUNC(val_wpoint, ecdsa_public, (ARG(val_mpint, private_key), ARG(keyalg, alg))) +FUNC(val_epoint, eddsa_public, (ARG(val_mpint, private_key), ARG(keyalg, alg))) +FUNC(val_string, des_encrypt_xdmauth, (ARG(val_string_ptrlen, key), ARG(val_string_ptrlen, blk))) +FUNC(val_string, des_decrypt_xdmauth, (ARG(val_string_ptrlen, key), ARG(val_string_ptrlen, blk))) +FUNC(val_string, des3_encrypt_pubkey, (ARG(val_string_ptrlen, key), ARG(val_string_ptrlen, blk))) +FUNC(val_string, des3_decrypt_pubkey, (ARG(val_string_ptrlen, key), ARG(val_string_ptrlen, blk))) +FUNC(val_string, des3_encrypt_pubkey_ossh, (ARG(val_string_ptrlen, key), ARG(val_string_ptrlen, iv), ARG(val_string_ptrlen, blk))) +FUNC(val_string, des3_decrypt_pubkey_ossh, (ARG(val_string_ptrlen, key), ARG(val_string_ptrlen, iv), ARG(val_string_ptrlen, blk))) +FUNC(val_string, aes256_encrypt_pubkey, (ARG(val_string_ptrlen, key), ARG(val_string_ptrlen, iv), ARG(val_string_ptrlen, blk))) +FUNC(val_string, aes256_decrypt_pubkey, (ARG(val_string_ptrlen, key), ARG(val_string_ptrlen, iv), ARG(val_string_ptrlen, blk))) +FUNC(uint, crc32_rfc1662, (ARG(val_string_ptrlen, data))) +FUNC(uint, crc32_ssh1, (ARG(val_string_ptrlen, data))) +FUNC(uint, crc32_update, (ARG(uint, crc_input), ARG(val_string_ptrlen, data))) +FUNC(boolean, crcda_detect, (ARG(val_string_ptrlen, packet), ARG(val_string_ptrlen, iv))) +FUNC(val_string, get_implementations_commasep, (ARG(val_string_ptrlen, alg))) +FUNC(void, http_digest_response, (ARG(out_val_string_binarysink, bs), ARG(val_string_ptrlen, username), ARG(val_string_ptrlen, password), ARG(val_string_ptrlen, realm), ARG(val_string_ptrlen, method), ARG(val_string_ptrlen, uri), ARG(val_string_ptrlen, qop), ARG(val_string_ptrlen, nonce), ARG(val_string_ptrlen, opaque), ARG(uint, nonce_count), ARG(httpdigesthash, hash), ARG(boolean, hash_username))) /* * These functions aren't part of PuTTY's own API, but are additions * by testcrypt itself for administrative purposes. */ -FUNC1(void, random_queue, val_string_ptrlen) -FUNC0(uint, random_queue_len) -FUNC2(void, random_make_prng, hashalg, val_string_ptrlen) -FUNC0(void, random_clear) +FUNC(void, random_queue, (ARG(val_string_ptrlen, pl))) +FUNC(uint, random_queue_len, (VOID)) +FUNC(void, random_make_prng, (ARG(hashalg, hashalg), ARG(val_string_ptrlen, seed))) +FUNC(void, random_clear, (VOID))