+static int known_digest_nids[OSSL_NELEM(gost_digest_array)];
+static int known_cipher_nids[OSSL_NELEM(gost_cipher_array)];
+/* `- 1' because of terminating zero element */
+static int known_meths_nids[OSSL_NELEM(gost_meth_array) - 1];
+
+/* ENGINE_DIGESTS_PTR callback installed by ENGINE_set_digests */
+static int gost_digests(ENGINE *e, const EVP_MD **digest,
+ const int **nids, int nid)
+{
+ int i;
+
+ if (!digest) {
+ int *n = known_digest_nids;
+
+ *nids = n;
+ for (i = 0; i < OSSL_NELEM(gost_digest_array); i++)
+ *n++ = gost_digest_array[i]->nid;
+ return i;
+ }
+
+ for (i = 0; i < OSSL_NELEM(gost_digest_array); i++)
+ if (nid == gost_digest_array[i]->nid) {
+ *digest = GOST_init_digest(gost_digest_array[i]);
+ return 1;
+ }
+ *digest = NULL;
+ return 0;
+}
+
+/* ENGINE_CIPHERS_PTR callback installed by ENGINE_set_ciphers */
+static int gost_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
+ const int **nids, int nid)
+{
+ int i;
+
+ if (!cipher) {
+ int *n = known_cipher_nids;
+
+ *nids = n;
+ for (i = 0; i < OSSL_NELEM(gost_cipher_array); i++)
+ *n++ = gost_cipher_array[i]->nid;
+ return i;
+ }
+
+ for (i = 0; i < OSSL_NELEM(gost_cipher_array); i++)
+ if (nid == gost_cipher_array[i]->nid) {
+ *cipher = GOST_init_cipher(gost_cipher_array[i]);
+ return 1;
+ }
+ *cipher = NULL;
+ return 0;
+}
+
+static int gost_meth_nids(const int **nids)
+{
+ struct gost_meth_minfo *info = gost_meth_array;
+ int *n = known_meths_nids;
+
+ *nids = n;
+ for (; info->nid; info++)
+ *n++ = info->nid;
+ return OSSL_NELEM(known_meths_nids);
+}
+
+/* ENGINE_PKEY_METHS_PTR installed by ENGINE_set_pkey_meths */
+static int gost_pkey_meths(ENGINE *e, EVP_PKEY_METHOD **pmeth,
+ const int **nids, int nid)
+{
+ struct gost_meth_minfo *info;
+
+ if (!pmeth)
+ return gost_meth_nids(nids);
+
+ for (info = gost_meth_array; info->nid; info++)
+ if (nid == info->nid) {
+ *pmeth = *info->pmeth;
+ return 1;
+ }
+ *pmeth = NULL;
+ return 0;
+}
+
+/* ENGINE_PKEY_ASN1_METHS_PTR installed by ENGINE_set_pkey_asn1_meths */
+static int gost_pkey_asn1_meths(ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth,
+ const int **nids, int nid)
+{
+ struct gost_meth_minfo *info;
+
+ if (!ameth)
+ return gost_meth_nids(nids);
+
+ for (info = gost_meth_array; info->nid; info++)
+ if (nid == info->nid) {
+ *ameth = *info->ameth;
+ return 1;
+ }
+ *ameth = NULL;
+ return 0;
+}