aboutsummaryrefslogtreecommitdiff
path: root/crypto-vala
diff options
context:
space:
mode:
authorMarvin W <git@larma.de>2021-05-14 19:26:05 +0200
committerMarvin W <git@larma.de>2021-05-14 19:26:05 +0200
commit6399892bf2c53fc3701438c752718638baff8e27 (patch)
treef2d60570240109e5f65f1250807ce90812b484f2 /crypto-vala
parentbec73ed3714fc89627392b1dfc74d1b919dbe355 (diff)
downloaddino-6399892bf2c53fc3701438c752718638baff8e27.tar.gz
dino-6399892bf2c53fc3701438c752718638baff8e27.zip
Move crypto-vala to shared library
Diffstat (limited to 'crypto-vala')
-rw-r--r--crypto-vala/CMakeLists.txt41
-rw-r--r--crypto-vala/src/cipher.vala152
-rw-r--r--crypto-vala/src/cipher_converter.vala102
-rw-r--r--crypto-vala/src/error.vala15
-rw-r--r--crypto-vala/src/random.vala5
-rw-r--r--crypto-vala/src/srtp.vala122
-rw-r--r--crypto-vala/vapi/gcrypt.vapi872
-rw-r--r--crypto-vala/vapi/libsrtp2.vapi115
8 files changed, 1424 insertions, 0 deletions
diff --git a/crypto-vala/CMakeLists.txt b/crypto-vala/CMakeLists.txt
new file mode 100644
index 00000000..f1f3f9d7
--- /dev/null
+++ b/crypto-vala/CMakeLists.txt
@@ -0,0 +1,41 @@
+find_package(GCrypt REQUIRED)
+find_package(Srtp2 REQUIRED)
+find_packages(CRYPTO_VALA_PACKAGES REQUIRED
+ GLib
+ GObject
+ GIO
+)
+
+vala_precompile(CRYPTO_VALA_C
+SOURCES
+ "src/cipher.vala"
+ "src/cipher_converter.vala"
+ "src/error.vala"
+ "src/random.vala"
+ "src/srtp.vala"
+CUSTOM_VAPIS
+ "${CMAKE_CURRENT_SOURCE_DIR}/vapi/gcrypt.vapi"
+ "${CMAKE_CURRENT_SOURCE_DIR}/vapi/libsrtp2.vapi"
+PACKAGES
+ ${CRYPTO_VALA_PACKAGES}
+GENERATE_VAPI
+ crypto-vala
+GENERATE_HEADER
+ crypto-vala
+)
+
+add_custom_target(crypto-vala-vapi
+DEPENDS
+ ${CMAKE_BINARY_DIR}/exports/crypto-vala.vapi
+ ${CMAKE_BINARY_DIR}/exports/crypto-vala.deps
+)
+
+add_definitions(${VALA_CFLAGS} -DG_LOG_DOMAIN="crypto-vala")
+add_library(crypto-vala SHARED ${CRYPTO_VALA_C})
+add_dependencies(crypto-vala crypto-vala-vapi)
+target_link_libraries(crypto-vala ${CRYPTO_VALA_PACKAGES} gcrypt libsrtp2)
+set_target_properties(crypto-vala PROPERTIES VERSION 0.0 SOVERSION 0)
+
+install(TARGETS crypto-vala ${TARGET_INSTALL})
+install(FILES ${CMAKE_BINARY_DIR}/exports/crypto-vala.vapi ${CMAKE_BINARY_DIR}/exports/crypto-vala.deps DESTINATION ${VAPI_INSTALL_DIR})
+install(FILES ${CMAKE_BINARY_DIR}/exports/crypto-vala.h DESTINATION ${INCLUDE_INSTALL_DIR})
diff --git a/crypto-vala/src/cipher.vala b/crypto-vala/src/cipher.vala
new file mode 100644
index 00000000..306dafa8
--- /dev/null
+++ b/crypto-vala/src/cipher.vala
@@ -0,0 +1,152 @@
+namespace Crypto {
+public class SymmetricCipher {
+ private GCrypt.Cipher.Cipher cipher;
+
+ public static bool supports(string algo_name) {
+ GCrypt.Cipher.Algorithm algo;
+ GCrypt.Cipher.Mode mode;
+ GCrypt.Cipher.Flag flags;
+ return parse(algo_name, out algo, out mode, out flags);
+ }
+
+ private static unowned string mode_to_string(GCrypt.Cipher.Mode mode) {
+ switch (mode) {
+ case GCrypt.Cipher.Mode.ECB: return "ECB";
+ case GCrypt.Cipher.Mode.CFB: return "CFB";
+ case GCrypt.Cipher.Mode.CBC: return "CBC";
+ case GCrypt.Cipher.Mode.STREAM: return "STREAM";
+ case GCrypt.Cipher.Mode.OFB: return "OFB";
+ case GCrypt.Cipher.Mode.CTR: return "CTR";
+ case GCrypt.Cipher.Mode.AESWRAP: return "AESWRAP";
+ case GCrypt.Cipher.Mode.GCM: return "GCM";
+ case GCrypt.Cipher.Mode.POLY1305: return "POLY1305";
+ case GCrypt.Cipher.Mode.OCB: return "OCB";
+ case GCrypt.Cipher.Mode.CFB8: return "CFB8";
+ // case GCrypt.Cipher.Mode.XTS: return "XTS"; // Not supported in gcrypt < 1.8
+ }
+ return "NONE";
+ }
+
+ private static GCrypt.Cipher.Mode mode_from_string(string name) {
+ switch (name) {
+ case "ECB": return GCrypt.Cipher.Mode.ECB;
+ case "CFB": return GCrypt.Cipher.Mode.CFB;
+ case "CBC": return GCrypt.Cipher.Mode.CBC;
+ case "STREAM": return GCrypt.Cipher.Mode.STREAM;
+ case "OFB": return GCrypt.Cipher.Mode.OFB;
+ case "CTR": return GCrypt.Cipher.Mode.CTR;
+ case "AESWRAP": return GCrypt.Cipher.Mode.AESWRAP;
+ case "GCM": return GCrypt.Cipher.Mode.GCM;
+ case "POLY1305": return GCrypt.Cipher.Mode.POLY1305;
+ case "OCB": return GCrypt.Cipher.Mode.OCB;
+ case "CFB8": return GCrypt.Cipher.Mode.CFB8;
+ // case "XTS": return GCrypt.Cipher.Mode.XTS; // Not supported in gcrypt < 1.8
+ }
+ return GCrypt.Cipher.Mode.NONE;
+ }
+
+ private static string flags_to_string(GCrypt.Cipher.Flag flags) {
+ string? s = null;
+ if ((GCrypt.Cipher.Flag.CBC_MAC & flags) != 0) s = (s == null ? "" : @"$s-") + "MAC";
+ if ((GCrypt.Cipher.Flag.CBC_CTS & flags) != 0) s = (s == null ? "" : @"$s-") + "CTS";
+ if ((GCrypt.Cipher.Flag.ENABLE_SYNC & flags) != 0) s = (s == null ? "" : @"$s-") + "SYNC";
+ if ((GCrypt.Cipher.Flag.SECURE & flags) != 0) s = (s == null ? "" : @"$s-") + "SECURE";
+ return s ?? "NONE";
+ }
+
+ private static GCrypt.Cipher.Flag flag_from_string(string flag_name) {
+ if (flag_name == "SECURE") return GCrypt.Cipher.Flag.SECURE;
+ if (flag_name == "SYNC") return GCrypt.Cipher.Flag.ENABLE_SYNC;
+ if (flag_name == "CTS") return GCrypt.Cipher.Flag.CBC_CTS;
+ if (flag_name == "MAC") return GCrypt.Cipher.Flag.CBC_MAC;
+ return 0;
+ }
+
+ private static GCrypt.Cipher.Flag flags_from_string(string flag_names) {
+ GCrypt.Cipher.Flag flags = 0;
+ foreach(string flag in flag_names.split("-")) {
+ flags |= flag_from_string(flag);
+ }
+ return flags;
+ }
+
+ private static bool parse(string algo_name, out GCrypt.Cipher.Algorithm algo, out GCrypt.Cipher.Mode mode, out GCrypt.Cipher.Flag flags) {
+ algo = GCrypt.Cipher.Algorithm.NONE;
+ mode = GCrypt.Cipher.Mode.NONE;
+ flags = 0;
+ string[] algo_parts = algo_name.split("-", 3);
+
+ algo = GCrypt.Cipher.Algorithm.from_string(algo_parts[0]);
+ if (algo_parts.length >= 2) {
+ mode = mode_from_string(algo_parts[1]);
+ }
+ if (algo_parts.length == 3) {
+ flags |= flags_from_string(algo_parts[2]);
+ }
+ return to_algo_name(algo, mode, flags) == algo_name;
+ }
+
+ private static string to_algo_name(GCrypt.Cipher.Algorithm algo = GCrypt.Cipher.Algorithm.NONE, GCrypt.Cipher.Mode mode = GCrypt.Cipher.Mode.NONE, GCrypt.Cipher.Flag flags = 0) {
+ if (flags != 0) {
+ return @"$algo-$(mode_to_string(mode))-$(flags_to_string(flags))";
+ } else if (mode != GCrypt.Cipher.Mode.NONE) {
+ return @"$algo-$(mode_to_string(mode))";
+ } else {
+ return algo.to_string();
+ }
+ }
+
+ public SymmetricCipher(string algo_name) throws Error {
+ GCrypt.Cipher.Algorithm algo;
+ GCrypt.Cipher.Mode mode;
+ GCrypt.Cipher.Flag flags;
+ if (parse(algo_name, out algo, out mode, out flags)) {
+ this.gcrypt(algo, mode, flags);
+ } else {
+ throw new Error.ILLEGAL_ARGUMENTS(@"The algorithm $algo_name is not supported");
+ }
+ }
+
+ private SymmetricCipher.gcrypt(GCrypt.Cipher.Algorithm algo, GCrypt.Cipher.Mode mode, GCrypt.Cipher.Flag flags) throws Error {
+ may_throw_gcrypt_error(GCrypt.Cipher.Cipher.open(out this.cipher, algo, mode, flags));
+ }
+
+ public void set_key(uint8[] key) throws Error {
+ may_throw_gcrypt_error(cipher.set_key(key));
+ }
+
+ public void set_iv(uint8[] iv) throws Error {
+ may_throw_gcrypt_error(cipher.set_iv(iv));
+ }
+
+ public void set_counter_vector(uint8[] ctr) throws Error {
+ may_throw_gcrypt_error(cipher.set_counter_vector(ctr));
+ }
+
+ public void reset() throws Error {
+ may_throw_gcrypt_error(cipher.reset());
+ }
+
+ public uint8[] get_tag(size_t taglen) throws Error {
+ uint8[] tag = new uint8[taglen];
+ may_throw_gcrypt_error(cipher.get_tag(tag));
+ return tag;
+ }
+
+ public void check_tag(uint8[] tag) throws Error {
+ may_throw_gcrypt_error(cipher.check_tag(tag));
+ }
+
+ public void encrypt(uint8[] output, uint8[] input) throws Error {
+ may_throw_gcrypt_error(cipher.encrypt(output, input));
+ }
+
+ public void decrypt(uint8[] output, uint8[] input) throws Error {
+ may_throw_gcrypt_error(cipher.decrypt(output, input));
+ }
+
+ public void sync() throws Error {
+ may_throw_gcrypt_error(cipher.sync());
+ }
+}
+}
diff --git a/crypto-vala/src/cipher_converter.vala b/crypto-vala/src/cipher_converter.vala
new file mode 100644
index 00000000..b2b52c5a
--- /dev/null
+++ b/crypto-vala/src/cipher_converter.vala
@@ -0,0 +1,102 @@
+using GLib;
+
+namespace Crypto {
+public abstract class SymmetricCipherConverter : Converter, Object {
+ internal SymmetricCipher cipher;
+ internal size_t attached_taglen;
+
+ public abstract ConverterResult convert(uint8[] inbuf, uint8[] outbuf, ConverterFlags flags, out size_t bytes_read, out size_t bytes_written) throws IOError;
+
+ public uint8[] get_tag(size_t taglen) throws Error {
+ return cipher.get_tag(taglen);
+ }
+
+ public void check_tag(uint8[] tag) throws Error {
+ cipher.check_tag(tag);
+ }
+
+ public void reset() {
+ try {
+ cipher.reset();
+ } catch (Crypto.Error e) {
+ warning(@"$(e.domain) error while resetting cipher: $(e.message)");
+ }
+ }
+}
+
+public class SymmetricCipherEncrypter : SymmetricCipherConverter {
+ public SymmetricCipherEncrypter(owned SymmetricCipher cipher, size_t attached_taglen = 0) {
+ this.cipher = (owned) cipher;
+ this.attached_taglen = attached_taglen;
+ }
+
+ public override ConverterResult convert(uint8[] inbuf, uint8[] outbuf, ConverterFlags flags, out size_t bytes_read, out size_t bytes_written) throws IOError {
+ if (inbuf.length > outbuf.length) {
+ throw new IOError.NO_SPACE("CipherConverter needs at least the size of input as output space");
+ }
+ if ((flags & ConverterFlags.INPUT_AT_END) != 0 && inbuf.length + attached_taglen > outbuf.length) {
+ throw new IOError.NO_SPACE("CipherConverter needs additional output space to attach tag");
+ }
+ try {
+ if (inbuf.length > 0) {
+ cipher.encrypt(outbuf, inbuf);
+ }
+ bytes_read = inbuf.length;
+ bytes_written = inbuf.length;
+ if ((flags & ConverterFlags.INPUT_AT_END) != 0) {
+ if (attached_taglen > 0) {
+ Memory.copy((uint8*)outbuf + inbuf.length, get_tag(attached_taglen), attached_taglen);
+ bytes_written = inbuf.length + attached_taglen;
+ }
+ return ConverterResult.FINISHED;
+ }
+ if ((flags & ConverterFlags.FLUSH) != 0) {
+ return ConverterResult.FLUSHED;
+ }
+ return ConverterResult.CONVERTED;
+ } catch (Crypto.Error e) {
+ throw new IOError.FAILED(@"$(e.domain) error while decrypting: $(e.message)");
+ }
+ }
+}
+
+public class SymmetricCipherDecrypter : SymmetricCipherConverter {
+ public SymmetricCipherDecrypter(owned SymmetricCipher cipher, size_t attached_taglen = 0) {
+ this.cipher = (owned) cipher;
+ this.attached_taglen = attached_taglen;
+ }
+
+ public override ConverterResult convert(uint8[] inbuf, uint8[] outbuf, ConverterFlags flags, out size_t bytes_read, out size_t bytes_written) throws IOError {
+ if (inbuf.length > outbuf.length + attached_taglen) {
+ throw new IOError.NO_SPACE("CipherConverter needs at least the size of input as output space");
+ }
+ if ((flags & ConverterFlags.INPUT_AT_END) != 0 && inbuf.length < attached_taglen) {
+ throw new IOError.PARTIAL_INPUT("CipherConverter needs additional input to read tag");
+ } else if ((flags & ConverterFlags.INPUT_AT_END) == 0 && inbuf.length < attached_taglen + 1) {
+ throw new IOError.PARTIAL_INPUT("CipherConverter needs additional input to make sure to not accidentally read tag");
+ }
+ try {
+ inbuf.length -= (int) attached_taglen;
+ if (inbuf.length > 0) {
+ cipher.decrypt(outbuf, inbuf);
+ }
+ bytes_read = inbuf.length;
+ bytes_written = inbuf.length;
+ inbuf.length += (int) attached_taglen;
+ if ((flags & ConverterFlags.INPUT_AT_END) != 0) {
+ if (attached_taglen > 0) {
+ check_tag(inbuf[(inbuf.length - attached_taglen):inbuf.length]);
+ bytes_read = inbuf.length;
+ }
+ return ConverterResult.FINISHED;
+ }
+ if ((flags & ConverterFlags.FLUSH) != 0) {
+ return ConverterResult.FLUSHED;
+ }
+ return ConverterResult.CONVERTED;
+ } catch (Crypto.Error e) {
+ throw new IOError.FAILED(@"$(e.domain) error while decrypting: $(e.message)");
+ }
+ }
+}
+}
diff --git a/crypto-vala/src/error.vala b/crypto-vala/src/error.vala
new file mode 100644
index 00000000..5007d725
--- /dev/null
+++ b/crypto-vala/src/error.vala
@@ -0,0 +1,15 @@
+namespace Crypto {
+
+public errordomain Error {
+ ILLEGAL_ARGUMENTS,
+ GCRYPT,
+ AUTHENTICATION_FAILED,
+ UNKNOWN
+}
+
+internal void may_throw_gcrypt_error(GCrypt.Error e) throws Error {
+ if (((int)e) != 0) {
+ throw new Crypto.Error.GCRYPT(e.to_string());
+ }
+}
+} \ No newline at end of file
diff --git a/crypto-vala/src/random.vala b/crypto-vala/src/random.vala
new file mode 100644
index 00000000..3f5d3ba9
--- /dev/null
+++ b/crypto-vala/src/random.vala
@@ -0,0 +1,5 @@
+namespace Crypto {
+public static void randomize(uint8[] buffer) {
+ GCrypt.Random.randomize(buffer);
+}
+} \ No newline at end of file
diff --git a/crypto-vala/src/srtp.vala b/crypto-vala/src/srtp.vala
new file mode 100644
index 00000000..c7f45da3
--- /dev/null
+++ b/crypto-vala/src/srtp.vala
@@ -0,0 +1,122 @@
+using Srtp;
+
+namespace Crypto.Srtp {
+public const string AES_CM_128_HMAC_SHA1_80 = "AES_CM_128_HMAC_SHA1_80";
+public const string AES_CM_128_HMAC_SHA1_32 = "AES_CM_128_HMAC_SHA1_32";
+public const string F8_128_HMAC_SHA1_80 = "F8_128_HMAC_SHA1_80";
+
+public class Session {
+ public bool has_encrypt { get; private set; default = false; }
+ public bool has_decrypt { get; private set; default = false; }
+
+ private Context encrypt_context;
+ private Context decrypt_context;
+
+ static construct {
+ init();
+ install_log_handler(log);
+ }
+
+ private static void log(LogLevel level, string msg) {
+ print(@"SRTP[$level]: $msg\n");
+ }
+
+ public Session() {
+ Context.create(out encrypt_context, null);
+ Context.create(out decrypt_context, null);
+ }
+
+ public uint8[] encrypt_rtp(uint8[] data) throws Error {
+ uint8[] buf = new uint8[data.length + MAX_TRAILER_LEN];
+ Memory.copy(buf, data, data.length);
+ int buf_use = data.length;
+ ErrorStatus res = encrypt_context.protect(buf, ref buf_use);
+ if (res != ErrorStatus.ok) {
+ throw new Error.UNKNOWN(@"SRTP encrypt failed: $res");
+ }
+ uint8[] ret = new uint8[buf_use];
+ GLib.Memory.copy(ret, buf, buf_use);
+ return ret;
+ }
+
+ public uint8[] decrypt_rtp(uint8[] data) throws Error {
+ uint8[] buf = new uint8[data.length];
+ Memory.copy(buf, data, data.length);
+ int buf_use = data.length;
+ ErrorStatus res = decrypt_context.unprotect(buf, ref buf_use);
+ switch (res) {
+ case ErrorStatus.auth_fail:
+ throw new Error.AUTHENTICATION_FAILED("SRTP packet failed the message authentication check");
+ case ErrorStatus.ok:
+ break;
+ default:
+ throw new Error.UNKNOWN(@"SRTP decrypt failed: $res");
+ }
+ uint8[] ret = new uint8[buf_use];
+ GLib.Memory.copy(ret, buf, buf_use);
+ return ret;
+ }
+
+ public uint8[] encrypt_rtcp(uint8[] data) throws Error {
+ uint8[] buf = new uint8[data.length + MAX_TRAILER_LEN + 4];
+ Memory.copy(buf, data, data.length);
+ int buf_use = data.length;
+ ErrorStatus res = encrypt_context.protect_rtcp(buf, ref buf_use);
+ if (res != ErrorStatus.ok) {
+ throw new Error.UNKNOWN(@"SRTCP encrypt failed: $res");
+ }
+ uint8[] ret = new uint8[buf_use];
+ GLib.Memory.copy(ret, buf, buf_use);
+ return ret;
+ }
+
+ public uint8[] decrypt_rtcp(uint8[] data) throws Error {
+ uint8[] buf = new uint8[data.length];
+ Memory.copy(buf, data, data.length);
+ int buf_use = data.length;
+ ErrorStatus res = decrypt_context.unprotect_rtcp(buf, ref buf_use);
+ switch (res) {
+ case ErrorStatus.auth_fail:
+ throw new Error.AUTHENTICATION_FAILED("SRTCP packet failed the message authentication check");
+ case ErrorStatus.ok:
+ break;
+ default:
+ throw new Error.UNKNOWN(@"SRTP decrypt failed: $res");
+ }
+ uint8[] ret = new uint8[buf_use];
+ GLib.Memory.copy(ret, buf, buf_use);
+ return ret;
+ }
+
+ private Policy create_policy(string profile) {
+ Policy policy = Policy();
+ switch (profile) {
+ case AES_CM_128_HMAC_SHA1_80:
+ policy.rtp.set_aes_cm_128_hmac_sha1_80();
+ policy.rtcp.set_aes_cm_128_hmac_sha1_80();
+ break;
+ }
+ return policy;
+ }
+
+ public void set_encryption_key(string profile, uint8[] key, uint8[] salt) {
+ Policy policy = create_policy(profile);
+ policy.ssrc.type = SsrcType.any_outbound;
+ policy.key = new uint8[key.length + salt.length];
+ Memory.copy(policy.key, key, key.length);
+ Memory.copy(((uint8*)policy.key) + key.length, salt, salt.length);
+ encrypt_context.add_stream(ref policy);
+ has_encrypt = true;
+ }
+
+ public void set_decryption_key(string profile, uint8[] key, uint8[] salt) {
+ Policy policy = create_policy(profile);
+ policy.ssrc.type = SsrcType.any_inbound;
+ policy.key = new uint8[key.length + salt.length];
+ Memory.copy(policy.key, key, key.length);
+ Memory.copy(((uint8*)policy.key) + key.length, salt, salt.length);
+ decrypt_context.add_stream(ref policy);
+ has_decrypt = true;
+ }
+}
+} \ No newline at end of file
diff --git a/crypto-vala/vapi/gcrypt.vapi b/crypto-vala/vapi/gcrypt.vapi
new file mode 100644
index 00000000..0fa69a02
--- /dev/null
+++ b/crypto-vala/vapi/gcrypt.vapi
@@ -0,0 +1,872 @@
+/* gcrypt.vapi
+ *
+ * Copyright:
+ * 2008 Jiqing Qiang
+ * 2008, 2010, 2012-2013 Evan Nemerson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Jiqing Qiang <jiqing.qiang@gmail.com>
+ * Evan Nemerson <evan@coeus-group.com>
+ */
+
+
+[CCode (cheader_filename = "gcrypt.h", lower_case_cprefix = "gcry_")]
+namespace GCrypt {
+ [CCode (cname = "gpg_err_source_t", cprefix = "GPG_ERR_SOURCE_")]
+ public enum ErrorSource {
+ UNKNOWN,
+ GCRYPT,
+ GPG,
+ GPGSM,
+ GPGAGENT,
+ PINENTRY,
+ SCD,
+ GPGME,
+ KEYBOX,
+ KSBA,
+ DIRMNGR,
+ GSTI,
+ ANY,
+ USER_1,
+ USER_2,
+ USER_3,
+ USER_4,
+
+ /* This is one more than the largest allowed entry. */
+ DIM
+ }
+
+ [CCode (cname = "gpg_err_code_t", cprefix = "GPG_ERR_")]
+ public enum ErrorCode {
+ NO_ERROR,
+ GENERAL,
+ UNKNOWN_PACKET,
+ UNKNOWN_VERSION,
+ PUBKEY_ALGO,
+ DIGEST_ALGO,
+ BAD_PUBKEY,
+ BAD_SECKEY,
+ BAD_SIGNATURE,
+ NO_PUBKEY,
+ CHECKSUM,
+ BAD_PASSPHRASE,
+ CIPHER_ALGO,
+ KEYRING_OPEN,
+ INV_PACKET,
+ INV_ARMOR,
+ NO_USER_ID,
+ NO_SECKEY,
+ WRONG_SECKEY,
+ BAD_KEY,
+ COMPR_ALGO,
+ NO_PRIME,
+ NO_ENCODING_METHOD,
+ NO_ENCRYPTION_SCHEME,
+ NO_SIGNATURE_SCHEME,
+ INV_ATTR,
+ NO_VALUE,
+ NOT_FOUND,
+ VALUE_NOT_FOUND,
+ SYNTAX,
+ BAD_MPI,
+ INV_PASSPHRASE,
+ SIG_CLASS,
+ RESOURCE_LIMIT,
+ INV_KEYRING,
+ TRUSTDB,
+ BAD_CERT,
+ INV_USER_ID,
+ UNEXPECTED,
+ TIME_CONFLICT,
+ KEYSERVER,
+ WRONG_PUBKEY_ALGO,
+ TRIBUTE_TO_D_A,
+ WEAK_KEY,
+ INV_KEYLEN,
+ INV_ARG,
+ BAD_URI,
+ INV_URI,
+ NETWORK,
+ UNKNOWN_HOST,
+ SELFTEST_FAILED,
+ NOT_ENCRYPTED,
+ NOT_PROCESSED,
+ UNUSABLE_PUBKEY,
+ UNUSABLE_SECKEY,
+ INV_VALUE,
+ BAD_CERT_CHAIN,
+ MISSING_CERT,
+ NO_DATA,
+ BUG,
+ NOT_SUPPORTED,
+ INV_OP,
+ TIMEOUT,
+ INTERNAL,
+ EOF_GCRYPT,
+ INV_OBJ,
+ TOO_SHORT,
+ TOO_LARGE,
+ NO_OBJ,
+ NOT_IMPLEMENTED,
+ CONFLICT,
+ INV_CIPHER_MODE,
+ INV_FLAG,
+ INV_HANDLE,
+ TRUNCATED,
+ INCOMPLETE_LINE,
+ INV_RESPONSE,
+ NO_AGENT,
+ AGENT,
+ INV_DATA,
+ ASSUAN_SERVER_FAULT,
+ ASSUAN,
+ INV_SESSION_KEY,
+ INV_SEXP,
+ UNSUPPORTED_ALGORITHM,
+ NO_PIN_ENTRY,
+ PIN_ENTRY,
+ BAD_PIN,
+ INV_NAME,
+ BAD_DATA,
+ INV_PARAMETER,
+ WRONG_CARD,
+ NO_DIRMNGR,
+ DIRMNGR,
+ CERT_REVOKED,
+ NO_CRL_KNOWN,
+ CRL_TOO_OLD,
+ LINE_TOO_LONG,
+ NOT_TRUSTED,
+ CANCELED,
+ BAD_CA_CERT,
+ CERT_EXPIRED,
+ CERT_TOO_YOUNG,
+ UNSUPPORTED_CERT,
+ UNKNOWN_SEXP,
+ UNSUPPORTED_PROTECTION,
+ CORRUPTED_PROTECTION,
+ AMBIGUOUS_NAME,
+ CARD,
+ CARD_RESET,
+ CARD_REMOVED,
+ INV_CARD,
+ CARD_NOT_PRESENT,
+ NO_PKCS15_APP,
+ NOT_CONFIRMED,
+ CONFIGURATION,
+ NO_POLICY_MATCH,
+ INV_INDEX,
+ INV_ID,
+ NO_SCDAEMON,
+ SCDAEMON,
+ UNSUPPORTED_PROTOCOL,
+ BAD_PIN_METHOD,
+ CARD_NOT_INITIALIZED,
+ UNSUPPORTED_OPERATION,
+ WRONG_KEY_USAGE,
+ NOTHING_FOUND,
+ WRONG_BLOB_TYPE,
+ MISSING_VALUE,
+ HARDWARE,
+ PIN_BLOCKED,
+ USE_CONDITIONS,
+ PIN_NOT_SYNCED,
+ INV_CRL,
+ BAD_BER,
+ INV_BER,
+ ELEMENT_NOT_FOUND,
+ IDENTIFIER_NOT_FOUND,
+ INV_TAG,
+ INV_LENGTH,
+ INV_KEYINFO,
+ UNEXPECTED_TAG,
+ NOT_DER_ENCODED,
+ NO_CMS_OBJ,
+ INV_CMS_OBJ,
+ UNKNOWN_CMS_OBJ,
+ UNSUPPORTED_CMS_OBJ,
+ UNSUPPORTED_ENCODING,
+ UNSUPPORTED_CMS_VERSION,
+ UNKNOWN_ALGORITHM,
+ INV_ENGINE,
+ PUBKEY_NOT_TRUSTED,
+ DECRYPT_FAILED,
+ KEY_EXPIRED,
+ SIG_EXPIRED,
+ ENCODING_PROBLEM,
+ INV_STATE,
+ DUP_VALUE,
+ MISSING_ACTION,
+ MODULE_NOT_FOUND,
+ INV_OID_STRING,
+ INV_TIME,
+ INV_CRL_OBJ,
+ UNSUPPORTED_CRL_VERSION,
+ INV_CERT_OBJ,
+ UNKNOWN_NAME,
+ LOCALE_PROBLEM,
+ NOT_LOCKED,
+ PROTOCOL_VIOLATION,
+ INV_MAC,
+ INV_REQUEST,
+ UNKNOWN_EXTN,
+ UNKNOWN_CRIT_EXTN,
+ LOCKED,
+ UNKNOWN_OPTION,
+ UNKNOWN_COMMAND,
+ BUFFER_TOO_SHORT,
+ SEXP_INV_LEN_SPEC,
+ SEXP_STRING_TOO_LONG,
+ SEXP_UNMATCHED_PAREN,
+ SEXP_NOT_CANONICAL,
+ SEXP_BAD_CHARACTER,
+ SEXP_BAD_QUOTATION,
+ SEXP_ZERO_PREFIX,
+ SEXP_NESTED_DH,
+ SEXP_UNMATCHED_DH,
+ SEXP_UNEXPECTED_PUNC,
+ SEXP_BAD_HEX_CHAR,
+ SEXP_ODD_HEX_NUMBERS,
+ SEXP_BAD_OCT_CHAR,
+ ASS_GENERAL,
+ ASS_ACCEPT_FAILED,
+ ASS_CONNECT_FAILED,
+ ASS_INV_RESPONSE,
+ ASS_INV_VALUE,
+ ASS_INCOMPLETE_LINE,
+ ASS_LINE_TOO_LONG,
+ ASS_NESTED_COMMANDS,
+ ASS_NO_DATA_CB,
+ ASS_NO_INQUIRE_CB,
+ ASS_NOT_A_SERVER,
+ ASS_NOT_A_CLIENT,
+ ASS_SERVER_START,
+ ASS_READ_ERROR,
+ ASS_WRITE_ERROR,
+ ASS_TOO_MUCH_DATA,
+ ASS_UNEXPECTED_CMD,
+ ASS_UNKNOWN_CMD,
+ ASS_SYNTAX,
+ ASS_CANCELED,
+ ASS_NO_INPUT,
+ ASS_NO_OUTPUT,
+ ASS_PARAMETER,
+ ASS_UNKNOWN_INQUIRE,
+ USER_1,
+ USER_2,
+ USER_3,
+ USER_4,
+ USER_5,
+ USER_6,
+ USER_7,
+ USER_8,
+ USER_9,
+ USER_10,
+ USER_11,
+ USER_12,
+ USER_13,
+ USER_14,
+ USER_15,
+ USER_16,
+ MISSING_ERRNO,
+ UNKNOWN_ERRNO,
+ EOF,
+
+ E2BIG,
+ EACCES,
+ EADDRINUSE,
+ EADDRNOTAVAIL,
+ EADV,
+ EAFNOSUPPORT,
+ EAGAIN,
+ EALREADY,
+ EAUTH,
+ EBACKGROUND,
+ EBADE,
+ EBADF,
+ EBADFD,
+ EBADMSG,
+ EBADR,
+ EBADRPC,
+ EBADRQC,
+ EBADSLT,
+ EBFONT,
+ EBUSY,
+ ECANCELED,
+ ECHILD,
+ ECHRNG,
+ ECOMM,
+ ECONNABORTED,
+ ECONNREFUSED,
+ ECONNRESET,
+ ED,
+ EDEADLK,
+ EDEADLOCK,
+ EDESTADDRREQ,
+ EDIED,
+ EDOM,
+ EDOTDOT,
+ EDQUOT,
+ EEXIST,
+ EFAULT,
+ EFBIG,
+ EFTYPE,
+ EGRATUITOUS,
+ EGREGIOUS,
+ EHOSTDOWN,
+ EHOSTUNREACH,
+ EIDRM,
+ EIEIO,
+ EILSEQ,
+ EINPROGRESS,
+ EINTR,
+ EINVAL,
+ EIO,
+ EISCONN,
+ EISDIR,
+ EISNAM,
+ EL2HLT,
+ EL2NSYNC,
+ EL3HLT,
+ EL3RST,
+ ELIBACC,
+ ELIBBAD,
+ ELIBEXEC,
+ ELIBMAX,
+ ELIBSCN,
+ ELNRNG,
+ ELOOP,
+ EMEDIUMTYPE,
+ EMFILE,
+ EMLINK,
+ EMSGSIZE,
+ EMULTIHOP,
+ ENAMETOOLONG,
+ ENAVAIL,
+ ENEEDAUTH,
+ ENETDOWN,
+ ENETRESET,
+ ENETUNREACH,
+ ENFILE,
+ ENOANO,
+ ENOBUFS,
+ ENOCSI,
+ ENODATA,
+ ENODEV,
+ ENOENT,
+ ENOEXEC,
+ ENOLCK,
+ ENOLINK,
+ ENOMEDIUM,
+ ENOMEM,
+ ENOMSG,
+ ENONET,
+ ENOPKG,
+ ENOPROTOOPT,
+ ENOSPC,
+ ENOSR,
+ ENOSTR,
+ ENOSYS,
+ ENOTBLK,
+ ENOTCONN,
+ ENOTDIR,
+ ENOTEMPTY,
+ ENOTNAM,
+ ENOTSOCK,
+ ENOTSUP,
+ ENOTTY,
+ ENOTUNIQ,
+ ENXIO,
+ EOPNOTSUPP,
+ EOVERFLOW,
+ EPERM,
+ EPFNOSUPPORT,
+ EPIPE,
+ EPROCLIM,
+ EPROCUNAVAIL,
+ EPROGMISMATCH,
+ EPROGUNAVAIL,
+ EPROTO,
+ EPROTONOSUPPORT,
+ EPROTOTYPE,
+ ERANGE,
+ EREMCHG,
+ EREMOTE,
+ EREMOTEIO,
+ ERESTART,
+ EROFS,
+ ERPCMISMATCH,
+ ESHUTDOWN,
+ ESOCKTNOSUPPORT,
+ ESPIPE,
+ ESRCH,
+ ESRMNT,
+ ESTALE,
+ ESTRPIPE,
+ ETIME,
+ ETIMEDOUT,
+ ETOOMANYREFS,
+ ETXTBSY,
+ EUCLEAN,
+ EUNATCH,
+ EUSERS,
+ EWOULDBLOCK,
+ EXDEV,
+ EXFULL,
+
+ /* This is one more than the largest allowed entry. */
+ CODE_DIM
+ }
+
+ [CCode (cname = "gcry_error_t", cprefix = "gpg_err_")]
+ public struct Error : uint {
+ [CCode (cname = "gcry_err_make")]
+ public Error (ErrorSource source, ErrorCode code);
+ [CCode (cname = "gcry_err_make_from_errno")]
+ public Error.from_errno (ErrorSource source, int err);
+ public ErrorCode code ();
+ public ErrorSource source ();
+
+ [CCode (cname = "gcry_strerror")]
+ public unowned string to_string ();
+
+ [CCode (cname = "gcry_strsource")]
+ public unowned string source_to_string ();
+ }
+
+ [CCode (cname = "enum gcry_ctl_cmds", cprefix = "GCRYCTL_")]
+ public enum ControlCommand {
+ SET_KEY,
+ SET_IV,
+ CFB_SYNC,
+ RESET,
+ FINALIZE,
+ GET_KEYLEN,
+ GET_BLKLEN,
+ TEST_ALGO,
+ IS_SECURE,
+ GET_ASNOID,
+ ENABLE_ALGO,
+ DISABLE_ALGO,
+ DUMP_RANDOM_STATS,
+ DUMP_SECMEM_STATS,
+ GET_ALGO_NPKEY,
+ GET_ALGO_NSKEY,
+ GET_ALGO_NSIGN,
+ GET_ALGO_NENCR,
+ SET_VERBOSITY,
+ SET_DEBUG_FLAGS,
+ CLEAR_DEBUG_FLAGS,
+ USE_SECURE_RNDPOOL,
+ DUMP_MEMORY_STATS,
+ INIT_SECMEM,
+ TERM_SECMEM,
+ DISABLE_SECMEM_WARN,
+ SUSPEND_SECMEM_WARN,
+ RESUME_SECMEM_WARN,
+ DROP_PRIVS,
+ ENABLE_M_GUARD,
+ START_DUMP,
+ STOP_DUMP,
+ GET_ALGO_USAGE,
+ IS_ALGO_ENABLED,
+ DISABLE_INTERNAL_LOCKING,
+ DISABLE_SECMEM,
+ INITIALIZATION_FINISHED,
+ INITIALIZATION_FINISHED_P,
+ ANY_INITIALIZATION_P,
+ SET_CBC_CTS,
+ SET_CBC_MAC,
+ SET_CTR,
+ ENABLE_QUICK_RANDOM,
+ SET_RANDOM_SEED_FILE,
+ UPDATE_RANDOM_SEED_FILE,
+ SET_THREAD_CBS,
+ FAST_POLL
+ }
+ public Error control (ControlCommand cmd, ...);
+
+ [CCode (lower_case_cname = "cipher_")]
+ namespace Cipher {
+ [CCode (cname = "enum gcry_cipher_algos", cprefix = "GCRY_CIPHER_")]
+ public enum Algorithm {
+ NONE,
+ IDEA,
+ 3DES,
+ CAST5,
+ BLOWFISH,
+ SAFER_SK128,
+ DES_SK,
+ AES,
+ AES128,
+ RIJNDAEL,
+ RIJNDAEL128,
+ AES192,
+ RIJNDAEL192,
+ AES256,
+ RIJNDAEL256,
+ TWOFISH,
+ TWOFISH128,
+ ARCFOUR,
+ DES,
+ SERPENT128,
+ SERPENT192,
+ SERPENT256,
+ RFC2268_40,
+ RFC2268_128,
+ SEED,
+ CAMELLIA128,
+ CAMELLIA192,
+ CAMELLIA256,
+ SALSA20,
+ SALSA20R12,
+ GOST28147,
+ CHACHA20;
+
+ [CCode (cname = "gcry_cipher_algo_info")]
+ public Error info (ControlCommand what, ref uchar[] buffer);
+ [CCode (cname = "gcry_cipher_algo_name")]
+ public unowned string to_string ();
+ [CCode (cname = "gcry_cipher_map_name")]
+ public static Algorithm from_string (string name);
+ [CCode (cname = "gcry_cipher_map_oid")]
+ public static Algorithm from_oid (string oid);
+ }
+
+ [CCode (cname = "enum gcry_cipher_modes", cprefix = "GCRY_CIPHER_MODE_")]
+ public enum Mode {
+ NONE, /* No mode specified */
+ ECB, /* Electronic Codebook */
+ CFB, /* Cipher Feedback */
+ CBC, /* Cipher Block Chaining */
+ STREAM, /* Used with stream ciphers */
+ OFB, /* Output Feedback */
+ CTR, /* Counter */
+ AESWRAP, /* AES-WRAP algorithm */
+ CCM, /* Counter with CBC-MAC */
+ GCM, /* Galois/Counter Mode */
+ POLY1305, /* Poly1305 based AEAD mode */
+ OCB, /* OCB3 mode */
+ CFB8, /* Cipher Feedback /* Poly1305 based AEAD mode. */
+ XTS; /* XTS mode */
+
+ public unowned string to_string () {
+ switch (this) {
+ case ECB: return "ECB";
+ case CFB: return "CFB";
+ case CBC: return "CBC";
+ case STREAM: return "STREAM";
+ case OFB: return "OFB";
+ case CTR: return "CTR";
+ case AESWRAP: return "AESWRAP";
+ case GCM: return "GCM";
+ case POLY1305: return "POLY1305";
+ case OCB: return "OCB";
+ case CFB8: return "CFB8";
+ case XTS: return "XTS";
+ }
+ return "NONE";
+ }
+
+ public static Mode from_string (string name) {
+ switch (name) {
+ case "ECB": return ECB;
+ case "CFB": return CFB;
+ case "CBC": return CBC;
+ case "STREAM": return STREAM;
+ case "OFB": return OFB;
+ case "CTR": return CTR;
+ case "AESWRAP": return AESWRAP;
+ case "GCM": return GCM;
+ case "POLY1305": return POLY1305;
+ case "OCB": return OCB;
+ case "CFB8": return CFB8;
+ case "XTS": return XTS;
+ }
+ return NONE;
+ }
+ }
+
+ [CCode (cname = "enum gcry_cipher_flags", cprefix = "GCRY_CIPHER_")]
+ public enum Flag {
+ SECURE, /* Allocate in secure memory. */
+ ENABLE_SYNC, /* Enable CFB sync mode. */
+ CBC_CTS, /* Enable CBC cipher text stealing (CTS). */
+ CBC_MAC /* Enable CBC message auth. code (MAC). */
+ }
+ [CCode (cname = "gcry_cipher_hd_t", lower_case_cprefix = "gcry_cipher_", free_function = "gcry_cipher_close")]
+ [SimpleType]
+ public struct Cipher {
+ public static Error open (out Cipher cipher, Algorithm algo, Mode mode, Flag flags);
+ public void close ();
+ [CCode (cname = "gcry_cipher_ctl")]
+ public Error control (ControlCommand cmd, uchar[] buffer);
+ public Error info (ControlCommand what, ref uchar[] buffer);
+
+ public Error encrypt (uchar[] out_buffer, uchar[] in_buffer);
+ public Error decrypt (uchar[] out_buffer, uchar[] in_buffer);
+
+ [CCode (cname = "gcry_cipher_setkey")]
+ public Error set_key (uchar[] key_data);
+ [CCode (cname = "gcry_cipher_setiv")]
+ public Error set_iv (uchar[] iv_data);
+ [CCode (cname = "gcry_cipher_setctr")]
+ public Error set_counter_vector (uchar[] counter_vector);
+
+ [CCode (cname = "gcry_cipher_gettag")]
+ public Error get_tag(uchar[] out_buffer);
+ [CCode (cname = "gcry_cipher_checktag")]
+ public Error check_tag(uchar[] in_buffer);
+
+ public Error reset ();
+ public Error sync ();
+ }
+ }
+
+ [Compact, CCode (cname = "struct gcry_md_handle", cprefix = "gcry_md_", free_function = "gcry_md_close")]
+ public class Hash {
+ [CCode (cname = "enum gcry_md_algos", cprefix = "GCRY_MD_")]
+ public enum Algorithm {
+ NONE,
+ SHA1,
+ RMD160,
+ MD5,
+ MD4,
+ MD2,
+ TIGER,
+ TIGER1,
+ TIGER2,
+ HAVAL,
+ SHA224,
+ SHA256,
+ SHA384,
+ SHA512,
+ SHA3_224,
+ SHA3_256,
+ SHA3_384,
+ SHA3_512,
+ SHAKE128,
+ SHAKE256,
+ CRC32,
+ CRC32_RFC1510,
+ CRC24_RFC2440,
+ WHIRLPOOL,
+ GOSTR3411_94,
+ STRIBOG256,
+ STRIBOG512;
+
+ [CCode (cname = "gcry_md_get_algo_dlen")]
+ public size_t get_digest_length ();
+ [CCode (cname = "gcry_md_algo_info")]
+ public Error info (ControlCommand what, ref uchar[] buffer);
+ [CCode (cname = "gcry_md_algo_name")]
+ public unowned string to_string ();
+ [CCode (cname = "gcry_md_map_name")]
+ public static Algorithm from_string (string name);
+ [CCode (cname = "gcry_md_test_algo")]
+ public Error is_available ();
+ [CCode (cname = "gcry_md_get_asnoid")]
+ public Error get_oid (uchar[] buffer);
+ }
+
+ [CCode (cname = "enum gcry_md_flags", cprefix = "GCRY_MD_FLAG_")]
+ public enum Flag {
+ SECURE,
+ HMAC,
+ BUGEMU1
+ }
+
+ public static Error open (out Hash hash, Algorithm algo, Flag flag);
+ public void close ();
+ public Error enable (Algorithm algo);
+ [CCode (instance_pos = -1)]
+ public Error copy (out Hash dst);
+ public void reset ();
+ [CCode (cname = "enum gcry_md_ctl")]
+ public Error control (ControlCommand cmd, uchar[] buffer);
+ public void write (uchar[] buffer);
+ [CCode (array_length = false)]
+ public unowned uchar[] read (Algorithm algo);
+ public static void hash_buffer (Algorithm algo, [CCode (array_length = false)] uchar[] digest, uchar[] buffer);
+ public Algorithm get_algo ();
+ public bool is_enabled (Algorithm algo);
+ public bool is_secure ();
+ public Error info (ControlCommand what, uchar[] buffer);
+ [CCode (cname = "gcry_md_setkey")]
+ public Error set_key (uchar[] key_data);
+ public void putc (char c);
+ public void final ();
+ public static Error list (ref Algorithm[] algos);
+ }
+
+ namespace Random {
+ [CCode (cname = "gcry_random_level_t")]
+ public enum Level {
+ [CCode (cname = "GCRY_WEAK_RANDOM")]
+ WEAK,
+ [CCode (cname = "GCRY_STRONG_RANDOM")]
+ STRONG,
+ [CCode (cname = "GCRY_VERY_STRONG_RANDOM")]
+ VERY_STRONG
+ }
+
+ [CCode (cname = "gcry_randomize")]
+ public static void randomize (uchar[] buffer, Level level = Level.VERY_STRONG);
+ [CCode (cname = "gcry_fast_random_poll")]
+ public static Error poll ();
+ [CCode (cname = "gcry_random_bytes", array_length = false)]
+ public static uchar[] random_bytes (size_t nbytes, Level level = Level.VERY_STRONG);
+ [CCode (cname = "gcry_random_bytes_secure")]
+ public static uchar[] random_bytes_secure (size_t nbytes, Level level = Level.VERY_STRONG);
+ [CCode (cname = "gcry_create_nonce")]
+ public static void nonce (uchar[] buffer);
+ }
+
+ [Compact, CCode (cname = "struct gcry_mpi", cprefix = "gcry_mpi_", free_function = "gcry_mpi_release")]
+ public class MPI {
+ [CCode (cname = "enum gcry_mpi_format", cprefix = "GCRYMPI_FMT_")]
+ public enum Format {
+ NONE,
+ STD,
+ PGP,
+ SSH,
+ HEX,
+ USG
+ }
+
+ [CCode (cname = "enum gcry_mpi_flag", cprefix = "GCRYMPI_FLAG_")]
+ public enum Flag {
+ SECURE,
+ OPAQUE
+ }
+
+ public MPI (uint nbits);
+ [CCode (cname = "gcry_mpi_snew")]
+ public MPI.secure (uint nbits);
+ public MPI copy ();
+ public void set (MPI u);
+ public void set_ui (ulong u);
+ public void swap ();
+ public int cmp (MPI v);
+ public int cmp_ui (ulong v);
+
+ public static Error scan (out MPI ret, MPI.Format format, [CCode (array_length = false)] uchar[] buffer, size_t buflen, out size_t nscanned);
+ [CCode (instance_pos = -1)]
+ public Error print (MPI.Format format, [CCode (array_length = false)] uchar[] buffer, size_t buflen, out size_t nwritter);
+ [CCode (instance_pos = -1)]
+ public Error aprint (MPI.Format format, out uchar[] buffer);
+
+ public void add (MPI u, MPI v);
+ public void add_ui (MPI u, ulong v);
+ public void addm (MPI u, MPI v, MPI m);
+ public void sub (MPI u, MPI v);
+ public void sub_ui (MPI u, MPI v);
+ public void subm (MPI u, MPI v, MPI m);
+ public void mul (MPI u, MPI v);
+ public void mul_ui (MPI u, ulong v);
+ public void mulm (MPI u, MPI v, MPI m);
+ public void mul_2exp (MPI u, ulong cnt);
+ public void div (MPI q, MPI r, MPI dividend, MPI divisor, int round);
+ public void mod (MPI dividend, MPI divisor);
+ public void powm (MPI b, MPI e, MPI m);
+ public int gcd (MPI a, MPI b);
+ public int invm (MPI a, MPI m);
+
+ public uint get_nbits ();
+ public int test_bit (uint n);
+ public void set_bit (uint n);
+ public void clear_bit (uint n);
+ public void set_highbit (uint n);
+ public void clear_highbit (uint n);
+ public void rshift (MPI a, uint n);
+ public void lshift (MPI a, uint n);
+
+ public void set_flag (MPI.Flag flag);
+ public void clear_flag (MPI.Flag flag);
+ public int get_flag (MPI.Flag flag);
+ }
+
+ [Compact, CCode (cname = "struct gcry_sexp", free_function = "gcry_sexp_release")]
+ public class SExp {
+ [CCode (cprefix = "GCRYSEXP_FMT_")]
+ public enum Format {
+ DEFAULT,
+ CANON,
+ BASE64,
+ ADVANCED
+ }
+
+ public static Error @new (out SExp retsexp, void * buffer, size_t length, int autodetect);
+ public static Error create (out SExp retsexp, void * buffer, size_t length, int autodetect, GLib.DestroyNotify free_function);
+ public static Error sscan (out SExp retsexp, out size_t erroff, char[] buffer);
+ public static Error build (out SExp retsexp, out size_t erroff, string format, ...);
+ public size_t sprint (Format mode, char[] buffer);
+ public static size_t canon_len (uchar[] buffer, out size_t erroff, out int errcode);
+ public SExp find_token (string token, size_t token_length = 0);
+ public int length ();
+ public SExp? nth (int number);
+ public SExp? car ();
+ public SExp? cdr ();
+ public unowned char[] nth_data (int number);
+ public gcry_string nth_string (int number);
+ public MPI nth_mpi (int number, MPI.Format mpifmt);
+ }
+
+ [CCode (cname = "char", free_function = "gcry_free")]
+ public class gcry_string : string { }
+
+ [CCode (lower_case_cprefix = "gcry_pk_")]
+ namespace PublicKey {
+ [CCode (cname = "enum gcry_pk_algos")]
+ public enum Algorithm {
+ RSA,
+ ELG_E,
+ DSA,
+ ELG,
+ ECDSA;
+
+ [CCode (cname = "gcry_pk_algo_name")]
+ public unowned string to_string ();
+ [CCode (cname = "gcry_pk_map_name")]
+ public static Algorithm map_name (string name);
+ }
+
+ public static Error encrypt (out SExp ciphertext, SExp data, SExp pkey);
+ public static Error decrypt (out SExp plaintext, SExp data, SExp skey);
+ public static Error sign (out SExp signature, SExp data, SExp skey);
+ public static Error verify (SExp signature, SExp data, SExp pkey);
+ public static Error testkey (SExp key);
+ public static Error genkey (out SExp r_key, SExp s_params);
+ public static uint get_nbits (SExp key);
+ }
+
+ [CCode (lower_case_cprefix = "gcry_kdf_")]
+ namespace KeyDerivation {
+ [CCode (cname = "gcry_kdf_algos", cprefix = "GCRY_KDF_", has_type_id = false)]
+ public enum Algorithm {
+ NONE,
+ SIMPLE_S2K,
+ SALTED_S2K,
+ ITERSALTED_S2K,
+ PBKDF1,
+ PBKDF2,
+ SCRYPT
+ }
+
+ public GCrypt.Error derive ([CCode (type = "const void*", array_length_type = "size_t")] uint8[] passphrasse, GCrypt.KeyDerivation.Algorithm algo, GCrypt.Hash.Algorithm subalgo, [CCode (type = "const void*", array_length_type = "size_t")] uint8[] salt, ulong iterations, [CCode (type = "void*", array_length_type = "size_t", array_length_pos = 5.5)] uint8[] keybuffer);
+ }
+}
diff --git a/crypto-vala/vapi/libsrtp2.vapi b/crypto-vala/vapi/libsrtp2.vapi
new file mode 100644
index 00000000..5ceedced
--- /dev/null
+++ b/crypto-vala/vapi/libsrtp2.vapi
@@ -0,0 +1,115 @@
+[CCode (cheader_filename = "srtp2/srtp.h")]
+namespace Srtp {
+public const uint MAX_TRAILER_LEN;
+
+public static ErrorStatus init();
+public static ErrorStatus shutdown();
+
+[Compact]
+[CCode (cname = "srtp_ctx_t", cprefix = "srtp_", free_function = "srtp_dealloc")]
+public class Context {
+ public static ErrorStatus create(out Context session, Policy? policy);
+
+ public ErrorStatus protect([CCode (type = "void*", array_length = false)] uint8[] rtp, ref int len);
+ public ErrorStatus unprotect([CCode (type = "void*", array_length = false)] uint8[] rtp, ref int len);
+
+ public ErrorStatus protect_rtcp([CCode (type = "void*", array_length = false)] uint8[] rtcp, ref int len);
+ public ErrorStatus unprotect_rtcp([CCode (type = "void*", array_length = false)] uint8[] rtcp, ref int len);
+
+ public ErrorStatus add_stream(ref Policy policy);
+ public ErrorStatus update_stream(ref Policy policy);
+ public ErrorStatus remove_stream(uint ssrc);
+ public ErrorStatus update(ref Policy policy);
+}
+
+[CCode (cname = "srtp_ssrc_t")]
+public struct Ssrc {
+ public SsrcType type;
+ public uint value;
+}
+
+[CCode (cname = "srtp_ssrc_type_t", cprefix = "ssrc_")]
+public enum SsrcType {
+ undefined, specific, any_inbound, any_outbound
+}
+
+[CCode (cname = "srtp_policy_t", destroy_function = "")]
+public struct Policy {
+ public Ssrc ssrc;
+ public CryptoPolicy rtp;
+ public CryptoPolicy rtcp;
+ [CCode (array_length = false)]
+ public uint8[] key;
+ public ulong num_master_keys;
+ public ulong window_size;
+ public int allow_repeat_tx;
+ [CCode (array_length_cname = "enc_xtn_hdr_count")]
+ public int[] enc_xtn_hdr;
+}
+
+[CCode (cname = "srtp_crypto_policy_t")]
+public struct CryptoPolicy {
+ public CipherType cipher_type;
+ public int cipher_key_len;
+ public AuthType auth_type;
+ public int auth_key_len;
+ public int auth_tag_len;
+ public SecurityServices sec_serv;
+
+ public void set_aes_cm_128_hmac_sha1_80();
+ public void set_aes_cm_128_hmac_sha1_32();
+ public void set_aes_cm_128_null_auth();
+ public void set_aes_cm_192_hmac_sha1_32();
+ public void set_aes_cm_192_hmac_sha1_80();
+ public void set_aes_cm_192_null_auth();
+ public void set_aes_cm_256_hmac_sha1_32();
+ public void set_aes_cm_256_hmac_sha1_80();
+ public void set_aes_cm_256_null_auth();
+ public void set_aes_gcm_128_16_auth();
+ public void set_aes_gcm_128_8_auth();
+ public void set_aes_gcm_128_8_only_auth();
+ public void set_aes_gcm_256_16_auth();
+ public void set_aes_gcm_256_8_auth();
+ public void set_aes_gcm_256_8_only_auth();
+ public void set_null_cipher_hmac_null();
+ public void set_null_cipher_hmac_sha1_80();
+
+ public void set_rtp_default();
+ public void set_rtcp_default();
+
+ public void set_from_profile_for_rtp(Profile profile);
+ public void set_from_profile_for_rtcp(Profile profile);
+}
+
+[CCode (cname = "srtp_profile_t", cprefix = "srtp_profile_")]
+public enum Profile {
+ reserved, aes128_cm_sha1_80, aes128_cm_sha1_32, null_sha1_80, null_sha1_32, aead_aes_128_gcm, aead_aes_256_gcm
+}
+
+[CCode (cname = "srtp_cipher_type_id_t")]
+public struct CipherType : uint32 {}
+
+[CCode (cname = "srtp_auth_type_id_t")]
+public struct AuthType : uint32 {}
+
+[CCode (cname = "srtp_sec_serv_t", cprefix = "sec_serv_")]
+public enum SecurityServices {
+ none, conf, auth, conf_and_auth;
+}
+
+[CCode (cname = "srtp_err_status_t", cprefix = "srtp_err_status_", has_type_id = false)]
+public enum ErrorStatus {
+ ok, fail, bad_param, alloc_fail, dealloc_fail, init_fail, terminus, auth_fail, cipher_fail, replay_fail, algo_fail, no_such_op, no_ctx, cant_check, key_expired, socket_err, signal_err, nonce_bad, encode_err, semaphore_err, pfkey_err, bad_mki, pkt_idx_old, pkt_idx_adv
+}
+
+[CCode (cname = "srtp_log_level_t", cprefix = "srtp_log_level_", has_type_id = false)]
+public enum LogLevel {
+ error, warning, info, debug
+}
+
+[CCode (cname = "srtp_log_handler_func_t")]
+public delegate void LogHandler(LogLevel level, string msg);
+
+public static ErrorStatus install_log_handler(LogHandler func);
+
+} \ No newline at end of file