diff options
Diffstat (limited to 'g10/misc.c')
-rw-r--r-- | g10/misc.c | 126 |
1 files changed, 125 insertions, 1 deletions
diff --git a/g10/misc.c b/g10/misc.c index 97809692e..1e6df5f67 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -71,6 +71,11 @@ #include "../common/zb32.h" +/* FIXME: Libgcrypt 1.9 will support EAX. Until we kame this a + * requirement we hardwire the enum used for EAX. */ +#define MY_GCRY_CIPHER_MODE_EAX 14 + + #ifdef ENABLE_SELINUX_HACKS /* A object and a global variable to keep track of files marked as secured. */ @@ -397,7 +402,7 @@ print_further_info (const char *format, ...) log_info (_("(further info: ")); va_start (arg_ptr, format); - log_logv (GPGRT_LOG_CONT, format, arg_ptr); + log_logv (GPGRT_LOGLVL_CONT, format, arg_ptr); va_end (arg_ptr); log_printf (")\n"); } @@ -583,6 +588,80 @@ openpgp_cipher_algo_name (cipher_algo_t algo) } +/* Return 0 if ALGO is supported. Return an error if not. */ +gpg_error_t +openpgp_aead_test_algo (aead_algo_t algo) +{ + /* FIXME: We currently have no easy way to test whether libgcrypt + * implements a mode. The only way we can do this is to open a + * cipher context with that mode and close it immediately. That is + * a bit costly. So we look at the libgcrypt version and assume + * nothing has been patched out. */ + switch (algo) + { + case AEAD_ALGO_NONE: + break; + + case AEAD_ALGO_EAX: +#if GCRYPT_VERSION_NUMBER < 0x010900 + break; +#else + return 0; +#endif + + case AEAD_ALGO_OCB: + return 0; + } + + return gpg_error (GPG_ERR_INV_CIPHER_MODE); +} + + +/* Map the OpenPGP AEAD algorithm with ID ALGO to a string + * representation of the algorithm name. For unknown algorithm IDs + * this function returns "?". */ +const char * +openpgp_aead_algo_name (aead_algo_t algo) +{ + switch (algo) + { + case AEAD_ALGO_NONE: break; + case AEAD_ALGO_EAX: return "EAX"; + case AEAD_ALGO_OCB: return "OCB"; + } + + return "?"; +} + + +/* Return information for the AEAD algorithm ALGO. The corresponding + * Libgcrypt ciphermode is stored at R_MODE and the required number of + * octets for the nonce at R_NONCELEN. On error and error code is + * returned. Note that the taglen is always 128 bits. */ +gpg_error_t +openpgp_aead_algo_info (aead_algo_t algo, enum gcry_cipher_modes *r_mode, + unsigned int *r_noncelen) +{ + switch (algo) + { + case AEAD_ALGO_OCB: + *r_mode = GCRY_CIPHER_MODE_OCB; + *r_noncelen = 15; + break; + + case AEAD_ALGO_EAX: + *r_mode = MY_GCRY_CIPHER_MODE_EAX; + *r_noncelen = 16; + break; + + default: + log_error ("unsupported AEAD algo %d\n", algo); + return gpg_error (GPG_ERR_INV_CIPHER_MODE); + } + return 0; +} + + /* Return 0 if ALGO is a supported OpenPGP public key algorithm. */ int openpgp_pk_test_algo (pubkey_algo_t algo) @@ -1113,6 +1192,39 @@ string_to_cipher_algo (const char *string) return val; } + +/* + * Map an AEAD mode string to a an AEAD algorithm number as defined by + * rrc4880bis. Also support the "An" syntax as used by the preference + * strings. + */ +aead_algo_t +string_to_aead_algo (const char *string) +{ + int result; + + if (!string) + result = 0; + if (!ascii_strcasecmp (string, "EAX")) + result = 1; + else if (!ascii_strcasecmp (string, "OCB")) + result = 2; + else if ((string[0]=='A' || string[0]=='a')) + { + char *endptr; + + string++; + result = strtol (string, &endptr, 10); + if (!*string || *endptr || result < 1 || result > 2) + result = 0; + } + else + result = 0; + + return result; +} + + /* * Wrapper around gcry_md_map_name to provide a fallback using the * "Hn" syntax as used by the preference strings. @@ -1229,6 +1341,18 @@ default_cipher_algo(void) return opt.s2k_cipher_algo; } + +aead_algo_t +default_aead_algo(void) +{ + if(opt.def_aead_algo) + return opt.def_aead_algo; + else if(opt.personal_aead_prefs) + return opt.personal_aead_prefs[0].value; + else + return DEFAULT_AEAD_ALGO; +} + /* There is no default_digest_algo function, but see sign.c:hash_for() */ |