Repository: randombit/botan
Pull request #3457 (2023-03-31 12:05:00)

FFI fixes


Patch:
diff --git a/src/lib/ffi/ffi.h b/src/lib/ffi/ffi.h
index 7a4e05efe..8596ec6a6 100644
--- a/src/lib/ffi/ffi.h
+++ b/src/lib/ffi/ffi.h
@@ -2103,7 +2103,7 @@ int botan_srp6_server_session_step2(botan_srp6_server_session_t srp6,
 * @return 0 on success, negative on failure
 */
 BOTAN_PUBLIC_API(3,0)
-int botan_generate_srp6_verifier(const char *identifier, const char *password,
+int botan_srp6_generate_verifier(const char *identifier, const char *password,
                                  const uint8_t salt[], size_t salt_len,
                                  const char *group_id, const char *hash_id,
                                  uint8_t verifier[], size_t *verifier_len);
diff --git a/src/lib/ffi/ffi_srp6.cpp b/src/lib/ffi/ffi_srp6.cpp
index 04519a353..b05547a26 100644
--- a/src/lib/ffi/ffi_srp6.cpp
+++ b/src/lib/ffi/ffi_srp6.cpp
@@ -130,7 +130,7 @@ int botan_srp6_server_session_step2(botan_srp6_server_session_t srp6,
 #endif
    }
 
-int botan_generate_srp6_verifier(const char* username, const char* password,
+int botan_srp6_generate_verifier(const char* username, const char* password,
                                  const uint8_t salt[], size_t salt_len,
                                  const char* group_id, const char* hash_id,
                                  uint8_t verifier[], size_t* verifier_len)
@@ -145,7 +145,7 @@ int botan_generate_srp6_verifier(const char* username, const char* password,
       try
          {
          std::vector<uint8_t> salt_vec(salt, salt + salt_len);
-         auto verifier_bn = Botan::generate_srp6_verifier(
+         auto verifier_bn = Botan::srp6_generate_verifier(
             username, password, salt_vec, group_id, hash_id);
          return write_vec_output(verifier, verifier_len,
                                  Botan::BigInt::encode(verifier_bn));
diff --git a/src/lib/misc/srp6/srp6.cpp b/src/lib/misc/srp6/srp6.cpp
index dd9919bbf..b7af9a396 100644
--- a/src/lib/misc/srp6/srp6.cpp
+++ b/src/lib/misc/srp6/srp6.cpp
@@ -137,17 +137,17 @@ srp6_client_agree(const std::string& identifier,
    return std::make_pair(A, Sk);
    }
 
-BigInt generate_srp6_verifier(const std::string& identifier,
+BigInt srp6_generate_verifier(const std::string& identifier,
                               const std::string& password,
                               const std::vector<uint8_t>& salt,
                               const std::string& group_id,
                               const std::string& hash_id)
    {
    DL_Group group(group_id);
-   return generate_srp6_verifier(identifier, password, salt, group, hash_id);
+   return srp6_generate_verifier(identifier, password, salt, group, hash_id);
    }
 
-BigInt generate_srp6_verifier(const std::string& identifier,
+BigInt srp6_generate_verifier(const std::string& identifier,
                               const std::string& password,
                               const std::vector<uint8_t>& salt,
                               const DL_Group& group,
diff --git a/src/lib/misc/srp6/srp6.h b/src/lib/misc/srp6/srp6.h
index 42b724b23..2c8f634ca 100644
--- a/src/lib/misc/srp6/srp6.h
+++ b/src/lib/misc/srp6/srp6.h
@@ -71,7 +71,7 @@ std::pair<BigInt,SymmetricKey> BOTAN_PUBLIC_API(2,11)
 * @param hash_id specifies a secure hash function
 */
 BigInt BOTAN_PUBLIC_API(2,0)
-   generate_srp6_verifier(const std::string& identifier,
+   srp6_generate_verifier(const std::string& identifier,
                           const std::string& password,
                           const std::vector<uint8_t>& salt,
                           const std::string& group_id,
@@ -86,7 +86,7 @@ BigInt BOTAN_PUBLIC_API(2,0)
 * @param hash_id specifies a secure hash function
 */
 BigInt BOTAN_PUBLIC_API(2,11)
-   generate_srp6_verifier(const std::string& identifier,
+   srp6_generate_verifier(const std::string& identifier,
                           const std::string& password,
                           const std::vector<uint8_t>& salt,
                           const DL_Group& group,
diff --git a/src/python/botan3.py b/src/python/botan3.py
index 6b6c20e2b..ff1afb6a7 100755
--- a/src/python/botan3.py
+++ b/src/python/botan3.py
@@ -475,7 +475,7 @@ def _set_prototypes(dll):
             [c_void_p, c_char_p, c_size_t, c_char_p, c_char_p, c_void_p, c_char_p, POINTER(c_size_t)])
     ffi_api(dll.botan_srp6_server_session_step2,
             [c_void_p, c_char_p, c_size_t, c_char_p, POINTER(c_size_t)])
-    ffi_api(dll.botan_generate_srp6_verifier,
+    ffi_api(dll.botan_srp6_generate_verifier,
             [c_char_p, c_char_p, c_char_p, c_size_t, c_char_p, c_char_p, c_char_p, POINTER(c_size_t)])
     ffi_api(dll.botan_srp6_client_agree,
             [c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_size_t, c_char_p, c_size_t, c_void_p,
@@ -1971,11 +1971,11 @@ class Srp6ServerSession:
                                                                            a, len(a),
                                                                            k, kl))
 
-def generate_srp6_verifier(identifier, password, salt, group, hsh):
+def srp6_generate_verifier(identifier, password, salt, group, hsh):
     sz = _call_fn_returning_sz(lambda l: _DLL.botan_srp6_group_size(_ctype_str(group), l))
 
     return _call_fn_returning_vec(sz, lambda v, vl:
-                                  _DLL.botan_generate_srp6_verifier(_ctype_str(identifier),
+                                  _DLL.botan_srp6_generate_verifier(_ctype_str(identifier),
                                                                     _ctype_str(password),
                                                                     salt, len(salt),
                                                                     _ctype_str(group),
diff --git a/src/scripts/dev_tools/gen_ffi_decls.py b/src/scripts/dev_tools/gen_ffi_decls.py
index d7a998259..6cf189b26 100755
--- a/src/scripts/dev_tools/gen_ffi_decls.py
+++ b/src/scripts/dev_tools/gen_ffi_decls.py
@@ -3,11 +3,12 @@
 """
 Automatically generate declarations for the FFI layer
 
-(C) 2019 Jack Lloyd
+(C) 2019, 2023 Jack Lloyd
 
 Botan is released under the Simplified BSD License (see license.txt)
 """
 
+import traceback
 from pycparser import c_ast, parse_file
 
 ffi_header = 'src/lib/ffi/ffi.h'
@@ -17,6 +18,14 @@ def to_ctype(typ, is_ptr):
     if typ.startswith('botan_') and typ.endswith('_t'):
         return 'c_void_p'
 
+    if typ == 'botan_view_ctx':
+        return 'c_void_p'
+
+    if typ == 'botan_view_bin_fn':
+        return 'VIEW_BIN_CALLBACK'
+    if typ == 'botan_view_str_fn':
+        return 'VIEW_STR_CALLBACK'
+
     if is_ptr is False:
         if typ == 'uint32':
             return 'c_uint32'
@@ -50,9 +59,24 @@ def to_ctype(typ, is_ptr):
 
     raise Exception("Unknown type %s/%d" % (typ, is_ptr))
 
-GROUP = None
-
 class FuncDefVisitor(c_ast.NodeVisitor):
+    def __init__(self):
+        self.fn_decls = []
+
+    def emit_decls(self):
+        decls = ''
+        for (fn_name, fn_args) in self.fn_decls:
+            decl = "    ffi_api(dll.%s," % (fn_name)
+            if len(fn_args) > 4:
+                decl += "\n            "
+            else:
+                decl += ' '
+
+            decl += '[' + ', '.join(fn_args) + '])\n'
+
+            decls += decl
+        return decls
+
     def visit_FuncDecl(self, node):
 
         if not isinstance(node.type, c_ast.TypeDecl):
@@ -66,48 +90,50 @@ class FuncDefVisitor(c_ast.NodeVisitor):
         # all functions returning ints:
         fn_name = node.type.declname
 
-        fn_group = fn_name.split('_')[1]
-        if fn_group == 'privkey':
-            fn_group = 'pubkey' # hack
-
-        global GROUP
-
-        if fn_group != GROUP:
-            if fn_group in ['rng', 'hash', 'mac', 'cipher', 'block', 'mp', 'pubkey', 'pk', 'x509', 'hotp', 'totp', 'fpe']:
-                print("\n    # ", fn_group.upper())
-            else:
-                print("")
-            GROUP = fn_group
-
+        ignored = [
+            'botan_view_bin_fn',
+            'botan_view_str_fn',
+            'botan_same_mem', # deprecated
+            'botan_mceies_encrypt', # dead
+            'botan_mceies_decrypt', # dead
+            'botan_rng_init_custom', # fixme
+        ]
+        if fn_name in ignored:
+            return
 
         fn_args = []
 
-        for param in node.args.params:
+        try:
+            for param in node.args.params:
 
-            is_ptr = False
-            typ = None
-            if isinstance(param.type, c_ast.PtrDecl):
-                is_ptr = True
-                typ = param.type.type.type.names[0]
-            elif isinstance(param.type, c_ast.ArrayDecl):
-                is_ptr = True
-                typ = param.type.type.type.names[0]
-            else:
-                typ = param.type.type.names[0]
+                is_ptr = False
+                typ = None
 
-            ctype = to_ctype(typ, is_ptr)
-            fn_args.append(ctype)
+                if isinstance(param.type, c_ast.PtrDecl):
+                    is_ptr = True
 
-        decl = "    ffi_api(dll.%s," % (fn_name)
-        if len(fn_args) > 4:
-            decl += "\n            "
-        else:
-            decl += ' '
+                    if isinstance(param.type.type, c_ast.PtrDecl):
+                        typ = param.type.type.type.type.names[0]
+                    else:
+                        typ = param.type.type.type.names[0]
+                elif isinstance(param.type, c_ast.ArrayDecl):
+                    is_ptr = True
+                    typ = param.type.type.type.names[0]
+                else:
+                    typ = param.type.type.names[0]
 
-        decl += '[' + ', '.join(fn_args) + '])'
+                ctype = to_ctype(typ, is_ptr)
+                fn_args.append(ctype)
 
-        print(decl)
+            self.fn_decls.append((fn_name, fn_args))
+        except Exception as e:
+            print(traceback.format_exc())
+            print("FAILED for '%s': %s" % (fn_name, e))
 
-ast = parse_file(ffi_header, use_cpp=True, cpp_args=['-Ibuild/include', '-std=c89', '-DBOTAN_DLL='])
+ast = parse_file(ffi_header, use_cpp=True, cpp_args=['-Ibuild/include', '-std=c89', '-DBOTAN_DLL=', '-DBOTAN_NO_DEPRECATED_WARNINGS'])
+#print(ast)
 v = FuncDefVisitor()
 v.visit(ast)
+
+#print("\n".join(v.fn_decls))
+print(v.emit_decls())


Test patch:
diff --git a/src/scripts/test_python.py b/src/scripts/test_python.py
index 96b13ac14..d20c2cd24 100644
--- a/src/scripts/test_python.py
+++ b/src/scripts/test_python.py
@@ -771,7 +771,7 @@ ofvkP1EDmpx50fHLawIDAQAB
         # Test successful authentication
         server = botan.Srp6ServerSession(group)
         salt = rng.get(24)
-        verifier = botan.generate_srp6_verifier(identity, password, salt, group, hash_fn)
+        verifier = botan.srp6_generate_verifier(identity, password, salt, group, hash_fn)
         b = server.step1(verifier, hash_fn, rng)
         (a, key_c) = botan.srp6_client_agree(identity, password, group, hash_fn, salt, b, rng)
         key_s = server.step2(a)
diff --git a/src/tests/test_srp6.cpp b/src/tests/test_srp6.cpp
index 8a27d38f6..06efdae45 100644
--- a/src/tests/test_srp6.cpp
+++ b/src/tests/test_srp6.cpp
@@ -61,7 +61,7 @@ class SRP6_KAT_Tests final : public Text_Based_Test
 
          Botan::DL_Group group(group_id);
 
-         const Botan::BigInt v = Botan::generate_srp6_verifier(username, password, salt, group_id, hash);
+         const Botan::BigInt v = Botan::srp6_generate_verifier(username, password, salt, group_id, hash);
          result.test_eq("SRP verifier", v, exp_v);
 
          Botan::SRP6_Server_Session server;
@@ -120,7 +120,7 @@ class SRP6_RT_Tests final : public Test
                Test::rng().random_vec(salt, 16);
 
                const Botan::BigInt verifier =
-                  Botan::generate_srp6_verifier(username, password, salt, group_id, hash_id);
+                  Botan::srp6_generate_verifier(username, password, salt, group_id, hash_id);
 
                Botan::SRP6_Server_Session server;