From cvs at cvs.gnupg.org Fri Nov 2 17:50:20 2012 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Fri, 02 Nov 2012 17:50:20 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.0beta3-92-g8f8c29d Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 8f8c29d24ca13f987e6c118702b428a2051b7072 (commit) from 8df89f3e9cf0255f11011c2f1df0d419a5c23a8c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 8f8c29d24ca13f987e6c118702b428a2051b7072 Author: NIIBE Yutaka Date: Wed Oct 31 16:09:06 2012 +0900 agent: Fix wrong use of gcry_sexp_build_array * findkey.c (agent_public_key_from_file): Fix use of gcry_sexp_build_array. -- A test case leading to a segv in Libgcrypt is gpg-connect-agent \ "READKEY 9277C5875C8AFFCB727661C18BE4E0A0DEED9260" /bye The keygrip was created by "monkeysphere s", which has a comment. gcry_sexp_build_array expects pointers to the arguments which is quite surprising. Probably ARG_NEXT was accidentally implemented wrongly. Anyway, we can't do anything about it and thus need to fix the check the users of this function. Some-comments-by: Werner Koch diff --git a/agent/findkey.c b/agent/findkey.c index 0b57390..b17870e 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -948,15 +948,15 @@ agent_public_key_from_file (ctrl_t ctrl, { p = stpcpy (p, "(uri %b)"); assert (argidx+1 < DIM (args)); - args[argidx++] = (void *)uri_length; - args[argidx++] = (void *)uri; + args[argidx++] = (void *)&uri_length; + args[argidx++] = (void *)&uri; } if (comment) { p = stpcpy (p, "(comment %b)"); assert (argidx+1 < DIM (args)); - args[argidx++] = (void *)comment_length; - args[argidx++] = (void*)comment; + args[argidx++] = (void *)&comment_length; + args[argidx++] = (void*)&comment; } *p++ = ')'; *p = 0; ----------------------------------------------------------------------- Summary of changes: agent/findkey.c | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Nov 2 18:00:14 2012 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Fri, 02 Nov 2012 18:00:14 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-0, updated. gnupg-2.0.19-37-gd5c46ac Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-0 has been updated via d5c46ac6f447e92722fd7e904bf520b1265a0ce0 (commit) from 80a34c0b5008c59979561dcee40536d7e25246f6 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d5c46ac6f447e92722fd7e904bf520b1265a0ce0 Author: NIIBE Yutaka Date: Wed Oct 31 16:09:06 2012 +0900 agent: Fix wrong use of gcry_sexp_build_array * findkey.c (agent_public_key_from_file): Fix use of gcry_sexp_build_array. -- A test case leading to a segv in Libgcrypt is gpg-connect-agent \ "READKEY 9277C5875C8AFFCB727661C18BE4E0A0DEED9260" /bye The keygrip was created by "monkeysphere s", which has a comment. gcry_sexp_build_array expects pointers to the arguments which is quite surprising. Probably ARG_NEXT was accidentally implemented wrongly. Anyway, we can't do anything about it and thus need to fix the check the users of this function. Some-comments-by: Werner Koch diff --git a/agent/findkey.c b/agent/findkey.c index 800db88..550e403 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -824,15 +824,15 @@ agent_public_key_from_file (ctrl_t ctrl, { p = stpcpy (p, "(uri %b)"); assert (argidx+1 < DIM (args)); - args[argidx++] = (void *)uri_length; - args[argidx++] = (void *)uri; + args[argidx++] = (void *)&uri_length; + args[argidx++] = (void *)&uri; } if (comment) { p = stpcpy (p, "(comment %b)"); assert (argidx+1 < DIM (args)); - args[argidx++] = (void *)comment_length; - args[argidx++] = (void*)comment; + args[argidx++] = (void *)&comment_length; + args[argidx++] = (void*)&comment; } *p++ = ')'; *p = 0; ----------------------------------------------------------------------- Summary of changes: agent/findkey.c | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Nov 5 21:45:29 2012 From: cvs at cvs.gnupg.org (by Milan Broz) Date: Mon, 05 Nov 2012 21:45:29 +0100 Subject: [git] GCRYPT - branch, LIBGCRYPT-1-5-BRANCH, updated. libgcrypt-1.5.0-11-g542d354 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, LIBGCRYPT-1-5-BRANCH has been updated via 542d354b902c72d7fb19f9a0e5f3f3d21909f21a (commit) via d020143792013295f20e75e18a2b75d5b2e90c43 (commit) from 7a37ea4a49916439474b5a0e445333fa72889f55 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 542d354b902c72d7fb19f9a0e5f3f3d21909f21a Author: Milan Broz Date: Mon Oct 29 17:18:09 2012 +0100 PBKDF2: Allow empty passphrase. * cipher/kdf.c (gcry_kdf_derive): Allow empty passphrase for PBKDF2. * tests/t-kdf.c (check_pbkdf2): Add test case for above. -- While it is insecure, the PBKDF2 implementations usually allows to derive key only from salt. This particular case is used e.g. in cryptsetup when you use empty file as keyfile for LUKS keyslot. Test vector is compared with two independent implementations. Signed-off-by: Milan Broz diff --git a/cipher/kdf.c b/cipher/kdf.c index d981022..46e8550 100644 --- a/cipher/kdf.c +++ b/cipher/kdf.c @@ -238,7 +238,7 @@ gcry_kdf_derive (const void *passphrase, size_t passphraselen, { gpg_err_code_t ec; - if (!passphrase || !passphraselen) + if (!passphrase || (!passphraselen && algo != GCRY_KDF_PBKDF2)) { ec = GPG_ERR_INV_DATA; goto leave; diff --git a/tests/t-kdf.c b/tests/t-kdf.c index 7209525..06c0026 100644 --- a/tests/t-kdf.c +++ b/tests/t-kdf.c @@ -917,7 +917,15 @@ check_pbkdf2 (void) 16, "\x56\xfa\x6a\xa7\x55\x48\x09\x9d\xcc\x37" "\xd7\xf0\x34\x25\xe0\xc3" - } + }, + { /* empty password test, not in RFC-6070 */ + "", 0, + "salt", 4, + 2, + 20, + "\x13\x3a\x4c\xe8\x37\xb4\xd2\x52\x1e\xe2" + "\xbf\x03\xe1\x1c\x71\xca\x79\x4e\x07\x97" + }, }; int tvidx; gpg_error_t err; commit d020143792013295f20e75e18a2b75d5b2e90c43 Author: Werner Koch Date: Mon Nov 5 19:01:01 2012 +0100 Avoid dereferencing pointer right after the end * mpi/mpicoder.c (do_get_buffer): Check the length before derefing P. -- Christian Grothoff found this bug using Valgrind. diff --git a/mpi/mpicoder.c b/mpi/mpicoder.c index f499796..a3435ed 100644 --- a/mpi/mpicoder.c +++ b/mpi/mpicoder.c @@ -270,7 +270,7 @@ do_get_buffer (gcry_mpi_t a, unsigned int *nbytes, int *sign, int force_secure) /* This is sub-optimal but we need to do the shift operation because the caller has to free the returned buffer. */ - for (p=buffer; !*p && *nbytes; p++, --*nbytes) + for (p=buffer; *nbytes && !*p; p++, --*nbytes) ; if (p != buffer) memmove (buffer,p, *nbytes); ----------------------------------------------------------------------- Summary of changes: cipher/kdf.c | 2 +- mpi/mpicoder.c | 2 +- tests/t-kdf.c | 10 +++++++++- 3 files changed, 11 insertions(+), 3 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Tue Nov 6 16:07:32 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 06 Nov 2012 16:07:32 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-0, updated. gnupg-2.0.19-39-gab4ea45 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-0 has been updated via ab4ea45f54006eba55db11263431c4c0c4f557dc (commit) via c0a20d6124118a91e18aa707d2c1102c67d6798f (commit) from d5c46ac6f447e92722fd7e904bf520b1265a0ce0 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit ab4ea45f54006eba55db11263431c4c0c4f557dc Author: Werner Koch Date: Tue Nov 6 14:39:22 2012 +0100 Allow decryption with card keys > 3072 bit * scd/command.c (MAXLEN_SETDATA): New. (cmd_setdata): Add option --append. * g10/call-agent.c (agent_scd_pkdecrypt): Use new option for long data * scd/app-openpgp.c (struct app_local_s): Add field manufacturer. (app_select_openpgp): Store manufacturer. (do_decipher): Print a note for broken cards. -- Please note that I was not able to run a full test because I only have broken cards (S/N < 346) available. diff --git a/g10/call-agent.c b/g10/call-agent.c index cded773..373d8c9 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -1034,7 +1034,7 @@ agent_scd_pksign (const char *serialno, int hashalgo, /* Decrypt INDATA of length INDATALEN using the card identified by - SERIALNO. Return the plaintext in a nwly allocated buffer stored + SERIALNO. Return the plaintext in a newly allocated buffer stored at the address of R_BUF. Note, we currently support only RSA or more exactly algorithms @@ -1058,20 +1058,26 @@ agent_scd_pkdecrypt (const char *serialno, return rc; /* FIXME: use secure memory where appropriate */ - if (indatalen*2 + 50 > DIM(line)) - return gpg_error (GPG_ERR_GENERAL); rc = select_openpgp (serialno); if (rc) return rc; - sprintf (line, "SCD SETDATA "); - p = line + strlen (line); - for (i=0; i < indatalen ; i++, p += 2 ) - sprintf (p, "%02X", indata[i]); - rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); + for (len = 0; len < indatalen;) + { + p = stpcpy (line, "SCD SETDATA "); + if (len) + p = stpcpy (p, "--append "); + for (i=0; len < indatalen && (i*2 < DIM(line)-50); i++, len++) + { + sprintf (p, "%02X", indata[len]); + p += 2; + } + rc = assuan_transact (agent_ctx, line, + NULL, NULL, NULL, NULL, NULL, NULL); if (rc) return rc; + } init_membuf (&data, 1024); snprintf (line, DIM(line)-1, "SCD PKDECRYPT %s", serialno); diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index ff26b36..141b2b7 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -158,6 +158,8 @@ struct app_local_s { unsigned char status_indicator; /* The card status indicator. */ + unsigned int manufacturer:16; /* Manufacturer ID from the s/n. */ + /* Keep track of the ISO card capabilities. */ struct { @@ -3462,6 +3464,12 @@ do_decipher (app_t app, const char *keyidstr, indata, indatalen, le_value, padind, outdata, outdatalen); xfree (fixbuf); + + if (gpg_err_code (rc) == GPG_ERR_CARD /* actual SW is 0x640a */ + && app->app_local->manufacturer == 5 + && app->card_version == 0x0200) + log_info ("NOTE: Cards with manufacturer id 5 and s/n <= 346 (0x15a)" + " do not work with encryption keys > 2048 bits\n"); } return rc; @@ -3749,6 +3757,8 @@ app_select_openpgp (app_t app) goto leave; } + app->app_local->manufacturer = manufacturer; + if (app->card_version >= 0x0200) app->app_local->extcap.is_v2 = 1; diff --git a/scd/command.c b/scd/command.c index 6053fc6..3ce4a57 100644 --- a/scd/command.c +++ b/scd/command.c @@ -46,6 +46,9 @@ /* Maximum allowed size of key data as used in inquiries. */ #define MAXLEN_KEYDATA 4096 +/* Maximum allowed total data size for SETDATA. */ +#define MAXLEN_SETDATA 4096 + /* Maximum allowed size of certificate data as used in inquiries. */ #define MAXLEN_CERTDATA 16384 @@ -820,17 +823,24 @@ cmd_readkey (assuan_context_t ctx, char *line) static const char hlp_setdata[] = - "SETDATA \n" + "SETDATA [--append] \n" "\n" - "The client should use this command to tell us the data he want to sign."; + "The client should use this command to tell us the data he want to sign.\n" + "With the option --append, the data is appended to the data set by a\n" + "previous SETDATA command."; static gpg_error_t cmd_setdata (assuan_context_t ctx, char *line) { ctrl_t ctrl = assuan_get_pointer (ctx); - int n; + int append; + int n, i, off; char *p; unsigned char *buf; + append = (ctrl->in_data.value && has_option (line, "--append")); + + line = skip_options (line); + if (locked_session && locked_session != ctrl->server_local) return gpg_error (GPG_ERR_LOCKED); @@ -844,14 +854,30 @@ cmd_setdata (assuan_context_t ctx, char *line) if ((n&1)) return set_error (GPG_ERR_ASS_PARAMETER, "odd number of digits"); n /= 2; + if (append) + { + if (ctrl->in_data.valuelen + n > MAXLEN_SETDATA) + return set_error (GPG_ERR_TOO_LARGE, + "limit on total size of data reached"); + buf = xtrymalloc (ctrl->in_data.valuelen + n); + } + else buf = xtrymalloc (n); if (!buf) return out_of_core (); + if (append) + { + memcpy (buf, ctrl->in_data.value, ctrl->in_data.valuelen); + off = ctrl->in_data.valuelen; + } + else + off = 0; + for (p=line, i=0; i < n; p += 2, i++) + buf[off+i] = xtoi_2 (p); + ctrl->in_data.value = buf; - ctrl->in_data.valuelen = n; - for (p=line, n=0; n < ctrl->in_data.valuelen; p += 2, n++) - buf[n] = xtoi_2 (p); + ctrl->in_data.valuelen = off + n; return 0; } commit c0a20d6124118a91e18aa707d2c1102c67d6798f Author: Werner Koch Date: Tue Nov 6 14:34:32 2012 +0100 Remove trailing white space from some files -- diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 2a85250..ff26b36 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -118,13 +118,13 @@ static struct { /* The format of RSA private keys. */ typedef enum - { + { RSA_UNKNOWN_FMT, RSA_STD, RSA_STD_N, RSA_CRT, RSA_CRT_N - } + } rsa_key_format_t; @@ -141,7 +141,7 @@ struct cache_s { struct app_local_s { /* A linked list with cached DOs. */ struct cache_s *cache; - + /* Keep track of the public keys. */ struct { @@ -166,7 +166,7 @@ struct app_local_s { } cardcap; /* Keep track of extended card capabilities. */ - struct + struct { unsigned int is_v2:1; /* This is a v2.0 compatible card. */ unsigned int get_challenge:1; @@ -195,7 +195,7 @@ struct app_local_s { of this strucuire is only valid if this is not 0. */ unsigned int e_bits; /* Size of the public exponent in bits. */ - rsa_key_format_t format; + rsa_key_format_t format; } keyattr[3]; }; @@ -213,7 +213,7 @@ static gpg_error_t do_auth (app_t app, const char *keyidstr, unsigned char **outdata, size_t *outdatalen); static void parse_algorithm_attribute (app_t app, int keyno); static gpg_error_t change_keyattr_from_string - (app_t app, + (app_t app, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg, const void *value, size_t valuelen); @@ -253,7 +253,7 @@ do_deinit (app_t app) bypassed. With TRY_EXTLEN extended lengths APDUs are use if supported by the card. */ static gpg_error_t -get_cached_data (app_t app, int tag, +get_cached_data (app_t app, int tag, unsigned char **result, size_t *resultlen, int get_immediate, int try_extlen) { @@ -280,13 +280,13 @@ get_cached_data (app_t app, int tag, memcpy (p, c->data, c->length); *result = p; } - + *resultlen = c->length; - + return 0; } } - + if (try_extlen && app->app_local->cardcap.ext_lc_le) exmode = app->app_local->extcap.max_rsp_data; else @@ -313,7 +313,7 @@ get_cached_data (app_t app, int tag, /* Okay, cache it. */ for (c=app->app_local->cache; c; c = c->next) assert (c->tag != tag); - + c = xtrymalloc (sizeof *c + len); if (c) { @@ -439,7 +439,7 @@ get_one_do (app_t app, int tag, unsigned char **result, size_t *nbytes, { rc = get_cached_data (app, data_objects[i].get_from, &buffer, &buflen, - (data_objects[i].dont_cache + (data_objects[i].dont_cache || data_objects[i].get_immediate_in_v11), data_objects[i].try_extlen); if (!rc) @@ -463,7 +463,7 @@ get_one_do (app_t app, int tag, unsigned char **result, size_t *nbytes, if (!value) /* Not in a constructed DO, try simple. */ { rc = get_cached_data (app, tag, &buffer, &buflen, - (data_objects[i].dont_cache + (data_objects[i].dont_cache || data_objects[i].get_immediate_in_v11), data_objects[i].try_extlen); if (!rc) @@ -490,7 +490,7 @@ dump_all_do (int slot) int rc, i, j; unsigned char *buffer; size_t buflen; - + for (i=0; data_objects[i].tag; i++) { if (data_objects[i].get_from) @@ -501,7 +501,7 @@ dump_all_do (int slot) rc = iso7816_get_data (slot, 0, data_objects[i].tag, &buffer, &buflen); if (gpg_err_code (rc) == GPG_ERR_NO_OBJ) ; - else if (rc) + else if (rc) log_info ("DO `%s' not available: %s\n", data_objects[i].desc, gpg_strerror (rc)); else @@ -522,7 +522,7 @@ dump_all_do (int slot) { const unsigned char *value; size_t valuelen; - + if (j==i || data_objects[i].tag != data_objects[j].get_from) continue; value = find_tlv_unchecked (buffer, buflen, @@ -634,7 +634,7 @@ parse_login_data (app_t app) next: for (; buflen && *buffer != '\x18'; buflen--, buffer++) if (*buffer == '\n') - buflen = 1; + buflen = 1; } while (buflen); @@ -642,17 +642,17 @@ parse_login_data (app_t app) } /* Note, that FPR must be at least 20 bytes. */ -static gpg_error_t +static gpg_error_t store_fpr (app_t app, int keynumber, u32 timestamp, const unsigned char *m, size_t mlen, - const unsigned char *e, size_t elen, + const unsigned char *e, size_t elen, unsigned char *fpr, unsigned int card_version) { unsigned int n, nbits; unsigned char *buffer, *p; int tag, tag2; int rc; - + for (; mlen && !*m; mlen--, m++) /* strip leading zeroes */ ; for (; elen && !*e; elen--, e++) /* strip leading zeroes */ @@ -662,7 +662,7 @@ store_fpr (app_t app, int keynumber, u32 timestamp, p = buffer = xtrymalloc (3 + n); if (!buffer) return gpg_error_from_syserror (); - + *p++ = 0x99; /* ctb */ *p++ = n >> 8; /* 2 byte length header */ *p++ = n; @@ -680,7 +680,7 @@ store_fpr (app_t app, int keynumber, u32 timestamp, *p++ = nbits >> 8; *p++ = nbits; memcpy (p, e, elen); p += elen; - + gcry_md_hash_buffer (GCRY_MD_SHA1, fpr, buffer, n+3); xfree (buffer); @@ -712,11 +712,11 @@ store_fpr (app_t app, int keynumber, u32 timestamp, return rc; } - + static void send_fpr_if_not_null (ctrl_t ctrl, const char *keyword, int number, const unsigned char *fpr) -{ +{ int i; char buf[41]; char numbuf[25]; @@ -738,7 +738,7 @@ send_fpr_if_not_null (ctrl_t ctrl, const char *keyword, static void send_fprtime_if_not_null (ctrl_t ctrl, const char *keyword, int number, const unsigned char *stamp) -{ +{ char numbuf1[50], numbuf2[50]; unsigned long value; @@ -753,7 +753,7 @@ send_fprtime_if_not_null (ctrl_t ctrl, const char *keyword, } static void -send_key_data (ctrl_t ctrl, const char *name, +send_key_data (ctrl_t ctrl, const char *name, const unsigned char *a, size_t alen) { char *buffer, *buf; @@ -784,7 +784,7 @@ send_key_data (ctrl_t ctrl, const char *name, static void send_key_attr (ctrl_t ctrl, app_t app, const char *keyword, int number) -{ +{ char buffer[200]; assert (number >=0 && number < DIM(app->app_local->keyattr)); @@ -801,7 +801,7 @@ send_key_attr (ctrl_t ctrl, app_t app, const char *keyword, int number) /* Implement the GETATTR command. This is similar to the LEARN command but returns just one value via the status interface. */ -static gpg_error_t +static gpg_error_t do_getattr (app_t app, ctrl_t ctrl, const char *name) { static struct { @@ -818,7 +818,7 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name) { "KEY-TIME", 0x00CD, 4 }, { "KEY-ATTR", 0x0000, -5 }, { "CA-FPR", 0x00C6, 3 }, - { "CHV-STATUS", 0x00C4, 1 }, + { "CHV-STATUS", 0x00C4, 1 }, { "SIG-COUNTER", 0x0093, 2 }, { "SERIALNO", 0x004F, -1 }, { "AID", 0x004F }, @@ -839,8 +839,8 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name) for (idx=0; table[idx].name && strcmp (table[idx].name, name); idx++) ; if (!table[idx].name) - return gpg_error (GPG_ERR_INV_NAME); - + return gpg_error (GPG_ERR_INV_NAME); + if (table[idx].special == -1) { /* The serial number is very special. We could have used the @@ -868,7 +868,7 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name) char tmp[100]; snprintf (tmp, sizeof tmp, - "gc=%d ki=%d fc=%d pd=%d mcl3=%u aac=%d sm=%d", + "gc=%d ki=%d fc=%d pd=%d mcl3=%u aac=%d sm=%d", app->app_local->extcap.get_challenge, app->app_local->extcap.key_import, app->app_local->extcap.change_force_chv, @@ -891,7 +891,7 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name) { char *serial; time_t stamp; - + if (!app_get_serial_and_stamp (app, &serial, &stamp)) { if (strlen (serial) > 16+12) @@ -902,7 +902,7 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name) } xfree (serial); } - return gpg_error (GPG_ERR_INV_NAME); + return gpg_error (GPG_ERR_INV_NAME); } if (table[idx].special == -5) { @@ -917,9 +917,9 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name) if (table[idx].special == 1) { char numbuf[7*23]; - + for (i=0,*numbuf=0; i < valuelen && i < 7; i++) - sprintf (numbuf+strlen (numbuf), " %d", value[i]); + sprintf (numbuf+strlen (numbuf), " %d", value[i]); send_status_info (ctrl, table[idx].name, numbuf, strlen (numbuf), NULL, 0); } @@ -1045,7 +1045,7 @@ retrieve_key_material (FILE *fp, const char *hexkeyid, found_key = 1; continue; } - + if ( !strcmp (fields[0], "sub") || !strcmp (fields[0], "pub") ) break; /* Next key - stop. */ @@ -1058,7 +1058,7 @@ retrieve_key_material (FILE *fp, const char *hexkeyid, err = gpg_error (GPG_ERR_GENERAL); goto leave; /* Error: Invalid key data record or not an RSA key. */ } - + err = gcry_mpi_scan (&mpi, GCRYMPI_FMT_HEX, fields[3], 0, NULL); if (err) mpi = NULL; @@ -1070,7 +1070,7 @@ retrieve_key_material (FILE *fp, const char *hexkeyid, if (err) goto leave; } - + if (m_new && e_new) { *m = m_new; @@ -1145,10 +1145,10 @@ get_public_key (app_t app, int keyno) le_value = 256; /* Use legacy value. */ } - err = iso7816_read_public_key + err = iso7816_read_public_key (app->slot, exmode, (const unsigned char*)(keyno == 0? "\xB6" : - keyno == 1? "\xB8" : "\xA4"), 2, + keyno == 1? "\xB8" : "\xA4"), 2, le_value, &buffer, &buflen); if (err) @@ -1164,7 +1164,7 @@ get_public_key (app_t app, int keyno) log_error (_("response does not contain the public key data\n")); goto leave; } - + m = find_tlv (keydata, keydatalen, 0x0081, &mlen); if (!m) { @@ -1172,7 +1172,7 @@ get_public_key (app_t app, int keyno) log_error (_("response does not contain the RSA modulus\n")); goto leave; } - + e = find_tlv (keydata, keydatalen, 0x0082, &elen); if (!e) @@ -1275,7 +1275,7 @@ get_public_key (app_t app, int keyno) err = gpg_error_from_syserror (); goto leave; } - + sprintf (keybuf, "(10:public-key(3:rsa(1:n%u:", (unsigned int) mlen); keybuf_p = keybuf + strlen (keybuf); memcpy (keybuf_p, m, mlen); @@ -1286,7 +1286,7 @@ get_public_key (app_t app, int keyno) keybuf_p += elen; strcpy (keybuf_p, ")))"); keybuf_p += strlen (keybuf_p); - + app->app_local->pk[keyno].key = (unsigned char*)keybuf; app->app_local->pk[keyno].keylen = (keybuf_p - keybuf); @@ -1319,7 +1319,7 @@ send_keypair_info (app_t app, ctrl_t ctrl, int keyno) err = get_public_key (app, keyno); if (err) goto leave; - + assert (keyno >= 1 && keyno <= 3); if (!app->app_local->pk[keyno-1].key) goto leave; /* No such key - ignore. */ @@ -1329,19 +1329,19 @@ send_keypair_info (app_t app, ctrl_t ctrl, int keyno) grip); if (err) goto leave; - + bin2hex (grip, 20, gripstr); sprintf (idbuf, "OPENPGP.%d", keyno); - send_status_info (ctrl, "KEYPAIRINFO", - gripstr, 40, - idbuf, strlen (idbuf), + send_status_info (ctrl, "KEYPAIRINFO", + gripstr, 40, + idbuf, strlen (idbuf), NULL, (size_t)0); leave: #endif /* GNUPG_MAJOR_VERSION > 1 */ - return err; + return err; } @@ -1350,7 +1350,7 @@ static gpg_error_t do_learn_status (app_t app, ctrl_t ctrl, unsigned int flags) { (void)flags; - + do_getattr (app, ctrl, "EXTCAP"); do_getattr (app, ctrl, "DISP-NAME"); do_getattr (app, ctrl, "DISP-LANG"); @@ -1533,16 +1533,16 @@ verify_a_chv (app_t app, else prompt = _("||Please enter the PIN"); - + if (!opt.disable_keypad && !iso7816_check_keypad (app->slot, ISO7816_VERIFY, &pininfo) ) { /* The reader supports the verify command through the keypad. Note that the pincb appends a text to the prompt telling the user to use the keypad. */ - rc = pincb (pincb_arg, prompt, NULL); + rc = pincb (pincb_arg, prompt, NULL); prompt = NULL; - xfree (prompt_buffer); + xfree (prompt_buffer); prompt_buffer = NULL; if (rc) { @@ -1559,9 +1559,9 @@ verify_a_chv (app_t app, else { /* The reader has no keypad or we don't want to use it. */ - rc = pincb (pincb_arg, prompt, pinvalue); + rc = pincb (pincb_arg, prompt, pinvalue); prompt = NULL; - xfree (prompt_buffer); + xfree (prompt_buffer); prompt_buffer = NULL; if (rc) { @@ -1569,7 +1569,7 @@ verify_a_chv (app_t app, gpg_strerror (rc)); return rc; } - + if (strlen (*pinvalue) < minlen) { log_error (_("PIN for CHV%d is too short;" @@ -1582,7 +1582,7 @@ verify_a_chv (app_t app, rc = iso7816_verify (app->slot, 0x80+chvno, *pinvalue, strlen (*pinvalue)); } - + if (rc) { log_error (_("verify CHV%d failed: %s\n"), chvno, gpg_strerror (rc)); @@ -1605,14 +1605,14 @@ verify_chv2 (app_t app, int rc; char *pinvalue; - if (app->did_chv2) + if (app->did_chv2) return 0; /* We already verified CHV2. */ rc = verify_a_chv (app, pincb, pincb_arg, 2, 0, &pinvalue); if (rc) return rc; app->did_chv2 = 1; - + if (!app->did_chv1 && !app->force_chv1 && pinvalue) { /* For convenience we verify CHV1 here too. We do this only if @@ -1639,7 +1639,7 @@ verify_chv2 (app_t app, /* Build the prompt to enter the Admin PIN. The prompt depends on the current sdtate of the card. */ -static gpg_error_t +static gpg_error_t build_enter_admin_pin_prompt (app_t app, char **r_prompt) { void *relptr; @@ -1665,7 +1665,7 @@ build_enter_admin_pin_prompt (app_t app, char **r_prompt) } remaining = value[6]; xfree (relptr); - + log_info(_("%d Admin PIN attempts remaining before card" " is permanently locked\n"), remaining); @@ -1678,10 +1678,10 @@ build_enter_admin_pin_prompt (app_t app, char **r_prompt) } else prompt = xtrystrdup (_("|A|Please enter the Admin PIN")); - + if (!prompt) return gpg_error_from_syserror (); - + *r_prompt = prompt; return 0; } @@ -1702,8 +1702,8 @@ verify_chv3 (app_t app, return gpg_error (GPG_ERR_EACCES); } #endif - - if (!app->did_chv3) + + if (!app->did_chv3) { iso7816_pininfo_t pininfo; int minlen = 8; @@ -1721,7 +1721,7 @@ verify_chv3 (app_t app, && !iso7816_check_keypad (app->slot, ISO7816_VERIFY, &pininfo) ) { /* The reader supports the verify command through the keypad. */ - rc = pincb (pincb_arg, prompt, NULL); + rc = pincb (pincb_arg, prompt, NULL); xfree (prompt); prompt = NULL; if (rc) @@ -1738,7 +1738,7 @@ verify_chv3 (app_t app, { char *pinvalue; - rc = pincb (pincb_arg, prompt, &pinvalue); + rc = pincb (pincb_arg, prompt, &pinvalue); xfree (prompt); prompt = NULL; if (rc) @@ -1747,7 +1747,7 @@ verify_chv3 (app_t app, gpg_strerror (rc)); return rc; } - + if (strlen (pinvalue) < minlen) { log_error (_("PIN for CHV%d is too short;" @@ -1755,11 +1755,11 @@ verify_chv3 (app_t app, xfree (pinvalue); return gpg_error (GPG_ERR_BAD_PIN); } - + rc = iso7816_verify (app->slot, 0x83, pinvalue, strlen (pinvalue)); xfree (pinvalue); } - + if (rc) { log_error (_("verify CHV%d failed: %s\n"), 3, gpg_strerror (rc)); @@ -1774,7 +1774,7 @@ verify_chv3 (app_t app, /* Handle the SETATTR operation. All arguments are already basically checked. */ -static gpg_error_t +static gpg_error_t do_setattr (app_t app, const char *name, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg, @@ -1813,7 +1813,7 @@ do_setattr (app_t app, const char *name, for (idx=0; table[idx].name && strcmp (table[idx].name, name); idx++) ; if (!table[idx].name) - return gpg_error (GPG_ERR_INV_NAME); + return gpg_error (GPG_ERR_INV_NAME); if (table[idx].need_v2 && !app->app_local->extcap.is_v2) return gpg_error (GPG_ERR_NOT_SUPPORTED); /* Not yet supported. */ @@ -1864,7 +1864,7 @@ do_setattr (app_t app, const char *name, callback. */ static gpg_error_t do_writecert (app_t app, ctrl_t ctrl, - const char *certidstr, + const char *certidstr, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg, const unsigned char *certdata, size_t certdatalen) @@ -1902,8 +1902,8 @@ do_writecert (app_t app, ctrl_t ctrl, - 2 2 Verify Reset Code and set a new PW1. - 3 any Verify CHV3/PW3 and set a new CHV3/PW3. */ -static gpg_error_t -do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, +static gpg_error_t +do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, unsigned int flags, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg) @@ -1947,7 +1947,7 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, /* On a v1.x card CHV1 and CVH2 should always have the same value, thus we enforce it here. */ int save_force = app->force_chv1; - + app->force_chv1 = 0; app->did_chv1 = 0; app->did_chv2 = 0; @@ -1979,7 +1979,7 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, rc = verify_chv3 (app, pincb, pincb_arg); if (rc) goto leave; - + if (chvno == 2) set_resetcode = 1; } @@ -2244,7 +2244,7 @@ does_key_exist (app_t app, int keyidx, int generating, int force) of tag and length. A LENGTH greater than 65535 is truncated. */ static size_t add_tlv (unsigned char *buffer, unsigned int tag, size_t length) -{ +{ unsigned char *p = buffer; assert (tag <= 0xffff); @@ -2370,15 +2370,15 @@ build_privkey_template (app_t app, int keyno, /* Right justify E. */ memmove (tp + rsa_e_reqlen - rsa_e_len, tp, rsa_e_len); memset (tp, 0, rsa_e_reqlen - rsa_e_len); - } + } tp += rsa_e_reqlen; - + memcpy (tp, rsa_p, rsa_p_len); tp += rsa_p_len; - + memcpy (tp, rsa_q, rsa_q_len); tp += rsa_q_len; - + if (app->app_local->keyattr[keyno].format == RSA_STD_N || app->app_local->keyattr[keyno].format == RSA_CRT_N) { @@ -2423,7 +2423,7 @@ change_keyattr (app_t app, int keyno, unsigned int nbits, xfree (relptr); return gpg_error (GPG_ERR_CARD); } - + /* We only change n_bits and don't touch anything else. Before we do so, we round up NBITS to a sensible way in the same way as gpg's key generation does it. This may help to sort out problems @@ -2458,8 +2458,8 @@ change_keyattr (app_t app, int keyno, unsigned int nbits, /* Helper to process an setattr command for name KEY-ATTR. It expects a string "--force " in (VALUE,VALUELEN). */ -static gpg_error_t -change_keyattr_from_string (app_t app, +static gpg_error_t +change_keyattr_from_string (app_t app, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg, const void *value, size_t valuelen) @@ -2539,13 +2539,13 @@ do_writekey (app_t app, ctrl_t ctrl, keyno = 2; else return gpg_error (GPG_ERR_INV_ID); - + err = does_key_exist (app, keyno, 0, force); if (err) return err; - /* + /* Parse the S-expression */ buf = keydata; @@ -2593,10 +2593,10 @@ do_writekey (app_t app, ctrl_t ctrl, switch (*tok) { - case 'n': mpi = &rsa_n; mpi_len = &rsa_n_len; break; - case 'e': mpi = &rsa_e; mpi_len = &rsa_e_len; break; - case 'p': mpi = &rsa_p; mpi_len = &rsa_p_len; break; - case 'q': mpi = &rsa_q; mpi_len = &rsa_q_len;break; + case 'n': mpi = &rsa_n; mpi_len = &rsa_n_len; break; + case 'e': mpi = &rsa_e; mpi_len = &rsa_e_len; break; + case 'p': mpi = &rsa_p; mpi_len = &rsa_p_len; break; + case 'q': mpi = &rsa_q; mpi_len = &rsa_q_len;break; default: mpi = NULL; mpi_len = NULL; break; } if (mpi && *mpi) @@ -2668,7 +2668,7 @@ do_writekey (app_t app, ctrl_t ctrl, maxbits = app->app_local->keyattr[keyno].n_bits; nbits = rsa_n? count_bits (rsa_n, rsa_n_len) : 0; if (opt.verbose) - log_info ("RSA modulus size is %u bits (%u bytes)\n", + log_info ("RSA modulus size is %u bits (%u bytes)\n", nbits, (unsigned int)rsa_n_len); if (nbits && nbits != maxbits && app->app_local->extcap.algo_attr_change) @@ -2680,7 +2680,7 @@ do_writekey (app_t app, ctrl_t ctrl, } if (nbits != maxbits) { - log_error (_("RSA modulus missing or not of size %d bits\n"), + log_error (_("RSA modulus missing or not of size %d bits\n"), (int)maxbits); err = gpg_error (GPG_ERR_BAD_SECKEY); goto leave; @@ -2702,7 +2702,7 @@ do_writekey (app_t app, ctrl_t ctrl, nbits = rsa_p? count_bits (rsa_p, rsa_p_len) : 0; if (nbits != maxbits) { - log_error (_("RSA prime %s missing or not of size %d bits\n"), + log_error (_("RSA prime %s missing or not of size %d bits\n"), "P", (int)maxbits); err = gpg_error (GPG_ERR_BAD_SECKEY); goto leave; @@ -2710,12 +2710,12 @@ do_writekey (app_t app, ctrl_t ctrl, nbits = rsa_q? count_bits (rsa_q, rsa_q_len) : 0; if (nbits != maxbits) { - log_error (_("RSA prime %s missing or not of size %d bits\n"), + log_error (_("RSA prime %s missing or not of size %d bits\n"), "Q", (int)maxbits); err = gpg_error (GPG_ERR_BAD_SECKEY); goto leave; } - + /* We need to remove the cached public key. */ xfree (app->app_local->pk[keyno].key); app->app_local->pk[keyno].key = NULL; @@ -2728,7 +2728,7 @@ do_writekey (app_t app, ctrl_t ctrl, /* Build the private key template as described in section 4.3.3.7 of the OpenPGP card specs version 2.0. */ int exmode; - + err = build_privkey_template (app, keyno, rsa_n, rsa_n_len, rsa_e, rsa_e_len, @@ -2758,8 +2758,8 @@ do_writekey (app_t app, ctrl_t ctrl, /* Build the private key template as described in section 4.3.3.6 of the OpenPGP card specs version 1.1: 0xC0 public exponent - 0xC1 prime p - 0xC2 prime q + 0xC1 prime p + 0xC2 prime q */ assert (rsa_e_len <= 4); template_len = (1 + 1 + 4 @@ -2779,21 +2779,21 @@ do_writekey (app_t app, ctrl_t ctrl, /* Right justify E. */ memmove (tp+4-rsa_e_len, tp, rsa_e_len); memset (tp, 0, 4-rsa_e_len); - } + } tp += 4; - + *tp++ = 0xC1; *tp++ = rsa_p_len; memcpy (tp, rsa_p, rsa_p_len); tp += rsa_p_len; - + *tp++ = 0xC2; *tp++ = rsa_q_len; memcpy (tp, rsa_q, rsa_q_len); tp += rsa_q_len; - + assert (tp - template == template_len); - + /* Prepare for storing the key. */ err = verify_chv3 (app, pincb, pincb_arg); if (err) @@ -2809,7 +2809,7 @@ do_writekey (app_t app, ctrl_t ctrl, log_error (_("failed to store the key: %s\n"), gpg_strerror (err)); goto leave; } - + err = store_fpr (app, keyno, created_at, rsa_n, rsa_n_len, rsa_e, rsa_e_len, fprbuf, app->card_version); @@ -2824,7 +2824,7 @@ do_writekey (app_t app, ctrl_t ctrl, /* Handle the GENKEY command. */ -static gpg_error_t +static gpg_error_t do_genkey (app_t app, ctrl_t ctrl, const char *keynostr, unsigned int flags, time_t createtime, gpg_error_t (*pincb)(void*, const char *, char **), @@ -2842,7 +2842,7 @@ do_genkey (app_t app, ctrl_t ctrl, const char *keynostr, unsigned int flags, time_t start_at; int exmode; int le_value; - unsigned int keybits; + unsigned int keybits; if (keyno < 1 || keyno > 3) return gpg_error (GPG_ERR_INV_ID); @@ -2866,7 +2866,7 @@ do_genkey (app_t app, ctrl_t ctrl, const char *keynostr, unsigned int flags, /* Because we send the key parameter back via status lines we need to put a limit on the max. allowed keysize. 2048 bit will already lead to a 527 byte long status line and thus a 4096 bit - key would exceed the Assuan line length limit. */ + key would exceed the Assuan line length limit. */ keybits = app->app_local->keyattr[keyno].n_bits; if (keybits > 4096) return gpg_error (GPG_ERR_TOO_LARGE); @@ -2884,7 +2884,7 @@ do_genkey (app_t app, ctrl_t ctrl, const char *keynostr, unsigned int flags, le_value = app->app_local->extcap.max_rsp_data; /* No need to check le_value because it comes from a 16 bit value and thus can't create an overflow on a 32 bit - system. */ + system. */ } else { @@ -2894,10 +2894,10 @@ do_genkey (app_t app, ctrl_t ctrl, const char *keynostr, unsigned int flags, log_info (_("please wait while key is being generated ...\n")); start_at = time (NULL); - rc = iso7816_generate_keypair + rc = iso7816_generate_keypair /* # warning key generation temporary replaced by reading an existing key. */ /* rc = iso7816_read_public_key */ - (app->slot, exmode, + (app->slot, exmode, (const unsigned char*)(keyno == 0? "\xB6" : keyno == 1? "\xB8" : "\xA4"), 2, le_value, @@ -2918,7 +2918,7 @@ do_genkey (app_t app, ctrl_t ctrl, const char *keynostr, unsigned int flags, log_error (_("response does not contain the public key data\n")); goto leave; } - + m = find_tlv (keydata, keydatalen, 0x0081, &mlen); if (!m) { @@ -2995,7 +2995,7 @@ compare_fingerprint (app_t app, int keyno, unsigned char *sha1fpr) unsigned char *buffer; size_t buflen, n; int rc, i; - + assert (keyno >= 1 && keyno <= 3); rc = get_cached_data (app, 0x006E, &buffer, &buflen, 0, 0); @@ -3059,12 +3059,12 @@ check_against_given_fingerprint (app_t app, const char *fpr, int keyno) Note that this function may return the error code GPG_ERR_WRONG_CARD to indicate that the card currently present does not match the one required for the requested action (e.g. the - serial number does not match). - + serial number does not match). + As a special feature a KEYIDSTR of "OPENPGP.3" redirects the operation to the auth command. */ -static gpg_error_t +static gpg_error_t do_sign (app_t app, const char *keyidstr, int hashalgo, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg, @@ -3116,7 +3116,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo, { \ indata = (const char*)indata + sizeof b ## _prefix; \ indatalen -= sizeof b ## _prefix; \ - } + } if (indatalen == 20) ; /* Assume a plain SHA-1 or RMD160 digest has been given. */ @@ -3126,7 +3126,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo, else X(SHA256, sha256, 32, app->app_local->extcap.is_v2) else X(SHA384, sha384, 48, app->app_local->extcap.is_v2) else X(SHA512, sha512, 64, app->app_local->extcap.is_v2) - else if ((indatalen == 28 || indatalen == 32 + else if ((indatalen == 28 || indatalen == 32 || indatalen == 48 || indatalen ==64) && app->app_local->extcap.is_v2) ; /* Assume a plain SHA-3 digest has been given. */ @@ -3155,7 +3155,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo, else if (!*s) ; /* no fingerprint given: we allow this for now. */ else if (*s == '/') - fpr = s + 1; + fpr = s + 1; else return gpg_error (GPG_ERR_INV_ID); @@ -3186,7 +3186,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo, assert (datalen <= sizeof data); \ memcpy (data, b ## _prefix, sizeof b ## _prefix); \ memcpy (data + sizeof b ## _prefix, indata, indatalen); \ - } + } X(SHA1, sha1, 1) else X(RMD160, rmd160, 1) @@ -3194,7 +3194,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo, else X(SHA256, sha256, app->app_local->extcap.is_v2) else X(SHA384, sha384, app->app_local->extcap.is_v2) else X(SHA512, sha512, app->app_local->extcap.is_v2) - else + else return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); #undef X @@ -3211,7 +3211,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo, log_info (_("signatures created so far: %lu\n"), sigcount); /* Check CHV if needed. */ - if (!app->did_chv1 || app->force_chv1 ) + if (!app->did_chv1 || app->force_chv1 ) { char *pinvalue; @@ -3252,7 +3252,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo, else { exmode = 0; - le_value = 0; + le_value = 0; } rc = iso7816_compute_ds (app->slot, exmode, data, datalen, le_value, outdata, outdatalen); @@ -3269,7 +3269,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo, GPG_ERR_WRONG_CARD to indicate that the card currently present does not match the one required for the requested action (e.g. the serial number does not match). */ -static gpg_error_t +static gpg_error_t do_auth (app_t app, const char *keyidstr, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg, @@ -3301,13 +3301,13 @@ do_auth (app_t app, const char *keyidstr, else if (!*s) ; /* no fingerprint given: we allow this for now. */ else if (*s == '/') - fpr = s + 1; + fpr = s + 1; else return gpg_error (GPG_ERR_INV_ID); for (s=keyidstr, n=0; n < 16; s += 2, n++) tmp_sn[n] = xtoi_2 (s); - + if (app->serialnolen != 16) return gpg_error (GPG_ERR_INV_CARD); if (memcmp (app->serialno, tmp_sn, 16)) @@ -3337,7 +3337,7 @@ do_auth (app_t app, const char *keyidstr, else { exmode = 0; - le_value = 0; + le_value = 0; } rc = iso7816_internal_authenticate (app->slot, exmode, indata, indatalen, le_value, @@ -3347,7 +3347,7 @@ do_auth (app_t app, const char *keyidstr, } -static gpg_error_t +static gpg_error_t do_decipher (app_t app, const char *keyidstr, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg, @@ -3378,13 +3378,13 @@ do_decipher (app_t app, const char *keyidstr, else if (!*s) ; /* no fingerprint given: we allow this for now. */ else if (*s == '/') - fpr = s + 1; + fpr = s + 1; else return gpg_error (GPG_ERR_INV_ID); - + for (s=keyidstr, n=0; n < 16; s += 2, n++) tmp_sn[n] = xtoi_2 (s); - + if (app->serialnolen != 16) return gpg_error (GPG_ERR_INV_CARD); if (memcmp (app->serialno, tmp_sn, 16)) @@ -3437,7 +3437,7 @@ do_decipher (app_t app, const char *keyidstr, fixbuf = xtrymalloc (fixuplen + indatalen); if (!fixbuf) return gpg_error_from_syserror (); - + memset (fixbuf, 0, fixuplen); memcpy (fixbuf+fixuplen, indata, indatalen); indata = fixbuf; @@ -3456,9 +3456,9 @@ do_decipher (app_t app, const char *keyidstr, le_value = 0; } else - exmode = le_value = 0; + exmode = le_value = 0; - rc = iso7816_decipher (app->slot, exmode, + rc = iso7816_decipher (app->slot, exmode, indata, indatalen, le_value, padind, outdata, outdatalen); xfree (fixbuf); @@ -3478,12 +3478,12 @@ do_decipher (app_t app, const char *keyidstr, There is a special mode if the keyidstr is "[CHV3]" with the "[CHV3]" being a literal string: The Admin Pin is checked if and only if the retry counter is still at 3. */ -static gpg_error_t +static gpg_error_t do_check_pin (app_t app, const char *keyidstr, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg) { - unsigned char tmp_sn[20]; + unsigned char tmp_sn[20]; const char *s; int n; int admin_pin = 0; @@ -3494,7 +3494,7 @@ do_check_pin (app_t app, const char *keyidstr, /* Check whether an OpenPGP card of any version has been requested. */ if (strlen (keyidstr) < 32 || strncmp (keyidstr, "D27600012401", 12)) return gpg_error (GPG_ERR_INV_ID); - + for (s=keyidstr, n=0; hexdigitp (s); s++, n++) ; if (n != 32) @@ -3527,7 +3527,7 @@ do_check_pin (app_t app, const char *keyidstr, unsigned char *value; size_t valuelen; int count; - + relptr = get_one_do (app, 0x00C4, &value, &valuelen, NULL); if (!relptr || valuelen < 7) { @@ -3588,7 +3588,7 @@ show_caps (struct app_local_s *s) /* Parse the historical bytes in BUFFER of BUFLEN and store them in APPLOC. */ static void -parse_historical (struct app_local_s *apploc, +parse_historical (struct app_local_s *apploc, const unsigned char * buffer, size_t buflen) { /* Example buffer: 00 31 C5 73 C0 01 80 00 90 00 */ @@ -3600,9 +3600,9 @@ parse_historical (struct app_local_s *apploc, if (*buffer) { log_error ("warning: bad category indicator in historical bytes\n"); - return; + return; } - + /* Skip category indicator. */ buffer++; buflen--; @@ -3637,9 +3637,9 @@ parse_historical (struct app_local_s *apploc, /* Parse and optionally show the algorithm attributes for KEYNO. KEYNO must be in the range 0..2. */ -static void +static void parse_algorithm_attribute (app_t app, int keyno) -{ +{ unsigned char *buffer; size_t buflen; void *relptr; @@ -3648,7 +3648,7 @@ parse_algorithm_attribute (app_t app, int keyno) assert (keyno >=0 && keyno <= 2); app->app_local->keyattr[keyno].n_bits = 0; - + relptr = get_one_do (app, 0xC1+keyno, &buffer, &buflen, NULL); if (!relptr) { @@ -3675,7 +3675,7 @@ parse_algorithm_attribute (app_t app, int keyno) app->app_local->keyattr[keyno].format = (buffer[5] == 0? RSA_STD : buffer[5] == 1? RSA_STD_N : buffer[5] == 2? RSA_CRT : - buffer[5] == 3? RSA_CRT_N : + buffer[5] == 3? RSA_CRT_N : RSA_UNKNOWN_FMT); if (opt.verbose) @@ -3705,7 +3705,7 @@ app_select_openpgp (app_t app) unsigned char *buffer; size_t buflen; void *relptr; - + /* Note that the card can't cope with P2=0xCO, thus we need to pass a special flag value. */ rc = iso7816_select_application (slot, aid, sizeof aid, 0x0001); @@ -3798,7 +3798,7 @@ app_select_openpgp (app_t app) { /* Available with v2 cards. */ app->app_local->extcap.sm_aes128 = (buffer[1] == 1); - app->app_local->extcap.max_get_challenge + app->app_local->extcap.max_get_challenge = (buffer[2] << 8 | buffer[3]); app->app_local->extcap.max_certlen_3 = (buffer[4] << 8 | buffer[5]); app->app_local->extcap.max_cmd_data = (buffer[6] << 8 | buffer[7]); @@ -3819,7 +3819,7 @@ app_select_openpgp (app_t app) parse_algorithm_attribute (app, 0); parse_algorithm_attribute (app, 1); parse_algorithm_attribute (app, 2); - + if (opt.verbose > 1) dump_all_do (slot); diff --git a/scd/command.c b/scd/command.c index 227057e..6053fc6 100644 --- a/scd/command.c +++ b/scd/command.c @@ -76,7 +76,7 @@ static int reader_disabled; /* This structure is used to keep track of open readers (slots). */ -struct slot_status_s +struct slot_status_s { int valid; /* True if the other objects are valid. */ int slot; /* Slot number of the reader or -1 if not open. */ @@ -93,11 +93,11 @@ struct slot_status_s /* Data used to associate an Assuan context with local server data. This object describes the local properties of one session. */ -struct server_local_s +struct server_local_s { /* We keep a list of all active sessions with the anchor at SESSION_LIST (see below). This field is used for linking. */ - struct server_local_s *next_session; + struct server_local_s *next_session; /* This object is usually assigned to a CTRL object (which is globally visible). While enumerating all sessions we sometimes @@ -113,10 +113,10 @@ struct server_local_s #else int event_signal; /* Or 0 if not used. */ #endif - + /* True if the card has been removed and a reset is required to continue operation. */ - int card_removed; + int card_removed; /* Flag indicating that the application context needs to be released at the next opportunity. */ @@ -127,7 +127,7 @@ struct server_local_s /* If set to true we will be terminate ourself at the end of the this session. */ - int stopme; + int stopme; }; @@ -260,7 +260,7 @@ hex_to_buffer (const char *string, size_t *r_length) return NULL; for (s=string, n=0; *s; s++) { - if (spacep (s) || *s == ':') + if (spacep (s) || *s == ':') continue; if (hexdigitp (s) && hexdigitp (s+1)) { @@ -297,7 +297,7 @@ do_reset (ctrl_t ctrl, int send_reset) if (send_reset) { struct server_local_s *sl; - + for (sl=session_list; sl; sl = sl->next_session) if (sl->ctrl_backlink && sl->ctrl_backlink->reader_slot == slot) @@ -357,7 +357,7 @@ do_reset (ctrl_t ctrl, int send_reset) static gpg_error_t reset_notify (assuan_context_t ctx, char *line) { - ctrl_t ctrl = assuan_get_pointer (ctx); + ctrl_t ctrl = assuan_get_pointer (ctx); (void) line; @@ -503,7 +503,7 @@ open_card (ctrl_t ctrl, const char *apptype) } -static const char hlp_serialno[] = +static const char hlp_serialno[] = "SERIALNO []\n" "\n" "Return the serial number of the card using a status reponse. This\n" @@ -565,7 +565,7 @@ cmd_serialno (assuan_context_t ctx, char *line) } -static const char hlp_learn[] = +static const char hlp_learn[] = "LEARN [--force] [--keypairinfo]\n" "\n" "Learn all useful information of the currently inserted card. When\n" @@ -653,7 +653,7 @@ cmd_learn (assuan_context_t ctx, char *line) char *serial_and_stamp; char *serial; time_t stamp; - + rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp); if (rc) return rc; @@ -664,11 +664,11 @@ cmd_learn (assuan_context_t ctx, char *line) return out_of_core (); rc = 0; assuan_write_status (ctx, "SERIALNO", serial_and_stamp); - + if (!has_option (line, "--force")) { char *command; - + rc = estream_asprintf (&command, "KNOWNCARDP %s", serial_and_stamp); if (rc < 0) { @@ -676,7 +676,7 @@ cmd_learn (assuan_context_t ctx, char *line) return out_of_core (); } rc = 0; - rc = assuan_inquire (ctx, command, NULL, NULL, 0); + rc = assuan_inquire (ctx, command, NULL, NULL, 0); xfree (command); if (rc) { @@ -684,13 +684,13 @@ cmd_learn (assuan_context_t ctx, char *line) log_error ("inquire KNOWNCARDP failed: %s\n", gpg_strerror (rc)); xfree (serial_and_stamp); - return rc; + return rc; } /* Not canceled, so we have to proceeed. */ } xfree (serial_and_stamp); } - + /* Let the application print out its collection of useful status information. */ if (!rc) @@ -736,7 +736,7 @@ cmd_readcert (assuan_context_t ctx, char *line) } -static const char hlp_readkey[] = +static const char hlp_readkey[] = "READKEY \n" "\n" "Return the public key for the given cert or key ID as a standard\n" @@ -774,7 +774,7 @@ cmd_readkey (assuan_context_t ctx, char *line) if (gpg_err_code (rc) != GPG_ERR_UNSUPPORTED_OPERATION) log_error ("app_readkey failed: %s\n", gpg_strerror (rc)); - else + else { rc = app_readcert (ctrl->app_ctx, line, &cert, &ncert); if (rc) @@ -784,7 +784,7 @@ cmd_readkey (assuan_context_t ctx, char *line) line = NULL; if (rc) goto leave; - + rc = ksba_cert_new (&kc); if (rc) { @@ -819,7 +819,7 @@ cmd_readkey (assuan_context_t ctx, char *line) -static const char hlp_setdata[] = +static const char hlp_setdata[] = "SETDATA \n" "\n" "The client should use this command to tell us the data he want to sign."; @@ -857,7 +857,7 @@ cmd_setdata (assuan_context_t ctx, char *line) -static gpg_error_t +static gpg_error_t pin_cb (void *opaque, const char *info, char **retstr) { assuan_context_t ctx = opaque; @@ -877,14 +877,14 @@ pin_cb (void *opaque, const char *info, char **retstr) rc = estream_asprintf (&command, "POPUPKEYPADPROMPT %s", info); if (rc < 0) return gpg_error (gpg_err_code_from_errno (errno)); - rc = assuan_inquire (ctx, command, &value, &valuelen, MAXLEN_PIN); - xfree (command); + rc = assuan_inquire (ctx, command, &value, &valuelen, MAXLEN_PIN); + xfree (command); } else { log_debug ("dismiss keypad entry prompt\n"); rc = assuan_inquire (ctx, "DISMISSKEYPADPROMPT", - &value, &valuelen, MAXLEN_PIN); + &value, &valuelen, MAXLEN_PIN); } if (!rc) xfree (value); @@ -900,8 +900,8 @@ pin_cb (void *opaque, const char *info, char **retstr) /* Fixme: Write an inquire function which returns the result in secure memory and check all further handling of the PIN. */ - rc = assuan_inquire (ctx, command, &value, &valuelen, MAXLEN_PIN); - xfree (command); + rc = assuan_inquire (ctx, command, &value, &valuelen, MAXLEN_PIN); + xfree (command); if (rc) return rc; @@ -916,7 +916,7 @@ pin_cb (void *opaque, const char *info, char **retstr) } -static const char hlp_pksign[] = +static const char hlp_pksign[] = "PKSIGN [--hash=[rmd160|sha{1,224,256,384,512}|md5]] \n" "\n" "The --hash option is optional; the default is SHA1."; @@ -945,7 +945,7 @@ cmd_pksign (assuan_context_t ctx, char *line) else if (has_option (line, "--hash=md5")) hash_algo = GCRY_MD_MD5; else if (!strstr (line, "--")) - hash_algo = GCRY_MD_SHA1; + hash_algo = GCRY_MD_SHA1; else return set_error (GPG_ERR_ASS_PARAMETER, "invalid hash algorithm"); @@ -963,7 +963,7 @@ cmd_pksign (assuan_context_t ctx, char *line) keyidstr = xtrystrdup (line); if (!keyidstr) return out_of_core (); - + rc = app_sign (ctrl->app_ctx, keyidstr, hash_algo, pin_cb, ctx, @@ -988,7 +988,7 @@ cmd_pksign (assuan_context_t ctx, char *line) } -static const char hlp_pkauth[] = +static const char hlp_pkauth[] = "PKAUTH "; static gpg_error_t cmd_pkauth (assuan_context_t ctx, char *line) @@ -1014,7 +1014,7 @@ cmd_pkauth (assuan_context_t ctx, char *line) keyidstr = xtrystrdup (line); if (!keyidstr) return out_of_core (); - + rc = app_auth (ctrl->app_ctx, keyidstr, pin_cb, ctx, @@ -1038,7 +1038,7 @@ cmd_pkauth (assuan_context_t ctx, char *line) } -static const char hlp_pkdecrypt[] = +static const char hlp_pkdecrypt[] = "PKDECRYPT "; static gpg_error_t cmd_pkdecrypt (assuan_context_t ctx, char *line) @@ -1059,7 +1059,7 @@ cmd_pkdecrypt (assuan_context_t ctx, char *line) if (!keyidstr) return out_of_core (); rc = app_decipher (ctrl->app_ctx, - keyidstr, + keyidstr, pin_cb, ctx, ctrl->in_data.value, ctrl->in_data.valuelen, &outdata, &outdatalen); @@ -1082,7 +1082,7 @@ cmd_pkdecrypt (assuan_context_t ctx, char *line) } -static const char hlp_getattr[] = +static const char hlp_getattr[] = "GETATTR \n" "\n" "This command is used to retrieve data from a smartcard. The\n" @@ -1121,7 +1121,7 @@ cmd_getattr (assuan_context_t ctx, char *line) } -static const char hlp_setattr[] = +static const char hlp_setattr[] = "SETATTR \n" "\n" "This command is used to store data on a a smartcard. The allowed\n" @@ -1174,7 +1174,7 @@ cmd_setattr (assuan_context_t ctx, char *orig_line) } -static const char hlp_writecert[] = +static const char hlp_writecert[] = "WRITECERT \n" "\n" "This command is used to store a certifciate on a smartcard. The\n" @@ -1226,7 +1226,7 @@ cmd_writecert (assuan_context_t ctx, char *line) } /* Write the certificate to the card. */ - rc = app_writecert (ctrl->app_ctx, ctrl, certid, + rc = app_writecert (ctrl->app_ctx, ctrl, certid, pin_cb, ctx, certdata, certdatalen); xfree (certid); xfree (certdata); @@ -1236,7 +1236,7 @@ cmd_writecert (assuan_context_t ctx, char *line) } -static const char hlp_writekey[] = +static const char hlp_writekey[] = "WRITEKEY [--force] \n" "\n" "This command is used to store a secret key on a a smartcard. The\n" @@ -1303,7 +1303,7 @@ cmd_writekey (assuan_context_t ctx, char *line) } -static const char hlp_genkey[] = +static const char hlp_genkey[] = "GENKEY [--force] [--timestamp=] \n" "\n" "Generate a key on-card identified by NO, which is application\n" @@ -1381,7 +1381,7 @@ cmd_genkey (assuan_context_t ctx, char *line) } -static const char hlp_random[] = +static const char hlp_random[] = "RANDOM \n" "\n" "Get NBYTES of random from the card and send them back as data.\n" @@ -1398,7 +1398,7 @@ cmd_random (assuan_context_t ctx, char *line) unsigned char *buffer; if (!*line) - return set_error (GPG_ERR_ASS_PARAMETER, + return set_error (GPG_ERR_ASS_PARAMETER, "number of requested bytes missing"); nbytes = strtoul (line, NULL, 0); @@ -1464,7 +1464,7 @@ cmd_passwd (assuan_context_t ctx, char *line) if (!ctrl->app_ctx) return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - + chvnostr = xtrystrdup (chvnostr); if (!chvnostr) return out_of_core (); @@ -1478,7 +1478,7 @@ cmd_passwd (assuan_context_t ctx, char *line) } -static const char hlp_checkpin[] = +static const char hlp_checkpin[] = "CHECKPIN \n" "\n" "Perform a VERIFY operation without doing anything else. This may\n" @@ -1532,7 +1532,7 @@ cmd_checkpin (assuan_context_t ctx, char *line) idstr = xtrystrdup (line); if (!idstr) return out_of_core (); - + rc = app_check_pin (ctrl->app_ctx, idstr, pin_cb, ctx); xfree (idstr); if (rc) @@ -1543,7 +1543,7 @@ cmd_checkpin (assuan_context_t ctx, char *line) } -static const char hlp_lock[] = +static const char hlp_lock[] = "LOCK [--wait]\n" "\n" "Grant exclusive card access to this session. Note that there is\n" @@ -1580,14 +1580,14 @@ cmd_lock (assuan_context_t ctx, char *line) goto retry; } #endif /*USE_GNU_PTH*/ - + if (rc) log_error ("cmd_lock failed: %s\n", gpg_strerror (rc)); return rc; } -static const char hlp_unlock[] = +static const char hlp_unlock[] = "UNLOCK\n" "\n" "Release exclusive card access."; @@ -1615,7 +1615,7 @@ cmd_unlock (assuan_context_t ctx, char *line) } -static const char hlp_getinfo[] = +static const char hlp_getinfo[] = "GETINFO \n" "\n" "Multi purpose command to return certain information. \n" @@ -1677,7 +1677,7 @@ cmd_getinfo (assuan_context_t ctx, char *line) if (!ctrl->server_local->card_removed && slot != -1) { struct slot_status_s *ss; - + if (!(slot >= 0 && slot < DIM(slot_table))) BUG (); @@ -1695,7 +1695,7 @@ cmd_getinfo (assuan_context_t ctx, char *line) #else char *s = NULL; #endif - + if (s) rc = assuan_send_data (ctx, s, strlen (s)); else @@ -1719,7 +1719,7 @@ cmd_getinfo (assuan_context_t ctx, char *line) } -static const char hlp_restart[] = +static const char hlp_restart[] = "RESTART\n" "\n" "Restart the current connection; this is a kind of warm reset. It\n" @@ -1750,7 +1750,7 @@ cmd_restart (assuan_context_t ctx, char *line) } -static const char hlp_disconnect[] = +static const char hlp_disconnect[] = "DISCONNECT\n" "\n" "Disconnect the card if it is not any longer used by other\n" @@ -1761,14 +1761,14 @@ cmd_disconnect (assuan_context_t ctx, char *line) ctrl_t ctrl = assuan_get_pointer (ctx); (void)line; - + ctrl->server_local->disconnect_allowed = 1; return 0; } -static const char hlp_apdu[] = +static const char hlp_apdu[] = "APDU [--atr] [--more] [--exlen[=N]] [hexstring]\n" "\n" "Send an APDU to the current reader. This command bypasses the high\n" @@ -1825,7 +1825,7 @@ cmd_apdu (assuan_context_t ctx, char *line) unsigned char *atr; size_t atrlen; char hexbuf[400]; - + atr = apdu_get_atr (ctrl->reader_slot, &atrlen); if (!atr || atrlen > sizeof hexbuf - 2 ) { @@ -1867,7 +1867,7 @@ cmd_apdu (assuan_context_t ctx, char *line) } -static const char hlp_killscd[] = +static const char hlp_killscd[] = "KILLSCD\n" "\n" "Commit suicide."; @@ -1901,8 +1901,8 @@ register_commands (assuan_context_t ctx) { "PKSIGN", cmd_pksign, hlp_pksign }, { "PKAUTH", cmd_pkauth, hlp_pkauth }, { "PKDECRYPT", cmd_pkdecrypt,hlp_pkdecrypt }, - { "INPUT", NULL }, - { "OUTPUT", NULL }, + { "INPUT", NULL }, + { "OUTPUT", NULL }, { "GETATTR", cmd_getattr, hlp_getattr }, { "SETATTR", cmd_setattr, hlp_setattr }, { "WRITECERT", cmd_writecert,hlp_writecert }, @@ -1928,7 +1928,7 @@ register_commands (assuan_context_t ctx) table[i].help); if (rc) return rc; - } + } assuan_set_hello_line (ctx, "GNU Privacy Guard's Smartcard server ready"); assuan_register_reset_notify (ctx, reset_notify); @@ -1946,7 +1946,7 @@ scd_command_handler (ctrl_t ctrl, int fd) int rc; assuan_context_t ctx = NULL; int stopme; - + rc = assuan_new (&ctx); if (rc) { @@ -2014,7 +2014,7 @@ scd_command_handler (ctrl_t ctrl, int fd) log_info ("Assuan accept problem: %s\n", gpg_strerror (rc)); break; } - + rc = assuan_process (ctx); if (rc) { @@ -2024,7 +2024,7 @@ scd_command_handler (ctrl_t ctrl, int fd) } /* Cleanup. We don't send an explicit reset to the card. */ - do_reset (ctrl, 0); + do_reset (ctrl, 0); /* Release the server object. */ if (session_list == ctrl->server_local) @@ -2032,7 +2032,7 @@ scd_command_handler (ctrl_t ctrl, int fd) else { struct server_local_s *sl; - + for (sl=session_list; sl->next_session; sl = sl->next_session) if (sl->next_session == ctrl->server_local) break; @@ -2067,10 +2067,10 @@ send_status_info (ctrl_t ctrl, const char *keyword, ...) char buf[950], *p; size_t n; assuan_context_t ctx = ctrl->server_local->assuan_ctx; - + va_start (arg_ptr, keyword); - p = buf; + p = buf; n = 0; while ( (value = va_arg (arg_ptr, const unsigned char *)) ) { @@ -2120,17 +2120,17 @@ static void send_client_notifications (void) { struct { - pid_t pid; + pid_t pid; #ifdef HAVE_W32_SYSTEM HANDLE handle; #else - int signo; + int signo; #endif } killed[50]; int killidx = 0; int kidx; struct server_local_s *sl; - + for (sl=session_list; sl; sl = sl->next_session) { if (sl->event_signal && sl->assuan_ctx) @@ -2138,9 +2138,9 @@ send_client_notifications (void) pid_t pid = assuan_get_pid (sl->assuan_ctx); #ifdef HAVE_W32_SYSTEM HANDLE handle = (void *)sl->event_signal; - + for (kidx=0; kidx < killidx; kidx++) - if (killed[kidx].pid == pid + if (killed[kidx].pid == pid && killed[kidx].handle == handle) break; if (kidx < killidx) @@ -2162,11 +2162,11 @@ send_client_notifications (void) } #else /*!HAVE_W32_SYSTEM*/ int signo = sl->event_signal; - + if (pid != (pid_t)(-1) && pid && signo > 0) { for (kidx=0; kidx < killidx; kidx++) - if (killed[kidx].pid == pid + if (killed[kidx].pid == pid && killed[kidx].signo == signo) break; if (kidx < killidx) @@ -2217,7 +2217,7 @@ update_reader_status_file (int set_card_removed_flag) if (!ss->valid || ss->slot == -1) continue; /* Not valid or reader not yet open. */ - + sw_apdu = apdu_get_status (ss->slot, 0, &status, &changed); if (sw_apdu == SW_HOST_NO_READER) { @@ -2231,7 +2231,7 @@ update_reader_status_file (int set_card_removed_flag) else if (sw_apdu) { /* Get status failed. Ignore that. */ - continue; + continue; } if (!ss->any || ss->status != status || ss->changed != changed ) @@ -2260,14 +2260,14 @@ update_reader_status_file (int set_card_removed_flag) fclose (fp); } xfree (fname); - + /* If a status script is executable, run it. */ { const char *args[9], *envs[2]; char numbuf1[30], numbuf2[30], numbuf3[30]; char *homestr, *envstr; gpg_error_t err; - + homestr = make_filename (opt.homedir, NULL); if (estream_asprintf (&envstr, "GNUPGHOME=%s", homestr) < 0) log_error ("out of core while building environment\n"); @@ -2280,16 +2280,16 @@ update_reader_status_file (int set_card_removed_flag) sprintf (numbuf2, "0x%04X", ss->status); sprintf (numbuf3, "0x%04X", status); args[0] = "--reader-port"; - args[1] = numbuf1; + args[1] = numbuf1; args[2] = "--old-code"; - args[3] = numbuf2; + args[3] = numbuf2; args[4] = "--new-code"; - args[5] = numbuf3; + args[5] = numbuf3; args[6] = "--status"; args[7] = ((status & 1)? "USABLE": (status & 4)? "ACTIVE": (status & 2)? "PRESENT": "NOCARD"); - args[8] = NULL; + args[8] = NULL; fname = make_filename (opt.homedir, "scd-event", NULL); err = gnupg_spawn_process_detached (fname, args, envs); @@ -2307,19 +2307,19 @@ update_reader_status_file (int set_card_removed_flag) SERIALNO request must be done in any case. */ if (ss->any && set_card_removed_flag) update_card_removed (idx, 1); - + ss->any = 1; /* Send a signal to all clients who applied for it. */ send_client_notifications (); } - + /* Check whether a disconnect is pending. */ if (opt.card_timeout) { for (sl=session_list; sl; sl = sl->next_session) if (!sl->disconnect_allowed) - break; + break; if (session_list && !sl) { /* FIXME: Use a real timeout. */ @@ -2328,7 +2328,7 @@ update_reader_status_file (int set_card_removed_flag) apdu_disconnect (ss->slot); } } - + } } ----------------------------------------------------------------------- Summary of changes: g10/call-agent.c | 22 +++-- scd/app-openpgp.c | 310 +++++++++++++++++++++++++++-------------------------- scd/command.c | 208 ++++++++++++++++++++---------------- 3 files changed, 291 insertions(+), 249 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Nov 6 16:23:54 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 06 Nov 2012 16:23:54 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.0beta3-93-g905b6a3 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 905b6a36d3ca21b2f619721e1de892398e5eb759 (commit) from 8f8c29d24ca13f987e6c118702b428a2051b7072 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 905b6a36d3ca21b2f619721e1de892398e5eb759 Author: Werner Koch Date: Tue Nov 6 12:02:25 2012 +0100 Allow decryption with card keys > 3072 bits * scd/command.c (MAXLEN_SETDATA): New. (cmd_setdata): Add option --append. * agent/call-scd.c (agent_card_pkdecrypt): Use new option for long data. * scd/app-openpgp.c (struct app_local_s): Add field manufacturer. (app_select_openpgp): Store manufacturer. (do_decipher): Print a note for broken cards. -- Please note that I was not able to run a full test because I only have broken cards (S/N < 346) available. diff --git a/agent/call-scd.c b/agent/call-scd.c index 8fc0054..2bda377 100644 --- a/agent/call-scd.c +++ b/agent/call-scd.c @@ -926,17 +926,22 @@ agent_card_pkdecrypt (ctrl_t ctrl, return rc; /* FIXME: use secure memory where appropriate */ - if (indatalen*2 + 50 > DIM(line)) - return unlock_scd (ctrl, gpg_error (GPG_ERR_GENERAL)); - sprintf (line, "SETDATA "); - p = line + strlen (line); - for (i=0; i < indatalen ; i++, p += 2 ) - sprintf (p, "%02X", indata[i]); - rc = assuan_transact (ctrl->scd_local->ctx, line, - NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return unlock_scd (ctrl, rc); + for (len = 0; len < indatalen;) + { + p = stpcpy (line, "SETDATA "); + if (len) + p = stpcpy (p, "--append "); + for (i=0; len < indatalen && (i*2 < DIM(line)-50); i++, len++) + { + sprintf (p, "%02X", indata[len]); + p += 2; + } + rc = assuan_transact (ctrl->scd_local->ctx, line, + NULL, NULL, NULL, NULL, NULL, NULL); + if (rc) + return unlock_scd (ctrl, rc); + } init_membuf (&data, 1024); inqparm.ctx = ctrl->scd_local->ctx; diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 9c8ef59..5a9214c 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -158,6 +158,8 @@ struct app_local_s { unsigned char status_indicator; /* The card status indicator. */ + unsigned int manufacturer:16; /* Manufacturer ID from the s/n. */ + /* Keep track of the ISO card capabilities. */ struct { @@ -3474,6 +3476,12 @@ do_decipher (app_t app, const char *keyidstr, indata, indatalen, le_value, padind, outdata, outdatalen); xfree (fixbuf); + + if (gpg_err_code (rc) == GPG_ERR_CARD /* actual SW is 0x640a */ + && app->app_local->manufacturer == 5 + && app->card_version == 0x0200) + log_info ("NOTE: Cards with manufacturer id 5 and s/n <= 346 (0x15a)" + " do not work with encryption keys > 2048 bits\n"); } return rc; @@ -3761,6 +3769,8 @@ app_select_openpgp (app_t app) goto leave; } + app->app_local->manufacturer = manufacturer; + if (app->card_version >= 0x0200) app->app_local->extcap.is_v2 = 1; diff --git a/scd/command.c b/scd/command.c index 1027158..17da5b7 100644 --- a/scd/command.c +++ b/scd/command.c @@ -48,6 +48,9 @@ /* Maximum allowed size of key data as used in inquiries. */ #define MAXLEN_KEYDATA 4096 +/* Maximum allowed total data size for SETDATA. */ +#define MAXLEN_SETDATA 4096 + /* Maximum allowed size of certificate data as used in inquiries. */ #define MAXLEN_CERTDATA 16384 @@ -848,17 +851,24 @@ cmd_readkey (assuan_context_t ctx, char *line) static const char hlp_setdata[] = - "SETDATA \n" + "SETDATA [--append] \n" "\n" - "The client should use this command to tell us the data he want to sign."; + "The client should use this command to tell us the data he want to sign.\n" + "With the option --append, the data is appended to the data set by a\n" + "previous SETDATA command."; static gpg_error_t cmd_setdata (assuan_context_t ctx, char *line) { ctrl_t ctrl = assuan_get_pointer (ctx); - int n; + int append; + int n, i, off; char *p; unsigned char *buf; + append = (ctrl->in_data.value && has_option (line, "--append")); + + line = skip_options (line); + if (locked_session && locked_session != ctrl->server_local) return gpg_error (GPG_ERR_LOCKED); @@ -872,15 +882,31 @@ cmd_setdata (assuan_context_t ctx, char *line) if ((n&1)) return set_error (GPG_ERR_ASS_PARAMETER, "odd number of digits"); n /= 2; - buf = xtrymalloc (n); + if (append) + { + if (ctrl->in_data.valuelen + n > MAXLEN_SETDATA) + return set_error (GPG_ERR_TOO_LARGE, + "limit on total size of data reached"); + buf = xtrymalloc (ctrl->in_data.valuelen + n); + } + else + buf = xtrymalloc (n); if (!buf) return out_of_core (); + if (append) + { + memcpy (buf, ctrl->in_data.value, ctrl->in_data.valuelen); + off = ctrl->in_data.valuelen; + } + else + off = 0; + for (p=line, i=0; i < n; p += 2, i++) + buf[off+i] = xtoi_2 (p); + xfree (ctrl->in_data.value); ctrl->in_data.value = buf; - ctrl->in_data.valuelen = n; - for (p=line, n=0; n < ctrl->in_data.valuelen; p += 2, n++) - buf[n] = xtoi_2 (p); + ctrl->in_data.valuelen = off+n; return 0; } ----------------------------------------------------------------------- Summary of changes: agent/call-scd.c | 25 +++++++++++++++---------- scd/app-openpgp.c | 10 ++++++++++ scd/command.c | 40 +++++++++++++++++++++++++++++++++------- 3 files changed, 58 insertions(+), 17 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Nov 6 18:42:04 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 06 Nov 2012 18:42:04 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-1-4, updated. gnupg-1.4.12-9-g5093bed Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-1-4 has been updated via 5093bed27580e608de073bcc5953bd76b6b8b2de (commit) via bb4df020fe1c50698aab8c9bf6b11bc3725f785d (commit) from a1856e767ac4cefe3252211a81ef479f6e3e4e5f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 5093bed27580e608de073bcc5953bd76b6b8b2de Author: Werner Koch Date: Tue Nov 6 17:14:04 2012 +0100 Fix extern inline use for gcc > 4.3 in c99 mode * mpi/mpi-inline.h [!G10_MPI_INLINE_DECL]: Take care of changed extern inline semantics in gcc. -- I am not use how this will work out with non-gcc. However, we had no problems in the past and thus this change is the least invasive for non-gcc compilers. diff --git a/mpi/mpi-inline.h b/mpi/mpi-inline.h index c32adae..6e44518 100644 --- a/mpi/mpi-inline.h +++ b/mpi/mpi-inline.h @@ -28,8 +28,15 @@ #ifndef G10_MPI_INLINE_H #define G10_MPI_INLINE_H +/* Starting with gcc 4.3 "extern inline" conforms in c99 mode to the + c99 semantics. To keep the useful old semantics we use an + attribute. */ #ifndef G10_MPI_INLINE_DECL -#define G10_MPI_INLINE_DECL extern __inline__ +# ifdef __GNUC_STDC_INLINE__ +# define G10_MPI_INLINE_DECL extern inline __attribute__ ((__gnu_inline__)) +# else +# define G10_MPI_INLINE_DECL extern __inline__ +# endif #endif G10_MPI_INLINE_DECL mpi_limb_t commit bb4df020fe1c50698aab8c9bf6b11bc3725f785d Author: Werner Koch Date: Tue Nov 6 16:21:52 2012 +0100 autogen.sh: Do not use -c with chmod. -- diff --git a/scripts/autogen.sh b/scripts/autogen.sh index d820696..6423483 100755 --- a/scripts/autogen.sh +++ b/scripts/autogen.sh @@ -272,14 +272,14 @@ if [ -d .git ]; then and .git/hooks/pre-commit.sample out of the way. EOF cp -av .git/hooks/pre-commit.sample .git/hooks/pre-commit - chmod -c +x .git/hooks/pre-commit + chmod +x .git/hooks/pre-commit fi if [ -f scripts/git-hooks/commit-msg -a ! -f .git/hooks/commit-msg ] ; then cat <&2 *** Activating commit log message check hook. *** EOF cp -av scripts/git-hooks/commit-msg .git/hooks/commit-msg - chmod -c +x .git/hooks/commit-msg + chmod +x .git/hooks/commit-msg fi tmp=$(git config --get filter.cleanpo.clean) if [ "$tmp" != "awk '/^\"POT-Creation-Date:/&&!s{s=1;next};!/^#: /{print}'" ] ----------------------------------------------------------------------- Summary of changes: mpi/mpi-inline.h | 9 ++++++++- scripts/autogen.sh | 4 ++-- 2 files changed, 10 insertions(+), 3 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Nov 6 19:52:10 2012 From: cvs at cvs.gnupg.org (by Thomas Klausner) Date: Tue, 06 Nov 2012 19:52:10 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-1-4, updated. gnupg-1.4.12-11-g6a41f38 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-1-4 has been updated via 6a41f385c496c180ee730ce80ff5653746410759 (commit) via 620906643713e839b4a95714013ee4603fedc515 (commit) from 5093bed27580e608de073bcc5953bd76b6b8b2de (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 6a41f385c496c180ee730ce80ff5653746410759 Author: Thomas Klausner Date: Sat Oct 27 19:56:11 2012 +0200 Handle systems which have uint64_t but not the UINT64_C macro. * include/types.h (U64_C) [!UINT64_C]: Add simple replacement. -- This could happen with UNIX98-type systems, such as the code on the netbsd-1-5 branch, and would prevent this package from building on such systems. diff --git a/include/types.h b/include/types.h index 7d93865..6baccdb 100644 --- a/include/types.h +++ b/include/types.h @@ -101,9 +101,14 @@ typedef unsigned long u32; # undef u64 /* maybe there is a macro with this name */ # if SIZEOF_UINT64_T == 8 typedef uint64_t u64; +# ifdef UINT64_C # define U64_C(c) (UINT64_C(c)) -# define HAVE_U64_TYPEDEF -# elif SIZEOF_UNSIGNED_INT == 8 +# else + /* make a best guess, could happen with UNIX98 */ +# define U64_C(c) (c) +# endif +# define HAVE_U64_TYPEDEF +#elif SIZEOF_UNSIGNED_INT == 8 typedef unsigned int u64; # define U64_C(c) (c ## U) # define HAVE_U64_TYPEDEF commit 620906643713e839b4a95714013ee4603fedc515 Author: Werner Koch Date: Tue Nov 6 17:44:11 2012 +0100 Indent nested cpp directives for better readability. -- diff --git a/include/types.h b/include/types.h index d6cd073..7d93865 100644 --- a/include/types.h +++ b/include/types.h @@ -21,23 +21,22 @@ #define G10_TYPES_H #ifdef HAVE_INTTYPES_H -/* For uint64_t */ -#include +# include /* For uint64_t */ #endif /* The AC_CHECK_SIZEOF() in configure fails for some machines. * we provide some fallback values here */ #if !SIZEOF_UNSIGNED_SHORT -#undef SIZEOF_UNSIGNED_SHORT -#define SIZEOF_UNSIGNED_SHORT 2 +# undef SIZEOF_UNSIGNED_SHORT +# define SIZEOF_UNSIGNED_SHORT 2 #endif #if !SIZEOF_UNSIGNED_INT -#undef SIZEOF_UNSIGNED_INT -#define SIZEOF_UNSIGNED_INT 4 +# undef SIZEOF_UNSIGNED_INT +# define SIZEOF_UNSIGNED_INT 4 #endif #if !SIZEOF_UNSIGNED_LONG -#undef SIZEOF_UNSIGNED_LONG -#define SIZEOF_UNSIGNED_LONG 4 +# undef SIZEOF_UNSIGNED_LONG +# define SIZEOF_UNSIGNED_LONG 4 #endif @@ -45,52 +44,52 @@ #ifndef HAVE_BYTE_TYPEDEF -#undef byte /* maybe there is a macro with this name */ -#ifndef __riscos__ +# undef byte /* maybe there is a macro with this name */ +# ifndef __riscos__ typedef unsigned char byte; -#else +# else /* Norcroft treats char = unsigned char as legal assignment but char* = unsigned char* as illegal assignment and the same applies to the signed variants as well */ typedef char byte; -#endif -#define HAVE_BYTE_TYPEDEF +# endif +# define HAVE_BYTE_TYPEDEF #endif #ifndef HAVE_USHORT_TYPEDEF -#undef ushort /* maybe there is a macro with this name */ +# undef ushort /* maybe there is a macro with this name */ typedef unsigned short ushort; -#define HAVE_USHORT_TYPEDEF +# define HAVE_USHORT_TYPEDEF #endif #ifndef HAVE_ULONG_TYPEDEF -#undef ulong /* maybe there is a macro with this name */ +# undef ulong /* maybe there is a macro with this name */ typedef unsigned long ulong; -#define HAVE_ULONG_TYPEDEF +# define HAVE_ULONG_TYPEDEF #endif #ifndef HAVE_U16_TYPEDEF -#undef u16 /* maybe there is a macro with this name */ -#if SIZEOF_UNSIGNED_INT == 2 +# undef u16 /* maybe there is a macro with this name */ +# if SIZEOF_UNSIGNED_INT == 2 typedef unsigned int u16; -#elif SIZEOF_UNSIGNED_SHORT == 2 +# elif SIZEOF_UNSIGNED_SHORT == 2 typedef unsigned short u16; -#else -#error no typedef for u16 -#endif -#define HAVE_U16_TYPEDEF +# else +# error no typedef for u16 +# endif +# define HAVE_U16_TYPEDEF #endif #ifndef HAVE_U32_TYPEDEF -#undef u32 /* maybe there is a macro with this name */ -#if SIZEOF_UNSIGNED_INT == 4 +# undef u32 /* maybe there is a macro with this name */ +# if SIZEOF_UNSIGNED_INT == 4 typedef unsigned int u32; -#elif SIZEOF_UNSIGNED_LONG == 4 +# elif SIZEOF_UNSIGNED_LONG == 4 typedef unsigned long u32; -#else -#error no typedef for u32 -#endif -#define HAVE_U32_TYPEDEF +# else +# error no typedef for u32 +# endif +# define HAVE_U32_TYPEDEF #endif /**************** @@ -99,24 +98,24 @@ typedef unsigned long u32; * Solaris and IRIX. */ #ifndef HAVE_U64_TYPEDEF -#undef u64 /* maybe there is a macro with this name */ -#if SIZEOF_UINT64_T == 8 +# undef u64 /* maybe there is a macro with this name */ +# if SIZEOF_UINT64_T == 8 typedef uint64_t u64; -#define U64_C(c) (UINT64_C(c)) -#define HAVE_U64_TYPEDEF -#elif SIZEOF_UNSIGNED_INT == 8 +# define U64_C(c) (UINT64_C(c)) +# define HAVE_U64_TYPEDEF +# elif SIZEOF_UNSIGNED_INT == 8 typedef unsigned int u64; -#define U64_C(c) (c ## U) -#define HAVE_U64_TYPEDEF -#elif SIZEOF_UNSIGNED_LONG == 8 +# define U64_C(c) (c ## U) +# define HAVE_U64_TYPEDEF +# elif SIZEOF_UNSIGNED_LONG == 8 typedef unsigned long u64; -#define U64_C(c) (c ## UL) -#define HAVE_U64_TYPEDEF +# define U64_C(c) (c ## UL) +# define HAVE_U64_TYPEDEF #elif SIZEOF_UNSIGNED_LONG_LONG == 8 typedef unsigned long long u64; -#define U64_C(c) (c ## ULL) -#define HAVE_U64_TYPEDEF -#endif +# define U64_C(c) (c ## ULL) +# define HAVE_U64_TYPEDEF +# endif #endif typedef union { ----------------------------------------------------------------------- Summary of changes: include/types.h | 90 ++++++++++++++++++++++++++++-------------------------- 1 files changed, 47 insertions(+), 43 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Nov 7 13:01:07 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 07 Nov 2012 13:01:07 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.5.0-46-g7af98ef Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 7af98ef78d45e813f47ae4e180a02757a379953f (commit) from 1241fbbc896e9bbad68f1007a17b20493f6cd1af (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 7af98ef78d45e813f47ae4e180a02757a379953f Author: Werner Koch Date: Mon Nov 5 20:28:03 2012 +0100 Prepare for a backported interface in 1.5.1. * configure.ac: Bump LT version at C20/A0/R0 to adjust for a planned API update in 1.5.1. diff --git a/NEWS b/NEWS index 465330a..a0fd09b 100644 --- a/NEWS +++ b/NEWS @@ -27,7 +27,7 @@ Noteworthy changes in version 1.6.0 (unreleased) gcry_md_list REMOVED. gcry_md_start_debug REMOVED (macro). gcry_md_stop_debug REMOVED (macro). - + GCRYCTL_SET_ENFORCED_FIPS_FLAG NEW. Noteworthy changes in version 1.5.0 (2011-06-29) diff --git a/configure.ac b/configure.ac index b152c0f..3a5bccd 100644 --- a/configure.ac +++ b/configure.ac @@ -52,7 +52,7 @@ AC_INIT([libgcrypt],[mym4_full_version],[http://bugs.gnupg.org]) # CAUTION: Due to the ABI change in 1.6 the LT version numbers below have # already been set for the next release. Thus don't update them for # the 1.6.0 release. -LIBGCRYPT_LT_CURRENT=19 +LIBGCRYPT_LT_CURRENT=20 LIBGCRYPT_LT_AGE=0 LIBGCRYPT_LT_REVISION=0 ----------------------------------------------------------------------- Summary of changes: NEWS | 2 +- configure.ac | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Wed Nov 7 16:34:44 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 07 Nov 2012 16:34:44 +0100 Subject: [git] GCRYPT - branch, LIBGCRYPT-1-5-BRANCH, updated. libgcrypt-1.5.0-12-g423571e Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, LIBGCRYPT-1-5-BRANCH has been updated via 423571e111d54dbf0aa6cc7e7ef1516ae4327b3d (commit) from 542d354b902c72d7fb19f9a0e5f3f3d21909f21a (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 423571e111d54dbf0aa6cc7e7ef1516ae4327b3d Author: Werner Koch Date: Wed Nov 7 15:02:06 2012 +0100 Fix memory leak in gcry_pk_testkey for ECC. * cipher/ecc.c (check_secret_key): Restructure for easier allocation tracking. Fix memory leak. diff --git a/cipher/ecc.c b/cipher/ecc.c index bbff7ee..b8487dc 100644 --- a/cipher/ecc.c +++ b/cipher/ecc.c @@ -642,47 +642,48 @@ test_keys (ECC_secret_key *sk, unsigned int nbits) static int check_secret_key (ECC_secret_key * sk) { + int rc = 1; mpi_point_t Q; - gcry_mpi_t y_2, y2 = mpi_alloc (0); - mpi_ec_t ctx; + gcry_mpi_t y_2, y2; + mpi_ec_t ctx = NULL; + + point_init (&Q); /* ?primarity test of 'p' */ /* (...) //!! */ /* G in E(F_p) */ y_2 = gen_y_2 (sk->E.G.x, &sk->E); /* y^2=x^3+a*x+b */ + y2 = mpi_alloc (0); mpi_mulm (y2, sk->E.G.y, sk->E.G.y, sk->E.p); /* y^2=y*y */ if (mpi_cmp (y_2, y2)) { if (DBG_CIPHER) log_debug ("Bad check: Point 'G' does not belong to curve 'E'!\n"); - return (1); + goto leave; } /* G != PaI */ if (!mpi_cmp_ui (sk->E.G.z, 0)) { if (DBG_CIPHER) log_debug ("Bad check: 'G' cannot be Point at Infinity!\n"); - return (1); + goto leave; } - point_init (&Q); ctx = _gcry_mpi_ec_init (sk->E.p, sk->E.a); + _gcry_mpi_ec_mul_point (&Q, sk->E.n, &sk->E.G, ctx); if (mpi_cmp_ui (Q.z, 0)) { if (DBG_CIPHER) log_debug ("check_secret_key: E is not a curve of order n\n"); - point_free (&Q); - _gcry_mpi_ec_free (ctx); - return 1; + goto leave; } /* pubkey cannot be PaI */ if (!mpi_cmp_ui (sk->Q.z, 0)) { if (DBG_CIPHER) log_debug ("Bad check: Q can not be a Point at Infinity!\n"); - _gcry_mpi_ec_free (ctx); - return (1); + goto leave; } /* pubkey = [d]G over E */ _gcry_mpi_ec_mul_point (&Q, sk->d, &sk->E.G, ctx); @@ -691,12 +692,16 @@ check_secret_key (ECC_secret_key * sk) if (DBG_CIPHER) log_debug ("Bad check: There is NO correspondence between 'd' and 'Q'!\n"); - _gcry_mpi_ec_free (ctx); - return (1); + goto leave; } + rc = 0; /* Okay. */ + + leave: _gcry_mpi_ec_free (ctx); + mpi_free (y2); + mpi_free (y_2); point_free (&Q); - return 0; + return rc; } ----------------------------------------------------------------------- Summary of changes: cipher/ecc.c | 31 ++++++++++++++++++------------- 1 files changed, 18 insertions(+), 13 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Wed Nov 7 16:35:23 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 07 Nov 2012 16:35:23 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.5.0-47-g8cbbad5 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 8cbbad5f94f6e0429fffe66d689aea20f7e35957 (commit) from 7af98ef78d45e813f47ae4e180a02757a379953f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 8cbbad5f94f6e0429fffe66d689aea20f7e35957 Author: Werner Koch Date: Wed Nov 7 15:02:06 2012 +0100 Fix memory leak in gcry_pk_testkey for ECC. * cipher/ecc.c (check_secret_key): Restructure for easier allocation tracking. Fix memory leak. diff --git a/cipher/ecc.c b/cipher/ecc.c index 70431fe..22de3d8 100644 --- a/cipher/ecc.c +++ b/cipher/ecc.c @@ -647,47 +647,48 @@ test_keys (ECC_secret_key *sk, unsigned int nbits) static int check_secret_key (ECC_secret_key * sk) { + int rc = 1; mpi_point_t Q; - gcry_mpi_t y_2, y2 = mpi_alloc (0); - mpi_ec_t ctx; + gcry_mpi_t y_2, y2; + mpi_ec_t ctx = NULL; + + point_init (&Q); /* ?primarity test of 'p' */ /* (...) //!! */ /* G in E(F_p) */ y_2 = gen_y_2 (sk->E.G.x, &sk->E); /* y^2=x^3+a*x+b */ + y2 = mpi_alloc (0); mpi_mulm (y2, sk->E.G.y, sk->E.G.y, sk->E.p); /* y^2=y*y */ if (mpi_cmp (y_2, y2)) { if (DBG_CIPHER) log_debug ("Bad check: Point 'G' does not belong to curve 'E'!\n"); - return (1); + goto leave; } /* G != PaI */ if (!mpi_cmp_ui (sk->E.G.z, 0)) { if (DBG_CIPHER) log_debug ("Bad check: 'G' cannot be Point at Infinity!\n"); - return (1); + goto leave; } - point_init (&Q); ctx = _gcry_mpi_ec_init (sk->E.p, sk->E.a); + _gcry_mpi_ec_mul_point (&Q, sk->E.n, &sk->E.G, ctx); if (mpi_cmp_ui (Q.z, 0)) { if (DBG_CIPHER) log_debug ("check_secret_key: E is not a curve of order n\n"); - point_free (&Q); - _gcry_mpi_ec_free (ctx); - return 1; + goto leave; } /* pubkey cannot be PaI */ if (!mpi_cmp_ui (sk->Q.z, 0)) { if (DBG_CIPHER) log_debug ("Bad check: Q can not be a Point at Infinity!\n"); - _gcry_mpi_ec_free (ctx); - return (1); + goto leave; } /* pubkey = [d]G over E */ _gcry_mpi_ec_mul_point (&Q, sk->d, &sk->E.G, ctx); @@ -696,12 +697,16 @@ check_secret_key (ECC_secret_key * sk) if (DBG_CIPHER) log_debug ("Bad check: There is NO correspondence between 'd' and 'Q'!\n"); - _gcry_mpi_ec_free (ctx); - return (1); + goto leave; } + rc = 0; /* Okay. */ + + leave: _gcry_mpi_ec_free (ctx); + mpi_free (y2); + mpi_free (y_2); point_free (&Q); - return 0; + return rc; } ----------------------------------------------------------------------- Summary of changes: cipher/ecc.c | 31 ++++++++++++++++++------------- 1 files changed, 18 insertions(+), 13 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Wed Nov 7 19:34:56 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 07 Nov 2012 19:34:56 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-1-4, updated. gnupg-1.4.12-13-gb1abc01 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-1-4 has been updated via b1abc01d4ad199258b3d2fb579ac06c6fea747fd (commit) via a74f05c32deb12373111510d4395ad52eb53d342 (commit) from 6a41f385c496c180ee730ce80ff5653746410759 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b1abc01d4ad199258b3d2fb579ac06c6fea747fd Author: Werner Koch Date: Wed Nov 7 18:06:27 2012 +0100 Improve handling of random_seed read errors. * cipher/random.c (read_seed_file): Distinguish between errors and short reads. -- This should help to avoid program aborts due to races. Nevertheless a better and cross-platform locking would be a more solid solution. GnuPG-bug-id: 1439 diff --git a/cipher/random.c b/cipher/random.c index caf35dd..b634161 100644 --- a/cipher/random.c +++ b/cipher/random.c @@ -489,14 +489,38 @@ read_seed_file(void) close(fd); return 0; } + do { n = read( fd, buffer, POOLSIZE ); } while( n == -1 && errno == EINTR ); - if( n != POOLSIZE ) { + /* The N==0, ENOENT, and N!=POOLSIZE cases may happen if another + process is updating the file. For consistency we use the same + recovery strategy as with the pre-read checks. */ + if (!n) { + log_info(_("note: random_seed file is empty\n") ); + allow_seed_file_update = 1; + close(fd); + return 0; + } + else if( n == -1 && errno == ENOENT) { + /* On a Unix system that should never happen. However, I can + imagine this error code on non-inode based systems. */ + log_info(_("can't read `%s': %s\n"), seed_file_name, strerror(errno)); + allow_seed_file_update = 1; + close(fd); + return 0; + } + else if( n == -1 ) { + /* A real read error. */ log_fatal(_("can't read `%s': %s\n"), seed_file_name,strerror(errno) ); close(fd); return 0; } + else if ( n != POOLSIZE ) { + log_info(_("WARNING: invalid size of random_seed file - not used\n") ); + close(fd); + return 0; + } close(fd); commit a74f05c32deb12373111510d4395ad52eb53d342 Author: Werner Koch Date: Wed Nov 7 18:00:45 2012 +0100 Remove trailing white space from one file -- diff --git a/cipher/random.c b/cipher/random.c index 460c2af..caf35dd 100644 --- a/cipher/random.c +++ b/cipher/random.c @@ -155,7 +155,7 @@ getfnc_gather_random (void))(void (*)(const void*, size_t, int), int, { #ifdef USE_ALL_RANDOM_MODULES static int (*fnc)(void (*)(const void*, size_t, int), int, size_t, int); - + if (fnc) return fnc; # ifdef USE_RNDLINUX @@ -231,7 +231,7 @@ static void burn_stack (int bytes) { char buf[128]; - + wipememory(buf,sizeof buf); bytes -= sizeof buf; if (bytes > 0) @@ -293,7 +293,7 @@ random_is_faked() } /* Disable locking of seed files. */ -void +void random_disable_locking () { no_seed_file_locking = 1; @@ -401,7 +401,7 @@ lock_seed_file (int fd, const char *fname, int for_write) if (no_seed_file_locking) return 0; - + /* We take a lock on the entire file. */ memset (&lck, 0, sizeof lck); lck.l_type = for_write? F_WRLCK : F_RDLCK; @@ -417,7 +417,7 @@ lock_seed_file (int fd, const char *fname, int for_write) if (backoff > 2) /* Show the first message after ~3.75 seconds. */ log_info( _("waiting for lock on `%s'...\n"), fname); - + tv.tv_sec = backoff; tv.tv_usec = 250000; select (0, NULL, NULL, NULL, &tv); @@ -569,10 +569,10 @@ update_random_seed_file() seed_file_name, strerror (errno)); return; } - + if (backoff > 2) /* Show the first message after ~3.75 seconds. */ log_info( _("waiting for lock on `%s'...\n"), seed_file_name); - + wait_vms( backoff+ 0.25); if (backoff < 10) backoff++ ; @@ -766,7 +766,7 @@ fast_random_poll() /* fall back to the generic function */ #if defined(HAVE_GETHRTIME) && !defined(HAVE_BROKEN_GETHRTIME) { hrtime_t tv; - /* On some Solaris and HPUX system gethrtime raises an SIGILL, but we + /* On some Solaris and HPUX system gethrtime raises an SIGILL, but we * checked this with configure */ tv = gethrtime(); add_randomness( &tv, sizeof(tv), 1 ); @@ -801,11 +801,11 @@ fast_random_poll() { struct rusage buf; /* QNX/Neutrino does return ENOSYS - so we just ignore it and * add whatever is in buf. In a chroot environment it might not - * work at all (i.e. because /proc/ is not accessible), so we better + * work at all (i.e. because /proc/ is not accessible), so we better * ignore all error codes and hope for the best */ getrusage( RUSAGE_SELF, &buf ); - + add_randomness( &buf, sizeof buf, 1 ); wipememory( &buf, sizeof buf ); } ----------------------------------------------------------------------- Summary of changes: cipher/random.c | 46 +++++++++++++++++++++++++++++++++++----------- 1 files changed, 35 insertions(+), 11 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Nov 7 23:06:14 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 07 Nov 2012 23:06:14 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-1-4, updated. gnupg-1.4.12-14-gc3a5448 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-1-4 has been updated via c3a5448379cdf07b408a265fe8f477901524170d (commit) from b1abc01d4ad199258b3d2fb579ac06c6fea747fd (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit c3a5448379cdf07b408a265fe8f477901524170d Author: Werner Koch Date: Wed Nov 7 21:38:27 2012 +0100 Fix usage of dlerror to conform to POSIX. * cipher/idea-stub.c: Clear last error before dlsym. -- This is required for NetBSD. Reported-by: Thomas Klausner diff --git a/cipher/idea-stub.c b/cipher/idea-stub.c index 8996c75..abfb929 100644 --- a/cipher/idea-stub.c +++ b/cipher/idea-stub.c @@ -25,9 +25,9 @@ problem with this, please see http://www.noepatents.org. However for research purposes and in certain situations it might be - useful to use this algorithm anyway. + useful to use this algorithm anyway. - We provide this stub which will dynload a idea module and is only + We provide this stub which will dynload a idea module and is only used if the configure run did't found statically linked file. See http://www.gnupg.org/why-not-dea.html for details. */ @@ -55,12 +55,12 @@ #define USE_DYNAMIC_LINKING 1 static int last_error = 0; - + void* dlopen (const char *pathname, int mode) { void *h = LoadLibrary (pathname); - if (!h) + if (!h) { log_error ("LoadLibrary failed: %s\n", w32_strerror (errno)); last_error = 1; @@ -130,14 +130,16 @@ load_module (const char *name) goto failure; } + dlerror (); /* Clear old errors or initialize dlerror. */ + sym = dlsym (handle, "idea_get_info"); if (dlerror ()) sym = dlsym (handle, "_idea_get_info"); - if ((err=dlerror())) + if ((err=dlerror())) goto failure; return (INFO_FNC)sym; - + failure: log_info ("invalid module `%s': %s\n", name?name:"???", err?err:"???"); if (handle) ----------------------------------------------------------------------- Summary of changes: cipher/idea-stub.c | 14 ++++++++------ 1 files changed, 8 insertions(+), 6 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Nov 8 14:53:02 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 08 Nov 2012 14:53:02 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-1-4, updated. gnupg-1.4.12-15-gb1eac93 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-1-4 has been updated via b1eac93431c377805984210a8ef76f5c314c8a5f (commit) from c3a5448379cdf07b408a265fe8f477901524170d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b1eac93431c377805984210a8ef76f5c314c8a5f Author: Werner Koch Date: Thu Nov 8 13:25:02 2012 +0100 Support the not anymore patented IDEA cipher algorithm. * cipher/idea.c: New. Take from Libgcrypt master and adjust for direct use in GnuPG. * cipher/idea-stub.c: Remove. * cipher/Makefile.am: Add idea.c and remove idea-stub.c rules. * configure.ac: Remove idea-stub code. * g10/gpg.c (check_permissions): Remove code path for ITEM==2. (main): Make --load-extension a dummy option. * g10/keygen.c (keygen_set_std_prefs): Include IDEA only in PGP2 compatibility mode. * g10/misc.c (idea_cipher_warn): Remove. Also remove all callers. * g10/seckey-cert.c (do_check): Remove emitting of STATUS_RSA_OR_IDEA. * g10/status.c (get_status_string): Remove STATUS_RSA_OR_IDEA. * g10/status.h (STATUS_RSA_OR_IDEA): Remove. -- To keep the number of actually used algorithms low, we support IDEA only in a basically read-only way (unless --pgp2 is used during key generation). It does not make sense to suggest the use of this old 64 bit blocksize algorithm. However, there is old data available where it might be helpful to have IDEA available. diff --git a/NEWS b/NEWS index c747abe..d5a4056 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,11 @@ +Noteworthy changes in version 1.4.13 (unreleased) +------------------------------------------------- + + * Add support for the old cipher algorithm IDEA. + + * Minor bug fixes. + + Noteworthy changes in version 1.4.12 (2012-01-30) ------------------------------------------------- diff --git a/README b/README index 586937c..1e2ec96 100644 --- a/README +++ b/README @@ -1,11 +1,11 @@ GnuPG - The GNU Privacy Guard ------------------------------- - Version 1.4.12 + Version 1.4.13 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, - 2010, 2012 Free Software Foundation, Inc. + 2010, 2012, 2013 Free Software Foundation, Inc. This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or @@ -31,13 +31,14 @@ list of systems which are known to work. GnuPG is distributed under the terms of the GNU General Public - License. See the file COPYING for copyright and warranty - information. + License. See the files AUTHORS and COPYING for copyright and + warranty information. - Because GnuPG does not use use any patented algorithms it is not - by default fully compatible with PGP 2.x, which uses the patented - IDEA algorithm. See http://www.gnupg.org/why-not-idea.html for - more information on this subject. + Because GnuPG does not use any patented algorithms it used not to + be fully compatible with PGP 2. Now, that the patent on the IDEA + cipher algorithm has expired, we support that algorithm and thus + provide full compatibility with PGP 2. This allows the decryption + of data once encrypted using PGP 2. The default public key algorithm is RSA, but DSA and Elgamal are also supported. Symmetric algorithms available are AES (with 128, @@ -57,7 +58,7 @@ this. Don't skip it - this is an important step! 2) Unpack the tarball. With GNU tar you can do it this way: - "tar xzvf gnupg-x.y.z.tar.gz". If got a bzip2 compressed + "tar xzvf gnupg-x.y.z.tar.gz". If you got a bzip2 compressed tarball you need to use: "tar xjvf gnupg-x.y.z.tar.bz2". 3) "cd gnupg-x.y.z" @@ -70,11 +71,11 @@ 7) You end up with a "gpg" binary in /usr/local/bin. - 8) To avoid swapping out of sensitive data, you can install "gpg" - setuid root. If you don't do so, you may want to add the - option "no-secmem-warning" to ~/.gnupg/gpg.conf. Note that on - modern GNU/Linux systems swapping protection does not anymore - require GPG to be installed setuid root. + 8) To avoid swapping out of sensitive data, you may need to + install "gpg" setuid root. If you don't do so, you may want to + add the option "no-secmem-warning" to ~/.gnupg/gpg.conf. Note + that on modern GNU/Linux systems swapping protection does not + anymore require GPG to be installed setuid root. How to Verify the Source @@ -93,7 +94,8 @@ is indeed a signature of gnupg-x.y.z.tar.gz. The key currently used to create this signature is: - "pub 1024R/1CE0C630 2006-01-01 Werner Koch (dist sig) " + "pub 2048R/4F25E3B6 2011-01-12 [expires: 2019-12-31] + "uid Werner Koch (dist sig) If you do not have this key, you can get it from the source in the file doc/samplekeys.asc (use "gpg --import doc/samplekeys.asc" @@ -101,7 +103,7 @@ make sure that this is really the key and not a faked one. You can do this by comparing the output of: - $ gpg --fingerprint 0x1CE0C630 + $ gpg --fingerprint 0x4F25E3B6 with the fingerprint published elsewhere. @@ -317,17 +319,20 @@ claims to own it. There are 2 steps to validate a key: + 1. First check that there is a complete chain of signed keys from the public key you want to use and your key and verify each signature. 2. Make sure that you have full trust in the certificates of all the introduces between the public key holder and you. + Step 2 is the more complicated part because there is no easy way for a computer to decide who is trustworthy and who is not. GnuPG leaves this decision to you and will ask you for a trust value (here also referenced as the owner-trust of a key) for every key needed to check the chain of certificates. You may choose from: + a) "I don't know" - then it is not possible to use any of the chains of certificates, in which this key is used as an introducer, to validate the target key. Use this if @@ -347,6 +352,7 @@ normally needs only one chain of signatures to validate a target key okay. (But this may be adjusted with the help of some options). + This information is confidential because it gives your personal opinion on the trustworthiness of someone else. Therefore this data is not stored in the keyring but in the "trustdb" @@ -429,14 +435,6 @@ "" - * By word match - - "+Heinrich Heine duesseldorf" - - All words must match exactly (not case sensitive) and appear in - any order in the user ID. Words are any sequences of letters, - digits, the underscore and characters with bit 7 set. - * Or by the usual substring: "Heine" @@ -822,7 +820,7 @@ Please direct questions about GnuPG to the users mailing list or one of the pgp newsgroups; please do not direct questions to one of the authors directly as we are busy working on improvements and - bug fixes. The English and German GnupG mailing lists are watched + bug fixes. The English and German GnuPG mailing lists are watched by the authors and we try to answer questions when time allows us to do so. diff --git a/cipher/Makefile.am b/cipher/Makefile.am index a10af20..6b923b2 100644 --- a/cipher/Makefile.am +++ b/cipher/Makefile.am @@ -7,12 +7,12 @@ # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. -# +# # GnuPG 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 General Public License for more details. -# +# # You should have received a copy of the GNU General Public License # along with this program; if not, see . ## Process this file with automake to produce Makefile.in @@ -37,6 +37,7 @@ libcipher_a_SOURCES = cipher.c \ cast5.c \ rijndael.c \ camellia.c camellia.h camellia-glue.c \ + idea.c \ elgamal.c \ elgamal.h \ rsa.c rsa.h \ @@ -73,7 +74,3 @@ endif if USE_SHA512 libcipher_a_SOURCES+=sha512.c endif - -EXTRA_libcipher_a_SOURCES=idea-stub.c -libcipher_a_DEPENDENCIES=@IDEA_O@ -libcipher_a_LIBADD=@IDEA_O@ diff --git a/cipher/idea-stub.c b/cipher/idea-stub.c deleted file mode 100644 index abfb929..0000000 --- a/cipher/idea-stub.c +++ /dev/null @@ -1,182 +0,0 @@ -/* idea-stub.c - Dummy module for the deprecated IDEA cipher. - * Copyright (C) 2002, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * GnuPG 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - */ - -/* IDEA is a patented algorithm and therefore the use of IDEA in - countries where this patent is valid can not be allowed due to the - terms of the GNU General Public License. Those restrictions are - there to help protecting the freedom of software. For more - information on the nonsense of software patents and the general - problem with this, please see http://www.noepatents.org. - - However for research purposes and in certain situations it might be - useful to use this algorithm anyway. - - We provide this stub which will dynload a idea module and is only - used if the configure run did't found statically linked file. - See http://www.gnupg.org/why-not-dea.html for details. -*/ - -#include -#include -#include -#include -#include -#ifdef HAVE_DL_DLOPEN -#include -#endif -#ifdef _WIN32 -#include -#endif -#include "util.h" -#include "algorithms.h" - -#ifndef RTLD_NOW -#define RTLD_NOW 1 -#endif - -#ifdef _WIN32 -#define HAVE_DL_DLOPEN 1 -#define USE_DYNAMIC_LINKING 1 - -static int last_error = 0; - -void* -dlopen (const char *pathname, int mode) -{ - void *h = LoadLibrary (pathname); - if (!h) - { - log_error ("LoadLibrary failed: %s\n", w32_strerror (errno)); - last_error = 1; - return NULL; - } - return h; -} - -int -dlclose ( void *handle ) -{ - last_error = 0; - return FreeLibrary (handle); -} - - -const char* -dlerror (void) -{ - if (last_error) - return w32_strerror (0); - return NULL; -} - -void* -dlsym (void *handle, const char *name) -{ - void *h = GetProcAddress (handle, name); - if (!h) - { - log_error ("GetProcAddress failed: %s\n", w32_strerror (errno)); - last_error = 1; - } - return h; -} -#endif /*_WIN32*/ - -/* We do only support dlopen and the Windows emulation of it. */ -#ifndef HAVE_DL_DLOPEN -#undef USE_DYNAMIC_LINKING -#endif - -typedef -const char *(*INFO_FNC)(int, size_t*, size_t*, size_t*, - int (**)( void *, const byte *, unsigned), - void (**)( void *, byte *, const byte *), - void (**)( void *, byte *, const byte *)); - -static INFO_FNC -load_module (const char *name) -{ -#ifdef USE_DYNAMIC_LINKING - const char *err; - void *handle; - void *sym; - -#ifndef _WIN32 - /* Make sure we are not setuid. */ - if (getuid () != geteuid ()) - log_bug("trying to load an extension while still setuid\n"); -#endif - - handle = dlopen (name, RTLD_NOW); - if (!handle) - { - err=dlerror(); - goto failure; - } - - dlerror (); /* Clear old errors or initialize dlerror. */ - - sym = dlsym (handle, "idea_get_info"); - if (dlerror ()) - sym = dlsym (handle, "_idea_get_info"); - if ((err=dlerror())) - goto failure; - - return (INFO_FNC)sym; - - failure: - log_info ("invalid module `%s': %s\n", name?name:"???", err?err:"???"); - if (handle) - dlclose (handle); -#endif /*USE_DYNAMIC_LINKING*/ - return NULL; -} - -const char * -idea_get_info( int algo, size_t *keylen, - size_t *blocksize, size_t *contextsize, - int (**r_setkey)( void *c, const byte *key, unsigned keylen ), - void (**r_encrypt)( void *c, byte *outbuf, const byte *inbuf ), - void (**r_decrypt)( void *c, byte *outbuf, const byte *inbuf ) - ) -{ - static int initialized; - static INFO_FNC info_fnc; - const char *rstr; - int i; - - if (!initialized) - { - initialized = 1; - for (i=0; (rstr = dynload_enum_module_names (i)); i++) - { - info_fnc = load_module (rstr); - if (info_fnc) - break; - } - } - if (!info_fnc) - return NULL; /* dynloadable module not found. */ - rstr = info_fnc (algo, keylen, blocksize, contextsize, - r_setkey, r_encrypt, r_decrypt); - if (rstr && *keylen == 128 && *blocksize == 8 - && *r_setkey && *r_encrypt && r_decrypt) - return rstr; - return NULL; -} diff --git a/cipher/idea.c b/cipher/idea.c new file mode 100644 index 0000000..8cda764 --- /dev/null +++ b/cipher/idea.c @@ -0,0 +1,411 @@ +/* idea.c - IDEA function + * Copyright (c) 1997, 1998, 1999, 2001 by Werner Koch (dd9jn) + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * WERNER KOCH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Werner Koch shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Werner Koch. + * + * Patents on IDEA have expired: + * Europe: EP0482154 on 2011-05-16, + * Japan: JP3225440 on 2011-05-16, + * U.S.: 5,214,703 on 2012-01-07. + */ + +/* + * Please see http://www.noepatents.org/ to learn why software patents + * are bad for society and what you can do to fight them. + * + * The code herein is based on the one from: + * Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996. + * ISBN 0-471-11709-9. + */ + + +#include +#include +#include +#include +#include + +#include "types.h" /* for byte and u32 typedefs */ +#include "util.h" +#include "errors.h" +#include "algorithms.h" + + +#define FNCCAST_SETKEY(f) ((int(*)(void*, byte*, unsigned int))(f)) +#define FNCCAST_CRYPT(f) ((void(*)(void*, byte*, byte*))(f)) + +#define CIPHER_ALGO_IDEA 1 + +#define IDEA_KEYSIZE 16 +#define IDEA_BLOCKSIZE 8 +#define IDEA_ROUNDS 8 +#define IDEA_KEYLEN (6*IDEA_ROUNDS+4) + +typedef struct { + u16 ek[IDEA_KEYLEN]; + u16 dk[IDEA_KEYLEN]; + int have_dk; +} IDEA_context; + +static const char *selftest(void); + +static void +burn_stack (int bytes) +{ + char buf[64]; + + wipememory(buf,sizeof buf); + bytes -= sizeof buf; + if (bytes > 0) + burn_stack (bytes); +} + + +static u16 +mul_inv( u16 x ) +{ + u16 t0, t1; + u16 q, y; + + if( x < 2 ) + return x; + t1 = 0x10001L / x; + y = 0x10001L % x; + if( y == 1 ) + return (1-t1) & 0xffff; + + t0 = 1; + do { + q = x / y; + x = x % y; + t0 += q * t1; + if( x == 1 ) + return t0; + q = y / x; + y = y % x; + t1 += q * t0; + } while( y != 1 ); + return (1-t1) & 0xffff; +} + + + +static void +expand_key( const byte *userkey, u16 *ek ) +{ + int i,j; + + for(j=0; j < 8; j++ ) { + ek[j] = (*userkey << 8) + userkey[1]; + userkey += 2; + } + for(i=0; j < IDEA_KEYLEN; j++ ) { + i++; + ek[i+7] = ek[i&7] << 9 | ek[(i+1)&7] >> 7; + ek += i & 8; + i &= 7; + } +} + + +static void +invert_key( u16 *ek, u16 dk[IDEA_KEYLEN] ) +{ + int i; + u16 t1, t2, t3; + u16 temp[IDEA_KEYLEN]; + u16 *p = temp + IDEA_KEYLEN; + + t1 = mul_inv( *ek++ ); + t2 = -*ek++; + t3 = -*ek++; + *--p = mul_inv( *ek++ ); + *--p = t3; + *--p = t2; + *--p = t1; + + for(i=0; i < IDEA_ROUNDS-1; i++ ) { + t1 = *ek++; + *--p = *ek++; + *--p = t1; + + t1 = mul_inv( *ek++ ); + t2 = -*ek++; + t3 = -*ek++; + *--p = mul_inv( *ek++ ); + *--p = t2; + *--p = t3; + *--p = t1; + } + t1 = *ek++; + *--p = *ek++; + *--p = t1; + + t1 = mul_inv( *ek++ ); + t2 = -*ek++; + t3 = -*ek++; + *--p = mul_inv( *ek++ ); + *--p = t3; + *--p = t2; + *--p = t1; + memcpy(dk, temp, sizeof(temp) ); + wipememory(temp, sizeof(temp) ); /* burn temp */ +} + + +static void +cipher( byte *outbuf, const byte *inbuf, u16 *key ) +{ + u16 x1, x2, x3,x4, s2, s3; + u16 *in, *out; + int r = IDEA_ROUNDS; + #define MUL(x,y) \ + do {u16 _t16; u32 _t32; \ + if( (_t16 = (y)) ) { \ + if( (x = (x)&0xffff) ) { \ + _t32 = (u32)x * _t16; \ + x = _t32 & 0xffff; \ + _t16 = _t32 >> 16; \ + x = ((x)-_t16) + (x<_t16?1:0); \ + } \ + else { \ + x = 1 - _t16; \ + } \ + } \ + else { \ + x = 1 - x; \ + } \ + } while(0) + + in = (u16*)inbuf; + x1 = *in++; + x2 = *in++; + x3 = *in++; + x4 = *in; + #ifndef WORDS_BIGENDIAN + x1 = (x1>>8) | (x1<<8); + x2 = (x2>>8) | (x2<<8); + x3 = (x3>>8) | (x3<<8); + x4 = (x4>>8) | (x4<<8); + #endif + do { + MUL(x1, *key++); + x2 += *key++; + x3 += *key++; + MUL(x4, *key++ ); + + s3 = x3; + x3 ^= x1; + MUL(x3, *key++); + s2 = x2; + x2 ^=x4; + x2 += x3; + MUL(x2, *key++); + x3 += x2; + + x1 ^= x2; + x4 ^= x3; + + x2 ^= s3; + x3 ^= s2; + } while( --r ); + MUL(x1, *key++); + x3 += *key++; + x2 += *key++; + MUL(x4, *key); + + out = (u16*)outbuf; + #ifndef WORDS_BIGENDIAN + *out++ = (x1>>8) | (x1<<8); + *out++ = (x3>>8) | (x3<<8); + *out++ = (x2>>8) | (x2<<8); + *out = (x4>>8) | (x4<<8); + #else + *out++ = x1; + *out++ = x3; + *out++ = x2; + *out = x4; + #endif + #undef MUL +} + + +static int +do_setkey( IDEA_context *c, const byte *key, unsigned int keylen ) +{ + static int initialized = 0; + static const char *selftest_failed = 0; + + if( !initialized ) { + initialized = 1; + selftest_failed = selftest(); + if( selftest_failed ) + log_error( "%s\n", selftest_failed ); + } + if( selftest_failed ) + return G10ERR_SELFTEST_FAILED; + + assert(keylen == 16); + c->have_dk = 0; + expand_key( key, c->ek ); + invert_key( c->ek, c->dk ); + return 0; +} + +static int +idea_setkey (void *context, const byte *key, unsigned int keylen) +{ + IDEA_context *ctx = context; + int rc = do_setkey (ctx, key, keylen); + burn_stack (23+6*sizeof(void*)); + return rc; +} + +static void +encrypt_block( IDEA_context *c, byte *outbuf, const byte *inbuf ) +{ + cipher( outbuf, inbuf, c->ek ); +} + +static void +idea_encrypt (void *context, byte *out, const byte *in) +{ + IDEA_context *ctx = context; + encrypt_block (ctx, out, in); + burn_stack (24+3*sizeof (void*)); +} + +static void +decrypt_block( IDEA_context *c, byte *outbuf, const byte *inbuf ) +{ + if( !c->have_dk ) { + c->have_dk = 1; + invert_key( c->ek, c->dk ); + } + cipher( outbuf, inbuf, c->dk ); +} + +static void +idea_decrypt (void *context, byte *out, const byte *in) +{ + IDEA_context *ctx = context; + decrypt_block (ctx, out, in); + burn_stack (24+3*sizeof (void*)); +} + + +static const char * +selftest( void ) +{ +static struct { + byte key[16]; + byte plain[8]; + byte cipher[8]; +} test_vectors[] = { + { { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, + 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 }, + { 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03 }, + { 0x11, 0xFB, 0xED, 0x2B, 0x01, 0x98, 0x6D, 0xE5 } }, + { { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, + 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 }, + { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }, + { 0x54, 0x0E, 0x5F, 0xEA, 0x18, 0xC2, 0xF8, 0xB1 } }, + { { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, + 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 }, + { 0x00, 0x19, 0x32, 0x4B, 0x64, 0x7D, 0x96, 0xAF }, + { 0x9F, 0x0A, 0x0A, 0xB6, 0xE1, 0x0C, 0xED, 0x78 } }, + { { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, + 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 }, + { 0xF5, 0x20, 0x2D, 0x5B, 0x9C, 0x67, 0x1B, 0x08 }, + { 0xCF, 0x18, 0xFD, 0x73, 0x55, 0xE2, 0xC5, 0xC5 } }, + { { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, + 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 }, + { 0xFA, 0xE6, 0xD2, 0xBE, 0xAA, 0x96, 0x82, 0x6E }, + { 0x85, 0xDF, 0x52, 0x00, 0x56, 0x08, 0x19, 0x3D } }, + { { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, + 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 }, + { 0x0A, 0x14, 0x1E, 0x28, 0x32, 0x3C, 0x46, 0x50 }, + { 0x2F, 0x7D, 0xE7, 0x50, 0x21, 0x2F, 0xB7, 0x34 } }, + { { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, + 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 }, + { 0x05, 0x0A, 0x0F, 0x14, 0x19, 0x1E, 0x23, 0x28 }, + { 0x7B, 0x73, 0x14, 0x92, 0x5D, 0xE5, 0x9C, 0x09 } }, + { { 0x00, 0x05, 0x00, 0x0A, 0x00, 0x0F, 0x00, 0x14, + 0x00, 0x19, 0x00, 0x1E, 0x00, 0x23, 0x00, 0x28 }, + { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }, + { 0x3E, 0xC0, 0x47, 0x80, 0xBE, 0xFF, 0x6E, 0x20 } }, + { { 0x3A, 0x98, 0x4E, 0x20, 0x00, 0x19, 0x5D, 0xB3, + 0x2E, 0xE5, 0x01, 0xC8, 0xC4, 0x7C, 0xEA, 0x60 }, + { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }, + { 0x97, 0xBC, 0xD8, 0x20, 0x07, 0x80, 0xDA, 0x86 } }, + { { 0x00, 0x64, 0x00, 0xC8, 0x01, 0x2C, 0x01, 0x90, + 0x01, 0xF4, 0x02, 0x58, 0x02, 0xBC, 0x03, 0x20 }, + { 0x05, 0x32, 0x0A, 0x64, 0x14, 0xC8, 0x19, 0xFA }, + { 0x65, 0xBE, 0x87, 0xE7, 0xA2, 0x53, 0x8A, 0xED } }, + { { 0x9D, 0x40, 0x75, 0xC1, 0x03, 0xBC, 0x32, 0x2A, + 0xFB, 0x03, 0xE7, 0xBE, 0x6A, 0xB3, 0x00, 0x06 }, + { 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 }, + { 0xF5, 0xDB, 0x1A, 0xC4, 0x5E, 0x5E, 0xF9, 0xF9 } } +}; + IDEA_context c; + byte buffer[8]; + int i; + + for(i=0; i < DIM(test_vectors); i++ ) { + do_setkey( &c, test_vectors[i].key, 16 ); + encrypt_block( &c, buffer, test_vectors[i].plain ); + if( memcmp( buffer, test_vectors[i].cipher, 8 ) ) + return "IDEA test encryption failed."; + decrypt_block( &c, buffer, test_vectors[i].cipher ); + if( memcmp( buffer, test_vectors[i].plain, 8 ) ) + return "IDEA test decryption failed."; + } + + return NULL; +} + + +/**************** + * Return some information about the algorithm. We need algo here to + * distinguish different flavors of the algorithm. + * Returns: A pointer to string describing the algorithm or NULL if + * the ALGO is invalid. + */ +const char * +idea_get_info( int algo, size_t *keylen, + size_t *blocksize, size_t *contextsize, + int (**r_setkey)( void *c, const byte *key, unsigned keylen ), + void (**r_encrypt)( void *c, byte *outbuf, const byte *inbuf ), + void (**r_decrypt)( void *c, byte *outbuf, const byte *inbuf ) + ) +{ + *keylen = 128; + *blocksize = IDEA_BLOCKSIZE; + *contextsize = sizeof(IDEA_context); + *r_setkey = idea_setkey; + *r_encrypt = idea_encrypt; + *r_decrypt = idea_decrypt; + + if( algo == CIPHER_ALGO_IDEA ) + return "IDEA"; + return NULL; +} diff --git a/configure.ac b/configure.ac index 5dc0a52..275cdb8 100644 --- a/configure.ac +++ b/configure.ac @@ -203,24 +203,6 @@ AC_ARG_ENABLE(idea, AC_MSG_RESULT($use_idea) if test x"$use_idea" = xyes ; then AC_DEFINE(USE_IDEA,1,[Define to include the IDEA cipher]) - -# We don't need idea but some people claim that they need it for -# research etc., so we allow to place an idea source code into the -# cipher directory and statically link it if available, otherwise we -# link to a stub. We don't use AC_CHECK_FILE to avoid caching. - - AC_MSG_CHECKING([for idea cipher module]) - tmp="" - if test -f $srcdir/cipher/idea.c; then - IDEA_O=idea.o - tmp=idea - else - IDEA_O=idea-stub.o - tmp=no - try_extensions=yes - fi - AC_SUBST(IDEA_O) - AC_MSG_RESULT($tmp) fi AC_MSG_CHECKING([whether to enable the CAST5 cipher]) diff --git a/doc/DETAILS b/doc/DETAILS index 986b908..fe55ae1 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -115,7 +115,7 @@ record. available. The advantage of using this value is that it is guaranteed to have been been build by the same lookup algorithm as gpgsm uses. - For "uid" recods this lists the preferences n the sameway the + For "uid" recods this lists the preferences n the sameway the -edit menu does. For "sig" records, this is the fingerprint of the key that issued the signature. Note that this is only filled in if @@ -280,8 +280,8 @@ more arguments in future versions. UNEXPECTED Unexpected data has been encountered - 0 - not further specified 1 - + 0 - not further specified 1 + TRUST_UNDEFINED TRUST_NEVER @@ -296,7 +296,7 @@ more arguments in future versions. PKA_TRUST_BAD Depending on the outcome of the PKA check one of the above status codes is emitted in addition to a TRUST_* status. - Without PKA info available or + Without PKA info available or SIGEXPIRED This is deprecated in favor of KEYEXPIRED. @@ -316,11 +316,9 @@ more arguments in future versions. The ASCII armor is corrupted. No arguments yet. RSA_OR_IDEA - The IDEA algorithms has been used in the data. A - program might want to fallback to another program to handle - the data if GnuPG failed. This status message used to be emitted - also for RSA but this has been dropped after the RSA patent expired. - However we can't change the name of the message. + Obsolete. This status message used to be emitted for requests + to use the IDEA or RSA algorithms. It has been dropped from + GnuPG 1.4 after the respective patents expired. SHM_INFO SHM_GET @@ -389,7 +387,7 @@ more arguments in future versions. 1 := Entirely new key. 2 := New user IDs 4 := New signatures - 8 := New subkeys + 8 := New subkeys 16 := Contains private key. The flags may be ORed. @@ -410,7 +408,7 @@ more arguments in future versions. operation: 1 - verify 2 - encrypt - 3 - decrypt + 3 - decrypt FILE_DONE Marks the end of a file processing which has been started @@ -457,7 +455,7 @@ more arguments in future versions. "starting_agent" - A gpg-agent was started because it is not running as a daemon. - + SIG_CREATED A signature has been created using these parameters. type: 'D' = detached @@ -469,7 +467,7 @@ more arguments in future versions. Note, that TIMESTAMP may either be a number with seconds since epoch or an ISO 8601 string which can be detected by the presence of the letter 'T' inside. - + KEY_CREATED [] A key has been created type: 'B' = primary and subkey @@ -490,13 +488,13 @@ more arguments in future versions. is used. The format is suitable to be passed to the option --override-session-key - NOTATION_NAME + NOTATION_NAME NOTATION_DATA name and string are %XX escaped; the data may be splitted among several notation_data lines. USERID_HINT - Give a hint about the user ID for a certain keyID. + Give a hint about the user ID for a certain keyID. POLICY_URL string is %XX escaped @@ -533,7 +531,7 @@ more arguments in future versions. The output was truncated to MAXNO items. This status code is issued for certain external requests - ERROR + ERROR This is a generic error status message, it might be followed by error location specific data. and @@ -1144,12 +1142,12 @@ Here is the format we use for detached signatures: "@B" - Detached signature follows. This emits a control packet (1,'B') -"@t" - Signed text follows. +"@t" - Signed text follows. This emits the control packet (2, 'B') "@." - End of operation. The final control packet forces signature verification -"@>" - End of stream +"@>" - End of stream diff --git a/g10/gpg.c b/g10/gpg.c index 75e3c2f..573bb90 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -1134,8 +1134,6 @@ rm_group(char *name) directory is group or other writable or not owned by us. Disable exec in this case. - 2) Extensions. Same as #1. - Returns true if the item is unsafe. */ static int check_permissions(const char *path,int item) @@ -1152,16 +1150,7 @@ check_permissions(const char *path,int item) assert(item==0 || item==1 || item==2); - /* extensions may attach a path */ - if(item==2 && path[0]!=DIRSEP_C) - { - if(strchr(path,DIRSEP_C)) - tmppath=make_filename(path,NULL); - else - tmppath=make_filename(GNUPG_LIBDIR,path,NULL); - } - else - tmppath=xstrdup(path); + tmppath=xstrdup(path); /* If the item is located in the homedir, but isn't the homedir, don't continue if we already checked the homedir itself. This is @@ -1218,9 +1207,9 @@ check_permissions(const char *path,int item) homedir_cache=ret; } } - else if(item==1 || item==2) + else if(item==1) { - /* The options or extension file. Okay unless it or its + /* The options file. Okay unless it or its containing directory is group or other writable or not owned by us or root. */ @@ -1271,48 +1260,36 @@ check_permissions(const char *path,int item) if(item==0) log_info(_("WARNING: unsafe ownership on" " homedir `%s'\n"),tmppath); - else if(item==1) - log_info(_("WARNING: unsafe ownership on" - " configuration file `%s'\n"),tmppath); else log_info(_("WARNING: unsafe ownership on" - " extension `%s'\n"),tmppath); + " configuration file `%s'\n"),tmppath); } if(perm) { if(item==0) log_info(_("WARNING: unsafe permissions on" " homedir `%s'\n"),tmppath); - else if(item==1) - log_info(_("WARNING: unsafe permissions on" - " configuration file `%s'\n"),tmppath); else log_info(_("WARNING: unsafe permissions on" - " extension `%s'\n"),tmppath); + " configuration file `%s'\n"),tmppath); } if(enc_dir_own) { if(item==0) log_info(_("WARNING: unsafe enclosing directory ownership on" " homedir `%s'\n"),tmppath); - else if(item==1) - log_info(_("WARNING: unsafe enclosing directory ownership on" - " configuration file `%s'\n"),tmppath); else log_info(_("WARNING: unsafe enclosing directory ownership on" - " extension `%s'\n"),tmppath); + " configuration file `%s'\n"),tmppath); } if(enc_dir_perm) { if(item==0) log_info(_("WARNING: unsafe enclosing directory permissions on" " homedir `%s'\n"),tmppath); - else if(item==1) - log_info(_("WARNING: unsafe enclosing directory permissions on" - " configuration file `%s'\n"),tmppath); else log_info(_("WARNING: unsafe enclosing directory permissions on" - " extension `%s'\n"),tmppath); + " configuration file `%s'\n"),tmppath); } } @@ -2318,19 +2295,7 @@ main (int argc, char **argv ) } break; case oLoadExtension: -#ifndef __riscos__ -#if defined(USE_DYNAMIC_LINKING) || defined(_WIN32) - if(check_permissions(pargs.r.ret_str,2)) - log_info(_("cipher extension `%s' not loaded due to" - " unsafe permissions\n"),pargs.r.ret_str); - else - register_cipher_extension(orig_argc? *orig_argv:NULL, - pargs.r.ret_str); -#endif -#else /* __riscos__ */ - riscos_not_implemented("load-extension"); -#endif /* __riscos__ */ - break; + break; /* This is a dummy option since 1.4.13. */ case oRFC1991: opt.compliance = CO_RFC1991; opt.force_v4_certs = 0; @@ -3037,7 +3002,6 @@ main (int argc, char **argv ) { log_info(_("encrypting a message in --pgp2 mode requires " "the IDEA cipher\n")); - idea_cipher_warn(1); unusable=1; } else if(cmd==aSym) @@ -3097,12 +3061,6 @@ main (int argc, char **argv ) * may try to load an module */ if( def_cipher_string ) { opt.def_cipher_algo = string_to_cipher_algo(def_cipher_string); - if(opt.def_cipher_algo==0 && - (ascii_strcasecmp(def_cipher_string,"idea")==0 - || ascii_strcasecmp(def_cipher_string,"s1")==0)) - { - idea_cipher_warn(1); - } xfree(def_cipher_string); def_cipher_string = NULL; if( check_cipher_algo(opt.def_cipher_algo) ) log_error(_("selected cipher algorithm is invalid\n")); diff --git a/g10/keygen.c b/g10/keygen.c index 90bddae..7c473cb 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -332,14 +332,15 @@ keygen_set_std_prefs (const char *string,int personal) if(!check_cipher_algo(CIPHER_ALGO_CAST5)) strcat(dummy_string,"S3 "); strcat(dummy_string,"S2 "); /* 3DES */ - /* If we have it, IDEA goes *after* 3DES so it won't be + /* If we have it and we are in PGP2 mode, + IDEA goes *after* 3DES so it won't be used unless we're encrypting along with a V3 key. Ideally, we would only put the S1 preference in if the key was RSA and <=2048 bits, as that is what won't break PGP2, but that is difficult with the current code, and not really worth checking as a non-RSA <=2048 bit key wouldn't be usable by PGP2 anyway. -dms */ - if(!check_cipher_algo(CIPHER_ALGO_IDEA)) + if(PGP2 && !check_cipher_algo(CIPHER_ALGO_IDEA)) strcat(dummy_string,"S1 "); @@ -415,12 +416,6 @@ keygen_set_std_prefs (const char *string,int personal) else { log_info (_("invalid item `%s' in preference string\n"),tok); - - /* Complain if IDEA is not available. */ - if(ascii_strcasecmp(tok,"s1")==0 - || ascii_strcasecmp(tok,"idea")==0) - idea_cipher_warn(1); - rc=-1; } } diff --git a/g10/main.h b/g10/main.h index 584c4c7..784ade0 100644 --- a/g10/main.h +++ b/g10/main.h @@ -85,12 +85,6 @@ int openpgp_pk_test_algo( int algo, unsigned int usage_flags ); int openpgp_pk_algo_usage ( int algo ); int openpgp_md_test_algo( int algo ); -#ifdef USE_IDEA -void idea_cipher_warn( int show ); -#else -#define idea_cipher_warn(a) -#endif - void md5_digest_warn (int show); void not_in_gpg1_notice (void); @@ -224,7 +218,7 @@ void import_print_stats (void *hd); int collapse_uids( KBNODE *keyblock ); -int auto_create_card_key_stub ( const char *serialnostr, +int auto_create_card_key_stub ( const char *serialnostr, const unsigned char *fpr1, const unsigned char *fpr2, const unsigned char *fpr3); diff --git a/g10/mainproc.c b/g10/mainproc.c index 3ffb049..9cbf9ad 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -260,14 +260,6 @@ symkey_decrypt_seskey( DEK *dek, byte *seskey, size_t slen ) if(dek->keylen > DIM(dek->key)) BUG (); - /* This is not completely accurate, since a bad passphrase may have - resulted in a garbage algorithm byte, but it's close enough since - a bogus byte here will fail later. */ - if(dek->algo==CIPHER_ALGO_IDEA) - { - idea_cipher_warn(0); - } - memcpy(dek->key, seskey + 1, dek->keylen); /*log_hexdump( "thekey", dek->key, dek->keylen );*/ @@ -565,7 +557,6 @@ proc_encrypted( CTX c, PACKET *pkt ) algo = opt.def_cipher_algo; if (!algo) algo = opt.s2k_cipher_algo; - idea_cipher_warn(1); log_info (_("IDEA cipher unavailable, " "optimistically attempting to use %s instead\n"), cipher_algo_to_string(algo)); diff --git a/g10/misc.c b/g10/misc.c index b688a93..68b4cea 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -39,7 +39,7 @@ #ifdef _WIN32 #include #include -#include +#include #include #ifndef CSIDL_APPDATA #define CSIDL_APPDATA 0x001a @@ -71,7 +71,7 @@ #ifdef ENABLE_SELINUX_HACKS /* A object and a global variable to keep track of files marked as secured. */ -struct secured_file_item +struct secured_file_item { struct secured_file_item *next; ino_t ino; @@ -141,7 +141,7 @@ register_secured_file (const char *fname) /* Note that we stop immediatley if something goes wrong here. */ if (stat (fname, &buf)) - log_fatal (_("fstat of `%s' failed in %s: %s\n"), fname, + log_fatal (_("fstat of `%s' failed in %s: %s\n"), fname, "register_secured_file", strerror (errno)); /* log_debug ("registering `%s' i=%lu.%lu\n", fname, */ /* (unsigned long)buf.st_dev, (unsigned long)buf.st_ino); */ @@ -191,8 +191,8 @@ unregister_secured_file (const char *fname) } /* Return true if FD is corresponds to a secured file. Using -1 for - FS is allowed and will return false. */ -int + FS is allowed and will return false. */ +int is_secured_file (int fd) { #ifdef ENABLE_SELINUX_HACKS @@ -206,7 +206,7 @@ is_secured_file (int fd) secure if something went wrong. */ if (fstat (fd, &buf)) { - log_error (_("fstat(%d) failed in %s: %s\n"), fd, + log_error (_("fstat(%d) failed in %s: %s\n"), fd, "is_secured_file", strerror (errno)); return 1; } @@ -224,8 +224,8 @@ is_secured_file (int fd) /* Return true if FNAME is corresponds to a secured file. Using NULL, "" or "-" for FS is allowed and will return false. This function is used before creating a file, thus it won't fail if the file does - not exist. */ -int + not exist. */ +int is_secured_filename (const char *fname) { #ifdef ENABLE_SELINUX_HACKS @@ -233,7 +233,7 @@ is_secured_filename (const char *fname) struct secured_file_item *sf; if (iobuf_is_pipe_filename (fname) || !*fname) - return 0; + return 0; /* Note that we print out a error here and claim that a file is secure if something went wrong. */ @@ -369,10 +369,10 @@ get_session_marker( size_t *rlen ) ulong a, b; initialized = 1; - /* also this marker is guessable it is not easy to use this + /* also this marker is guessable it is not easy to use this * for a faked control packet because an attacker does not - * have enough control about the time the verification does - * take place. Of course, we can add just more random but + * have enough control about the time the verification does + * take place. Of course, we can add just more random but * than we need the random generator even for verification * tasks - which does not make sense. */ a = aa ^ (ulong)getpid(); @@ -407,13 +407,13 @@ openpgp_pk_test_algo( int algo, unsigned int usage_flags ) return check_pubkey_algo2( algo, usage_flags ); } -int +int openpgp_pk_algo_usage ( int algo ) { - int use = 0; - + int use = 0; + /* they are hardwired in gpg 1.0 */ - switch ( algo ) { + switch ( algo ) { case PUBKEY_ALGO_RSA: use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG | PUBKEY_USAGE_ENC | PUBKEY_USAGE_AUTH; break; @@ -426,14 +426,14 @@ openpgp_pk_algo_usage ( int algo ) case PUBKEY_ALGO_ELGAMAL: /* Allow encryption with type 20 keys if RFC-2440 compliance has been selected. Signing is broken thus we won't allow - this. */ + this. */ if (RFC2440) use = PUBKEY_USAGE_ENC; break; case PUBKEY_ALGO_ELGAMAL_E: use = PUBKEY_USAGE_ENC; break; - case PUBKEY_ALGO_DSA: + case PUBKEY_ALGO_DSA: use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG | PUBKEY_USAGE_AUTH; break; default: @@ -450,23 +450,6 @@ openpgp_md_test_algo( int algo ) return check_digest_algo(algo); } -#ifdef USE_IDEA -/* Special warning for the IDEA cipher */ -void -idea_cipher_warn(int show) -{ - static int warned=0; - - if(!warned || show) - { - log_info(_("the IDEA cipher plugin is not present\n")); - log_info(_("please see %s for more information\n"), - "http://www.gnupg.org/faq/why-not-idea.html"); - warned=1; - } -} -#endif - /* Print a warning if the md5 digest algorithm has been used. This warning is printed only once unless SHOW is used. */ void @@ -500,7 +483,7 @@ not_in_gpg1_notice (void) } -static unsigned long +static unsigned long get_signature_count(PKT_secret_key *sk) { #ifdef ENABLE_CARD_SUPPORT @@ -509,7 +492,7 @@ get_signature_count(PKT_secret_key *sk) struct agent_card_info_s info; if(agent_scd_getattr("SIG-COUNTER",&info)==0) return info.sig_counter; - } + } #endif /* How to do this without a card? */ @@ -600,7 +583,7 @@ pct_expando(const char *string,struct expando_args *args) sprintf(&ret[idx],"%lu",get_signature_count(args->sk)); idx+=strlen(&ret[idx]); done=1; - } + } break; case 'p': /* primary pk fingerprint of a sk */ @@ -669,7 +652,7 @@ pct_expando(const char *string,struct expando_args *args) case 't': /* e.g. "jpg" */ str=image_type_to_string(args->imagetype,0); break; - + case 'T': /* e.g. "image/jpeg" */ str=image_type_to_string(args->imagetype,2); break; @@ -1148,7 +1131,7 @@ unescape_percent_string (const unsigned char *s) while (*s) { if (*s == '%' && s[1] && s[2]) - { + { s++; *d = xtoi_2 (s); if (!*d) @@ -1164,7 +1147,7 @@ unescape_percent_string (const unsigned char *s) else *d++ = *s++; } - *d = 0; + *d = 0; return buffer; } @@ -1186,7 +1169,7 @@ has_invalid_email_chars (const char *s) const char *valid_chars= "01234567890_-.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - for ( ; *s; s++ ) + for ( ; *s; s++ ) { if ( *s & 0x80 ) continue; /* We only care about ASCII. */ @@ -1271,7 +1254,7 @@ default_homedir (void) if (!dir || !*dir) { char path[MAX_PATH]; - + /* It might be better to use LOCAL_APPDATA because this is defined as "non roaming" and thus more likely to be kept locally. For private keys this is desired. However, given @@ -1279,13 +1262,13 @@ default_homedir (void) using a system roaming serives might be better than to let them do it manually. A security conscious user will anyway use the registry entry to have better control. */ - if (w32_shgetfolderpath (NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE, - NULL, 0, path) >= 0) + if (w32_shgetfolderpath (NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE, + NULL, 0, path) >= 0) { char *tmp = xmalloc (strlen (path) + 6 +1); strcpy (stpcpy (tmp, path), "\\gnupg"); dir = tmp; - + /* Try to create the directory if it does not yet exists. */ if (access (dir, F_OK)) @@ -1325,7 +1308,7 @@ get_libexecdir (void) else { log_debug ("bad filename `%s' returned for this process\n", dir); - *dir = 0; + *dir = 0; } } diff --git a/g10/pkclist.c b/g10/pkclist.c index d0d2a53..158ddf0 100644 --- a/g10/pkclist.c +++ b/g10/pkclist.c @@ -162,7 +162,7 @@ show_revocation_reason( PKT_public_key *pk, int mode ) * mode: 0 = standard * 1 = Without key info and additional menu option 'm' * this does also add an option to set the key to ultimately trusted. - * Returns: + * Returns: * -2 = nothing changed - caller should show some additional info * -1 = quit operation * 0 = nothing changed @@ -198,7 +198,7 @@ do_edit_ownertrust (PKT_public_key *pk, int mode, uppercase. Below you will find the matching strings which should be translated accordingly and the letter changed to match the one in the answer string. - + i = please show me more information m = back to the main menu s = skip this key @@ -206,9 +206,9 @@ do_edit_ownertrust (PKT_public_key *pk, int mode, */ const char *ans = _("iImMqQsS"); - if( !did_help ) + if( !did_help ) { - if( !mode ) + if( !mode ) { KBNODE keyblock, un; @@ -235,7 +235,7 @@ do_edit_ownertrust (PKT_public_key *pk, int mode, if (un->pkt->pkt.user_id->is_primary && !un->pkt->pkt.user_id->attrib_data ) continue; - + if((opt.verify_options&VERIFY_SHOW_PHOTOS) && un->pkt->pkt.user_id->attrib_data) show_photos(un->pkt->pkt.user_id->attribs, @@ -247,7 +247,7 @@ do_edit_ownertrust (PKT_public_key *pk, int mode, tty_printf(_(" aka \"%s\"\n"),p); } - + print_fingerprint (pk, NULL, 2); tty_printf("\n"); release_kbnode (keyblock); @@ -305,7 +305,7 @@ do_edit_ownertrust (PKT_public_key *pk, int mode, did_help = 0; else if( *p && p[1] ) ; - else if( !p[1] && ((*p >= '0'+min_num) && *p <= (mode?'5':'4')) ) + else if( !p[1] && ((*p >= '0'+min_num) && *p <= (mode?'5':'4')) ) { unsigned int trust; switch( *p ) @@ -331,14 +331,14 @@ do_edit_ownertrust (PKT_public_key *pk, int mode, } #if 0 /* not yet implemented */ - else if( *p == ans[0] || *p == ans[1] ) + else if( *p == ans[0] || *p == ans[1] ) { tty_printf(_("Certificates leading to an ultimately trusted key:\n")); show = 1; break; } #endif - else if( mode && (*p == ans[2] || *p == ans[3] || *p == CONTROL_D ) ) + else if( mode && (*p == ans[2] || *p == ans[3] || *p == CONTROL_D ) ) { break ; /* back to the menu */ } @@ -357,9 +357,9 @@ do_edit_ownertrust (PKT_public_key *pk, int mode, return show? -2: quit? -1 : changed; } -/* +/* * Display a menu to change the ownertrust of the key PK (which should - * be a primary key). + * be a primary key). * For mode values see do_edit_ownertrust () */ int @@ -416,7 +416,7 @@ do_we_trust( PKT_public_key *pk, unsigned int trustlevel ) log_error ("invalid trustlevel %u returned from validation layer\n", trustlevel); /* fall thru */ - case TRUST_UNKNOWN: + case TRUST_UNKNOWN: case TRUST_UNDEFINED: log_info(_("%s: There is no assurance this key belongs" " to the named user\n"),keystr_from_pk(pk)); @@ -491,7 +491,7 @@ check_signatures_trust( PKT_signature *sig ) int rc=0; rc = get_pubkey( pk, sig->keyid ); - if (rc) + if (rc) { /* this should not happen */ log_error("Ooops; the key vanished - can't check the trust\n"); rc = G10ERR_NO_PUBKEY; @@ -513,7 +513,7 @@ check_signatures_trust( PKT_signature *sig ) trustlevel = get_validity (pk, NULL); - if ( (trustlevel & TRUST_FLAG_REVOKED) ) + if ( (trustlevel & TRUST_FLAG_REVOKED) ) { write_status( STATUS_KEYREVOKED ); if(pk->is_revoked==2) @@ -524,13 +524,13 @@ check_signatures_trust( PKT_signature *sig ) log_info(_(" This could mean that the signature is forged.\n")); show_revocation_reason( pk, 0 ); } - else if ((trustlevel & TRUST_FLAG_SUB_REVOKED) ) + else if ((trustlevel & TRUST_FLAG_SUB_REVOKED) ) { write_status( STATUS_KEYREVOKED ); log_info(_("WARNING: This subkey has been revoked by its owner!\n")); show_revocation_reason( pk, 0 ); } - + if ((trustlevel & TRUST_FLAG_DISABLED)) log_info (_("Note: This key has been disabled.\n")); @@ -563,9 +563,9 @@ check_signatures_trust( PKT_signature *sig ) "does not match DNS entry\n"), sig->pka_info->email); } - switch ( (trustlevel & TRUST_MASK) ) + switch ( (trustlevel & TRUST_MASK) ) { - case TRUST_UNKNOWN: + case TRUST_UNKNOWN: case TRUST_UNDEFINED: case TRUST_MARGINAL: if (okay && opt.verify_options&VERIFY_PKA_TRUST_INCREASE) @@ -587,18 +587,18 @@ check_signatures_trust( PKT_signature *sig ) } /* Now let the user know what up with the trustlevel. */ - switch ( (trustlevel & TRUST_MASK) ) + switch ( (trustlevel & TRUST_MASK) ) { case TRUST_EXPIRED: log_info(_("Note: This key has expired!\n")); print_fingerprint (pk, NULL, 1); break; - + default: log_error ("invalid trustlevel %u returned from validation layer\n", trustlevel); /* fall thru */ - case TRUST_UNKNOWN: + case TRUST_UNKNOWN: case TRUST_UNDEFINED: write_status( STATUS_TRUST_UNDEFINED ); log_info(_("WARNING: This key is not certified with" @@ -790,7 +790,7 @@ build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned int use ) /* Check whether there are any recipients in the list and build the * list of the encrypt-to ones (we always trust them). */ - for ( rov = remusr; rov; rov = rov->next ) + for ( rov = remusr; rov; rov = rov->next ) { if ( !(rov->flags & 1) ) { @@ -809,7 +809,7 @@ build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned int use ) compliance_failure(); } } - else if ( (use & PUBKEY_USAGE_ENC) && !opt.no_encrypt_to ) + else if ( (use & PUBKEY_USAGE_ENC) && !opt.no_encrypt_to ) { /* Encryption has been requested and --encrypt-to has not been disabled. Check this encrypt-to key. */ @@ -818,7 +818,7 @@ build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned int use ) /* We explicitly allow encrypt-to to an disabled key; thus we pass 1 as last argument. */ - if ( (rc = get_pubkey_byname ( pk, rov->d, NULL, NULL, 1 )) ) + if ( (rc = get_pubkey_byname ( pk, rov->d, NULL, NULL, 1 )) ) { free_public_key ( pk ); pk = NULL; log_error (_("%s: skipped: %s\n"), rov->d, g10_errstr(rc) ); @@ -826,7 +826,7 @@ build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned int use ) rov->d, strlen (rov->d), -1); goto fail; } - else if ( !(rc=check_pubkey_algo2 (pk->pubkey_algo, use )) ) + else if ( !(rc=check_pubkey_algo2 (pk->pubkey_algo, use )) ) { /* Skip the actual key if the key is already present * in the list. Add it to our list if not. */ @@ -858,7 +858,7 @@ build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned int use ) } } } - else + else { /* The public key is not usable for encryption or not available. */ @@ -873,8 +873,8 @@ build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned int use ) /* If we don't have any recipients yet and we are not in batch mode drop into interactive selection mode. */ - if ( !any_recipients && !opt.batch ) - { + if ( !any_recipients && !opt.batch ) + { int have_def_rec; char *answer = NULL; STRLIST backlog = NULL; @@ -886,7 +886,7 @@ build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned int use ) if ( !have_def_rec ) tty_printf(_("You did not specify a user ID. (you may use \"-r\")\n")); - for (;;) + for (;;) { rc = 0; xfree(answer); @@ -896,7 +896,7 @@ build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned int use ) answer = def_rec; def_rec = NULL; } - else if (backlog) + else if (backlog) { /* This is part of our trick to expand and display groups. */ answer = pop_strlist (&backlog); @@ -939,8 +939,8 @@ build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned int use ) trim_spaces(answer); cpr_kill_prompt(); } - - if ( !answer || !*answer ) + + if ( !answer || !*answer ) { xfree(answer); break; /* No more recipients entered - get out of loop. */ @@ -960,12 +960,12 @@ build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned int use ) rc = get_pubkey_byname( pk, answer, NULL, NULL, 0 ); if (rc) tty_printf(_("No such user ID.\n")); - else if ( !(rc=check_pubkey_algo2(pk->pubkey_algo, use)) ) + else if ( !(rc=check_pubkey_algo2(pk->pubkey_algo, use)) ) { if ( have_def_rec ) { /* No validation for a default recipient. */ - if (!key_present_in_pk_list(pk_list, pk)) + if (!key_present_in_pk_list(pk_list, pk)) { free_public_key (pk); pk = NULL; log_info (_("skipped: public key " @@ -985,13 +985,13 @@ build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned int use ) else { /* Check validity of this key. */ int trustlevel; - + trustlevel = get_validity (pk, pk->user_id); - if ( (trustlevel & TRUST_FLAG_DISABLED) ) + if ( (trustlevel & TRUST_FLAG_DISABLED) ) { tty_printf (_("Public key is disabled.\n") ); } - else if ( do_we_trust_pre (pk, trustlevel) ) + else if ( do_we_trust_pre (pk, trustlevel) ) { /* Skip the actual key if the key is already * present in the list */ @@ -1023,7 +1023,7 @@ build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned int use ) pk = NULL; } } - else if ( !any_recipients && (def_rec = default_recipient()) ) + else if ( !any_recipients && (def_rec = default_recipient()) ) { /* We are in batch mode and have only a default recipient. */ pk = xmalloc_clear( sizeof *pk ); @@ -1034,7 +1034,7 @@ build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned int use ) rc = get_pubkey_byname (pk, def_rec, NULL, NULL, 1); if (rc) log_error(_("unknown default recipient \"%s\"\n"), def_rec ); - else if ( !(rc=check_pubkey_algo2(pk->pubkey_algo, use)) ) + else if ( !(rc=check_pubkey_algo2(pk->pubkey_algo, use)) ) { /* Mark any_recipients here since the default recipient would have been used if it wasn't already there. It @@ -1044,7 +1044,7 @@ build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned int use ) if (!key_present_in_pk_list(pk_list, pk)) log_info (_("skipped: public key already set " "as default recipient\n")); - else + else { PK_LIST r = xmalloc( sizeof *r ); r->pk = pk; pk = NULL; @@ -1060,18 +1060,18 @@ build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned int use ) } xfree(def_rec); def_rec = NULL; } - else + else { /* General case: Check all keys. */ any_recipients = 0; - for (; remusr; remusr = remusr->next ) + for (; remusr; remusr = remusr->next ) { if ( (remusr->flags & 1) ) continue; /* encrypt-to keys are already handled. */ pk = xmalloc_clear( sizeof *pk ); pk->req_usage = use; - if ( (rc = get_pubkey_byname( pk, remusr->d, NULL, NULL, 0 )) ) + if ( (rc = get_pubkey_byname( pk, remusr->d, NULL, NULL, 0 )) ) { /* Key not found or other error. */ free_public_key( pk ); pk = NULL; @@ -1081,13 +1081,13 @@ build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned int use ) -1); goto fail; } - else if ( !(rc=check_pubkey_algo2(pk->pubkey_algo, use )) ) + else if ( !(rc=check_pubkey_algo2(pk->pubkey_algo, use )) ) { /* Key found and usable. Check validity. */ int trustlevel; - + trustlevel = get_validity (pk, pk->user_id); - if ( (trustlevel & TRUST_FLAG_DISABLED) ) + if ( (trustlevel & TRUST_FLAG_DISABLED) ) { /*Key has been disabled. */ free_public_key(pk); pk = NULL; @@ -1100,7 +1100,7 @@ build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned int use ) rc=G10ERR_UNU_PUBKEY; goto fail; } - else if ( do_we_trust_pre( pk, trustlevel ) ) + else if ( do_we_trust_pre( pk, trustlevel ) ) { /* Note: do_we_trust may have changed the trustlevel */ @@ -1110,7 +1110,7 @@ build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned int use ) /* Skip the actual key if the key is already present * in the list */ - if (!key_present_in_pk_list(pk_list, pk)) + if (!key_present_in_pk_list(pk_list, pk)) { free_public_key(pk); pk = NULL; log_info(_("%s: skipped: public key already present\n"), @@ -1150,14 +1150,14 @@ build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned int use ) } } } - - if ( !rc && !any_recipients ) + + if ( !rc && !any_recipients ) { log_error(_("no valid addressees\n")); write_status_text (STATUS_NO_RECP, "0"); rc = G10ERR_NO_USER_ID; } - + fail: if ( rc ) @@ -1196,7 +1196,7 @@ algo_available( preftype_t preftype, int algo, const union pref_hint *hint ) && algo != CIPHER_ALGO_3DES && algo != CIPHER_ALGO_CAST5)) return 0; - + if(PGP7 && (algo != CIPHER_ALGO_IDEA && algo != CIPHER_ALGO_3DES && algo != CIPHER_ALGO_CAST5 @@ -1287,8 +1287,7 @@ select_algo_from_prefs(PK_LIST pk_list, int preftype, /* IDEA is implicitly there for v3 keys with v3 selfsigs if --pgp2 mode is on. This was a 2440 thing that was dropped from 4880 but is still relevant to GPG's 1991 - support. All this doesn't mean IDEA is actually - available, of course. */ + support. */ if(PGP2 && pkr->pk->version<4 && pkr->pk->selfsigversion<4) implicit=CIPHER_ALGO_IDEA; else @@ -1402,7 +1401,7 @@ select_algo_from_prefs(PK_LIST pk_list, int preftype, if(result==-1) { - unsigned int best=-1; + unsigned int best=-1; /* At this point, we have not selected an algorithm due to a special request or via personal prefs. Pick the highest @@ -1451,7 +1450,7 @@ select_algo_from_prefs(PK_LIST pk_list, int preftype, /* * Select the MDC flag from the pk_list. We can only use MDC if all recipients - * support this feature + * support this feature */ int select_mdc_from_pklist (PK_LIST pk_list) diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c index 041409a..51b5c55 100644 --- a/g10/pubkey-enc.c +++ b/g10/pubkey-enc.c @@ -49,7 +49,7 @@ is_algo_in_prefs ( KBNODE keyblock, preftype_t type, int algo ) if (k->pkt->pkttype == PKT_USER_ID) { PKT_user_id *uid = k->pkt->pkt.user_id; prefitem_t *prefs = uid->prefs; - + if (uid->created && prefs && !uid->is_revoked && !uid->is_expired ) { for (; prefs->type; prefs++ ) @@ -152,7 +152,7 @@ get_it( PKT_pubkey_enc *enc, DEK *dek, PKT_secret_key *sk, u32 *keyid ) byte *frame = NULL; unsigned n, nframe; u16 csum, csum2; - + int card = 0; if (sk->is_protected && sk->protect.s2k.mode == 1002) @@ -234,15 +234,11 @@ get_it( PKT_pubkey_enc *enc, DEK *dek, PKT_secret_key *sk, u32 *keyid ) dek->keylen = nframe - (n+1) - 2; dek->algo = frame[n++]; - if( dek->algo == CIPHER_ALGO_IDEA ) - write_status(STATUS_RSA_OR_IDEA); rc = check_cipher_algo( dek->algo ); if( rc ) { if( !opt.quiet && rc == G10ERR_CIPHER_ALGO ) { log_info(_("cipher algorithm %d%s is unknown or disabled\n"), dek->algo, dek->algo == CIPHER_ALGO_IDEA? " (IDEA)":""); - if(dek->algo==CIPHER_ALGO_IDEA) - idea_cipher_warn(0); } dek->algo = 0; goto leave; @@ -281,9 +277,9 @@ get_it( PKT_pubkey_enc *enc, DEK *dek, PKT_secret_key *sk, u32 *keyid ) " preferences\n"),cipher_algo_to_string(dek->algo)); if (!rc) { KBNODE k; - + for (k=pkb; k; k = k->next) { - if (k->pkt->pkttype == PKT_PUBLIC_KEY + if (k->pkt->pkttype == PKT_PUBLIC_KEY || k->pkt->pkttype == PKT_PUBLIC_SUBKEY){ u32 aki[2]; keyid_from_pk(k->pkt->pkt.public_key, aki); diff --git a/g10/seckey-cert.c b/g10/seckey-cert.c index 74f80c4..cad4e63 100644 --- a/g10/seckey-cert.c +++ b/g10/seckey-cert.c @@ -58,11 +58,6 @@ do_check( PKT_secret_key *sk, const char *tryagain_text, int mode, if( check_cipher_algo( sk->protect.algo ) ) { log_info(_("protection algorithm %d%s is not supported\n"), sk->protect.algo,sk->protect.algo==1?" (IDEA)":"" ); - if (sk->protect.algo==CIPHER_ALGO_IDEA) - { - write_status (STATUS_RSA_OR_IDEA); - idea_cipher_warn (0); - } return G10ERR_CIPHER_ALGO; } if(check_digest_algo(sk->protect.s2k.hash_algo)) @@ -110,7 +105,7 @@ do_check( PKT_secret_key *sk, const char *tryagain_text, int mode, attack */ sk->csum = 0; csum = 1; - if( ndata < 20 ) + if( ndata < 20 ) log_error("not enough bytes for SHA-1 checksum\n"); else { MD_HANDLE h = md_open (DIGEST_ALGO_SHA1, 1); @@ -359,10 +354,10 @@ protect_secret_key( PKT_secret_key *sk, DEK *dek ) p += narr[j]; xfree(bufarr[j]); } - + if (opt.simple_sk_checksum) { log_info (_("generating the deprecated 16-bit checksum" - " for secret key protection\n")); + " for secret key protection\n")); csum = checksum( data, ndata-2); sk->csum = csum; *p++ = csum >> 8; @@ -410,7 +405,7 @@ protect_secret_key( PKT_secret_key *sk, DEK *dek ) data[1] = nbits; cipher_encrypt (cipher_hd, data+2, buffer, nbytes); xfree( buffer ); - + mpi_free (sk->skey[i]); sk->skey[i] = mpi_set_opaque (NULL, data, nbytes+2); } diff --git a/g10/status.c b/g10/status.c index 9ce9ca8..5c43b27 100644 --- a/g10/status.c +++ b/g10/status.c @@ -91,7 +91,6 @@ get_status_string ( int no ) case STATUS_BADSIG : s = "BADSIG"; break; case STATUS_ERRSIG : s = "ERRSIG"; break; case STATUS_BADARMOR : s = "BADARMOR"; break; - case STATUS_RSA_OR_IDEA : s= "RSA_OR_IDEA"; break; case STATUS_TRUST_UNDEFINED: s = "TRUST_UNDEFINED"; break; case STATUS_TRUST_NEVER : s = "TRUST_NEVER"; break; case STATUS_TRUST_MARGINAL : s = "TRUST_MARGINAL"; break; diff --git a/g10/status.h b/g10/status.h index 61a0fce..6533d73 100644 --- a/g10/status.h +++ b/g10/status.h @@ -30,7 +30,8 @@ #define STATUS_BADARMOR 7 -#define STATUS_RSA_OR_IDEA 8 +/* Not anymore used: STATUS_RSA_OR_IDEA 8 */ + #define STATUS_KEYEXPIRED 9 #define STATUS_KEYREVOKED 10 diff --git a/gnupg.txt b/gnupg.txt index 4bb5603..3a9c8a8 100644 --- a/gnupg.txt +++ b/gnupg.txt @@ -10,14 +10,14 @@ Texts. A copy of the license is included in the file COPYING. %%name: GnuPG %%short-description: Complete implementation of the OpenPGP Internet standard. - + %%full-description: A complete and free replacement for PGP. The program does not use any patented algorithms, and can be used as a filter program. Can handle all OpenPGP messages and messages generated -by PGP 5.0 and newer unless they use the IDEA algorithm. +by PGP 5.0 and later. Supports ElGamal (signature and encrytion), DSA, AES, 3DES, Blowfish, -Twofish, CAST5, MD5, SHA-1, RIPE-MD-160 and TIGER, and has language +Twofish, CAST5, IDEA, MD5, SHA-1, RIPE-MD-160, and has language support for sixteen different languages. It is believed to be fully OpenPGP (as defined in RFC2440) conform, @@ -34,9 +34,9 @@ useful extra features like anonymous message recipients. %%updated: 1 Jun 2001 -%%keywords: PGP, security, decryption, encryption, digital signatures +%%keywords: PGP, security, decryption, encryption, digital signatures -%%programs: +%%programs: %%GNU: yes @@ -51,7 +51,7 @@ http://www.dewinter.com/gnupg_howto/english/; French HOWTO available from http://www.gnupg.org/howtos/fr/; German HOWTO available from http://www.gnupg.org/howtos/de/; Spanish HOWTO available from http://www.dewinter.com/gnupg_howto/spanish. - + %%developers: Matthew Skala, Michael Roth, Niklas Hernaeus, Remi Guyomarch, Werner Koch . @@ -89,7 +89,7 @@ Guyomarch, Werner Koch . %%help-list: gnupg-users at gnupg.org -%%help-news: +%%help-news: %%dev-list: gnupg-devel at gnupg.org ----------------------------------------------------------------------- Summary of changes: NEWS | 8 + README | 48 +++--- cipher/Makefile.am | 9 +- cipher/idea-stub.c | 182 ----------------------- cipher/idea.c | 411 ++++++++++++++++++++++++++++++++++++++++++++++++++++ configure.ac | 18 --- doc/DETAILS | 34 ++--- g10/gpg.c | 58 +------- g10/keygen.c | 11 +- g10/main.h | 8 +- g10/mainproc.c | 9 - g10/misc.c | 77 ++++------ g10/pkclist.c | 111 +++++++------- g10/pubkey-enc.c | 12 +- g10/seckey-cert.c | 13 +- g10/status.c | 1 - g10/status.h | 3 +- gnupg.txt | 14 +- 18 files changed, 575 insertions(+), 452 deletions(-) delete mode 100644 cipher/idea-stub.c create mode 100644 cipher/idea.c hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Nov 8 17:06:54 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 08 Nov 2012 17:06:54 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.5.0-48-g5abc061 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 5abc06114e91beca0177331e1c79815f5fb6d7be (commit) from 8cbbad5f94f6e0429fffe66d689aea20f7e35957 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 5abc06114e91beca0177331e1c79815f5fb6d7be Author: Werner Koch Date: Thu Nov 8 15:38:44 2012 +0100 Fix extern inline use for gcc > 4.3 in c99 mode * mpi/mpi-inline.h [!G10_MPI_INLINE_DECL]: Take care of changed extern inline semantics in gcc. -- I am not use how this will work out with non-gcc. However, we had no problems in the past and thus this change is the least invasive for non-gcc compilers. GnuPG-bug-id: 1406, 1435 diff --git a/mpi/mpi-inline.h b/mpi/mpi-inline.h index 88d9f56..94e2aec 100644 --- a/mpi/mpi-inline.h +++ b/mpi/mpi-inline.h @@ -28,8 +28,15 @@ #ifndef G10_MPI_INLINE_H #define G10_MPI_INLINE_H +/* Starting with gcc 4.3 "extern inline" conforms in c99 mode to the + c99 semantics. To keep the useful old semantics we use an + attribute. */ #ifndef G10_MPI_INLINE_DECL -#define G10_MPI_INLINE_DECL extern __inline__ +# ifdef __GNUC_STDC_INLINE__ +# define G10_MPI_INLINE_DECL extern inline __attribute__ ((__gnu_inline__)) +# else +# define G10_MPI_INLINE_DECL extern __inline__ +# endif #endif G10_MPI_INLINE_DECL mpi_limb_t ----------------------------------------------------------------------- Summary of changes: mpi/mpi-inline.h | 9 ++++++++- 1 files changed, 8 insertions(+), 1 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Thu Nov 8 17:08:08 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 08 Nov 2012 17:08:08 +0100 Subject: [git] GCRYPT - branch, LIBGCRYPT-1-5-BRANCH, updated. libgcrypt-1.5.0-13-g6feb29a Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, LIBGCRYPT-1-5-BRANCH has been updated via 6feb29a67a0e6660c876055ee59f2e716ef8e7c2 (commit) from 423571e111d54dbf0aa6cc7e7ef1516ae4327b3d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 6feb29a67a0e6660c876055ee59f2e716ef8e7c2 Author: Werner Koch Date: Thu Nov 8 15:38:44 2012 +0100 Fix extern inline use for gcc > 4.3 in c99 mode * mpi/mpi-inline.h [!G10_MPI_INLINE_DECL]: Take care of changed extern inline semantics in gcc. -- I am not use how this will work out with non-gcc. However, we had no problems in the past and thus this change is the least invasive for non-gcc compilers. GnuPG-bug-id: 1406, 1435 diff --git a/mpi/mpi-inline.h b/mpi/mpi-inline.h index 88d9f56..94e2aec 100644 --- a/mpi/mpi-inline.h +++ b/mpi/mpi-inline.h @@ -28,8 +28,15 @@ #ifndef G10_MPI_INLINE_H #define G10_MPI_INLINE_H +/* Starting with gcc 4.3 "extern inline" conforms in c99 mode to the + c99 semantics. To keep the useful old semantics we use an + attribute. */ #ifndef G10_MPI_INLINE_DECL -#define G10_MPI_INLINE_DECL extern __inline__ +# ifdef __GNUC_STDC_INLINE__ +# define G10_MPI_INLINE_DECL extern inline __attribute__ ((__gnu_inline__)) +# else +# define G10_MPI_INLINE_DECL extern __inline__ +# endif #endif G10_MPI_INLINE_DECL mpi_limb_t ----------------------------------------------------------------------- Summary of changes: mpi/mpi-inline.h | 9 ++++++++- 1 files changed, 8 insertions(+), 1 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Thu Nov 8 17:40:04 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 08 Nov 2012 17:40:04 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-1-4, updated. gnupg-1.4.12-16-g64e7c23 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-1-4 has been updated via 64e7c237db1eb5f463f4b810b09eda232da83676 (commit) from b1eac93431c377805984210a8ef76f5c314c8a5f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 64e7c237db1eb5f463f4b810b09eda232da83676 Author: Werner Koch Date: Thu Nov 8 15:59:47 2012 +0100 Create off-line card encryption key with the right size. * g10/keygen.c (gen_card_key_with_backup): Get the size of the key from the card. -- Formerly the off-line encryption key was created with a fixed length of 1024 bit. With this change the key is created as expected. GnuPG-bug-id: 1230 diff --git a/g10/keygen.c b/g10/keygen.c index 7c473cb..30ec370 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -3711,10 +3711,25 @@ gen_card_key_with_backup (int algo, int keyno, int is_primary, PKT_public_key *pk; size_t n; int i; + unsigned int nbits; sk_unprotected = NULL; sk_protected = NULL; - rc = generate_raw_key (algo, 1024, timestamp, + + /* Get the size of the key directly from the card. */ + { + struct agent_card_info_s info; + + memset (&info, 0, sizeof info); + if (!agent_scd_getattr ("KEY-ATTR", &info) + && info.key_attr[1].algo) + nbits = info.key_attr[1].nbits; + else + nbits = 1024; /* All pre-v2.0 cards. */ + agent_release_card_info (&info); + } + + rc = generate_raw_key (algo, nbits, timestamp, &sk_unprotected, &sk_protected); if (rc) return rc; ----------------------------------------------------------------------- Summary of changes: g10/keygen.c | 17 ++++++++++++++++- 1 files changed, 16 insertions(+), 1 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Nov 8 17:59:12 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 08 Nov 2012 17:59:12 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-1-4, updated. gnupg-1.4.12-17-ge3e5406 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-1-4 has been updated via e3e540604930d06ba23692ae3e4c43ec422a31b9 (commit) from 64e7c237db1eb5f463f4b810b09eda232da83676 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e3e540604930d06ba23692ae3e4c43ec422a31b9 Author: Werner Koch Date: Thu Nov 8 16:31:22 2012 +0100 de.po: Grammar fix * po/de.po: Grammar fix by Daniel Leidert -- GnuPG-bug-id: 1276 diff --git a/po/de.po b/po/de.po index 161e921..4b59683 100644 --- a/po/de.po +++ b/po/de.po @@ -4486,12 +4486,12 @@ msgid "" msgstr "" "Widerrufszertifikat wurde erzeugt.\n" "\n" -"Bitte speichern Sie es auf einem Medium welches Sie wegschlie?en\n" +"Bitte speichern Sie es auf einem Medium, welches Sie wegschlie?en\n" "k?nnen; falls Mallory (ein Angreifer) Zugang zu diesem Zertifikat\n" "erh?lt, kann er Ihren Schl?ssel unbrauchbar machen. Es w?re klug,\n" "dieses Widerrufszertifikat auch auszudrucken und sicher aufzubewahren,\n" "falls das urspr?ngliche Medium nicht mehr lesbar ist. Aber Obacht: Das\n" -"Drucksystem kann unter Umst?nden eine Kopie anderen Nutzern zug?nglich\n" +"Drucksystem kann unter Umst?nden anderen Nutzern eine Kopie zug?nglich\n" "machen.\n" msgid "Please select the reason for the revocation:\n" ----------------------------------------------------------------------- Summary of changes: po/de.po | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Nov 8 18:45:38 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 08 Nov 2012 18:45:38 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-1-4, updated. gnupg-1.4.12-18-g95347cf Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-1-4 has been updated via 95347cf950e2e26d1726791f9f4278af70dccce9 (commit) from e3e540604930d06ba23692ae3e4c43ec422a31b9 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 95347cf950e2e26d1726791f9f4278af70dccce9 Author: Werner Koch Date: Thu Nov 8 17:16:40 2012 +0100 tests: Skip secret key import check in SELinux mode * configure.ac (ENABLE_SELINUX_HACKS): New am_conditional. * checks/Makefile.am (prepared.stamp): Replace by defs-config.inc. (defs-config.inc): Create and set enable_selinux_hacks variable. * checks/defs.inc: Include defs-config.inc. * checks/armor.test: Do not run the last test in selinux mode. GnuPG-bug-id: 1390 diff --git a/checks/Makefile.am b/checks/Makefile.am index 70ae58b..0cfbe1c 100644 --- a/checks/Makefile.am +++ b/checks/Makefile.am @@ -6,12 +6,12 @@ # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. -# +# # GnuPG 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 General Public License for more details. -# +# # You should have received a copy of the GNU General Public License # along with this program; if not, see . # Process this file with automake to create Makefile.in @@ -39,22 +39,29 @@ DATA_FILES = data-500 data-9000 data-32000 data-80000 plain-large EXTRA_DIST = defs.inc $(TESTS) $(TEST_FILES) \ mkdemodirs signdemokey -CLEANFILES = prepared.stamp x y yy z out err $(DATA_FILES) \ +CLEANFILES = defs-config.inc x y yy z out err $(DATA_FILES) \ plain-1 plain-2 plain-3 trustdb.gpg *.lock .\#lk* \ *.test.log gpg_dearmor gpg.conf \ pubring.gpg secring.gpg pubring.pkr secring.skr DISTCLEANFILES = pubring.gpg~ random_seed -all-local: prepared.stamp +all-local: defs-config.inc distclean-local: $(srcdir)/mkdemodirs --clean -prepared.stamp: ./pubring.gpg ./secring.gpg ./plain-1 ./plain-2 ./plain-3 \ +defs-config.inc: ./pubring.gpg ./secring.gpg ./plain-1 ./plain-2 ./plain-3 \ ./pubring.pkr ./secring.skr ./gpg_dearmor $(DATA_FILES) - $(GPG_IMPORT) $(srcdir)/pubdemo.asc - echo timestamp >./prepared.stamp + $(GPG_IMPORT) $(srcdir)/pubdemo.asc + echo '# Do not edit - created by the Makefile. -*- sh -*-' \ + > defs-config.inc +if ENABLE_SELINUX_HACKS + echo enable_selinux_hacks=yes >> defs-config.inc +else + echo enable_selinux_hacks=no >> defs-config.inc +endif + ./gpg_dearmor: echo '#!/bin/sh' >./gpg_dearmor diff --git a/checks/armor.test b/checks/armor.test index 9fb9292..cfd2359 100755 --- a/checks/armor.test +++ b/checks/armor.test @@ -739,9 +739,14 @@ wg7Md81a5RI3F2FG8747t9gX # armor filter gpg swalled the CRC line and passed the '-----END...' # line on to the decryption layer. -# Can only perform this test if we have Twofish +# Can only perform this test if we have Twofish. We also can't use it +# if we have SELinux support, because that will fail on secret key +# import. -if $GPG --with-colons --list-config ciphername | grep TWOFISH > /dev/null 2>/dev/null ; then +if test x$enable_selinux_hacks = xyes ; then + echo "SELinux support is enabled: skipping secret key import check" +else + if $GPG --with-colons --list-config ciphername | grep TWOFISH > /dev/null 2>/dev/null ; then i=alpha_seckey info "importing: $i" eval "(IFS=; echo \"\$$i\")" >x @@ -755,4 +760,5 @@ if $GPG --with-colons --list-config ciphername | grep TWOFISH > /dev/null 2>/dev else error "bug#1179 is back in town" fi + fi fi diff --git a/checks/defs.inc b/checks/defs.inc index 080db3b..564828b 100755 --- a/checks/defs.inc +++ b/checks/defs.inc @@ -1,9 +1,12 @@ -# definitions for the check scripts +# definitions for the check scripts -*- sh -*- #-------------------------------- #------ constants --------------- #-------------------------------- +# First the Makefile generated constants +. ./defs-config.inc || exit 3 + # Note that usrpass1 is also used in Makefile.am usrname1="one" usrpass1="def" @@ -50,7 +53,7 @@ error () { defs_error_seen=yes echo "$pgmname:" $* >&5 if [ x$defs_stop_on_error != xyes ]; then - exit 1 + exit 1 fi } @@ -115,7 +118,7 @@ echo_n () { # Special function for zOS. my_chtag () { - #FIXME: Is there an envvar to test for the OS or do we + #FIXME: Is there an envvar to test for the OS or do we # need to resort to a configure test #if test "$FOO" = "bar"; then # chtag -tc ISO8859-1 $1 diff --git a/configure.ac b/configure.ac index 275cdb8..80d6e8a 100644 --- a/configure.ac +++ b/configure.ac @@ -920,6 +920,7 @@ fi AM_CONDITIONAL(ENABLE_CARD_SUPPORT, test "$card_support" = yes) AM_CONDITIONAL(ENABLE_AGENT_SUPPORT, test "$agent_support" = yes) +AM_CONDITIONAL(ENABLE_SELINUX_HACKS, test "$selinux_support" = yes) dnl Checks for header files. AC_HEADER_STDC ----------------------------------------------------------------------- Summary of changes: checks/Makefile.am | 21 ++++++++++++++------- checks/armor.test | 10 ++++++++-- checks/defs.inc | 9 ++++++--- configure.ac | 1 + 4 files changed, 29 insertions(+), 12 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Nov 8 19:42:04 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 08 Nov 2012 19:42:04 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.0beta3-94-g9f0e9ea Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 9f0e9ea80ca30269770eb955e33b54401bff917f (commit) from 905b6a36d3ca21b2f619721e1de892398e5eb759 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 9f0e9ea80ca30269770eb955e33b54401bff917f Author: Werner Koch Date: Tue Nov 6 18:51:47 2012 +0100 agent: Use wipememory instead of memset in one place. * agent/command.c (clear_outbuf): Use wipememory. Suggested by Ben Kibbey. diff --git a/agent/command.c b/agent/command.c index 88cd62c..3ba921b 100644 --- a/agent/command.c +++ b/agent/command.c @@ -158,7 +158,7 @@ clear_outbuf (membuf_t *mb) p = get_membuf (mb, &n); if (p) { - memset (p, 0, n); + wipememory (p, n); xfree (p); } } ----------------------------------------------------------------------- Summary of changes: agent/command.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Nov 12 17:00:01 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 12 Nov 2012 17:00:01 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.0beta3-95-g6505a99 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 6505a995f93fb82adc7ed560f177901aef6328b5 (commit) from 9f0e9ea80ca30269770eb955e33b54401bff917f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 6505a995f93fb82adc7ed560f177901aef6328b5 Author: Werner Koch Date: Sat Nov 10 11:34:21 2012 +0100 Fix description of validity flag 'n'. -- Thanks to Hauke Laging for spotting this. diff --git a/doc/DETAILS b/doc/DETAILS index 59434f1..4e87394 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -52,7 +52,7 @@ record; gpg2 does this by default and the option is a dummy. q = Undefined validity '-' and 'q' may safely be treated as the same value for most purposes - n = The key is valid + n = The key is not valid m = The key is marginal valid. f = The key is fully valid u = The key is ultimately valid. This often means ----------------------------------------------------------------------- Summary of changes: doc/DETAILS | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Nov 15 15:56:19 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 15 Nov 2012 15:56:19 +0100 Subject: [git] GPA - branch, master, updated. gpa-0.9.3-3-gdc37a3e Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Assistant". The branch, master has been updated via dc37a3e81712ffba565002c5e66cba1e62b108aa (commit) from 29fc35bedb2aff64453e817903f8951ac8663a65 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit dc37a3e81712ffba565002c5e66cba1e62b108aa Author: Werner Koch Date: Thu Nov 15 14:27:13 2012 +0100 Use native theme under Windows. * src/gpa.c (main) [WIN32]: Set Theme to MS-Windows. Suggested by Colin Leroy. diff --git a/src/gpa.c b/src/gpa.c index b6181ef..26d8274 100644 --- a/src/gpa.c +++ b/src/gpa.c @@ -366,6 +366,12 @@ main (int argc, char *argv[]) } gtk_init (&argc, &argv); +#ifdef G_OS_WIN32 + gtk_settings_set_string_property(gtk_settings_get_default(), + "gtk-theme-name", + "MS-Windows", + "XProperty"); +#endif /* Default icon for all windows. */ gtk_window_set_default_icon_from_file (GPA_DATADIR "/gpa.png", &err); ----------------------------------------------------------------------- Summary of changes: src/gpa.c | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-) hooks/post-receive -- The GNU Privacy Assistant http://git.gnupg.org From cvs at cvs.gnupg.org Fri Nov 16 12:10:41 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 16 Nov 2012 12:10:41 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.0beta3-98-ge7bc501 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via e7bc5012c568da9ceb0a80a8f3fe3edf3dac9564 (commit) via 011faa0c68cf0c628ef581193166e9ac9bf22b71 (commit) via ac775780fef3ef63f896e822add9ff6ea7e5119c (commit) from 6505a995f93fb82adc7ed560f177901aef6328b5 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e7bc5012c568da9ceb0a80a8f3fe3edf3dac9564 Author: Werner Koch Date: Fri Nov 16 10:36:53 2012 +0100 Fix non-portable use of chmod in autogen.sh. * autogen.sh: Remove option -c from chmod. diff --git a/autogen.sh b/autogen.sh index 0ec134d..dcb3834 100755 --- a/autogen.sh +++ b/autogen.sh @@ -287,7 +287,7 @@ if [ -d .git ]; then and .git/hooks/pre-commit.sample out of the way. EOF cp -av .git/hooks/pre-commit.sample .git/hooks/pre-commit - chmod -c +x .git/hooks/pre-commit + chmod +x .git/hooks/pre-commit fi tmp=$(git config --get filter.cleanpo.clean) if [ "$tmp" != "awk '/^\"POT-Creation-Date:/&&!s{s=1;next};!/^#: /{print}'" ] @@ -301,7 +301,7 @@ EOF *** Activating commit log message check hook. *** EOF cp -av scripts/git-hooks/commit-msg .git/hooks/commit-msg - chmod -c +x .git/hooks/commit-msg + chmod +x .git/hooks/commit-msg fi fi commit 011faa0c68cf0c628ef581193166e9ac9bf22b71 Author: Werner Koch Date: Fri Nov 16 10:35:33 2012 +0100 Improve parsing of the GIT revision number. * configure.ac (mmm4_revision): Use git rev-parse. diff --git a/configure.ac b/configure.ac index 0241a9d..90c77fa 100644 --- a/configure.ac +++ b/configure.ac @@ -31,8 +31,8 @@ m4_define([mym4_version], [2.1.0]) # the decimalized short revision number, a beta version string and a # flag indicating a development version (mym4_isgit). Note that the # m4 processing is done by autoconf and not during the configure run. -m4_define([mym4_revision], m4_esyscmd([git branch -v 2>/dev/null \ - | awk '/^\* / {printf "%s",$3}'])) +m4_define([mym4_revision], + m4_esyscmd([git rev-parse --short HEAD | tr -d '\n\r'])) m4_define([mym4_revision_dec], m4_esyscmd_s([echo $((0x$(echo ]mym4_revision[|head -c 4)))])) m4_define([mym4_betastring], commit ac775780fef3ef63f896e822add9ff6ea7e5119c Author: Werner Koch Date: Thu Nov 15 14:34:20 2012 +0100 Add an OpenPGP card vendor. * g10/card-util.c (get_manufacturer): Add Yubico. diff --git a/g10/card-util.c b/g10/card-util.c index 533489c..8358685 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -204,8 +204,9 @@ get_manufacturer (unsigned int no) case 0x0001: return "PPC Card Systems"; case 0x0002: return "Prism"; case 0x0003: return "OpenFortress"; - case 0x0004: return "Wewid AB"; + case 0x0004: return "Wewid"; case 0x0005: return "ZeitControl"; + case 0x0006: return "Yubico"; case 0x002A: return "Magrathea"; ----------------------------------------------------------------------- Summary of changes: autogen.sh | 4 ++-- configure.ac | 4 ++-- g10/card-util.c | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Nov 16 12:22:23 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 16 Nov 2012 12:22:23 +0100 Subject: [git] GPG-ERROR - branch, master, updated. libgpg-error-1.10-46-gb2e4d03 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Error codes used by GnuPG et al.". The branch, master has been updated via b2e4d03c88823151aa30f8a878ad1a30618d1340 (commit) via 17c8c16ee2dcb33abb7fdf50c40015f1b9d13689 (commit) from 33459ef19989db045f6437cdb35ddc203c7b90b7 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b2e4d03c88823151aa30f8a878ad1a30618d1340 Author: Werner Koch Date: Fri Nov 16 10:52:59 2012 +0100 Improve parsing of the GIT revision number. * configure.ac (git_revision): Use git rev-parse. diff --git a/configure.ac b/configure.ac index ee42f9e..85f9362 100644 --- a/configure.ac +++ b/configure.ac @@ -29,8 +29,8 @@ m4_define([my_issvn], [yes]) m4_define([svn_revision], m4_esyscmd([printf "%d" $(svn info 2>/dev/null \ | sed -n '/^Revision:/ s/[^0-9]//gp'|head -1)])) -m4_define([git_revision], m4_esyscmd([git branch -v 2>/dev/null \ - | awk '/^\* / {printf "%s",$3}'])) +m4_define([git_revision], + m4_esyscmd([git rev-parse --short HEAD | tr -d '\n\r'])) m4_define([my_full_version], [my_version[]m4_if(my_issvn,[yes], [m4_if(git_revision,[],[-svn[]svn_revision],[-git[]git_revision])])]) AC_INIT([libgpg-error],[my_full_version], [http://bugs.gnupg.org]) commit 17c8c16ee2dcb33abb7fdf50c40015f1b9d13689 Author: Werner Koch Date: Fri Nov 16 10:51:28 2012 +0100 Fix non-portable use of chmod in autogen.sh. * autogen.sh: Remove option -c from chmod. diff --git a/autogen.sh b/autogen.sh index 596565b..bf2c490 100755 --- a/autogen.sh +++ b/autogen.sh @@ -256,7 +256,7 @@ if [ -d .git ]; then and .git/hooks/pre-commit.sample out of the way. EOF cp -av .git/hooks/pre-commit.sample .git/hooks/pre-commit - chmod -c +x .git/hooks/pre-commit + chmod +x .git/hooks/pre-commit fi tmp=$(git config --get filter.cleanpo.clean) if [ "$tmp" != "awk '/^\"POT-Creation-Date:/&&!s{s=1;next};!/^#: /{print}'" ] ----------------------------------------------------------------------- Summary of changes: autogen.sh | 2 +- configure.ac | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) hooks/post-receive -- Error codes used by GnuPG et al. http://git.gnupg.org From cvs at cvs.gnupg.org Fri Nov 16 12:26:19 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 16 Nov 2012 12:26:19 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.5.0-49-g4b18e53 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 4b18e530f417d4af401a3fd721ad2a07e5310e3e (commit) from 5abc06114e91beca0177331e1c79815f5fb6d7be (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 4b18e530f417d4af401a3fd721ad2a07e5310e3e Author: Werner Koch Date: Fri Nov 16 10:57:26 2012 +0100 Improve parsing of the GIT revision number. * configure.ac (mmm4_revision): Use git rev-parse. diff --git a/configure.ac b/configure.ac index 3a5bccd..0e99ca5 100644 --- a/configure.ac +++ b/configure.ac @@ -33,8 +33,8 @@ m4_define(mym4_version, [1.6.0]) # decimalized short revision number, a beta version string, and a flag # indicating a development version (mym4_isgit). Note that the m4 # processing is done by autoconf and not during the configure run. -m4_define([mym4_revision], m4_esyscmd([git branch -v 2>/dev/null \ - | awk '/^\* / {printf "%s",$3}'])) +m4_define([mym4_revision], + m4_esyscmd([git rev-parse --short HEAD | tr -d '\n\r'])) m4_define([mym4_revision_dec], m4_esyscmd_s([echo $((0x$(echo ]mym4_revision[|head -c 4)))])) m4_define([mym4_betastring], ----------------------------------------------------------------------- Summary of changes: configure.ac | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Fri Nov 16 12:32:19 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 16 Nov 2012 12:32:19 +0100 Subject: [git] GCRYPT - branch, LIBGCRYPT-1-5-BRANCH, updated. libgcrypt-1.5.0-15-g322a9b5 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, LIBGCRYPT-1-5-BRANCH has been updated via 322a9b53e6f7e71aca46a45b12b036ecf46be8ee (commit) via 65c2a52a1cce0aa609b3b6c68c0e89890171209b (commit) from 6feb29a67a0e6660c876055ee59f2e716ef8e7c2 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 322a9b53e6f7e71aca46a45b12b036ecf46be8ee Author: Werner Koch Date: Fri Nov 16 11:03:10 2012 +0100 Improve parsing of the GIT revision number. * configure.ac (git_revision): Use git rev-parse. diff --git a/configure.ac b/configure.ac index 546dab7..a2f6b01 100644 --- a/configure.ac +++ b/configure.ac @@ -31,8 +31,9 @@ m4_define([my_issvn], [yes]) m4_define([svn_revision], m4_esyscmd([printf "%d" $(svn info 2>/dev/null \ | sed -n '/^Revision:/ s/[^0-9]//gp'|head -1)])) -m4_define([git_revision], m4_esyscmd([git branch -v 2>/dev/null \ - | awk '/^\* / {printf "%s",$3}'])) +m4_define([git_revision], + m4_esyscmd([git rev-parse --short HEAD | tr -d '\n\r'])) + AC_INIT([libgcrypt], [my_version[]m4_if(my_issvn,[yes], [m4_if(git_revision,[],[-svn[]svn_revision],[-git[]git_revision])])], commit 65c2a52a1cce0aa609b3b6c68c0e89890171209b Author: Werner Koch Date: Fri Nov 16 11:02:02 2012 +0100 Fix non-portable use of chmod in autogen.sh. * autogen.sh: Remove option -c from chmod. diff --git a/autogen.sh b/autogen.sh index d9a6586..92cc0d6 100755 --- a/autogen.sh +++ b/autogen.sh @@ -250,7 +250,7 @@ if [ -d .git ]; then and .git/hooks/pre-commit.sample out of the way. EOF cp -av .git/hooks/pre-commit.sample .git/hooks/pre-commit - chmod -c +x .git/hooks/pre-commit + chmod +x .git/hooks/pre-commit fi fi ----------------------------------------------------------------------- Summary of changes: autogen.sh | 2 +- configure.ac | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Fri Nov 16 15:00:53 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 16 Nov 2012 15:00:53 +0100 Subject: [git] Assuan - branch, master, updated. libassuan-2.0.3-11-g76ceeb3 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "IPC library used by GnuPG". The branch, master has been updated via 76ceeb3582bba138227bf76167b451ee017d38fc (commit) via e6688eebc03fda7c8c81789c24ad13c06f648a9f (commit) from ca3f8e4b5bbe5549bd7804cf3bff36be21db1b82 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 76ceeb3582bba138227bf76167b451ee017d38fc Author: Werner Koch Date: Fri Nov 16 13:27:48 2012 +0100 Improve parsing of the GIT revision number. * configure.ac (mmm4_revision): Use git rev-parse. Print version information at the end of a configure run. diff --git a/configure.ac b/configure.ac index c908ef2..b420f48 100644 --- a/configure.ac +++ b/configure.ac @@ -30,8 +30,9 @@ m4_define([my_issvn], [yes]) m4_define([svn_revision], m4_esyscmd([printf "%d" $( (svn info 2>/dev/null \ || echo 'Revision: 0')|sed -n '/^Revision:/ {s/[^0-9]//gp;q;}')])) -m4_define([git_revision], m4_esyscmd([git branch -v 2>/dev/null \ - | awk '/^\* / {printf "%s",$3}'])) +m4_define([git_revision], + m4_esyscmd([git rev-parse --short HEAD | tr -d '\n\r'])) + m4_define([my_full_version], [my_version[]m4_if(my_issvn,[yes], [m4_if(git_revision,[],[-svn[]svn_revision],[-git[]git_revision])])]) @@ -382,3 +383,10 @@ AC_CONFIG_FILES([src/libassuan-config], [chmod +x src/libassuan-config]) AC_CONFIG_FILES([src/versioninfo.rc]) AC_OUTPUT + +echo " + Libassuan v${VERSION} has been configured as follows: + + Revision: git_revision + Platform: $host +" commit e6688eebc03fda7c8c81789c24ad13c06f648a9f Author: Werner Koch Date: Fri Nov 16 13:26:39 2012 +0100 Fix non-portable use of chmod in autogen.sh. * autogen.sh: Remove option -c from chmod. diff --git a/autogen.sh b/autogen.sh index 42e00d5..875edde 100755 --- a/autogen.sh +++ b/autogen.sh @@ -259,14 +259,14 @@ if [ -d .git ]; then and .git/hooks/pre-commit.sample out of the way. EOF cp -av .git/hooks/pre-commit.sample .git/hooks/pre-commit - chmod -c +x .git/hooks/pre-commit + chmod +x .git/hooks/pre-commit fi if [ -f build-aux/git-hooks/commit-msg -a ! -f .git/hooks/commit-msg ] ; then cat <&2 *** Activating commit log message check hook. *** EOF cp -av build-aux/git-hooks/commit-msg .git/hooks/commit-msg - chmod -c +x .git/hooks/commit-msg + chmod +x .git/hooks/commit-msg fi fi ----------------------------------------------------------------------- Summary of changes: autogen.sh | 4 ++-- configure.ac | 12 ++++++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) hooks/post-receive -- IPC library used by GnuPG http://git.gnupg.org From cvs at cvs.gnupg.org Fri Nov 16 15:09:06 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 16 Nov 2012 15:09:06 +0100 Subject: [git] KSBA - branch, master, updated. libksba-1.3.0-3-g7b9662f Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "KSBA is a library to access X.509 certificates and CMS data.". The branch, master has been updated via 7b9662f2bf28feb575c4b2b181d88ca61ad43d53 (commit) via c18bf9d08d95a73192e12580ce5eae3454c07c0d (commit) from 31f4cbeb71b463a80f6d7842ac5e4df4f5c9d829 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 7b9662f2bf28feb575c4b2b181d88ca61ad43d53 Author: Werner Koch Date: Fri Nov 16 13:36:50 2012 +0100 Improve parsing of the GIT revision number. * configure.ac (mmm4_revision): Use git rev-parse. diff --git a/configure.ac b/configure.ac index e6de2a2..fe76192 100644 --- a/configure.ac +++ b/configure.ac @@ -33,8 +33,8 @@ m4_define(mym4_version, [1.3.1]) # decimalized short revision number, a beta version string, and a flag # indicating a development version (mym4_isgit). Note that the m4 # processing is done by autoconf and not during the configure run. -m4_define([mym4_revision], m4_esyscmd([git branch -v 2>/dev/null \ - | awk '/^\* / {printf "%s",$3}'])) +m4_define([mym4_revision], + m4_esyscmd([git rev-parse --short HEAD | tr -d '\n\r'])) m4_define([mym4_revision_dec], m4_esyscmd_s([echo $((0x$(echo ]mym4_revision[|head -c 4)))])) m4_define([mym4_betastring], @@ -409,6 +409,7 @@ AC_OUTPUT echo " Libksba v${VERSION} has been configured as follows: + Revision: mym4_revision (mym4_revision_dec) Platform: $host " commit c18bf9d08d95a73192e12580ce5eae3454c07c0d Author: Werner Koch Date: Fri Nov 16 13:36:37 2012 +0100 Fix non-portable use of chmod in autogen.sh. * autogen.sh: Remove option -c from chmod. diff --git a/autogen.sh b/autogen.sh index 17c3380..8f6c953 100755 --- a/autogen.sh +++ b/autogen.sh @@ -261,14 +261,14 @@ if [ -d .git ]; then and .git/hooks/pre-commit.sample out of the way. EOF cp -av .git/hooks/pre-commit.sample .git/hooks/pre-commit - chmod -c +x .git/hooks/pre-commit + chmod +x .git/hooks/pre-commit fi if [ -f build-aux/git-hooks/commit-msg -a ! -f .git/hooks/commit-msg ] ; then cat <&2 *** Activating commit log message check hook. *** EOF cp -av build-aux/git-hooks/commit-msg .git/hooks/commit-msg - chmod -c +x .git/hooks/commit-msg + chmod +x .git/hooks/commit-msg fi fi ----------------------------------------------------------------------- Summary of changes: autogen.sh | 4 ++-- configure.ac | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) hooks/post-receive -- KSBA is a library to access X.509 certificates and CMS data. http://git.gnupg.org From cvs at cvs.gnupg.org Fri Nov 16 15:20:02 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 16 Nov 2012 15:20:02 +0100 Subject: [git] GPGME - branch, master, updated. gpgme-1.3.2-25-g322552a Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GnuPG Made Easy". The branch, master has been updated via 322552a88db47896881e55c00ca301137cd160c6 (commit) via cd6de92f42cb6e5b85bc376d5544496cb4d6a88a (commit) via 1a17acd8e9b7c0ef924f98bfb1502fe12e83c363 (commit) from c97d067f27899d890a99036fcbed9263f4f68875 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 322552a88db47896881e55c00ca301137cd160c6 Author: Werner Koch Date: Fri Nov 16 13:50:58 2012 +0100 Improve parsing of the GIT revision number. * configure.ac (git_revision): Use git rev-parse. diff --git a/configure.ac b/configure.ac index c5300e3..75b6fcb 100644 --- a/configure.ac +++ b/configure.ac @@ -38,8 +38,8 @@ m4_define(my_isgit, [yes]) m4_define([svn_revision], m4_esyscmd([printf "%d" $( (svn info 2>/dev/null \ || echo 'Revision: 0')|sed -n '/^Revision:/ {s/[^0-9]//gp;q;}')])) -m4_define([git_revision], m4_esyscmd([git branch -v 2>/dev/null \ - | awk '/^\* / {printf "%s",$3}'])) +m4_define([git_revision], + m4_esyscmd([git rev-parse --short HEAD | tr -d '\n\r'])) m4_define([my_full_version], [my_version[]m4_if(my_isgit,[yes], [m4_if(git_revision,[],[-svn[]svn_revision],[-git[]git_revision])])]) @@ -970,15 +970,15 @@ AC_OUTPUT echo " GPGME v${VERSION} has been configured as follows: + Revision: git_revision (git_brevis) + Platform: $host + GnuPG path: $GPG GnuPG version: $GPG_VERSION, min. $NEED_GPG_VERSION - GpgSM path: $GPGSM GpgSM version: $GPGSM_VERSION, min. $NEED_GPGSM_VERSION - GpgConf path: $GPGCONF GpgConf version: $GPGCONF_VERSION, min. $NEED_GPGCONF_VERSION - G13 path: $G13 G13 version: $G13_VERSION, min. $NEED_G13_VERSION @@ -986,6 +986,5 @@ echo " UI Server: $uiserver FD Passing: $use_descriptor_passing - GPGME Pthread: $have_pthread " commit cd6de92f42cb6e5b85bc376d5544496cb4d6a88a Author: Werner Koch Date: Fri Nov 16 13:45:14 2012 +0100 Fix non-portable use of chmod in autogen.sh. * autogen.sh: Remove option -c from chmod. diff --git a/autogen.sh b/autogen.sh index 1f22367..abcfc27 100755 --- a/autogen.sh +++ b/autogen.sh @@ -261,14 +261,14 @@ if [ -d .git ]; then and .git/hooks/pre-commit.sample out of the way. EOF cp -av .git/hooks/pre-commit.sample .git/hooks/pre-commit - chmod -c +x .git/hooks/pre-commit + chmod +x .git/hooks/pre-commit fi if [ -f build-aux/git-hooks/commit-msg -a ! -f .git/hooks/commit-msg ] ; then cat <&2 *** Activating commit log message check hook. *** EOF cp -av build-aux/git-hooks/commit-msg .git/hooks/commit-msg - chmod -c +x .git/hooks/commit-msg + chmod +x .git/hooks/commit-msg fi fi commit 1a17acd8e9b7c0ef924f98bfb1502fe12e83c363 Author: Werner Koch Date: Thu Nov 15 11:14:58 2012 +0100 Make _gpgme_encode_percent_string work for memory buffers. * src/conversion.c (D_gpgme_encode_percent_string): Remove stray semicolon. Reported by Xi Wang. -- Obviously this function is not used with a supplied LEN argument != 0. diff --git a/src/conversion.c b/src/conversion.c index 356200c..b47d6de 100644 --- a/src/conversion.c +++ b/src/conversion.c @@ -282,7 +282,7 @@ _gpgme_encode_percent_string (const char *src, char **destp, size_t len) /* Set up the destination buffer. */ if (len) { - if (len < destlen); + if (len < destlen) return gpg_error (GPG_ERR_INTERNAL); dest = *destp; ----------------------------------------------------------------------- Summary of changes: autogen.sh | 4 ++-- configure.ac | 11 +++++------ src/conversion.c | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) hooks/post-receive -- GnuPG Made Easy http://git.gnupg.org From cvs at cvs.gnupg.org Fri Nov 16 15:24:36 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 16 Nov 2012 15:24:36 +0100 Subject: [git] GPA - branch, master, updated. gpa-0.9.3-5-gf33e483 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Assistant". The branch, master has been updated via f33e483ffc6dafe9b532f557237fd2352aadbd64 (commit) via 60585dad48784313984c33aadbc4b74ff68af068 (commit) from dc37a3e81712ffba565002c5e66cba1e62b108aa (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit f33e483ffc6dafe9b532f557237fd2352aadbd64 Author: Werner Koch Date: Fri Nov 16 13:55:26 2012 +0100 Improve parsing of the GIT revision number. * configure.ac (git_revision): Use git rev-parse. diff --git a/configure.ac b/configure.ac index 8a72808..87d857c 100644 --- a/configure.ac +++ b/configure.ac @@ -32,8 +32,8 @@ m4_define(my_issvn, no) m4_define([svn_revision], m4_esyscmd([printf "%d" $(svn info 2>/dev/null \ | sed -n '/^Revision:/ s/[^0-9]//gp'|head -1)])) -m4_define([git_revision], m4_esyscmd([git branch -v 2>/dev/null \ - | awk '/^\* / {printf "%s",$3}'])) +m4_define([git_revision], + m4_esyscmd([git rev-parse --short HEAD | tr -d '\n\r'])) m4_define([my_full_version], [my_version[]m4_if(my_issvn,[yes], [m4_if(git_revision,[],[-svn[]svn_revision],[-git[]git_revision])])]) AC_INIT([gpa],[my_full_version],[http://bugs.gnupg.org]) @@ -412,3 +412,10 @@ doc/Makefile AC_OUTPUT + +echo " + GPA v${VERSION} has been configured as follows: + + Revision: git_revision + Platform: $host +" commit 60585dad48784313984c33aadbc4b74ff68af068 Author: Werner Koch Date: Fri Nov 16 13:52:04 2012 +0100 Fix non-portable use of chmod in autogen.sh. * autogen.sh: Remove option -c from chmod. diff --git a/autogen.sh b/autogen.sh index f9be59e..b8edcbe 100755 --- a/autogen.sh +++ b/autogen.sh @@ -214,7 +214,7 @@ if [ -d .git ]; then and .git/hooks/pre-commit.sample out of the way. EOF cp -av .git/hooks/pre-commit.sample .git/hooks/pre-commit - chmod -c +x .git/hooks/pre-commit + chmod +x .git/hooks/pre-commit fi tmp=$(git config --get filter.cleanpo.clean) if [ "$tmp" != "awk '/^\"POT-Creation-Date:/&&!s{s=1;next};!/^#: /{print}'" ] @@ -228,7 +228,7 @@ EOF *** Activating commit log message check hook. *** EOF cp -av build-aux/git-hooks/commit-msg .git/hooks/commit-msg - chmod -c +x .git/hooks/commit-msg + chmod +x .git/hooks/commit-msg fi fi ----------------------------------------------------------------------- Summary of changes: autogen.sh | 4 ++-- configure.ac | 11 +++++++++-- 2 files changed, 11 insertions(+), 4 deletions(-) hooks/post-receive -- The GNU Privacy Assistant http://git.gnupg.org From cvs at cvs.gnupg.org Tue Nov 20 20:33:11 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 20 Nov 2012 20:33:11 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.0beta3-99-g835698b Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 835698b72bc509565aad52b0753f1c56c1a8f062 (commit) from e7bc5012c568da9ceb0a80a8f3fe3edf3dac9564 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 835698b72bc509565aad52b0753f1c56c1a8f062 Author: Werner Koch Date: Tue Nov 20 19:01:13 2012 +0100 Do not use a broken ttyname. * configure.ac (HAVE_BROKEN_TTYNAME): New ac_define set for Android systems. * common/util.h (gnupg_ttyname): New macro. Change all callers of ttyname to use this macro instead. (ttyname) [W32]: Rename to _gnupg_ttyname and use also if HAVE_BROKEN_TTYNAME is defined. * common/simple-pwquery.c (agent_send_all_options): Keep on using ttyname unless HAVE_BROKEN_TTYNAME is set. This is because this file may be used standalone. diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index b117849..32da578 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -662,7 +662,7 @@ main (int argc, char **argv ) } if (!err) { - s = ttyname (0); + s = gnupg_ttyname (0); if (s) err = session_env_setenv (opt.startup_env, "GPG_TTY", s); } @@ -984,7 +984,7 @@ main (int argc, char **argv ) } /* Make sure that we have a default ttyname. */ - if (!default_ttyname && ttyname (1)) + if (!default_ttyname && gnupg_ttyname (1)) default_ttyname = xstrdup (ttyname (1)); if (!default_ttytype && getenv ("TERM")) default_ttytype = xstrdup (getenv ("TERM")); diff --git a/common/session-env.c b/common/session-env.c index ff90447..478d5e3 100644 --- a/common/session-env.c +++ b/common/session-env.c @@ -338,8 +338,11 @@ session_env_getenv_or_default (session_env_t se, const char *name, /* Get the default value with an additional fallback for GPG_TTY. */ defvalue = getenv (name); - if ((!defvalue || !*defvalue) && !strcmp (name, "GPG_TTY") && ttyname (0)) - defvalue = ttyname (0); + if ((!defvalue || !*defvalue) && !strcmp (name, "GPG_TTY") + && gnupg_ttyname (0)) + { + defvalue = gnupg_ttyname (0); + } if (defvalue) { /* Record the default value for later use so that we are safe diff --git a/common/simple-pwquery.c b/common/simple-pwquery.c index 23e4b89..08f59d2 100644 --- a/common/simple-pwquery.c +++ b/common/simple-pwquery.c @@ -222,7 +222,7 @@ agent_send_all_options (int fd) } dft_ttyname = getenv ("GPG_TTY"); -#ifndef HAVE_W32_SYSTEM +#if !defined(HAVE_W32_SYSTEM) && !defined(HAVE_BROKEN_TTYNAME) if ((!dft_ttyname || !*dft_ttyname) && ttyname (0)) dft_ttyname = ttyname (0); #endif diff --git a/common/util.h b/common/util.h index 5ea7b81..c8a008f 100644 --- a/common/util.h +++ b/common/util.h @@ -291,15 +291,21 @@ int gnupg_compare_version (const char *a, const char *b); /*-- Simple replacement functions. */ -#ifndef HAVE_TTYNAME + +/* We use the gnupg_ttyname macro to be safe not to run into conflicts + which an extisting but broken ttyname. */ +#if !defined(HAVE_TTYNAME) || defined(HAVE_BROKEN_TTYNAME) +# define gnupg_ttyname(n) _gnupg_ttyname ((n)) /* Systems without ttyname (W32) will merely return NULL. */ static inline char * -ttyname (int fd) +_gnupg_ttyname (int fd) { (void)fd; return NULL; } -#endif /* !HAVE_TTYNAME */ +#else /*HAVE_TTYNAME*/ +# define gnupg_ttyname(n) ttyname ((n)) +#endif /*HAVE_TTYNAME */ #ifdef HAVE_W32CE_SYSTEM #define getpid() GetCurrentProcessId () diff --git a/configure.ac b/configure.ac index 90c77fa..e821b99 100644 --- a/configure.ac +++ b/configure.ac @@ -1247,6 +1247,12 @@ AC_CHECK_FUNCS([atexit raise getpagesize strftime nl_langinfo setlocale]) AC_CHECK_FUNCS([waitpid wait4 sigaction sigprocmask pipe getaddrinfo]) AC_CHECK_FUNCS([ttyname rand ftello fsync stat lstat]) +if test "$have_android_system" = yes; then + # On Android ttyname is a stub but prints an error message. + AC_DEFINE(HAVE_BROKEN_TTYNAME,1, + [Defined if ttyname does not work properly]) +fi + AC_CHECK_TYPES([struct sigaction, sigset_t],,,[#include ]) # Dirmngr requires mmap on Unix systems. diff --git a/sm/misc.c b/sm/misc.c index 4c6293f..ec9f97e 100644 --- a/sm/misc.c +++ b/sm/misc.c @@ -57,7 +57,7 @@ setup_pinentry_env (void) { log_error (_("GPG_TTY has not been set - " "using maybe bogus default\n")); - lc = ttyname (0); + lc = gnupg_ttyname (0); if (!lc) lc = "/dev/tty"; gnupg_setenv ("GPG_TTY", lc, 1); ----------------------------------------------------------------------- Summary of changes: agent/gpg-agent.c | 4 ++-- common/session-env.c | 7 +++++-- common/simple-pwquery.c | 2 +- common/util.h | 12 +++++++++--- configure.ac | 6 ++++++ sm/misc.c | 2 +- 6 files changed, 24 insertions(+), 9 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Nov 21 12:05:20 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 21 Nov 2012 12:05:20 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.5.0-50-ga96974d Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via a96974de734beb51a733a89b3283bcf7b433b54c (commit) from 4b18e530f417d4af401a3fd721ad2a07e5310e3e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a96974de734beb51a733a89b3283bcf7b433b54c Author: Werner Koch Date: Wed Nov 21 10:35:28 2012 +0100 Fix segv with AES-NI on some platforms. * cipher/rijndael.c (RIJNDAEL_context): Align on 16 bytes. -- The trigger for this problem is the allocation of the context in the selftest functions. The other code paths use a 16 byte alignment anyway by means of the allocation of the context in cipher.c Thanks to Gentoo hacker Joakim Tjernlund for figuring out the reason of this problem. GnuPG-bug-id: 1452 diff --git a/cipher/rijndael.c b/cipher/rijndael.c index d9a95cb..a2aedf0 100644 --- a/cipher/rijndael.c +++ b/cipher/rijndael.c @@ -126,7 +126,7 @@ typedef struct #ifdef USE_AESNI int use_aesni; /* AES-NI shall be used. */ #endif /*USE_AESNI*/ -} RIJNDAEL_context; +} RIJNDAEL_context ATTR_ALIGNED_16; /* Macros defining alias for the keyschedules. */ #define keyschenc u1.keyschedule ----------------------------------------------------------------------- Summary of changes: cipher/rijndael.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Wed Nov 21 12:15:13 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 21 Nov 2012 12:15:13 +0100 Subject: [git] GCRYPT - branch, LIBGCRYPT-1-5-BRANCH, updated. libgcrypt-1.5.0-16-gd30c864 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, LIBGCRYPT-1-5-BRANCH has been updated via d30c86465fef9531766fd7c124a5d87d7645850e (commit) from 322a9b53e6f7e71aca46a45b12b036ecf46be8ee (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d30c86465fef9531766fd7c124a5d87d7645850e Author: Werner Koch Date: Wed Nov 21 10:35:28 2012 +0100 Fix segv with AES-NI on some platforms. * cipher/rijndael.c (RIJNDAEL_context): Align on 16 bytes. -- The trigger for this problem is the allocation of the context in the selftest functions. The other code paths use a 16 byte alignment anyway by means of the allocation of the context in cipher.c Thanks to Gentoo hacker Joakim Tjernlund for figuring out the reason of this problem. GnuPG-bug-id: 1452 diff --git a/cipher/rijndael.c b/cipher/rijndael.c index 2df8ea9..92fa31d 100644 --- a/cipher/rijndael.c +++ b/cipher/rijndael.c @@ -124,7 +124,7 @@ typedef struct #ifdef USE_AESNI int use_aesni; /* AES-NI shall be used. */ #endif /*USE_AESNI*/ -} RIJNDAEL_context; +} RIJNDAEL_context ATTR_ALIGNED_16; /* Macros defining alias for the keyschedules. */ #define keyschenc u1.keyschedule ----------------------------------------------------------------------- Summary of changes: cipher/rijndael.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Wed Nov 21 14:28:43 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 21 Nov 2012 14:28:43 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.5.0-58-gdfb4673 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via dfb4673da8ee52d95e0a62c9f49ca8599943f22e (commit) via 3047795794eb238aa684bd0729acf64c82a19e09 (commit) via 7f90d3dff4f87c0c42fc9b9336bbe77e8d33d33a (commit) via 8afabc2813948778a3db52d9dee9a041a3dd50d4 (commit) via d8bdfa42ed582655c180e7db9b16d4e756a12a6e (commit) via 9e1552517f68459a165ddebbba85e7cf37ff4f0c (commit) via 19b9efd1f47a5de9c450ce8212dfa3174a029c7a (commit) via 6368ed542150956ff4ba8170a15bbc534143675c (commit) from a96974de734beb51a733a89b3283bcf7b433b54c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit dfb4673da8ee52d95e0a62c9f49ca8599943f22e Author: Werner Koch Date: Wed Nov 21 12:58:36 2012 +0100 Fix for strict aliasing rules. * cipher/rijndael.c (do_setkey, prepare_decryption): Use u32_a_t for casting. -- gcc 4.7.1 now show warnings for more functions. Like: rijndael.c:412:19: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing] This fixes them using the may_alias attribute. diff --git a/cipher/rijndael.c b/cipher/rijndael.c index 3418c99..d081b42 100644 --- a/cipher/rijndael.c +++ b/cipher/rijndael.c @@ -362,7 +362,7 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) for (j = KC-1; j >= 0; j--) { - *((u32*)tk[j]) = *((u32*)k[j]); + *((u32_a_t*)tk[j]) = *((u32_a_t*)k[j]); } r = 0; t = 0; @@ -371,7 +371,7 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) { for (; (j < KC) && (t < 4); j++, t++) { - *((u32*)W[r][t]) = *((u32*)tk[j]); + *((u32_a_t*)W[r][t]) = *((u32_a_t*)tk[j]); } if (t == 4) { @@ -394,14 +394,14 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) { for (j = 1; j < KC; j++) { - *((u32*)tk[j]) ^= *((u32*)tk[j-1]); + *((u32_a_t*)tk[j]) ^= *((u32_a_t*)tk[j-1]); } } else { for (j = 1; j < KC/2; j++) { - *((u32*)tk[j]) ^= *((u32*)tk[j-1]); + *((u32_a_t*)tk[j]) ^= *((u32_a_t*)tk[j-1]); } tk[KC/2][0] ^= S[tk[KC/2 - 1][0]]; tk[KC/2][1] ^= S[tk[KC/2 - 1][1]]; @@ -409,7 +409,7 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) tk[KC/2][3] ^= S[tk[KC/2 - 1][3]]; for (j = KC/2 + 1; j < KC; j++) { - *((u32*)tk[j]) ^= *((u32*)tk[j-1]); + *((u32_a_t*)tk[j]) ^= *((u32_a_t*)tk[j-1]); } } @@ -418,7 +418,7 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) { for (; (j < KC) && (t < 4); j++, t++) { - *((u32*)W[r][t]) = *((u32*)tk[j]); + *((u32_a_t*)W[r][t]) = *((u32_a_t*)tk[j]); } if (t == 4) { @@ -488,29 +488,29 @@ prepare_decryption( RIJNDAEL_context *ctx ) for (r=0; r < MAXROUNDS+1; r++ ) { - *((u32*)ctx->keyschdec[r][0]) = *((u32*)ctx->keyschenc[r][0]); - *((u32*)ctx->keyschdec[r][1]) = *((u32*)ctx->keyschenc[r][1]); - *((u32*)ctx->keyschdec[r][2]) = *((u32*)ctx->keyschenc[r][2]); - *((u32*)ctx->keyschdec[r][3]) = *((u32*)ctx->keyschenc[r][3]); + *((u32_a_t*)ctx->keyschdec[r][0]) = *((u32_a_t*)ctx->keyschenc[r][0]); + *((u32_a_t*)ctx->keyschdec[r][1]) = *((u32_a_t*)ctx->keyschenc[r][1]); + *((u32_a_t*)ctx->keyschdec[r][2]) = *((u32_a_t*)ctx->keyschenc[r][2]); + *((u32_a_t*)ctx->keyschdec[r][3]) = *((u32_a_t*)ctx->keyschenc[r][3]); } #define W (ctx->keyschdec) for (r = 1; r < ctx->rounds; r++) { w = W[r][0]; - *((u32*)w) = *((u32*)U1[w[0]]) ^ *((u32*)U2[w[1]]) - ^ *((u32*)U3[w[2]]) ^ *((u32*)U4[w[3]]); + *((u32_a_t*)w) = *((u32_a_t*)U1[w[0]]) ^ *((u32_a_t*)U2[w[1]]) + ^ *((u32_a_t*)U3[w[2]]) ^ *((u32_a_t*)U4[w[3]]); w = W[r][1]; - *((u32*)w) = *((u32*)U1[w[0]]) ^ *((u32*)U2[w[1]]) - ^ *((u32*)U3[w[2]]) ^ *((u32*)U4[w[3]]); + *((u32_a_t*)w) = *((u32_a_t*)U1[w[0]]) ^ *((u32_a_t*)U2[w[1]]) + ^ *((u32_a_t*)U3[w[2]]) ^ *((u32_a_t*)U4[w[3]]); w = W[r][2]; - *((u32*)w) = *((u32*)U1[w[0]]) ^ *((u32*)U2[w[1]]) - ^ *((u32*)U3[w[2]]) ^ *((u32*)U4[w[3]]); + *((u32_a_t*)w) = *((u32_a_t*)U1[w[0]]) ^ *((u32_a_t*)U2[w[1]]) + ^ *((u32_a_t*)U3[w[2]]) ^ *((u32_a_t*)U4[w[3]]); w = W[r][3]; - *((u32*)w) = *((u32*)U1[w[0]]) ^ *((u32*)U2[w[1]]) - ^ *((u32*)U3[w[2]]) ^ *((u32*)U4[w[3]]); + *((u32_a_t*)w) = *((u32_a_t*)U1[w[0]]) ^ *((u32_a_t*)U2[w[1]]) + ^ *((u32_a_t*)U3[w[2]]) ^ *((u32_a_t*)U4[w[3]]); } #undef W #undef w commit 3047795794eb238aa684bd0729acf64c82a19e09 Author: Werner Koch Date: Wed Nov 21 12:30:58 2012 +0100 Do not detect AES-NI support if disabled by configure. * src/hwfeatures.c (detect_ia32_gnuc): Detect AESNI support only if that support has been enabled. -- We better do not try to detect AESNI support if the support has been disabled in the configure run. Disabling the support might have been done due to problem with the AESNI support on a certain platform and we can't exclude problem for sure with the detection code either. diff --git a/src/hwfeatures.c b/src/hwfeatures.c index 89d7685..82c435b 100644 --- a/src/hwfeatures.c +++ b/src/hwfeatures.c @@ -118,8 +118,9 @@ detect_x86_64_gnuc (void) /* This is an AMD CPU. */ } - /* Detect Intel features, that might be supported also by other vendors - * also. */ + /* Detect Intel features, that might also be supported by other + vendors. */ +#ifdef ENABLE_AESNI_SUPPORT asm volatile ("movl $1, %%eax\n\t" /* Get CPU info and feature flags. */ "cpuid\n" @@ -132,6 +133,8 @@ detect_x86_64_gnuc (void) : : "%eax", "%ebx", "%ecx", "%edx", "cc" ); +#endif /*#ifdef ENABLE_AESNI_SUPPORT*/ + } #endif /* __x86_64__ && __GNUC__ */ @@ -246,8 +249,9 @@ detect_ia32_gnuc (void) } - /* Detect Intel features, that might be supported also by other vendors - * also. */ + /* Detect Intel features, that might also be supported by other + vendors. */ +#ifdef ENABLE_AESNI_SUPPORT asm volatile ("pushl %%ebx\n\t" /* Save GOT register. */ "movl $1, %%eax\n\t" /* Get CPU info and feature flags. */ @@ -262,6 +266,8 @@ detect_ia32_gnuc (void) : : "%eax", "%ecx", "%edx", "cc" ); +#endif /*ENABLE_AESNI_SUPPORT*/ + } #endif /* __i386__ && SIZEOF_UNSIGNED_LONG == 4 && __GNUC__ */ commit 7f90d3dff4f87c0c42fc9b9336bbe77e8d33d33a Author: Werner Koch Date: Wed Nov 21 11:53:27 2012 +0100 Add Jussi Kivilinna to the AUTHORS. -- diff --git a/AUTHORS b/AUTHORS index c0231d6..3aa54f9 100644 --- a/AUTHORS +++ b/AUTHORS @@ -107,6 +107,7 @@ Authors with a DCO DCO:2012-04-16:Tom?? Mr?z DCO:2012-04-20:Rafa?l Carr? +DCO:2012-11-14:Jussi Kivilinna More credits commit 8afabc2813948778a3db52d9dee9a041a3dd50d4 Author: Jussi Kivilinna Date: Fri Nov 16 10:45:43 2012 +0200 Fix too large burn_stack in camellia-glue.c * cipher/camellia-glue.c (camellia_encrypt, camellia_decrypt): Do not take full array size of KEY_TABLE_TYPE, but argument size instead. -- KEY_TABLE_TYPE is array type, and sizeof(KEY_TABLE_TYPE) gives full size of array. However what is wanted here is size of array argument in stack, so change sizeof(KEY_TABLE_TYPE) to sizeof(void*). This gives boost in speed for camellia cipher. On AMD Phenom II, x86-64: Before: $ tests/benchmark --cipher-repetitions 10 cipher camellia128 Running each test 10 times. ECB/Stream CBC CFB OFB CTR --------------- --------------- --------------- --------------- --------------- CAMELLIA128 250ms 240ms 270ms 260ms 250ms 250ms 260ms 250ms 340ms 330ms After: $ tests/benchmark --cipher-repetitions 10 cipher camellia128 Running each test 10 times. ECB/Stream CBC CFB OFB CTR --------------- --------------- --------------- --------------- --------------- CAMELLIA128 140ms 130ms 150ms 160ms 150ms 150ms 150ms 140ms 220ms 220ms [v2] - Add GNU style changelog Signed-off-by: Jussi Kivilinna diff --git a/cipher/camellia-glue.c b/cipher/camellia-glue.c index a263621..c5019d0 100644 --- a/cipher/camellia-glue.c +++ b/cipher/camellia-glue.c @@ -111,7 +111,7 @@ camellia_encrypt(void *c, byte *outbuf, const byte *inbuf) Camellia_EncryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf); _gcry_burn_stack - (sizeof(int)+2*sizeof(unsigned char *)+sizeof(KEY_TABLE_TYPE) + (sizeof(int)+2*sizeof(unsigned char *)+sizeof(void*/*KEY_TABLE_TYPE*/) +4*sizeof(u32) +2*sizeof(u32*)+4*sizeof(u32) +2*2*sizeof(void*) /* Function calls. */ @@ -125,7 +125,7 @@ camellia_decrypt(void *c, byte *outbuf, const byte *inbuf) Camellia_DecryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf); _gcry_burn_stack - (sizeof(int)+2*sizeof(unsigned char *)+sizeof(KEY_TABLE_TYPE) + (sizeof(int)+2*sizeof(unsigned char *)+sizeof(void*/*KEY_TABLE_TYPE*/) +4*sizeof(u32) +2*sizeof(u32*)+4*sizeof(u32) +2*2*sizeof(void*) /* Function calls. */ commit d8bdfa42ed582655c180e7db9b16d4e756a12a6e Author: Jussi Kivilinna Date: Fri Nov 16 10:44:54 2012 +0200 Add x86_64 support for AES-NI * cipher/rijndael.c [ENABLE_AESNI_SUPPORT]: Enable USE_AESNI on x86-64. (do_setkey) [USE_AESNI_is_disabled_here]: Use %[key] and %[ksch] directly as registers instead of using temporary register %%esi. [USE_AESNI] (do_aesni_enc_aligned, do_aesni_dec_aligned, do_aesni_cfb, do_aesni_ctr, do_aesni_ctr_4): Use %[key] directly as register instead of using temporary register %%esi. [USE_AESNI] (do_aesni_cfb, do_aesni_ctr, do_aesni_ctr_4): Change %[key] from generic "g" type to register "r". * src/hwfeatures.c (_gcry_detect_hw_features) [__x86_64__]: Do not clear AES-NI feature flag. -- AES-NI assembler uses %%esi for key-material pointer register. However %[key] can be marked as "r" (register) and automatically be 64bit on x86-64 and be 32bit on i386. So use %[key] for pointer register instead of %esi and that way make same AES-NI code work on both x86-64 and i386. [v2] - Add GNU style changelog - Fixed do_setkey changes, use %[ksch] for output instead of %[key] - Changed [key] assembler arguments from "g" to "r" to force use of registers in all cases (when tested v1, "g" did work as indented and %[key] mapped to register on i386 and x86-64, but that might not happen always). Signed-off-by: Jussi Kivilinna diff --git a/cipher/rijndael.c b/cipher/rijndael.c index b9ee8ad..3418c99 100644 --- a/cipher/rijndael.c +++ b/cipher/rijndael.c @@ -75,7 +75,7 @@ gcc 3. However, to be on the safe side we require at least gcc 4. */ #undef USE_AESNI #ifdef ENABLE_AESNI_SUPPORT -# if defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4 && __GNUC__ >= 4 +# if ((defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4) || defined(__x86_64__)) && __GNUC__ >= 4 # define USE_AESNI 1 # endif #endif /* ENABLE_AESNI_SUPPORT */ @@ -297,40 +297,38 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) than using the standard key schedule. We disable it for now and don't put any effort into implementing this for AES-192 and AES-256. */ - asm volatile ("movl %[key], %%esi\n\t" - "movdqu (%%esi), %%xmm1\n\t" /* xmm1 := key */ - "movl %[ksch], %%esi\n\t" - "movdqa %%xmm1, (%%esi)\n\t" /* ksch[0] := xmm1 */ + asm volatile ("movdqu (%[key]), %%xmm1\n\t" /* xmm1 := key */ + "movdqa %%xmm1, (%[ksch])\n\t" /* ksch[0] := xmm1 */ "aeskeygenassist $0x01, %%xmm1, %%xmm2\n\t" "call .Lexpand128_%=\n\t" - "movdqa %%xmm1, 0x10(%%esi)\n\t" /* ksch[1] := xmm1 */ + "movdqa %%xmm1, 0x10(%[ksch])\n\t" /* ksch[1] := xmm1 */ "aeskeygenassist $0x02, %%xmm1, %%xmm2\n\t" "call .Lexpand128_%=\n\t" - "movdqa %%xmm1, 0x20(%%esi)\n\t" /* ksch[2] := xmm1 */ + "movdqa %%xmm1, 0x20(%[ksch])\n\t" /* ksch[2] := xmm1 */ "aeskeygenassist $0x04, %%xmm1, %%xmm2\n\t" "call .Lexpand128_%=\n\t" - "movdqa %%xmm1, 0x30(%%esi)\n\t" /* ksch[3] := xmm1 */ + "movdqa %%xmm1, 0x30(%[ksch])\n\t" /* ksch[3] := xmm1 */ "aeskeygenassist $0x08, %%xmm1, %%xmm2\n\t" "call .Lexpand128_%=\n\t" - "movdqa %%xmm1, 0x40(%%esi)\n\t" /* ksch[4] := xmm1 */ + "movdqa %%xmm1, 0x40(%[ksch])\n\t" /* ksch[4] := xmm1 */ "aeskeygenassist $0x10, %%xmm1, %%xmm2\n\t" "call .Lexpand128_%=\n\t" - "movdqa %%xmm1, 0x50(%%esi)\n\t" /* ksch[5] := xmm1 */ + "movdqa %%xmm1, 0x50(%[ksch])\n\t" /* ksch[5] := xmm1 */ "aeskeygenassist $0x20, %%xmm1, %%xmm2\n\t" "call .Lexpand128_%=\n\t" - "movdqa %%xmm1, 0x60(%%esi)\n\t" /* ksch[6] := xmm1 */ + "movdqa %%xmm1, 0x60(%[ksch])\n\t" /* ksch[6] := xmm1 */ "aeskeygenassist $0x40, %%xmm1, %%xmm2\n\t" "call .Lexpand128_%=\n\t" - "movdqa %%xmm1, 0x70(%%esi)\n\t" /* ksch[7] := xmm1 */ + "movdqa %%xmm1, 0x70(%[ksch])\n\t" /* ksch[7] := xmm1 */ "aeskeygenassist $0x80, %%xmm1, %%xmm2\n\t" "call .Lexpand128_%=\n\t" - "movdqa %%xmm1, 0x80(%%esi)\n\t" /* ksch[8] := xmm1 */ + "movdqa %%xmm1, 0x80(%[ksch])\n\t" /* ksch[8] := xmm1 */ "aeskeygenassist $0x1b, %%xmm1, %%xmm2\n\t" "call .Lexpand128_%=\n\t" - "movdqa %%xmm1, 0x90(%%esi)\n\t" /* ksch[9] := xmm1 */ + "movdqa %%xmm1, 0x90(%[ksch])\n\t" /* ksch[9] := xmm1 */ "aeskeygenassist $0x36, %%xmm1, %%xmm2\n\t" "call .Lexpand128_%=\n\t" - "movdqa %%xmm1, 0xa0(%%esi)\n\t" /* ksch[10] := xmm1 */ + "movdqa %%xmm1, 0xa0(%[ksch])\n\t" /* ksch[10] := xmm1 */ "jmp .Lleave%=\n" ".Lexpand128_%=:\n\t" @@ -350,8 +348,8 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) "pxor %%xmm2, %%xmm2\n\t" "pxor %%xmm3, %%xmm3\n" : - : [key] "g" (key), [ksch] "g" (ctx->keyschenc) - : "%esi", "cc", "memory" ); + : [key] "r" (key), [ksch] "r" (ctx->keyschenc) + : "cc", "memory" ); } #endif /*USE_AESNI*/ else @@ -722,40 +720,39 @@ do_aesni_enc_aligned (const RIJNDAEL_context *ctx, aligned but that is a special case. We should better implement CFB direct in asm. */ asm volatile ("movdqu %[src], %%xmm0\n\t" /* xmm0 := *a */ - "movl %[key], %%esi\n\t" /* esi := keyschenc */ - "movdqa (%%esi), %%xmm1\n\t" /* xmm1 := key[0] */ + "movdqa (%[key]), %%xmm1\n\t" /* xmm1 := key[0] */ "pxor %%xmm1, %%xmm0\n\t" /* xmm0 ^= key[0] */ - "movdqa 0x10(%%esi), %%xmm1\n\t" + "movdqa 0x10(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 - "movdqa 0x20(%%esi), %%xmm1\n\t" + "movdqa 0x20(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 - "movdqa 0x30(%%esi), %%xmm1\n\t" + "movdqa 0x30(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 - "movdqa 0x40(%%esi), %%xmm1\n\t" + "movdqa 0x40(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 - "movdqa 0x50(%%esi), %%xmm1\n\t" + "movdqa 0x50(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 - "movdqa 0x60(%%esi), %%xmm1\n\t" + "movdqa 0x60(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 - "movdqa 0x70(%%esi), %%xmm1\n\t" + "movdqa 0x70(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 - "movdqa 0x80(%%esi), %%xmm1\n\t" + "movdqa 0x80(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 - "movdqa 0x90(%%esi), %%xmm1\n\t" + "movdqa 0x90(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 - "movdqa 0xa0(%%esi), %%xmm1\n\t" + "movdqa 0xa0(%[key]), %%xmm1\n\t" "cmp $10, %[rounds]\n\t" "jz .Lenclast%=\n\t" aesenc_xmm1_xmm0 - "movdqa 0xb0(%%esi), %%xmm1\n\t" + "movdqa 0xb0(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 - "movdqa 0xc0(%%esi), %%xmm1\n\t" + "movdqa 0xc0(%[key]), %%xmm1\n\t" "cmp $12, %[rounds]\n\t" "jz .Lenclast%=\n\t" aesenc_xmm1_xmm0 - "movdqa 0xd0(%%esi), %%xmm1\n\t" + "movdqa 0xd0(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 - "movdqa 0xe0(%%esi), %%xmm1\n" + "movdqa 0xe0(%[key]), %%xmm1\n" ".Lenclast%=:\n\t" aesenclast_xmm1_xmm0 @@ -764,7 +761,7 @@ do_aesni_enc_aligned (const RIJNDAEL_context *ctx, : [src] "m" (*a), [key] "r" (ctx->keyschenc), [rounds] "r" (ctx->rounds) - : "%esi", "cc", "memory"); + : "cc", "memory"); #undef aesenc_xmm1_xmm0 #undef aesenclast_xmm1_xmm0 } @@ -777,40 +774,39 @@ do_aesni_dec_aligned (const RIJNDAEL_context *ctx, #define aesdec_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xde, 0xc1\n\t" #define aesdeclast_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdf, 0xc1\n\t" asm volatile ("movdqu %[src], %%xmm0\n\t" /* xmm0 := *a */ - "movl %[key], %%esi\n\t" - "movdqa (%%esi), %%xmm1\n\t" + "movdqa (%[key]), %%xmm1\n\t" "pxor %%xmm1, %%xmm0\n\t" /* xmm0 ^= key[0] */ - "movdqa 0x10(%%esi), %%xmm1\n\t" + "movdqa 0x10(%[key]), %%xmm1\n\t" aesdec_xmm1_xmm0 - "movdqa 0x20(%%esi), %%xmm1\n\t" + "movdqa 0x20(%[key]), %%xmm1\n\t" aesdec_xmm1_xmm0 - "movdqa 0x30(%%esi), %%xmm1\n\t" + "movdqa 0x30(%[key]), %%xmm1\n\t" aesdec_xmm1_xmm0 - "movdqa 0x40(%%esi), %%xmm1\n\t" + "movdqa 0x40(%[key]), %%xmm1\n\t" aesdec_xmm1_xmm0 - "movdqa 0x50(%%esi), %%xmm1\n\t" + "movdqa 0x50(%[key]), %%xmm1\n\t" aesdec_xmm1_xmm0 - "movdqa 0x60(%%esi), %%xmm1\n\t" + "movdqa 0x60(%[key]), %%xmm1\n\t" aesdec_xmm1_xmm0 - "movdqa 0x70(%%esi), %%xmm1\n\t" + "movdqa 0x70(%[key]), %%xmm1\n\t" aesdec_xmm1_xmm0 - "movdqa 0x80(%%esi), %%xmm1\n\t" + "movdqa 0x80(%[key]), %%xmm1\n\t" aesdec_xmm1_xmm0 - "movdqa 0x90(%%esi), %%xmm1\n\t" + "movdqa 0x90(%[key]), %%xmm1\n\t" aesdec_xmm1_xmm0 - "movdqa 0xa0(%%esi), %%xmm1\n\t" + "movdqa 0xa0(%[key]), %%xmm1\n\t" "cmp $10, %[rounds]\n\t" "jz .Ldeclast%=\n\t" aesdec_xmm1_xmm0 - "movdqa 0xb0(%%esi), %%xmm1\n\t" + "movdqa 0xb0(%[key]), %%xmm1\n\t" aesdec_xmm1_xmm0 - "movdqa 0xc0(%%esi), %%xmm1\n\t" + "movdqa 0xc0(%[key]), %%xmm1\n\t" "cmp $12, %[rounds]\n\t" "jz .Ldeclast%=\n\t" aesdec_xmm1_xmm0 - "movdqa 0xd0(%%esi), %%xmm1\n\t" + "movdqa 0xd0(%[key]), %%xmm1\n\t" aesdec_xmm1_xmm0 - "movdqa 0xe0(%%esi), %%xmm1\n" + "movdqa 0xe0(%[key]), %%xmm1\n" ".Ldeclast%=:\n\t" aesdeclast_xmm1_xmm0 @@ -819,7 +815,7 @@ do_aesni_dec_aligned (const RIJNDAEL_context *ctx, : [src] "m" (*a), [key] "r" (ctx->keyschdec), [rounds] "r" (ctx->rounds) - : "%esi", "cc", "memory"); + : "cc", "memory"); #undef aesdec_xmm1_xmm0 #undef aesdeclast_xmm1_xmm0 } @@ -836,40 +832,39 @@ do_aesni_cfb (const RIJNDAEL_context *ctx, int decrypt_flag, #define aesenc_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xc1\n\t" #define aesenclast_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xc1\n\t" asm volatile ("movdqa %[iv], %%xmm0\n\t" /* xmm0 := IV */ - "movl %[key], %%esi\n\t" /* esi := keyschenc */ - "movdqa (%%esi), %%xmm1\n\t" /* xmm1 := key[0] */ + "movdqa (%[key]), %%xmm1\n\t" /* xmm1 := key[0] */ "pxor %%xmm1, %%xmm0\n\t" /* xmm0 ^= key[0] */ - "movdqa 0x10(%%esi), %%xmm1\n\t" + "movdqa 0x10(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 - "movdqa 0x20(%%esi), %%xmm1\n\t" + "movdqa 0x20(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 - "movdqa 0x30(%%esi), %%xmm1\n\t" + "movdqa 0x30(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 - "movdqa 0x40(%%esi), %%xmm1\n\t" + "movdqa 0x40(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 - "movdqa 0x50(%%esi), %%xmm1\n\t" + "movdqa 0x50(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 - "movdqa 0x60(%%esi), %%xmm1\n\t" + "movdqa 0x60(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 - "movdqa 0x70(%%esi), %%xmm1\n\t" + "movdqa 0x70(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 - "movdqa 0x80(%%esi), %%xmm1\n\t" + "movdqa 0x80(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 - "movdqa 0x90(%%esi), %%xmm1\n\t" + "movdqa 0x90(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 - "movdqa 0xa0(%%esi), %%xmm1\n\t" + "movdqa 0xa0(%[key]), %%xmm1\n\t" "cmp $10, %[rounds]\n\t" "jz .Lenclast%=\n\t" aesenc_xmm1_xmm0 - "movdqa 0xb0(%%esi), %%xmm1\n\t" + "movdqa 0xb0(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 - "movdqa 0xc0(%%esi), %%xmm1\n\t" + "movdqa 0xc0(%[key]), %%xmm1\n\t" "cmp $12, %[rounds]\n\t" "jz .Lenclast%=\n\t" aesenc_xmm1_xmm0 - "movdqa 0xd0(%%esi), %%xmm1\n\t" + "movdqa 0xd0(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 - "movdqa 0xe0(%%esi), %%xmm1\n" + "movdqa 0xe0(%[key]), %%xmm1\n" ".Lenclast%=:\n\t" aesenclast_xmm1_xmm0 @@ -886,10 +881,10 @@ do_aesni_cfb (const RIJNDAEL_context *ctx, int decrypt_flag, "movdqu %%xmm0, %[dst]\n" /* Store output. */ : [iv] "+m" (*iv), [dst] "=m" (*b) : [src] "m" (*a), - [key] "g" (ctx->keyschenc), + [key] "r" (ctx->keyschenc), [rounds] "g" (ctx->rounds), [decrypt] "m" (decrypt_flag) - : "%esi", "cc", "memory"); + : "cc", "memory"); #undef aesenc_xmm1_xmm0 #undef aesenclast_xmm1_xmm0 } @@ -915,40 +910,39 @@ do_aesni_ctr (const RIJNDAEL_context *ctx, "pshufb %[mask], %%xmm2\n\t" "movdqa %%xmm2, %[ctr]\n" /* Update CTR. */ - "movl %[key], %%esi\n\t" /* esi := keyschenc */ - "movdqa (%%esi), %%xmm1\n\t" /* xmm1 := key[0] */ + "movdqa (%[key]), %%xmm1\n\t" /* xmm1 := key[0] */ "pxor %%xmm1, %%xmm0\n\t" /* xmm0 ^= key[0] */ - "movdqa 0x10(%%esi), %%xmm1\n\t" + "movdqa 0x10(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 - "movdqa 0x20(%%esi), %%xmm1\n\t" + "movdqa 0x20(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 - "movdqa 0x30(%%esi), %%xmm1\n\t" + "movdqa 0x30(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 - "movdqa 0x40(%%esi), %%xmm1\n\t" + "movdqa 0x40(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 - "movdqa 0x50(%%esi), %%xmm1\n\t" + "movdqa 0x50(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 - "movdqa 0x60(%%esi), %%xmm1\n\t" + "movdqa 0x60(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 - "movdqa 0x70(%%esi), %%xmm1\n\t" + "movdqa 0x70(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 - "movdqa 0x80(%%esi), %%xmm1\n\t" + "movdqa 0x80(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 - "movdqa 0x90(%%esi), %%xmm1\n\t" + "movdqa 0x90(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 - "movdqa 0xa0(%%esi), %%xmm1\n\t" + "movdqa 0xa0(%[key]), %%xmm1\n\t" "cmp $10, %[rounds]\n\t" "jz .Lenclast%=\n\t" aesenc_xmm1_xmm0 - "movdqa 0xb0(%%esi), %%xmm1\n\t" + "movdqa 0xb0(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 - "movdqa 0xc0(%%esi), %%xmm1\n\t" + "movdqa 0xc0(%[key]), %%xmm1\n\t" "cmp $12, %[rounds]\n\t" "jz .Lenclast%=\n\t" aesenc_xmm1_xmm0 - "movdqa 0xd0(%%esi), %%xmm1\n\t" + "movdqa 0xd0(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 - "movdqa 0xe0(%%esi), %%xmm1\n" + "movdqa 0xe0(%[key]), %%xmm1\n" ".Lenclast%=:\n\t" aesenclast_xmm1_xmm0 @@ -958,7 +952,7 @@ do_aesni_ctr (const RIJNDAEL_context *ctx, : [ctr] "+m" (*ctr), [dst] "=m" (*b) : [src] "m" (*a), - [key] "g" (ctx->keyschenc), + [key] "r" (ctx->keyschenc), [rounds] "g" (ctx->rounds), [mask] "m" (*be_mask) : "%esi", "cc", "memory"); @@ -1012,82 +1006,81 @@ do_aesni_ctr_4 (const RIJNDAEL_context *ctx, "pshufb %[mask], %%xmm5\n\t" /* xmm5 := be(xmm5) */ "movdqa %%xmm5, %[ctr]\n" /* Update CTR. */ - "movl %[key], %%esi\n\t" /* esi := keyschenc */ - "movdqa (%%esi), %%xmm1\n\t" /* xmm1 := key[0] */ + "movdqa (%[key]), %%xmm1\n\t" /* xmm1 := key[0] */ "pxor %%xmm1, %%xmm0\n\t" /* xmm0 ^= key[0] */ "pxor %%xmm1, %%xmm2\n\t" /* xmm2 ^= key[0] */ "pxor %%xmm1, %%xmm3\n\t" /* xmm3 ^= key[0] */ "pxor %%xmm1, %%xmm4\n\t" /* xmm4 ^= key[0] */ - "movdqa 0x10(%%esi), %%xmm1\n\t" + "movdqa 0x10(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 aesenc_xmm1_xmm2 aesenc_xmm1_xmm3 aesenc_xmm1_xmm4 - "movdqa 0x20(%%esi), %%xmm1\n\t" + "movdqa 0x20(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 aesenc_xmm1_xmm2 aesenc_xmm1_xmm3 aesenc_xmm1_xmm4 - "movdqa 0x30(%%esi), %%xmm1\n\t" + "movdqa 0x30(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 aesenc_xmm1_xmm2 aesenc_xmm1_xmm3 aesenc_xmm1_xmm4 - "movdqa 0x40(%%esi), %%xmm1\n\t" + "movdqa 0x40(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 aesenc_xmm1_xmm2 aesenc_xmm1_xmm3 aesenc_xmm1_xmm4 - "movdqa 0x50(%%esi), %%xmm1\n\t" + "movdqa 0x50(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 aesenc_xmm1_xmm2 aesenc_xmm1_xmm3 aesenc_xmm1_xmm4 - "movdqa 0x60(%%esi), %%xmm1\n\t" + "movdqa 0x60(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 aesenc_xmm1_xmm2 aesenc_xmm1_xmm3 aesenc_xmm1_xmm4 - "movdqa 0x70(%%esi), %%xmm1\n\t" + "movdqa 0x70(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 aesenc_xmm1_xmm2 aesenc_xmm1_xmm3 aesenc_xmm1_xmm4 - "movdqa 0x80(%%esi), %%xmm1\n\t" + "movdqa 0x80(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 aesenc_xmm1_xmm2 aesenc_xmm1_xmm3 aesenc_xmm1_xmm4 - "movdqa 0x90(%%esi), %%xmm1\n\t" + "movdqa 0x90(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 aesenc_xmm1_xmm2 aesenc_xmm1_xmm3 aesenc_xmm1_xmm4 - "movdqa 0xa0(%%esi), %%xmm1\n\t" + "movdqa 0xa0(%[key]), %%xmm1\n\t" "cmp $10, %[rounds]\n\t" "jz .Lenclast%=\n\t" aesenc_xmm1_xmm0 aesenc_xmm1_xmm2 aesenc_xmm1_xmm3 aesenc_xmm1_xmm4 - "movdqa 0xb0(%%esi), %%xmm1\n\t" + "movdqa 0xb0(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 aesenc_xmm1_xmm2 aesenc_xmm1_xmm3 aesenc_xmm1_xmm4 - "movdqa 0xc0(%%esi), %%xmm1\n\t" + "movdqa 0xc0(%[key]), %%xmm1\n\t" "cmp $12, %[rounds]\n\t" "jz .Lenclast%=\n\t" aesenc_xmm1_xmm0 aesenc_xmm1_xmm2 aesenc_xmm1_xmm3 aesenc_xmm1_xmm4 - "movdqa 0xd0(%%esi), %%xmm1\n\t" + "movdqa 0xd0(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 aesenc_xmm1_xmm2 aesenc_xmm1_xmm3 aesenc_xmm1_xmm4 - "movdqa 0xe0(%%esi), %%xmm1\n" + "movdqa 0xe0(%[key]), %%xmm1\n" ".Lenclast%=:\n\t" aesenclast_xmm1_xmm0 @@ -1113,7 +1106,7 @@ do_aesni_ctr_4 (const RIJNDAEL_context *ctx, : [ctr] "+m" (*ctr), [dst] "=m" (*b) : [src] "m" (*a), - [key] "g" (ctx->keyschenc), + [key] "r" (ctx->keyschenc), [rounds] "g" (ctx->rounds), [mask] "m" (*be_mask) : "%esi", "cc", "memory"); diff --git a/src/hwfeatures.c b/src/hwfeatures.c index 606f3e7..89d7685 100644 --- a/src/hwfeatures.c +++ b/src/hwfeatures.c @@ -292,9 +292,6 @@ _gcry_detect_hw_features (unsigned int disabled_features) # ifdef __GNUC__ { detect_x86_64_gnuc (); - /* We don't have AESNI support for 64 bit yet. Thus we should not - announce it. */ - hw_features &= ~HWF_INTEL_AESNI; } # endif #endif commit 9e1552517f68459a165ddebbba85e7cf37ff4f0c Author: Jussi Kivilinna Date: Fri Nov 16 10:44:49 2012 +0200 Fix cpuid vendor-id check for i386 and x86-64 * src/hwfeatures.c (detect_x86_64_gnuc, detect_ia32_gnuc): Allow Intel features be detect from CPU by other vendors too. -- detect_x86_64_gnuc() and detect_ia32_gnuc() incorrectly exclude Intel features on all other vendor CPUs. What we want here, is to detect if CPU from any vendor support said Intel feature (in this case AES-NI). [v2] - Add GNU style changelog Signed-off-by: Jussi Kivilinna diff --git a/src/hwfeatures.c b/src/hwfeatures.c index 456c07a..606f3e7 100644 --- a/src/hwfeatures.c +++ b/src/hwfeatures.c @@ -112,24 +112,26 @@ detect_x86_64_gnuc (void) else if (!strcmp (vendor_id, "GenuineIntel")) { /* This is an Intel CPU. */ - asm volatile - ("movl $1, %%eax\n\t" /* Get CPU info and feature flags. */ - "cpuid\n" - "testl $0x02000000, %%ecx\n\t" /* Test bit 25. */ - "jz .Lno_aes%=\n\t" /* No AES support. */ - "orl $256, %0\n" /* Set our HWF_INTEL_AES bit. */ - - ".Lno_aes%=:\n" - : "+r" (hw_features) - : - : "%eax", "%ebx", "%ecx", "%edx", "cc" - ); } else if (!strcmp (vendor_id, "AuthenticAMD")) { /* This is an AMD CPU. */ - } + + /* Detect Intel features, that might be supported also by other vendors + * also. */ + asm volatile + ("movl $1, %%eax\n\t" /* Get CPU info and feature flags. */ + "cpuid\n" + "testl $0x02000000, %%ecx\n\t" /* Test bit 25. */ + "jz .Lno_aes%=\n\t" /* No AES support. */ + "orl $256, %0\n" /* Set our HWF_INTEL_AES bit. */ + + ".Lno_aes%=:\n" + : "+r" (hw_features) + : + : "%eax", "%ebx", "%ecx", "%edx", "cc" + ); } #endif /* __x86_64__ && __GNUC__ */ @@ -237,26 +239,29 @@ detect_ia32_gnuc (void) else if (!strcmp (vendor_id, "GenuineIntel")) { /* This is an Intel CPU. */ - asm volatile - ("pushl %%ebx\n\t" /* Save GOT register. */ - "movl $1, %%eax\n\t" /* Get CPU info and feature flags. */ - "cpuid\n" - "popl %%ebx\n\t" /* Restore GOT register. */ - "testl $0x02000000, %%ecx\n\t" /* Test bit 25. */ - "jz .Lno_aes%=\n\t" /* No AES support. */ - "orl $256, %0\n" /* Set our HWF_INTEL_AES bit. */ - - ".Lno_aes%=:\n" - : "+r" (hw_features) - : - : "%eax", "%ecx", "%edx", "cc" - ); } else if (!strcmp (vendor_id, "AuthenticAMD")) { /* This is an AMD CPU. */ } + + /* Detect Intel features, that might be supported also by other vendors + * also. */ + asm volatile + ("pushl %%ebx\n\t" /* Save GOT register. */ + "movl $1, %%eax\n\t" /* Get CPU info and feature flags. */ + "cpuid\n" + "popl %%ebx\n\t" /* Restore GOT register. */ + "testl $0x02000000, %%ecx\n\t" /* Test bit 25. */ + "jz .Lno_aes%=\n\t" /* No AES support. */ + "orl $256, %0\n" /* Set our HWF_INTEL_AES bit. */ + + ".Lno_aes%=:\n" + : "+r" (hw_features) + : + : "%eax", "%ecx", "%edx", "cc" + ); } #endif /* __i386__ && SIZEOF_UNSIGNED_LONG == 4 && __GNUC__ */ commit 19b9efd1f47a5de9c450ce8212dfa3174a029c7a Author: Jussi Kivilinna Date: Fri Nov 16 10:44:44 2012 +0200 Fix hwdetect assembler clobbers * src/hwfeatures.c (detect_x86_64_gnuc): Add missing %ebx assembler clobbers. (detect_x86_64_gnuc, detect_ia32_gnuc) [ENABLE_PADLOCK_SUPPORT]: Add missing %ecx assembler clobbers. -- detect_x86_64_gnuc() and detect_ia32_gnuc() have missing clobbers in assembler statements. "%ebx" is missing in x86-64, probably because copy-paste error (i386 code saves and restores %ebx to/from stack). "%ecx" is missing from PadLock detection. [v2] - add GNU style changelog Signed-off-by: Jussi Kivilinna diff --git a/src/hwfeatures.c b/src/hwfeatures.c index cf80fe0..456c07a 100644 --- a/src/hwfeatures.c +++ b/src/hwfeatures.c @@ -56,7 +56,7 @@ detect_x86_64_gnuc (void) "movl %%ecx, 8(%0)\n\t" : : "S" (&vendor_id[0]) - : "%eax", "%ecx", "%edx", "cc" + : "%eax", "%ebx", "%ecx", "%edx", "cc" ); vendor_id[12] = 0; @@ -105,7 +105,7 @@ detect_x86_64_gnuc (void) ".Lready%=:\n" : "+r" (hw_features) : - : "%eax", "%edx", "cc" + : "%eax", "%ebx", "%ecx", "%edx", "cc" ); } #endif /*ENABLE_PADLOCK_SUPPORT*/ @@ -122,7 +122,7 @@ detect_x86_64_gnuc (void) ".Lno_aes%=:\n" : "+r" (hw_features) : - : "%eax", "%ecx", "%edx", "cc" + : "%eax", "%ebx", "%ecx", "%edx", "cc" ); } else if (!strcmp (vendor_id, "AuthenticAMD")) @@ -230,7 +230,7 @@ detect_ia32_gnuc (void) ".Lready%=:\n" : "+r" (hw_features) : - : "%eax", "%edx", "cc" + : "%eax", "%ecx", "%edx", "cc" ); } #endif /*ENABLE_PADLOCK_SUPPORT*/ commit 6368ed542150956ff4ba8170a15bbc534143675c Author: Werner Koch Date: Wed Nov 21 11:47:35 2012 +0100 Use configure test for aligned attribute. * configure.ac (HAVE_GCC_ATTRIBUTE_ALIGNED): New test and ac_define. * cipher/cipher-internal.h, cipher/rijndael.c, random/rndhw.c: Use new macro instead of a fixed test for __GNUC__. -- We assume that compilers that grok "__attribute__ ((aligned (16)))" implement that in the same way as gcc does. In case it turns out that this is not the case we will need to do two more things: Detect such different behaviour and come up with a construct to allows the use of that other style of alignment forcing. diff --git a/cipher/cipher-internal.h b/cipher/cipher-internal.h index 437e9c0..025bf2e 100644 --- a/cipher/cipher-internal.h +++ b/cipher/cipher-internal.h @@ -31,7 +31,7 @@ We use the aligned attribute, thus it is only possible to implement this with gcc. */ #undef NEED_16BYTE_ALIGNED_CONTEXT -#if defined (__GNUC__) +#ifdef HAVE_GCC_ATTRIBUTE_ALIGNED # define NEED_16BYTE_ALIGNED_CONTEXT 1 #endif diff --git a/cipher/rijndael.c b/cipher/rijndael.c index a2aedf0..b9ee8ad 100644 --- a/cipher/rijndael.c +++ b/cipher/rijndael.c @@ -52,7 +52,7 @@ /* Helper macro to force alignment to 16 bytes. */ -#ifdef __GNUC__ +#ifdef HAVE_GCC_ATTRIBUTE_ALIGNED # define ATTR_ALIGNED_16 __attribute__ ((aligned (16))) #else # define ATTR_ALIGNED_16 @@ -63,7 +63,7 @@ code. */ #undef USE_PADLOCK #ifdef ENABLE_PADLOCK_SUPPORT -# ifdef __GNUC__ +# ifdef HAVE_GCC_ATTRIBUTE_ALIGNED # if (defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4) || defined(__x86_64__) # define USE_PADLOCK 1 # endif diff --git a/configure.ac b/configure.ac index 0e99ca5..a2235a8 100644 --- a/configure.ac +++ b/configure.ac @@ -789,6 +789,21 @@ if test "$gcry_cv_visibility_attribute" = "yes" \ fi +# +# Check whether the compiler supports the GCC style aligned attribute +# +AC_CACHE_CHECK([whether the GCC style aligned attribute is supported], + [gcry_cv_gcc_attribute_aligned], + [gcry_cv_gcc_attribute_aligned=no + AC_COMPILE_IFELSE([AC_LANG_SOURCE( + [[struct { int a; } foo __attribute__ ((aligned (16)));]])], + [gcry_cv_gcc_attribute_aligned=yes])]) +if test "$gcry_cv_gcc_attribute_aligned" = "yes" ; then + AC_DEFINE(HAVE_GCC_ATTRIBUTE_ALIGNED,1, + [Defined if a GCC style "__attribute__ ((aligned (n))" is supported]) +fi + + ####################################### #### Checks for library functions. #### ####################################### @@ -1286,6 +1301,15 @@ cat < This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "IPC library used by GnuPG". The branch, master has been updated via 76ea68c2a77cafe2424fe6bc97403c9d9a6b1e95 (commit) from 76ceeb3582bba138227bf76167b451ee017d38fc (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 76ea68c2a77cafe2424fe6bc97403c9d9a6b1e95 Author: Ben Kibbey Date: Tue Nov 20 21:53:31 2012 -0500 Support LOCAL_PEEREID (NetBSD) and getpeereid() (FreeBSD) * configure.ac: check for LOCAL_PEEREID and getpeereid(). * src/assuan-socket-server.c (accept_connection_bottom): make use of LOCAL_PEEREID and getpeereid(). -- For use with assuan_get_peercred(). Note that getpeereid() does not set the PID member. LOCAL_PEEREID is checked before getpeereid() since NetBSD has both of these. SO_PEERCRED is still checked first. [Second revision] This revision adds support for LOCAL_PEEREID which NetBSD uses. Its tested against NetBSD 6.0 and may work without problems with earlier versions. FreeBSD uses getpeereid() which does not have PID support. Recent OpenBSD versions do support SO_PEERCRED and old versions have getpeereid() but also may have LOCAL_PEEREID (not sure). diff --git a/configure.ac b/configure.ac index b420f48..5a2a8d6 100644 --- a/configure.ac +++ b/configure.ac @@ -367,9 +367,35 @@ AC_CACHE_VAL(assuan_cv_sys_so_peercred, assuan_cv_sys_so_peercred=no) ]) AC_MSG_RESULT($assuan_cv_sys_so_peercred) + if test $assuan_cv_sys_so_peercred = yes; then AC_DEFINE(HAVE_SO_PEERCRED, 1, [Defined if SO_PEERCRED is supported (Linux specific)]) +else + # + # Check for the getsockopt LOCAL_PEEREID (NetBSD) + # + AC_MSG_CHECKING(for LOCAL_PEEREID) + AC_CACHE_VAL(assuan_cv_sys_so_local_peereid, + [AC_TRY_COMPILE([#include + #include ], + [struct unpcbid unp; + int unpl = sizeof unp; + getsockopt (1, SOL_SOCKET, LOCAL_PEEREID, &unp, &unpl);], + assuan_cv_sys_so_local_peereid=yes, + assuan_cv_sys_so_local_peereid=no) + ]) + AC_MSG_RESULT($assuan_cv_sys_so_local_peereid) + + if test $assuan_cv_sys_so_local_peereid = yes; then + AC_DEFINE(HAVE_LOCAL_PEEREID, 1, + [Defined if LOCAL_PEEREID is supported (NetBSD specific)]) + else + # + # FreeBSD + # + AC_CHECK_FUNCS([getpeereid]) + fi fi diff --git a/src/assuan-socket-server.c b/src/assuan-socket-server.c index 27994a2..1e8e541 100644 --- a/src/assuan-socket-server.c +++ b/src/assuan-socket-server.c @@ -74,6 +74,27 @@ accept_connection_bottom (assuan_context_t ctx) ctx->pid = cr.pid; } } +#elif defined(HAVE_LOCAL_PEEREID) + { + struct unpcbid unp; + socklen_t unpl = sizeof unp; + + if (getsockopt(fd, 0, LOCAL_PEEREID, &unp, &unpl) != -1) + { + ctx->peercred.pid = unp.unp_pid; + ctx->peercred.uid = unp.unp_euid; + ctx->peercred.gid = unp.unp_egid; + ctx->peercred_valid = 1; + } + } +#elif defined(HAVE_GETPEEREID) + { + if (getpeereid(fd, &ctx->peercred.uid, &ctx->peercred.gid) != -1) + { + ctx->peercred.pid = ASSUAN_INVALID_PID; + ctx->peercred_valid = 1; + } + } #endif ctx->inbound.fd = fd; ----------------------------------------------------------------------- Summary of changes: configure.ac | 26 ++++++++++++++++++++++++++ src/assuan-socket-server.c | 21 +++++++++++++++++++++ 2 files changed, 47 insertions(+), 0 deletions(-) hooks/post-receive -- IPC library used by GnuPG http://git.gnupg.org From cvs at cvs.gnupg.org Mon Nov 26 11:50:44 2012 From: cvs at cvs.gnupg.org (by Jussi Kivilinna) Date: Mon, 26 Nov 2012 11:50:44 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.5.0-65-gfaec12e Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via faec12e23f03c7cd1614594bfdd51f1302cadb42 (commit) via fc37e805c6394c2e635d1a033670be961f36a6d2 (commit) via 35aff0cd43885b5f5c076432ec614698abeb63d8 (commit) via 5acd0e5ae2a58dda51c2b56c879b80a1a6d2c42f (commit) via be3768994ad362dfc849a8cd0146b4c9bb287d20 (commit) via 3369d960158ab4231b83926a0f982e2a8819f173 (commit) via 55b96be08531664ed3f4230acebe0f45954bbc33 (commit) from dfb4673da8ee52d95e0a62c9f49ca8599943f22e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit faec12e23f03c7cd1614594bfdd51f1302cadb42 Author: Jussi Kivilinna Date: Fri Nov 23 19:22:35 2012 +0200 Optimize wipememory2 for i386 and x86-64 * src/g10lib.h (wipememory2): Add call to fast_wipememory2. (fast_wipememory2): New macros for i386 and x86-64 architectures. Empty macro provided for other architectures. -- Optimizing wipememory2 give broad range of speed improvements, as seen below. Cipher speed ratios, old-vs-new (AMD Phenom II, x86-64): ECB/Stream CBC CFB OFB CTR --------------- --------------- --------------- --------------- --------------- IDEA 1.32x 1.35x 1.29x 1.25x 1.30x 1.33x 1.33x 1.33x 1.22x 1.22x 3DES 1.13x 1.10x 1.11x 1.12x 1.13x 1.16x 1.13x 1.13x 1.10x 1.12x CAST5 1.57x 1.51x 1.56x 1.43x 1.48x 1.50x 1.49x 1.51x 1.28x 1.27x BLOWFISH 1.53x 1.52x 1.56x 1.42x 1.50x 1.51x 1.49x 1.52x 1.27x 1.28x AES 1.33x 1.33x 1.00x 1.02x 1.04x 1.02x 1.26x 1.26x 1.00x 0.98x AES192 1.33x 1.36x 1.05x 1.00x 1.04x 1.00x 1.28x 1.24x 1.02x 1.00x AES256 1.22x 1.33x 0.98x 1.00x 1.03x 1.02x 1.28x 1.25x 1.00x 1.00x TWOFISH 1.34x 1.34x 1.44x 1.25x 1.35x 1.28x 1.37x 1.37x 1.14x 1.16x ARCFOUR 1.00x 1.00x DES 1.31x 1.30x 1.34x 1.25x 1.28x 1.28x 1.34x 1.26x 1.22x 1.24x TWOFISH128 1.41x 1.45x 1.46x 1.28x 1.32x 1.37x 1.34x 1.28x 1.16x 1.16x SERPENT128 1.16x 1.20x 1.22x 1.16x 1.16x 1.16x 1.18x 1.18x 1.14x 1.11x SERPENT192 1.16x 1.20x 1.23x 1.16x 1.19x 1.18x 1.16x 1.16x 1.10x 1.10x SERPENT256 1.18x 1.23x 1.23x 1.13x 1.18x 1.16x 1.18x 1.16x 1.11x 1.11x RFC2268_40 1.00x 1.00x 1.03x 0.96x 0.98x 1.00x 0.99x 1.00x 0.99x 0.98x SEED 1.20x 1.24x 1.25x 1.18x 1.19x 1.18x 1.21x 1.22x 1.14x 1.12x CAMELLIA128 1.60x 1.69x 1.56x 1.50x 1.60x 1.53x 1.64x 1.63x 1.29x 1.32x CAMELLIA192 1.55x 1.46x 1.44x 1.34x 1.42x 1.50x 1.46x 1.51x 1.26x 1.28x CAMELLIA256 1.52x 1.50x 1.47x 1.40x 1.51x 1.44x 1.41x 1.50x 1.28x 1.28x Cipher speed ratios, old-vs-new (AMD Phenom II, i386): ECB/Stream CBC CFB OFB CTR --------------- --------------- --------------- --------------- --------------- IDEA 1.15x 1.11x 1.10x 1.08x 1.09x 1.13x 1.16x 1.07x 1.10x 1.14x 3DES 1.08x 1.08x 1.08x 1.07x 1.06x 1.06x 1.06x 1.05x 1.05x 1.05x CAST5 1.23x 1.25x 1.18x 1.17x 1.25x 1.21x 1.22x 1.17x 1.14x 1.12x BLOWFISH 1.25x 1.22x 1.21x 1.11x 1.23x 1.23x 1.24x 1.17x 1.14x 1.14x AES 1.13x 1.13x 1.02x 1.02x 0.98x 0.98x 1.16x 1.03x 1.02x 0.98x AES192 1.11x 1.12x 1.02x 0.99x 1.02x 0.95x 1.06x 1.00x 0.94x 0.91x AES256 1.05x 1.05x 0.97x 1.00x 1.00x 0.99x 1.11x 1.01x 0.99x 1.00x TWOFISH 1.11x 1.15x 1.16x 1.13x 1.12x 1.14x 1.13x 1.05x 1.07x 1.08x ARCFOUR 1.00x 0.97x DES 1.14x 1.14x 1.10x 1.07x 1.11x 1.12x 1.14x 1.08x 1.11x 1.17x TWOFISH128 1.16x 1.23x 1.18x 1.15x 1.14x 1.20x 1.15x 1.05x 1.08x 1.08x SERPENT128 1.08x 1.08x 1.08x 1.05x 1.06x 1.05x 1.09x 1.04x 1.05x 1.05x SERPENT192 1.07x 1.08x 1.08x 1.04x 1.04x 1.06x 1.08x 1.04x 1.01x 1.05x SERPENT256 1.06x 1.08x 1.05x 1.04x 1.05x 1.08x 1.07x 1.03x 1.06x 1.06x RFC2268_40 1.00x 0.99x 1.02x 1.01x 1.01x 1.00x 1.02x 0.99x 0.98x 0.99x SEED 1.12x 1.07x 1.12x 1.07x 1.09x 1.10x 1.10x 1.03x 1.07x 1.05x CAMELLIA128 1.24x 1.21x 1.16x 1.17x 1.16x 1.16x 1.21x 1.16x 1.13x 1.12x CAMELLIA192 1.19x 1.20x 1.14x 1.19x 1.20x 1.20x 1.18x 1.13x 1.13x 1.15x CAMELLIA256 1.21x 1.19x 1.14x 1.17x 1.17x 1.16x 1.17x 1.11x 1.12x 1.14x Hash speed ratios, old-vs-new (Intel Sandy-Bridge, x86-64): MD5 1.00x 1.47x 1.07x 1.00x 1.00x SHA1 1.06x 1.27x 1.06x 1.00x 1.00x RIPEMD160 1.04x 1.32x 1.11x 1.00x 1.00x TIGER192 1.05x 1.50x 1.15x 1.03x 1.05x SHA256 1.05x 1.38x 1.21x 1.04x 1.03x SHA384 1.15x 1.76x 1.25x 1.10x 1.04x SHA512 1.15x 1.76x 1.27x 1.08x 1.04x SHA224 1.05x 1.38x 1.21x 1.06x 1.00x MD4 1.17x 1.55x 1.06x 1.06x 1.00x CRC32 1.00x 1.00x 0.99x 1.04x 1.00x CRC32RFC1510 0.93x 1.00x 1.01x 1.00x 1.00x CRC24RFC2440 1.00x 1.00x 1.00x 0.99x 1.00x WHIRLPOOL 1.02x 1.00x 0.99x 1.00x 1.00x TIGER 1.05x 1.50x 1.15x 1.09x 1.05x TIGER2 1.05x 1.48x 1.16x 1.06x 0.95x Signed-off-by: Jussi Kivilinna diff --git a/src/g10lib.h b/src/g10lib.h index c580c08..f1af399 100644 --- a/src/g10lib.h +++ b/src/g10lib.h @@ -238,11 +238,52 @@ void _gcry_burn_stack (int bytes); #define wipememory2(_ptr,_set,_len) do { \ volatile char *_vptr=(volatile char *)(_ptr); \ size_t _vlen=(_len); \ - while(_vlen) { *_vptr=(_set); _vptr++; _vlen--; } \ + unsigned char _vset=(_set); \ + fast_wipememory2(_vptr,_vset,_vlen); \ + while(_vlen) { *_vptr=(_vset); _vptr++; _vlen--; } \ } while(0) #define wipememory(_ptr,_len) wipememory2(_ptr,0,_len) +/* Optimized fast_wipememory2 for i386 and x86-64 architechtures. Maybe leave + tail bytes unhandled, in which case tail bytes are handled by wipememory2. + */ +#if defined(__x86_64__) && __GNUC__ >= 4 +#define fast_wipememory2(_vptr,_vset,_vlen) do { \ + unsigned long long int _vset8 = _vset; \ + if (_vlen < 8) \ + break; \ + _vset8 *= 0x0101010101010101ULL; \ + do { \ + asm volatile("movq %[set], %[ptr]\n\t" \ + : /**/ \ + : [set] "Cr" (_vset8), \ + [ptr] "m" (*_vptr) \ + : "memory"); \ + _vlen -= 8; \ + _vptr += 8; \ + } while (_vlen >= 8); \ + } while (0) +#elif defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4 && __GNUC__ >= 4 +#define fast_wipememory2(_ptr,_set,_len) do { \ + unsigned long _vset4 = _vset; \ + if (_vlen < 4) \ + break; \ + _vset4 *= 0x01010101; \ + do { \ + asm volatile("movl %[set], %[ptr]\n\t" \ + : /**/ \ + : [set] "Cr" (_vset4), \ + [ptr] "m" (*_vptr) \ + : "memory"); \ + _vlen -= 4; \ + _vptr += 4; \ + } while (_vlen >= 4); \ + } while (0) +#else +#define fast_wipememory2(_ptr,_set,_len) +#endif + /* Digit predicates. */ commit fc37e805c6394c2e635d1a033670be961f36a6d2 Author: Jussi Kivilinna Date: Fri Nov 23 19:22:30 2012 +0200 Fix missing 64bit carry handling in AES-NI CTR mode * cipher/rijndael.c [USE_AESNI] (do_aesni_ctr, do_aesni_ctr_4): Add carry handling to 64-bit addition. (selftest_ctr_128): New function for testing IV handling in bulk CTR function. (selftest): Add call to selftest_ctr_128. -- Carry handling checks if lower 64-bit part of SSE register was overflowed and if it was, increment upper parts since that point. Also add selftests to verify correct operation. Signed-off-by: Jussi Kivilinna diff --git a/cipher/rijndael.c b/cipher/rijndael.c index 34a0f8c..860dcf8 100644 --- a/cipher/rijndael.c +++ b/cipher/rijndael.c @@ -1011,16 +1011,33 @@ do_aesni_ctr (const RIJNDAEL_context *ctx, static unsigned char be_mask[16] __attribute__ ((aligned (16))) = { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; - asm volatile ("movdqa %[ctr], %%xmm0\n\t" /* xmm0, xmm2 := CTR */ + asm volatile ("movdqa (%[ctr]), %%xmm0\n\t" /* xmm0, xmm2 := CTR */ "movaps %%xmm0, %%xmm2\n\t" "mov $1, %%esi\n\t" /* xmm2++ (big-endian) */ "movd %%esi, %%xmm1\n\t" + + "movl 12(%[ctr]), %%esi\n\t" /* load lower parts of CTR */ + "bswapl %%esi\n\t" + "movl 8(%[ctr]), %%edi\n\t" + "bswapl %%edi\n\t" + "pshufb %[mask], %%xmm2\n\t" "paddq %%xmm1, %%xmm2\n\t" + + "addl $1, %%esi\n\t" + "adcl $0, %%edi\n\t" /* detect 64bit overflow */ + "jnc .Lno_carry%=\n\t" + + /* swap upper and lower halfs */ + "pshufd $0x4e, %%xmm1, %%xmm1\n\t" + "paddq %%xmm1, %%xmm2\n\t" /* add carry to upper 64bits */ + + ".Lno_carry%=:\n\t" + "pshufb %[mask], %%xmm2\n\t" - "movdqa %%xmm2, %[ctr]\n" /* Update CTR. */ + "movdqa %%xmm2, (%[ctr])\n" /* Update CTR. */ - "movdqa (%[key]), %%xmm1\n\t" /* xmm1 := key[0] */ + "movdqa (%[key]), %%xmm1\n\t" /* xmm1 := key[0] */ "pxor %%xmm1, %%xmm0\n\t" /* xmm0 ^= key[0] */ "movdqa 0x10(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 @@ -1060,12 +1077,13 @@ do_aesni_ctr (const RIJNDAEL_context *ctx, "pxor %%xmm1, %%xmm0\n\t" /* EncCTR ^= input */ "movdqu %%xmm0, %[dst]" /* Store EncCTR. */ - : [ctr] "+m" (*ctr), [dst] "=m" (*b) + : [dst] "=m" (*b) : [src] "m" (*a), + [ctr] "r" (ctr), [key] "r" (ctx->keyschenc), [rounds] "g" (ctx->rounds), [mask] "m" (*be_mask) - : "%esi", "cc", "memory"); + : "%esi", "%edi", "cc", "memory"); #undef aesenc_xmm1_xmm0 #undef aesenclast_xmm1_xmm0 } @@ -1098,10 +1116,16 @@ do_aesni_ctr_4 (const RIJNDAEL_context *ctx, xmm5 temp */ - asm volatile ("movdqa %[ctr], %%xmm0\n\t" /* xmm0, xmm2 := CTR */ + asm volatile ("movdqa (%[ctr]), %%xmm0\n\t" /* xmm0, xmm2 := CTR */ "movaps %%xmm0, %%xmm2\n\t" "mov $1, %%esi\n\t" /* xmm1 := 1 */ "movd %%esi, %%xmm1\n\t" + + "movl 12(%[ctr]), %%esi\n\t" /* load lower parts of CTR */ + "bswapl %%esi\n\t" + "movl 8(%[ctr]), %%edi\n\t" + "bswapl %%edi\n\t" + "pshufb %[mask], %%xmm2\n\t" /* xmm2 := le(xmm2) */ "paddq %%xmm1, %%xmm2\n\t" /* xmm2++ */ "movaps %%xmm2, %%xmm3\n\t" /* xmm3 := xmm2 */ @@ -1110,11 +1134,39 @@ do_aesni_ctr_4 (const RIJNDAEL_context *ctx, "paddq %%xmm1, %%xmm4\n\t" /* xmm4++ */ "movaps %%xmm4, %%xmm5\n\t" /* xmm5 := xmm4 */ "paddq %%xmm1, %%xmm5\n\t" /* xmm5++ */ + + /* swap upper and lower halfs */ + "pshufd $0x4e, %%xmm1, %%xmm1\n\t" + + "addl $1, %%esi\n\t" + "adcl $0, %%edi\n\t" /* detect 64bit overflow */ + "jc .Lcarry_xmm2%=\n\t" + "addl $1, %%esi\n\t" + "adcl $0, %%edi\n\t" /* detect 64bit overflow */ + "jc .Lcarry_xmm3%=\n\t" + "addl $1, %%esi\n\t" + "adcl $0, %%edi\n\t" /* detect 64bit overflow */ + "jc .Lcarry_xmm4%=\n\t" + "addl $1, %%esi\n\t" + "adcl $0, %%edi\n\t" /* detect 64bit overflow */ + "jc .Lcarry_xmm5%=\n\t" + "jmp .Lno_carry%=\n\t" + + ".Lcarry_xmm2%=:\n\t" + "paddq %%xmm1, %%xmm2\n\t" + ".Lcarry_xmm3%=:\n\t" + "paddq %%xmm1, %%xmm3\n\t" + ".Lcarry_xmm4%=:\n\t" + "paddq %%xmm1, %%xmm4\n\t" + ".Lcarry_xmm5%=:\n\t" + "paddq %%xmm1, %%xmm5\n\t" + + ".Lno_carry%=:\n\t" "pshufb %[mask], %%xmm2\n\t" /* xmm2 := be(xmm2) */ "pshufb %[mask], %%xmm3\n\t" /* xmm3 := be(xmm3) */ "pshufb %[mask], %%xmm4\n\t" /* xmm4 := be(xmm4) */ "pshufb %[mask], %%xmm5\n\t" /* xmm5 := be(xmm5) */ - "movdqa %%xmm5, %[ctr]\n" /* Update CTR. */ + "movdqa %%xmm5, (%[ctr])\n" /* Update CTR. */ "movdqa (%[key]), %%xmm1\n\t" /* xmm1 := key[0] */ "pxor %%xmm1, %%xmm0\n\t" /* xmm0 ^= key[0] */ @@ -1198,28 +1250,30 @@ do_aesni_ctr_4 (const RIJNDAEL_context *ctx, aesenclast_xmm1_xmm3 aesenclast_xmm1_xmm4 - "movdqu %[src], %%xmm1\n\t" /* Get block 1. */ + "movdqu (%[src]), %%xmm1\n\t" /* Get block 1. */ "pxor %%xmm1, %%xmm0\n\t" /* EncCTR-1 ^= input */ - "movdqu %%xmm0, %[dst]\n\t" /* Store block 1 */ + "movdqu %%xmm0, (%[dst])\n\t" /* Store block 1 */ - "movdqu (16)%[src], %%xmm1\n\t" /* Get block 2. */ + "movdqu 16(%[src]), %%xmm1\n\t" /* Get block 2. */ "pxor %%xmm1, %%xmm2\n\t" /* EncCTR-2 ^= input */ - "movdqu %%xmm2, (16)%[dst]\n\t" /* Store block 2. */ + "movdqu %%xmm2, 16(%[dst])\n\t" /* Store block 2. */ - "movdqu (32)%[src], %%xmm1\n\t" /* Get block 3. */ + "movdqu 32(%[src]), %%xmm1\n\t" /* Get block 3. */ "pxor %%xmm1, %%xmm3\n\t" /* EncCTR-3 ^= input */ - "movdqu %%xmm3, (32)%[dst]\n\t" /* Store block 3. */ + "movdqu %%xmm3, 32(%[dst])\n\t" /* Store block 3. */ - "movdqu (48)%[src], %%xmm1\n\t" /* Get block 4. */ + "movdqu 48(%[src]), %%xmm1\n\t" /* Get block 4. */ "pxor %%xmm1, %%xmm4\n\t" /* EncCTR-4 ^= input */ - "movdqu %%xmm4, (48)%[dst]" /* Store block 4. */ + "movdqu %%xmm4, 48(%[dst])" /* Store block 4. */ - : [ctr] "+m" (*ctr), [dst] "=m" (*b) - : [src] "m" (*a), + : + : [ctr] "r" (ctr), + [src] "r" (a), + [dst] "r" (b), [key] "r" (ctx->keyschenc), [rounds] "g" (ctx->rounds), [mask] "m" (*be_mask) - : "%esi", "cc", "memory"); + : "%esi", "%edi", "cc", "memory"); #undef aesenc_xmm1_xmm0 #undef aesenc_xmm1_xmm2 #undef aesenc_xmm1_xmm3 @@ -1970,6 +2024,102 @@ selftest_basic_256 (void) return NULL; } + +/* Run the self-tests for AES-CTR-128, tests IV increment of bulk CTR + encryption. Returns NULL on success. */ +static const char* +selftest_ctr_128 (void) +{ + RIJNDAEL_context ctx ATTR_ALIGNED_16; + unsigned char plaintext[7*16] ATTR_ALIGNED_16; + unsigned char ciphertext[7*16] ATTR_ALIGNED_16; + unsigned char plaintext2[7*16] ATTR_ALIGNED_16; + unsigned char iv[16] ATTR_ALIGNED_16; + unsigned char iv2[16] ATTR_ALIGNED_16; + int i, j, diff; + + static const unsigned char key[16] ATTR_ALIGNED_16 = { + 0x06,0x9A,0x00,0x7F,0xC7,0x6A,0x45,0x9F, + 0x98,0xBA,0xF9,0x17,0xFE,0xDF,0x95,0x21 + }; + static char error_str[128]; + + rijndael_setkey (&ctx, key, sizeof (key)); + + /* Test single block code path */ + memset(iv, 0xff, sizeof(iv)); + for (i = 0; i < 16; i++) + plaintext[i] = i; + + /* CTR manually. */ + rijndael_encrypt (&ctx, ciphertext, iv); + for (i = 0; i < 16; i++) + ciphertext[i] ^= plaintext[i]; + for (i = 16; i > 0; i--) + { + iv[i-1]++; + if (iv[i-1]) + break; + } + + memset(iv2, 0xff, sizeof(iv2)); + _gcry_aes_ctr_enc (&ctx, iv2, plaintext2, ciphertext, 1); + + if (memcmp(plaintext2, plaintext, 16)) + return "AES-128-CTR test failed (plaintext mismatch)"; + + if (memcmp(iv2, iv, 16)) + return "AES-128-CTR test failed (IV mismatch)"; + + /* Test parallelized code paths */ + for (diff = 0; diff < 7; diff++) { + memset(iv, 0xff, sizeof(iv)); + iv[15] -= diff; + + for (i = 0; i < sizeof(plaintext); i++) + plaintext[i] = i; + + /* Create CTR ciphertext manually. */ + for (i = 0; i < sizeof(plaintext); i+=16) + { + rijndael_encrypt (&ctx, &ciphertext[i], iv); + for (j = 0; j < 16; j++) + ciphertext[i+j] ^= plaintext[i+j]; + for (j = 16; j > 0; j--) + { + iv[j-1]++; + if (iv[j-1]) + break; + } + } + + /* Decrypt using bulk CTR and compare result. */ + memset(iv2, 0xff, sizeof(iv2)); + iv2[15] -= diff; + + _gcry_aes_ctr_enc (&ctx, iv2, plaintext2, ciphertext, + sizeof(ciphertext) / BLOCKSIZE); + + if (memcmp(plaintext2, plaintext, sizeof(plaintext))) + { + snprintf(error_str, sizeof(error_str), + "AES-128-CTR test failed (plaintext mismatch, diff: %d)", + diff); + return error_str; + } + if (memcmp(iv2, iv, sizeof(iv))) + { + snprintf(error_str, sizeof(error_str), + "AES-128-CTR test failed (IV mismatch, diff: %d)", + diff); + return error_str; + } + } + + return NULL; +} + + /* Run all the self-tests and return NULL on success. This function is used for the on-the-fly self-tests. */ static const char * @@ -1982,6 +2132,9 @@ selftest (void) || (r = selftest_basic_256 ()) ) return r; + if ( (r = selftest_ctr_128 ()) ) + return r; + return r; } commit 35aff0cd43885b5f5c076432ec614698abeb63d8 Author: Jussi Kivilinna Date: Fri Nov 23 19:22:14 2012 +0200 Add parallelized AES-NI CBC decryption * cipher/rijndael.c [USE_AESNI] (aesni_cleanup_5): New macro. [USE_AESNI] (do_aesni_dec_vec4): New function. (_gcry_aes_cbc_dec) [USE_AESNI]: Add parallelized CBC loop. (_gcry_aes_cbc_dec) [USE_AESNI]: Change IV storage register from xmm3 to xmm5. -- This gives ~60% improvement in CBC decryption speed on sandy-bridge (x86-64). Overall speed improvement with this and previous CBC patches is over 400%. Before: $ tests/benchmark --cipher-repetitions 1000 cipher aes aes192 aes256 Running each test 1000 times. ECB/Stream CBC CFB OFB CTR --------------- --------------- --------------- --------------- --------------- AES 670ms 770ms 2920ms 720ms 1900ms 660ms 2260ms 2250ms 480ms 500ms AES192 860ms 930ms 3250ms 870ms 2210ms 830ms 2580ms 2580ms 570ms 570ms AES256 1020ms 1080ms 3580ms 1030ms 2550ms 970ms 2880ms 2870ms 660ms 660ms After: $ tests/benchmark --cipher-repetitions 1000 cipher aes aes192 aes256 Running each test 1000 times. ECB/Stream CBC CFB OFB CTR --------------- --------------- --------------- --------------- --------------- AES 670ms 770ms 2130ms 450ms 1880ms 670ms 2250ms 2280ms 490ms 490ms AES192 880ms 920ms 2460ms 540ms 2210ms 830ms 2580ms 2570ms 580ms 570ms AES256 1020ms 1070ms 2800ms 620ms 2560ms 970ms 2880ms 2880ms 660ms 650ms Signed-off-by: Jussi Kivilinna diff --git a/cipher/rijndael.c b/cipher/rijndael.c index 69e1df1..34a0f8c 100644 --- a/cipher/rijndael.c +++ b/cipher/rijndael.c @@ -822,6 +822,115 @@ do_aesni_dec_aligned (const RIJNDAEL_context *ctx, } +/* Decrypt four blocks using the Intel AES-NI instructions. Blocks are input + * and output through SSE registers xmm1 to xmm4. */ +static void +do_aesni_dec_vec4 (const RIJNDAEL_context *ctx) +{ +#define aesdec_xmm0_xmm1 ".byte 0x66, 0x0f, 0x38, 0xde, 0xc8\n\t" +#define aesdec_xmm0_xmm2 ".byte 0x66, 0x0f, 0x38, 0xde, 0xd0\n\t" +#define aesdec_xmm0_xmm3 ".byte 0x66, 0x0f, 0x38, 0xde, 0xd8\n\t" +#define aesdec_xmm0_xmm4 ".byte 0x66, 0x0f, 0x38, 0xde, 0xe0\n\t" +#define aesdeclast_xmm0_xmm1 ".byte 0x66, 0x0f, 0x38, 0xdf, 0xc8\n\t" +#define aesdeclast_xmm0_xmm2 ".byte 0x66, 0x0f, 0x38, 0xdf, 0xd0\n\t" +#define aesdeclast_xmm0_xmm3 ".byte 0x66, 0x0f, 0x38, 0xdf, 0xd8\n\t" +#define aesdeclast_xmm0_xmm4 ".byte 0x66, 0x0f, 0x38, 0xdf, 0xe0\n\t" + asm volatile ("movdqa (%[key]), %%xmm0\n\t" + "pxor %%xmm0, %%xmm1\n\t" /* xmm1 ^= key[0] */ + "pxor %%xmm0, %%xmm2\n\t" /* xmm2 ^= key[0] */ + "pxor %%xmm0, %%xmm3\n\t" /* xmm3 ^= key[0] */ + "pxor %%xmm0, %%xmm4\n\t" /* xmm4 ^= key[0] */ + "movdqa 0x10(%[key]), %%xmm0\n\t" + aesdec_xmm0_xmm1 + aesdec_xmm0_xmm2 + aesdec_xmm0_xmm3 + aesdec_xmm0_xmm4 + "movdqa 0x20(%[key]), %%xmm0\n\t" + aesdec_xmm0_xmm1 + aesdec_xmm0_xmm2 + aesdec_xmm0_xmm3 + aesdec_xmm0_xmm4 + "movdqa 0x30(%[key]), %%xmm0\n\t" + aesdec_xmm0_xmm1 + aesdec_xmm0_xmm2 + aesdec_xmm0_xmm3 + aesdec_xmm0_xmm4 + "movdqa 0x40(%[key]), %%xmm0\n\t" + aesdec_xmm0_xmm1 + aesdec_xmm0_xmm2 + aesdec_xmm0_xmm3 + aesdec_xmm0_xmm4 + "movdqa 0x50(%[key]), %%xmm0\n\t" + aesdec_xmm0_xmm1 + aesdec_xmm0_xmm2 + aesdec_xmm0_xmm3 + aesdec_xmm0_xmm4 + "movdqa 0x60(%[key]), %%xmm0\n\t" + aesdec_xmm0_xmm1 + aesdec_xmm0_xmm2 + aesdec_xmm0_xmm3 + aesdec_xmm0_xmm4 + "movdqa 0x70(%[key]), %%xmm0\n\t" + aesdec_xmm0_xmm1 + aesdec_xmm0_xmm2 + aesdec_xmm0_xmm3 + aesdec_xmm0_xmm4 + "movdqa 0x80(%[key]), %%xmm0\n\t" + aesdec_xmm0_xmm1 + aesdec_xmm0_xmm2 + aesdec_xmm0_xmm3 + aesdec_xmm0_xmm4 + "movdqa 0x90(%[key]), %%xmm0\n\t" + aesdec_xmm0_xmm1 + aesdec_xmm0_xmm2 + aesdec_xmm0_xmm3 + aesdec_xmm0_xmm4 + "movdqa 0xa0(%[key]), %%xmm0\n\t" + "cmp $10, %[rounds]\n\t" + "jz .Ldeclast%=\n\t" + aesdec_xmm0_xmm1 + aesdec_xmm0_xmm2 + aesdec_xmm0_xmm3 + aesdec_xmm0_xmm4 + "movdqa 0xb0(%[key]), %%xmm0\n\t" + aesdec_xmm0_xmm1 + aesdec_xmm0_xmm2 + aesdec_xmm0_xmm3 + aesdec_xmm0_xmm4 + "movdqa 0xc0(%[key]), %%xmm0\n\t" + "cmp $12, %[rounds]\n\t" + "jz .Ldeclast%=\n\t" + aesdec_xmm0_xmm1 + aesdec_xmm0_xmm2 + aesdec_xmm0_xmm3 + aesdec_xmm0_xmm4 + "movdqa 0xd0(%[key]), %%xmm0\n\t" + aesdec_xmm0_xmm1 + aesdec_xmm0_xmm2 + aesdec_xmm0_xmm3 + aesdec_xmm0_xmm4 + "movdqa 0xe0(%[key]), %%xmm0\n" + + ".Ldeclast%=:\n\t" + aesdeclast_xmm0_xmm1 + aesdeclast_xmm0_xmm2 + aesdeclast_xmm0_xmm3 + aesdeclast_xmm0_xmm4 + : /* no output */ + : [key] "r" (ctx->keyschdec), + [rounds] "r" (ctx->rounds) + : "cc", "memory"); +#undef aesdec_xmm0_xmm1 +#undef aesdec_xmm0_xmm2 +#undef aesdec_xmm0_xmm3 +#undef aesdec_xmm0_xmm4 +#undef aesdeclast_xmm0_xmm1 +#undef aesdeclast_xmm0_xmm2 +#undef aesdeclast_xmm0_xmm3 +#undef aesdeclast_xmm0_xmm4 +} + + /* Perform a CFB encryption or decryption round using the initialization vector IV and the input block A. Write the result to the output block B and update IV. IV needs to be 16 byte @@ -1623,17 +1732,51 @@ _gcry_aes_cbc_dec (void *context, unsigned char *iv, ctx->decryption_prepared = 1; } - /* As we avoid memcpy to/from stack by using xmm2 and xmm3 for temporary - storage, out-of-order CPUs see parallellism even over loop iterations - and see 2.5x to 2.9x speed up on Intel Sandy-Bridge. Further - improvements are possible with do_aesni_cbc_dec_4() when implemented. - */ asm volatile - ("movdqu %[iv], %%xmm3\n\t" /* use xmm3 as fast IV storage */ + ("movdqu %[iv], %%xmm5\n\t" /* use xmm5 as fast IV storage */ : /* No output */ : [iv] "m" (*iv) : "memory"); + for ( ;nblocks > 3 ; nblocks -= 4 ) + { + asm volatile + ("movdqu 0*16(%[inbuf]), %%xmm1\n\t" /* load input blocks */ + "movdqu 1*16(%[inbuf]), %%xmm2\n\t" + "movdqu 2*16(%[inbuf]), %%xmm3\n\t" + "movdqu 3*16(%[inbuf]), %%xmm4\n\t" + : /* No output */ + : [inbuf] "r" (inbuf) + : "memory"); + + do_aesni_dec_vec4 (ctx); + + asm volatile + ("pxor %%xmm5, %%xmm1\n\t" /* xor IV with output */ + "movdqu 0*16(%[inbuf]), %%xmm5\n\t" /* load new IV */ + "movdqu %%xmm1, 0*16(%[outbuf])\n\t" + + "pxor %%xmm5, %%xmm2\n\t" /* xor IV with output */ + "movdqu 1*16(%[inbuf]), %%xmm5\n\t" /* load new IV */ + "movdqu %%xmm2, 1*16(%[outbuf])\n\t" + + "pxor %%xmm5, %%xmm3\n\t" /* xor IV with output */ + "movdqu 2*16(%[inbuf]), %%xmm5\n\t" /* load new IV */ + "movdqu %%xmm3, 2*16(%[outbuf])\n\t" + + "pxor %%xmm5, %%xmm4\n\t" /* xor IV with output */ + "movdqu 3*16(%[inbuf]), %%xmm5\n\t" /* load new IV */ + "movdqu %%xmm4, 3*16(%[outbuf])\n\t" + + : /* No output */ + : [inbuf] "r" (inbuf), + [outbuf] "r" (outbuf) + : "memory"); + + outbuf += 4*BLOCKSIZE; + inbuf += 4*BLOCKSIZE; + } + for ( ;nblocks; nblocks-- ) { asm volatile @@ -1647,9 +1790,9 @@ _gcry_aes_cbc_dec (void *context, unsigned char *iv, asm volatile ("movdqu %[outbuf], %%xmm0\n\t" - "pxor %%xmm3, %%xmm0\n\t" /* xor IV with output */ + "pxor %%xmm5, %%xmm0\n\t" /* xor IV with output */ "movdqu %%xmm0, %[outbuf]\n\t" - "movdqu %%xmm2, %%xmm3\n\t" /* store savebuf as new IV */ + "movdqu %%xmm2, %%xmm5\n\t" /* store savebuf as new IV */ : /* No output */ : [outbuf] "m" (*outbuf) : "memory"); @@ -1659,7 +1802,7 @@ _gcry_aes_cbc_dec (void *context, unsigned char *iv, } asm volatile - ("movdqu %%xmm3, %[iv]\n\t" /* store IV */ + ("movdqu %%xmm5, %[iv]\n\t" /* store IV */ : /* No output */ : [iv] "m" (*iv) : "memory"); commit 5acd0e5ae2a58dda51c2b56c879b80a1a6d2c42f Author: Jussi Kivilinna Date: Fri Nov 23 19:22:09 2012 +0200 Clear xmm5 after use in AES-NI CTR mode * cipher/rijndael.c [USE_AESNI]: Rename aesni_cleanup_2_4 to aesni_cleanup_2_5. [USE_AESNI] (aesni_cleanup_2_5): Clear xmm5 register. (_gcry_aes_ctr_enc, _gcry_aes_cbc_dec) [USE_AESNI]: Use aesni_cleanup_2_5 instead of aesni_cleanup_2_4. -- xmm5 register is used by parallelized AES-NI CTR mode, so it should be cleaned up after use too. Signed-off-by: Jussi Kivilinna diff --git a/cipher/rijndael.c b/cipher/rijndael.c index 982c54e..69e1df1 100644 --- a/cipher/rijndael.c +++ b/cipher/rijndael.c @@ -144,10 +144,11 @@ typedef struct do { asm volatile ("pxor %%xmm0, %%xmm0\n\t" \ "pxor %%xmm1, %%xmm1\n" :: ); \ } while (0) -# define aesni_cleanup_2_4() \ +# define aesni_cleanup_2_5() \ do { asm volatile ("pxor %%xmm2, %%xmm2\n\t" \ "pxor %%xmm3, %%xmm3\n" \ - "pxor %%xmm4, %%xmm4\n":: ); \ + "pxor %%xmm4, %%xmm4\n" \ + "pxor %%xmm5, %%xmm5\n":: ); \ } while (0) #else # define aesni_prepare() do { } while (0) @@ -1338,7 +1339,7 @@ _gcry_aes_ctr_enc (void *context, unsigned char *ctr, inbuf += BLOCKSIZE; } aesni_cleanup (); - aesni_cleanup_2_4 (); + aesni_cleanup_2_5 (); } #endif /*USE_AESNI*/ else @@ -1664,7 +1665,7 @@ _gcry_aes_cbc_dec (void *context, unsigned char *iv, : "memory"); aesni_cleanup (); - aesni_cleanup_2_4 (); + aesni_cleanup_2_5 (); } #endif /*USE_AESNI*/ else commit be3768994ad362dfc849a8cd0146b4c9bb287d20 Author: Jussi Kivilinna Date: Fri Nov 23 19:22:04 2012 +0200 Optimize AES-NI CBC encryption * cipher/rijndeal.c (_gcry_aes_cbc_enc) [USE_AESNI]: Add AES-NI spesific loop and use SSE2 assembler for xoring and copying of blocks. -- This gives ~35% improvement in 'tests/benchmark cipher aes' on Sandy-Bridge CPU (x86-64). Signed-off-by: Jussi Kivilinna diff --git a/cipher/rijndael.c b/cipher/rijndael.c index 104f869..982c54e 100644 --- a/cipher/rijndael.c +++ b/cipher/rijndael.c @@ -1249,23 +1249,50 @@ _gcry_aes_cbc_enc (void *context, unsigned char *iv, aesni_prepare (); for ( ;nblocks; nblocks-- ) { - for (ivp=iv, i=0; i < BLOCKSIZE; i++ ) - outbuf[i] = inbuf[i] ^ *ivp++; - if (0) ; -#ifdef USE_PADLOCK - else if (ctx->use_padlock) - do_padlock (ctx, 0, outbuf, outbuf); -#endif /*USE_PADLOCK*/ #ifdef USE_AESNI else if (ctx->use_aesni) - do_aesni (ctx, 0, outbuf, outbuf); + { + /* ~35% speed up on Sandy-Bridge when doing xoring and copying with + SSE registers. */ + asm volatile ("movdqu %[iv], %%xmm0\n\t" + "movdqu %[inbuf], %%xmm1\n\t" + "pxor %%xmm0, %%xmm1\n\t" + "movdqu %%xmm1, %[outbuf]\n\t" + : /* No output */ + : [iv] "m" (*iv), + [inbuf] "m" (*inbuf), + [outbuf] "m" (*outbuf) + : "memory" ); + + do_aesni (ctx, 0, outbuf, outbuf); + + asm volatile ("movdqu %[outbuf], %%xmm0\n\t" + "movdqu %%xmm0, %[iv]\n\t" + : /* No output */ + : [outbuf] "m" (*outbuf), + [iv] "m" (*iv) + : "memory" ); + } #endif /*USE_AESNI*/ else - do_encrypt (ctx, outbuf, outbuf ); + { + for (ivp=iv, i=0; i < BLOCKSIZE; i++ ) + outbuf[i] = inbuf[i] ^ *ivp++; + + if (0) + ; +#ifdef USE_PADLOCK + else if (ctx->use_padlock) + do_padlock (ctx, 0, outbuf, outbuf); +#endif /*USE_PADLOCK*/ + else + do_encrypt (ctx, outbuf, outbuf ); + + memcpy (iv, outbuf, BLOCKSIZE); + } - memcpy (iv, outbuf, BLOCKSIZE); inbuf += BLOCKSIZE; if (!cbc_mac) outbuf += BLOCKSIZE; commit 3369d960158ab4231b83926a0f982e2a8819f173 Author: Jussi Kivilinna Date: Fri Nov 23 19:21:59 2012 +0200 Improve parallelizability of CBC decryption for AES-NI * cipher/rijndael.c (_gcry_aes_cbc_dec) [USE_AESNI]: Add AES-NI specific CBC mode loop with temporary block and IV stored in free SSE registers. -- Benchmark results on Intel Core i5-2450M (x86-64) show ~2.5x improvement: Before: $ tests/benchmark --cipher-repetitions 1000 cipher aes aes192 aes256 Running each test 1000 times. ECB/Stream CBC CFB OFB CTR --------------- --------------- --------------- --------------- --------------- AES 690ms 780ms 2940ms 2110ms 1880ms 670ms 2250ms 2250ms 490ms 500ms AES192 890ms 930ms 3260ms 2390ms 2220ms 820ms 2580ms 2590ms 560ms 570ms AES256 1040ms 1070ms 3590ms 2640ms 2540ms 970ms 2880ms 2890ms 650ms 650ms After: $ tests/benchmark --cipher-repetitions 1000 cipher aes aes192 aes256 Running each test 1000 times. ECB/Stream CBC CFB OFB CTR --------------- --------------- --------------- --------------- --------------- AES 670ms 770ms 2920ms 720ms 1900ms 660ms 2260ms 2250ms 480ms 500ms AES192 860ms 930ms 3250ms 870ms 2210ms 830ms 2580ms 2580ms 570ms 570ms AES256 1020ms 1080ms 3580ms 1030ms 2550ms 970ms 2880ms 2870ms 660ms 660ms Signed-off-by: Jussi Kivilinna diff --git a/cipher/rijndael.c b/cipher/rijndael.c index d081b42..104f869 100644 --- a/cipher/rijndael.c +++ b/cipher/rijndael.c @@ -1582,33 +1582,86 @@ _gcry_aes_cbc_dec (void *context, unsigned char *iv, int i; unsigned char savebuf[BLOCKSIZE]; - aesni_prepare (); - for ( ;nblocks; nblocks-- ) + if (0) + ; +#ifdef USE_AESNI + else if (ctx->use_aesni) { - /* We need to save INBUF away because it may be identical to - OUTBUF. */ - memcpy (savebuf, inbuf, BLOCKSIZE); + aesni_prepare (); - if (0) - ; + if (!ctx->decryption_prepared ) + { + prepare_decryption ( ctx ); + ctx->decryption_prepared = 1; + } + + /* As we avoid memcpy to/from stack by using xmm2 and xmm3 for temporary + storage, out-of-order CPUs see parallellism even over loop iterations + and see 2.5x to 2.9x speed up on Intel Sandy-Bridge. Further + improvements are possible with do_aesni_cbc_dec_4() when implemented. + */ + asm volatile + ("movdqu %[iv], %%xmm3\n\t" /* use xmm3 as fast IV storage */ + : /* No output */ + : [iv] "m" (*iv) + : "memory"); + + for ( ;nblocks; nblocks-- ) + { + asm volatile + ("movdqu %[inbuf], %%xmm2\n\t" /* use xmm2 as savebuf */ + : /* No output */ + : [inbuf] "m" (*inbuf) + : "memory"); + + /* uses only xmm0 and xmm1 */ + do_aesni_dec_aligned (ctx, outbuf, inbuf); + + asm volatile + ("movdqu %[outbuf], %%xmm0\n\t" + "pxor %%xmm3, %%xmm0\n\t" /* xor IV with output */ + "movdqu %%xmm0, %[outbuf]\n\t" + "movdqu %%xmm2, %%xmm3\n\t" /* store savebuf as new IV */ + : /* No output */ + : [outbuf] "m" (*outbuf) + : "memory"); + + outbuf += BLOCKSIZE; + inbuf += BLOCKSIZE; + } + + asm volatile + ("movdqu %%xmm3, %[iv]\n\t" /* store IV */ + : /* No output */ + : [iv] "m" (*iv) + : "memory"); + + aesni_cleanup (); + aesni_cleanup_2_4 (); + } +#endif /*USE_AESNI*/ + else + for ( ;nblocks; nblocks-- ) + { + /* We need to save INBUF away because it may be identical to + OUTBUF. */ + memcpy (savebuf, inbuf, BLOCKSIZE); + + if (0) + ; #ifdef USE_PADLOCK - else if (ctx->use_padlock) - do_padlock (ctx, 1, outbuf, inbuf); + else if (ctx->use_padlock) + do_padlock (ctx, 1, outbuf, inbuf); #endif /*USE_PADLOCK*/ -#ifdef USE_AESNI - else if (ctx->use_aesni) - do_aesni (ctx, 1, outbuf, inbuf); -#endif /*USE_AESNI*/ - else - do_decrypt (ctx, outbuf, inbuf); + else + do_decrypt (ctx, outbuf, inbuf); - for (ivp=iv, i=0; i < BLOCKSIZE; i++ ) - outbuf[i] ^= *ivp++; - memcpy (iv, savebuf, BLOCKSIZE); - inbuf += BLOCKSIZE; - outbuf += BLOCKSIZE; - } - aesni_cleanup (); + for (ivp=iv, i=0; i < BLOCKSIZE; i++ ) + outbuf[i] ^= *ivp++; + memcpy (iv, savebuf, BLOCKSIZE); + inbuf += BLOCKSIZE; + outbuf += BLOCKSIZE; + } _gcry_burn_stack (48 + 2*sizeof(int) + BLOCKSIZE + 4*sizeof (char*)); } commit 55b96be08531664ed3f4230acebe0f45954bbc33 Author: Jussi Kivilinna Date: Fri Nov 23 19:21:54 2012 +0200 Extend test of chained modes for 128bit ciphers * tests/basic.c (check_one_cipher_core, check_one_cipher): Increase input and output buffer sizes from 16 bytes to 1024+16=1040 bytes. (check_one_cipher_core): Add asserts to verify sizes of temporary buffers. -- Currently check_one_cipher() has buffer size of 16 bytes, which is one block with 128bit cipher. As result chained modes for 128bit ciphers are not well tested. Increase buffer size to 1040 bytes, so that iterations of chained modes and parallellized code paths (AES-NI CTR, etc) are also tested. Extra 16 bytes after 1024 bytes to ensure that loop transision from parallelized code paths to serialized code paths get tested too. Signed-off-by: Jussi Kivilinna diff --git a/tests/basic.c b/tests/basic.c index 8001e86..656d76c 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -1367,13 +1367,15 @@ check_one_cipher_core (int algo, int mode, int flags, int bufshift, int pass) { gcry_cipher_hd_t hd; - unsigned char in_buffer[17], out_buffer[17]; + unsigned char in_buffer[1040+1], out_buffer[1040+1]; unsigned char *in, *out; int keylen; gcry_error_t err = 0; assert (nkey == 32); - assert (nplain == 16); + assert (nplain == 1040); + assert (sizeof(in_buffer) == nplain + 1); + assert (sizeof(out_buffer) == sizeof(in_buffer)); if (!bufshift) { @@ -1427,7 +1429,7 @@ check_one_cipher_core (int algo, int mode, int flags, return -1; } - err = gcry_cipher_encrypt (hd, out, 16, plain, 16); + err = gcry_cipher_encrypt (hd, out, nplain, plain, nplain); if (err) { fail ("pass %d, algo %d, mode %d, gcry_cipher_encrypt failed: %s\n", @@ -1438,7 +1440,7 @@ check_one_cipher_core (int algo, int mode, int flags, gcry_cipher_reset (hd); - err = gcry_cipher_decrypt (hd, in, 16, out, 16); + err = gcry_cipher_decrypt (hd, in, nplain, out, nplain); if (err) { fail ("pass %d, algo %d, mode %d, gcry_cipher_decrypt failed: %s\n", @@ -1447,15 +1449,15 @@ check_one_cipher_core (int algo, int mode, int flags, return -1; } - if (memcmp (plain, in, 16)) + if (memcmp (plain, in, nplain)) fail ("pass %d, algo %d, mode %d, encrypt-decrypt mismatch\n", pass, algo, mode); /* Again, using in-place encryption. */ gcry_cipher_reset (hd); - memcpy (out, plain, 16); - err = gcry_cipher_encrypt (hd, out, 16, NULL, 0); + memcpy (out, plain, nplain); + err = gcry_cipher_encrypt (hd, out, nplain, NULL, 0); if (err) { fail ("pass %d, algo %d, mode %d, in-place, gcry_cipher_encrypt failed:" @@ -1467,7 +1469,7 @@ check_one_cipher_core (int algo, int mode, int flags, gcry_cipher_reset (hd); - err = gcry_cipher_decrypt (hd, out, 16, NULL, 0); + err = gcry_cipher_decrypt (hd, out, nplain, NULL, 0); if (err) { fail ("pass %d, algo %d, mode %d, in-place, gcry_cipher_decrypt failed:" @@ -1477,7 +1479,7 @@ check_one_cipher_core (int algo, int mode, int flags, return -1; } - if (memcmp (plain, out, 16)) + if (memcmp (plain, out, nplain)) fail ("pass %d, algo %d, mode %d, in-place, encrypt-decrypt mismatch\n", pass, algo, mode); @@ -1492,34 +1494,43 @@ check_one_cipher_core (int algo, int mode, int flags, static void check_one_cipher (int algo, int mode, int flags) { - char key[33]; - unsigned char plain[17]; - int bufshift; + char key[32+1]; + unsigned char plain[1040+1]; + int bufshift, i; for (bufshift=0; bufshift < 4; bufshift++) { /* Pass 0: Standard test. */ memcpy (key, "0123456789abcdef.,;/[]{}-=ABCDEF", 32); memcpy (plain, "foobar42FOOBAR17", 16); - if (check_one_cipher_core (algo, mode, flags, key, 32, plain, 16, + for (i = 16; i < 1040; i += 16) + { + memcpy (&plain[i], &plain[i-16], 16); + if (!++plain[i+7]) + plain[i+6]++; + if (!++plain[i+15]) + plain[i+14]++; + } + + if (check_one_cipher_core (algo, mode, flags, key, 32, plain, 1040, bufshift, 0+10*bufshift)) return; /* Pass 1: Key not aligned. */ memmove (key+1, key, 32); - if (check_one_cipher_core (algo, mode, flags, key+1, 32, plain, 16, + if (check_one_cipher_core (algo, mode, flags, key+1, 32, plain, 1040, bufshift, 1+10*bufshift)) return; /* Pass 2: Key not aligned and data not aligned. */ - memmove (plain+1, plain, 16); - if (check_one_cipher_core (algo, mode, flags, key+1, 32, plain+1, 16, + memmove (plain+1, plain, 1024); + if (check_one_cipher_core (algo, mode, flags, key+1, 32, plain+1, 1040, bufshift, 2+10*bufshift)) return; /* Pass 3: Key aligned and data not aligned. */ memmove (key, key+1, 32); - if (check_one_cipher_core (algo, mode, flags, key, 32, plain+1, 16, + if (check_one_cipher_core (algo, mode, flags, key, 32, plain+1, 1040, bufshift, 3+10*bufshift)) return; } ----------------------------------------------------------------------- Summary of changes: cipher/rijndael.c | 483 +++++++++++++++++++++++++++++++++++++++++++++++------ src/g10lib.h | 43 +++++- tests/basic.c | 45 +++-- 3 files changed, 500 insertions(+), 71 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Mon Nov 26 16:05:56 2012 From: cvs at cvs.gnupg.org (by Ben Kibbey) Date: Mon, 26 Nov 2012 16:05:56 +0100 Subject: [git] Assuan - branch, master, updated. libassuan-2.0.3-13-gcd96daf Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "IPC library used by GnuPG". The branch, master has been updated via cd96daf5a4ddb4a7e9e373220a7aaead0a97c8cf (commit) from 76ea68c2a77cafe2424fe6bc97403c9d9a6b1e95 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit cd96daf5a4ddb4a7e9e373220a7aaead0a97c8cf Author: Ben Kibbey Date: Thu Nov 22 17:17:54 2012 -0500 Check for getpeerucred(). * configure.ac: check for getpeerucred() which (Open)Solaris/SunOS uses. * src/assuan-socket-server.c (accept_connection_bottom): make use of getpeerucred(). diff --git a/configure.ac b/configure.ac index 5a2a8d6..bc71578 100644 --- a/configure.ac +++ b/configure.ac @@ -391,10 +391,12 @@ else AC_DEFINE(HAVE_LOCAL_PEEREID, 1, [Defined if LOCAL_PEEREID is supported (NetBSD specific)]) else - # - # FreeBSD - # - AC_CHECK_FUNCS([getpeereid]) + # (Open)Solaris + AC_CHECK_FUNCS([getpeerucred], AC_CHECK_HEADERS([ucred.h])) + if test $ac_cv_func_getpeerucred != yes; then + # FreeBSD + AC_CHECK_FUNCS([getpeereid]) + fi fi fi diff --git a/src/assuan-socket-server.c b/src/assuan-socket-server.c index 1e8e541..964720b 100644 --- a/src/assuan-socket-server.c +++ b/src/assuan-socket-server.c @@ -30,6 +30,9 @@ #ifdef HAVE_SYS_TYPES_H # include #endif +#ifdef HAVE_UCRED_H +#include +#endif #ifdef HAVE_W32_SYSTEM # ifdef HAVE_WINSOCK2_H # include @@ -58,7 +61,7 @@ accept_connection_bottom (assuan_context_t ctx) ctx->peercred_valid = 0; #ifdef HAVE_SO_PEERCRED { - struct ucred cr; + struct ucred cr; socklen_t cl = sizeof cr; if ( !getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &cr, &cl)) @@ -70,16 +73,29 @@ accept_connection_bottom (assuan_context_t ctx) /* This overrides any already set PID if the function returns a valid one. */ - if (cr.pid != ASSUAN_INVALID_PID && cr.pid) + if (cr.pid != ASSUAN_INVALID_PID && cr.pid) ctx->pid = cr.pid; } } -#elif defined(HAVE_LOCAL_PEEREID) +#elif defined (HAVE_GETPEERUCRED) + { + ucred_t *ucred = NULL; + + if (getpeerucred (fd, &ucred) != -1) + { + ctx->peercred.uid = ucred_geteuid (ucred); + ctx->peercred.gid = ucred_getegid (ucred); + ctx->peercred.pid = ucred_getpid (ucred); + ctx->peercred_valid = 1; + ucred_free (ucred); + } + } +#elif defined (HAVE_LOCAL_PEEREID) { struct unpcbid unp; socklen_t unpl = sizeof unp; - if (getsockopt(fd, 0, LOCAL_PEEREID, &unp, &unpl) != -1) + if (getsockopt (fd, 0, LOCAL_PEEREID, &unp, &unpl) != -1) { ctx->peercred.pid = unp.unp_pid; ctx->peercred.uid = unp.unp_euid; @@ -89,7 +105,7 @@ accept_connection_bottom (assuan_context_t ctx) } #elif defined(HAVE_GETPEEREID) { - if (getpeereid(fd, &ctx->peercred.uid, &ctx->peercred.gid) != -1) + if (getpeereid (fd, &ctx->peercred.uid, &ctx->peercred.gid) != -1) { ctx->peercred.pid = ASSUAN_INVALID_PID; ctx->peercred_valid = 1; ----------------------------------------------------------------------- Summary of changes: configure.ac | 10 ++++++---- src/assuan-socket-server.c | 26 +++++++++++++++++++++----- 2 files changed, 27 insertions(+), 9 deletions(-) hooks/post-receive -- IPC library used by GnuPG http://git.gnupg.org From cvs at cvs.gnupg.org Mon Nov 26 16:06:28 2012 From: cvs at cvs.gnupg.org (by Ben Kibbey) Date: Mon, 26 Nov 2012 16:06:28 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.0beta3-100-g66331e1 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 66331e138ec17e176cc3f45bb095820866d5358c (commit) from 835698b72bc509565aad52b0753f1c56c1a8f062 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 66331e138ec17e176cc3f45bb095820866d5358c Author: Ben Kibbey Date: Thu Nov 22 17:17:33 2012 -0500 Check for inet_addr() in -lnsl. * configure.ac: Check for inet_addr() in libnsl. -- OpenSolaris/OpenIndiana requires this. diff --git a/configure.ac b/configure.ac index e821b99..db51121 100644 --- a/configure.ac +++ b/configure.ac @@ -1177,6 +1177,8 @@ AC_DECL_SYS_SIGLIST gl_HEADER_SYS_SOCKET gl_TYPE_SOCKLEN_T +AC_SEARCH_LIBS([inet_addr], [nsl]) + AC_ARG_ENABLE(endian-check, AC_HELP_STRING([--disable-endian-check], [disable the endian check and trust the OS provided macros]), ----------------------------------------------------------------------- Summary of changes: configure.ac | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Nov 27 19:07:19 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 27 Nov 2012 19:07:19 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-0, updated. gnupg-2.0.19-40-g978878b Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-0 has been updated via 978878b1be0be5bdce7b1bbc7dc9fa39ce8aa402 (commit) from ab4ea45f54006eba55db11263431c4c0c4f557dc (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 978878b1be0be5bdce7b1bbc7dc9fa39ce8aa402 Author: Werner Koch Date: Tue Nov 27 17:35:16 2012 +0100 Fix printing of ECC algo names in hkp keyserver listings. * g10/misc.c (map_pk_openpgp_to_gcry): New. * g10/keyserver.c (print_keyrec): Map OpenPGP algorithm ids. -- Although we don't have support for ECC, we want to print a proper algorithm name in keyserver listings. This will only work while using a ECC enabled Libgcrypt. Problem reported by Kristian Fiskerstrand. diff --git a/g10/keyserver.c b/g10/keyserver.c index 36c52f0..90e9000 100644 --- a/g10/keyserver.c +++ b/g10/keyserver.c @@ -483,9 +483,10 @@ print_keyrec(int number,struct keyrec *keyrec) if(keyrec->type) { - const char *str = gcry_pk_algo_name (keyrec->type); + const char *str; - if(str) + str = gcry_pk_algo_name (map_pk_openpgp_to_gcry (keyrec->type)); + if(str && strcmp (str, "?")) printf("%s ",str); else printf("unknown "); @@ -662,7 +663,7 @@ parse_keyrec(char *keystring) case 'R': work->flags|=1; break; - + case 'd': case 'D': work->flags|=2; @@ -867,7 +868,7 @@ keyserver_search_prompt(IOBUF buffer,const char *searchstr) if (opt.with_colons && opt.batch) break; - + for(;;) { if(show_prompt(desc,i,validcount?count:0,localstr)) @@ -921,7 +922,7 @@ keyserver_search_prompt(IOBUF buffer,const char *searchstr) /* Leave this commented out or now, and perhaps for a very long time. All HKPish servers return HTML error messages for no-key-found. */ - /* + /* if(!started) log_info(_("keyserver does not support searching\n")); else @@ -974,7 +975,7 @@ direct_uri_map(const char *scheme,unsigned int is_direct) #define KEYSERVER_ARGS_KEEP " -o \"%O\" \"%I\"" #define KEYSERVER_ARGS_NOKEEP " -o \"%o\" \"%i\"" -static int +static int keyserver_spawn(enum ks_action action,strlist_t list,KEYDB_SEARCH_DESC *desc, int count,int *prog,unsigned char **fpr,size_t *fpr_len, struct keyserver_spec *keyserver) @@ -1014,7 +1015,7 @@ keyserver_spawn(enum ks_action action,strlist_t list,KEYDB_SEARCH_DESC *desc, the program of this process lives. Fortunately Windows provides a way to retrieve this and our gnupg_libexecdir function has been modified to return just this. Setting the exec-path is not - anymore required. + anymore required. set_exec_path(libexecdir); */ #else @@ -1044,7 +1045,7 @@ keyserver_spawn(enum ks_action action,strlist_t list,KEYDB_SEARCH_DESC *desc, fetcher that can speak that protocol (this is a problem for LDAP). */ - strcat(command,GPGKEYS_PREFIX); + strcat(command,GPGKEYS_PREFIX); strcat(command,scheme); /* This "_uri" thing is in case we need to call a direct handler @@ -1074,7 +1075,7 @@ keyserver_spawn(enum ks_action action,strlist_t list,KEYDB_SEARCH_DESC *desc, { command=xrealloc(command,strlen(command)+ strlen(KEYSERVER_ARGS_NOKEEP)+1); - strcat(command,KEYSERVER_ARGS_NOKEEP); + strcat(command,KEYSERVER_ARGS_NOKEEP); } ret=exec_write(&spawn,NULL,command,NULL,0,0); @@ -1525,7 +1526,7 @@ keyserver_spawn(enum ks_action action,strlist_t list,KEYDB_SEARCH_DESC *desc, return ret; } -static int +static int keyserver_work(enum ks_action action,strlist_t list,KEYDB_SEARCH_DESC *desc, int count,unsigned char **fpr,size_t *fpr_len, struct keyserver_spec *keyserver) @@ -1595,7 +1596,7 @@ keyserver_work(enum ks_action action,strlist_t list,KEYDB_SEARCH_DESC *desc, #endif /* ! DISABLE_KEYSERVER_HELPERS*/ } -int +int keyserver_export(strlist_t users) { strlist_t sl=NULL; @@ -1627,7 +1628,7 @@ keyserver_export(strlist_t users) return rc; } -int +int keyserver_import(strlist_t users) { KEYDB_SEARCH_DESC *desc; @@ -1687,7 +1688,7 @@ keyserver_import_fprint(const byte *fprint,size_t fprint_len, return keyserver_work(KS_GET,NULL,&desc,1,NULL,NULL,keyserver); } -int +int keyserver_import_keyid(u32 *keyid,struct keyserver_spec *keyserver) { KEYDB_SEARCH_DESC desc; @@ -1702,7 +1703,7 @@ keyserver_import_keyid(u32 *keyid,struct keyserver_spec *keyserver) } /* code mostly stolen from do_export_stream */ -static int +static int keyidlist(strlist_t users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3) { int rc=0,ndesc,num=100; @@ -1725,10 +1726,10 @@ keyidlist(strlist_t users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3) } else { - for (ndesc=0, sl=users; sl; sl = sl->next, ndesc++) + for (ndesc=0, sl=users; sl; sl = sl->next, ndesc++) ; desc = xmalloc ( ndesc * sizeof *desc); - + for (ndesc=0, sl=users; sl; sl = sl->next) { if(classify_user_id (sl->d, desc+ndesc)) @@ -1741,7 +1742,7 @@ keyidlist(strlist_t users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3) while (!(rc = keydb_search (kdbhd, desc, ndesc))) { - if (!users) + if (!users) desc[0].mode = KEYDB_SEARCH_MODE_NEXT; /* read the keyblock */ @@ -1844,7 +1845,7 @@ keyidlist(strlist_t users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3) if(rc==-1) rc=0; - + leave: if(rc) xfree(*klist); @@ -2176,7 +2177,7 @@ keyserver_import_ldap(const char *name,unsigned char **fpr,size_t *fpr_len) snprintf(port,7,":%u",srvlist[i].port); strcat(keyserver->host,port); } - + strcat(keyserver->host," "); } @@ -2192,7 +2193,7 @@ keyserver_import_ldap(const char *name,unsigned char **fpr,size_t *fpr_len) strcat(keyserver->host,domain); append_to_strlist(&list,name); - + rc=keyserver_work(KS_GETNAME,list,NULL,0,fpr,fpr_len,keyserver); free_strlist(list); diff --git a/g10/main.h b/g10/main.h index 3a42137..35c9373 100644 --- a/g10/main.h +++ b/g10/main.h @@ -89,6 +89,7 @@ int map_cipher_openpgp_to_gcry (int algo); int openpgp_cipher_blocklen (int algo); int openpgp_cipher_test_algo( int algo ); const char *openpgp_cipher_algo_name (int algo); +int map_pk_openpgp_to_gcry (int algo); int openpgp_pk_test_algo( int algo ); int openpgp_pk_test_algo2 ( int algo, unsigned int use ); int openpgp_pk_algo_usage ( int algo ); @@ -113,7 +114,7 @@ char *pct_expando(const char *string,struct expando_args *args); void deprecated_warning(const char *configname,unsigned int configlineno, const char *option,const char *repl1,const char *repl2); void deprecated_command (const char *name); -void obsolete_option (const char *configname, unsigned int configlineno, +void obsolete_option (const char *configname, unsigned int configlineno, const char *name); int string_to_cipher_algo (const char *string); @@ -266,7 +267,7 @@ void import_print_stats (void *hd); int collapse_uids( KBNODE *keyblock ); -int auto_create_card_key_stub ( const char *serialnostr, +int auto_create_card_key_stub ( const char *serialnostr, const unsigned char *fpr1, const unsigned char *fpr2, const unsigned char *fpr3); diff --git a/g10/misc.c b/g10/misc.c index 8cc63ba..1a937f1 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -40,7 +40,7 @@ #ifdef HAVE_W32_SYSTEM #include #include -#include +#include #include #ifndef CSIDL_APPDATA #define CSIDL_APPDATA 0x001a @@ -81,7 +81,7 @@ string_count_chr (const char *string, int c) #ifdef ENABLE_SELINUX_HACKS /* A object and a global variable to keep track of files marked as secured. */ -struct secured_file_item +struct secured_file_item { struct secured_file_item *next; ino_t ino; @@ -106,7 +106,7 @@ register_secured_file (const char *fname) /* Note that we stop immediatley if something goes wrong here. */ if (stat (fname, &buf)) - log_fatal (_("fstat of `%s' failed in %s: %s\n"), fname, + log_fatal (_("fstat of `%s' failed in %s: %s\n"), fname, "register_secured_file", strerror (errno)); /* log_debug ("registering `%s' i=%lu.%lu\n", fname, */ /* (unsigned long)buf.st_dev, (unsigned long)buf.st_ino); */ @@ -160,8 +160,8 @@ unregister_secured_file (const char *fname) } /* Return true if FD is corresponds to a secured file. Using -1 for - FS is allowed and will return false. */ -int + FS is allowed and will return false. */ +int is_secured_file (int fd) { #ifdef ENABLE_SELINUX_HACKS @@ -175,7 +175,7 @@ is_secured_file (int fd) secure if something went wrong. */ if (fstat (fd, &buf)) { - log_error (_("fstat(%d) failed in %s: %s\n"), fd, + log_error (_("fstat(%d) failed in %s: %s\n"), fd, "is_secured_file", strerror (errno)); return 1; } @@ -195,8 +195,8 @@ is_secured_file (int fd) /* Return true if FNAME is corresponds to a secured file. Using NULL, "" or "-" for FS is allowed and will return false. This function is used before creating a file, thus it won't fail if the file does - not exist. */ -int + not exist. */ +int is_secured_filename (const char *fname) { #ifdef ENABLE_SELINUX_HACKS @@ -204,7 +204,7 @@ is_secured_filename (const char *fname) struct secured_file_item *sf; if (iobuf_is_pipe_filename (fname) || !*fname) - return 0; + return 0; /* Note that we print out a error here and claim that a file is secure if something went wrong. */ @@ -345,9 +345,9 @@ map_cipher_openpgp_to_gcry (int algo) { switch (algo) { - case CIPHER_ALGO_CAMELLIA128: return 310; - case CIPHER_ALGO_CAMELLIA192: return 311; - case CIPHER_ALGO_CAMELLIA256: return 312; + case CIPHER_ALGO_CAMELLIA128: return 310; + case CIPHER_ALGO_CAMELLIA192: return 311; + case CIPHER_ALGO_CAMELLIA256: return 312; default: return algo; } } @@ -367,7 +367,7 @@ map_cipher_gcry_to_openpgp (int algo) /* Return the block length of an OpenPGP cipher algorithm. */ -int +int openpgp_cipher_blocklen (int algo) { /* We use the numbers from OpenPGP to be sure that we get the right @@ -407,18 +407,33 @@ openpgp_cipher_test_algo( int algo ) string representation of the algorithm name. For unknown algorithm IDs this function returns "?". */ const char * -openpgp_cipher_algo_name (int algo) +openpgp_cipher_algo_name (int algo) { return gcry_cipher_algo_name (map_cipher_openpgp_to_gcry (algo)); } + +/* Map OpenPGP public key algorithm numbers to those used by + Libgcrypt. */ +int +map_pk_openpgp_to_gcry (int algo) +{ + switch (algo) + { + case PUBKEY_ALGO_ECDSA: return 301 /*GCRY_PK_ECDSA*/; + case PUBKEY_ALGO_ECDH: return 302 /*GCRY_PK_ECDH*/; + default: return algo; + } +} + + int openpgp_pk_test_algo( int algo ) { /* Dont't allow type 20 keys unless in rfc2440 mode. */ if (!RFC2440 && algo == 20) return gpg_error (GPG_ERR_PUBKEY_ALGO); - + if (algo == GCRY_PK_ELG_E) algo = GCRY_PK_ELG; @@ -445,13 +460,13 @@ openpgp_pk_test_algo2( int algo, unsigned int use ) return gcry_pk_algo_info (algo, GCRYCTL_TEST_ALGO, NULL, &use_buf); } -int +int openpgp_pk_algo_usage ( int algo ) { - int use = 0; - + int use = 0; + /* They are hardwired in gpg 1.0. */ - switch ( algo ) { + switch ( algo ) { case PUBKEY_ALGO_RSA: use = (PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG | PUBKEY_USAGE_ENC | PUBKEY_USAGE_AUTH); @@ -469,7 +484,7 @@ openpgp_pk_algo_usage ( int algo ) case PUBKEY_ALGO_ELGAMAL_E: use = PUBKEY_USAGE_ENC; break; - case PUBKEY_ALGO_DSA: + case PUBKEY_ALGO_DSA: use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG | PUBKEY_USAGE_AUTH; break; default: @@ -509,7 +524,7 @@ idea_cipher_warn(int show) #endif -static unsigned long +static unsigned long get_signature_count (PKT_secret_key *sk) { #ifdef ENABLE_CARD_SUPPORT @@ -518,7 +533,7 @@ get_signature_count (PKT_secret_key *sk) struct agent_card_info_s info; if(agent_scd_getattr("SIG-COUNTER",&info)==0) return info.sig_counter; - } + } #endif /* How to do this without a card? */ @@ -609,7 +624,7 @@ pct_expando(const char *string,struct expando_args *args) sprintf(&ret[idx],"%lu",get_signature_count(args->sk)); idx+=strlen(&ret[idx]); done=1; - } + } break; case 'p': /* primary pk fingerprint of a sk */ @@ -678,7 +693,7 @@ pct_expando(const char *string,struct expando_args *args) case 't': /* e.g. "jpg" */ str=image_type_to_string(args->imagetype,0); break; - + case 'T': /* e.g. "image/jpeg" */ str=image_type_to_string(args->imagetype,2); break; @@ -777,7 +792,7 @@ deprecated_command (const char *name) void -obsolete_option (const char *configname, unsigned int configlineno, +obsolete_option (const char *configname, unsigned int configlineno, const char *name) { if(configname) @@ -793,9 +808,9 @@ obsolete_option (const char *configname, unsigned int configlineno, * Wrapper around gcry_cipher_map_name to provide a fallback using the * "Sn" syntax as used by the preference strings. */ -int -string_to_cipher_algo (const char *string) -{ +int +string_to_cipher_algo (const char *string) +{ int val; val = map_cipher_gcry_to_openpgp (gcry_cipher_map_name (string)); @@ -816,9 +831,9 @@ string_to_cipher_algo (const char *string) * Wrapper around gcry_md_map_name to provide a fallback using the * "Hn" syntax as used by the preference strings. */ -int -string_to_digest_algo (const char *string) -{ +int +string_to_digest_algo (const char *string) +{ int val; val = gcry_md_map_name (string); @@ -1223,7 +1238,7 @@ has_invalid_email_chars (const char *s) const char *valid_chars= "01234567890_-.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - for ( ; *s; s++ ) + for ( ; *s; s++ ) { if ( (*s & 0x80) ) continue; /* We only care about ASCII. */ @@ -1344,7 +1359,7 @@ int pubkey_get_nenc( int algo ) { size_t n; - + if (algo == GCRY_PK_ELG_E) algo = GCRY_PK_ELG; if (gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NENCR, NULL, &n )) ----------------------------------------------------------------------- Summary of changes: g10/keyserver.c | 41 ++++++++++++++------------- g10/main.h | 5 ++- g10/misc.c | 81 ++++++++++++++++++++++++++++++++---------------------- 3 files changed, 72 insertions(+), 55 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Nov 27 19:07:55 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 27 Nov 2012 19:07:55 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.0beta3-101-g3d2da6c Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 3d2da6c82163ffbc2e827abc4144dc3197ed53db (commit) from 66331e138ec17e176cc3f45bb095820866d5358c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 3d2da6c82163ffbc2e827abc4144dc3197ed53db Author: Werner Koch Date: Tue Nov 27 16:51:09 2012 +0100 Fix printing of ECC algo names in hkp keyserver listings. * g10/keyserver.c (print_keyrec): Map OpenPGP algorithm ids. diff --git a/g10/keyserver.c b/g10/keyserver.c index 75234be..0e6bcf6 100644 --- a/g10/keyserver.c +++ b/g10/keyserver.c @@ -506,9 +506,11 @@ print_keyrec(int number,struct keyrec *keyrec) if(keyrec->type) { - const char *str = gcry_pk_algo_name (keyrec->type); + const char *str; - if(str) + str = gcry_pk_algo_name (map_pk_openpgp_to_gcry (keyrec->type)); + + if (str && strcmp (str, "?")) es_printf ("%s ",str); else es_printf ("unknown "); ----------------------------------------------------------------------- Summary of changes: g10/keyserver.c | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Nov 28 11:11:18 2012 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 28 Nov 2012 11:11:18 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.5.0-67-g6765e0a Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 6765e0a8618000d3dc7bda035163e0708c43791b (commit) via 99e272d938fe23efec25af409bdb91dae0e659e5 (commit) from faec12e23f03c7cd1614594bfdd51f1302cadb42 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 6765e0a8618000d3dc7bda035163e0708c43791b Author: Werner Koch Date: Wed Nov 28 09:40:57 2012 +0100 Make a cpp conditional in rijndael.c better readable. * cipher/rijndael.c (USE_AESNI): Modify cpp conditionals for better readability. diff --git a/cipher/rijndael.c b/cipher/rijndael.c index 0f5e07c..cc7f8d6 100644 --- a/cipher/rijndael.c +++ b/cipher/rijndael.c @@ -1,6 +1,6 @@ /* Rijndael (AES) for GnuPG * Copyright (C) 2000, 2001, 2002, 2003, 2007, - * 2008, 2011 Free Software Foundation, Inc. + * 2008, 2011, 2012 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * @@ -75,8 +75,10 @@ gcc 3. However, to be on the safe side we require at least gcc 4. */ #undef USE_AESNI #ifdef ENABLE_AESNI_SUPPORT -# if ((defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4) || defined(__x86_64__)) && __GNUC__ >= 4 -# define USE_AESNI 1 +# if ((defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4) || defined(__x86_64__)) +# if __GNUC__ >= 4 +# define USE_AESNI 1 +# endif # endif #endif /* ENABLE_AESNI_SUPPORT */ commit 99e272d938fe23efec25af409bdb91dae0e659e5 Author: Jussi Kivilinna Date: Tue Nov 27 23:44:13 2012 +0200 Fix building with Clang on x86-64 and i386 * cipher/rijndael.c [USE_AESNI] (do_aesni_enc_aligned) (do_aesni_dec_vec4, do_aesni_cfb, do_aesni_ctr, do_aesni_ctr_4): Add explicit suffix to 'cmp' instructions. -- Clang throws errors on missing instruction suffixes, such as: rijndael.c:1091:39: error: ambiguous instructions require an explicit suffix (could be 'cmpb', 'cmpw', 'cmpl', or 'cmpq') :39:2: note: instantiated into assembly here cmp $1, -44(%rbp) With this patch building on x86-64 works fine. Other issues still exists on i386, namely with MPI, which can be overcome with 'clang -fheinous-gnu-extensions'. [v2]: - remove do_aesni_enc_vec4 modification as that function didn't make it to upstream. Signed-off-by: Jussi Kivilinna NB: I still believe it is a bad idea of clang to define __GNUC__ and not being 100% compatible to gcc. [wk] diff --git a/cipher/rijndael.c b/cipher/rijndael.c index 860dcf8..0f5e07c 100644 --- a/cipher/rijndael.c +++ b/cipher/rijndael.c @@ -742,13 +742,13 @@ do_aesni_enc_aligned (const RIJNDAEL_context *ctx, "movdqa 0x90(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0xa0(%[key]), %%xmm1\n\t" - "cmp $10, %[rounds]\n\t" + "cmpl $10, %[rounds]\n\t" "jz .Lenclast%=\n\t" aesenc_xmm1_xmm0 "movdqa 0xb0(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0xc0(%[key]), %%xmm1\n\t" - "cmp $12, %[rounds]\n\t" + "cmpl $12, %[rounds]\n\t" "jz .Lenclast%=\n\t" aesenc_xmm1_xmm0 "movdqa 0xd0(%[key]), %%xmm1\n\t" @@ -796,13 +796,13 @@ do_aesni_dec_aligned (const RIJNDAEL_context *ctx, "movdqa 0x90(%[key]), %%xmm1\n\t" aesdec_xmm1_xmm0 "movdqa 0xa0(%[key]), %%xmm1\n\t" - "cmp $10, %[rounds]\n\t" + "cmpl $10, %[rounds]\n\t" "jz .Ldeclast%=\n\t" aesdec_xmm1_xmm0 "movdqa 0xb0(%[key]), %%xmm1\n\t" aesdec_xmm1_xmm0 "movdqa 0xc0(%[key]), %%xmm1\n\t" - "cmp $12, %[rounds]\n\t" + "cmpl $12, %[rounds]\n\t" "jz .Ldeclast%=\n\t" aesdec_xmm1_xmm0 "movdqa 0xd0(%[key]), %%xmm1\n\t" @@ -886,7 +886,7 @@ do_aesni_dec_vec4 (const RIJNDAEL_context *ctx) aesdec_xmm0_xmm3 aesdec_xmm0_xmm4 "movdqa 0xa0(%[key]), %%xmm0\n\t" - "cmp $10, %[rounds]\n\t" + "cmpl $10, %[rounds]\n\t" "jz .Ldeclast%=\n\t" aesdec_xmm0_xmm1 aesdec_xmm0_xmm2 @@ -898,7 +898,7 @@ do_aesni_dec_vec4 (const RIJNDAEL_context *ctx) aesdec_xmm0_xmm3 aesdec_xmm0_xmm4 "movdqa 0xc0(%[key]), %%xmm0\n\t" - "cmp $12, %[rounds]\n\t" + "cmpl $12, %[rounds]\n\t" "jz .Ldeclast%=\n\t" aesdec_xmm0_xmm1 aesdec_xmm0_xmm2 @@ -963,13 +963,13 @@ do_aesni_cfb (const RIJNDAEL_context *ctx, int decrypt_flag, "movdqa 0x90(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0xa0(%[key]), %%xmm1\n\t" - "cmp $10, %[rounds]\n\t" + "cmpl $10, %[rounds]\n\t" "jz .Lenclast%=\n\t" aesenc_xmm1_xmm0 "movdqa 0xb0(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0xc0(%[key]), %%xmm1\n\t" - "cmp $12, %[rounds]\n\t" + "cmpl $12, %[rounds]\n\t" "jz .Lenclast%=\n\t" aesenc_xmm1_xmm0 "movdqa 0xd0(%[key]), %%xmm1\n\t" @@ -981,7 +981,7 @@ do_aesni_cfb (const RIJNDAEL_context *ctx, int decrypt_flag, "movdqu %[src], %%xmm1\n\t" /* Save input. */ "pxor %%xmm1, %%xmm0\n\t" /* xmm0 = input ^ IV */ - "cmp $1, %[decrypt]\n\t" + "cmpl $1, %[decrypt]\n\t" "jz .Ldecrypt_%=\n\t" "movdqa %%xmm0, %[iv]\n\t" /* [encrypt] Store IV. */ "jmp .Lleave_%=\n" @@ -1058,13 +1058,13 @@ do_aesni_ctr (const RIJNDAEL_context *ctx, "movdqa 0x90(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0xa0(%[key]), %%xmm1\n\t" - "cmp $10, %[rounds]\n\t" + "cmpl $10, %[rounds]\n\t" "jz .Lenclast%=\n\t" aesenc_xmm1_xmm0 "movdqa 0xb0(%[key]), %%xmm1\n\t" aesenc_xmm1_xmm0 "movdqa 0xc0(%[key]), %%xmm1\n\t" - "cmp $12, %[rounds]\n\t" + "cmpl $12, %[rounds]\n\t" "jz .Lenclast%=\n\t" aesenc_xmm1_xmm0 "movdqa 0xd0(%[key]), %%xmm1\n\t" @@ -1219,7 +1219,7 @@ do_aesni_ctr_4 (const RIJNDAEL_context *ctx, aesenc_xmm1_xmm3 aesenc_xmm1_xmm4 "movdqa 0xa0(%[key]), %%xmm1\n\t" - "cmp $10, %[rounds]\n\t" + "cmpl $10, %[rounds]\n\t" "jz .Lenclast%=\n\t" aesenc_xmm1_xmm0 aesenc_xmm1_xmm2 @@ -1231,7 +1231,7 @@ do_aesni_ctr_4 (const RIJNDAEL_context *ctx, aesenc_xmm1_xmm3 aesenc_xmm1_xmm4 "movdqa 0xc0(%[key]), %%xmm1\n\t" - "cmp $12, %[rounds]\n\t" + "cmpl $12, %[rounds]\n\t" "jz .Lenclast%=\n\t" aesenc_xmm1_xmm0 aesenc_xmm1_xmm2 ----------------------------------------------------------------------- Summary of changes: cipher/rijndael.c | 34 ++++++++++++++++++---------------- 1 files changed, 18 insertions(+), 16 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Thu Nov 29 19:30:41 2012 From: cvs at cvs.gnupg.org (by David Shaw) Date: Thu, 29 Nov 2012 19:30:41 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-1-4, updated. gnupg-1.4.12-19-gd42dcbf Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-1-4 has been updated via d42dcbfa923cc2e97faf588b19c19f63c4db409d (commit) from 95347cf950e2e26d1726791f9f4278af70dccce9 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d42dcbfa923cc2e97faf588b19c19f63c4db409d Author: David Shaw Date: Thu Nov 29 12:00:46 2012 -0500 The keyserver search menu should honor --keyid-format * keyserver.c (print_keyrec): Honor --keyid-format when getting back full fingerprints from the keyserver (the comment in the code was correct, the code was not). diff --git a/g10/keyserver.c b/g10/keyserver.c index 80e934e..1eadff1 100644 --- a/g10/keyserver.c +++ b/g10/keyserver.c @@ -1,6 +1,6 @@ /* keyserver.c - generic keyserver code * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, - * 2009 Free Software Foundation, Inc. + * 2009, 2012 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -492,21 +492,27 @@ print_keyrec(int number,struct keyrec *keyrec) break; /* However, if it gave us a long keyid, we can honor - --keyid-format */ + --keyid-format via keystr(). */ case KEYDB_SEARCH_MODE_LONG_KID: printf("key %s",keystr(keyrec->desc.u.kid)); break; + /* If it gave us a PGP 2.x fingerprint, not much we can do + beyond displaying it. */ case KEYDB_SEARCH_MODE_FPR16: printf("key "); for(i=0;i<16;i++) printf("%02X",keyrec->desc.u.fpr[i]); break; + /* If we get a modern fingerprint, we have the most + flexibility. */ case KEYDB_SEARCH_MODE_FPR20: - printf("key "); - for(i=0;i<20;i++) - printf("%02X",keyrec->desc.u.fpr[i]); + { + u32 kid[2]; + keyid_from_fingerprint(keyrec->desc.u.fpr,20,kid); + printf("key %s",keystr(kid)); + } break; default: ----------------------------------------------------------------------- Summary of changes: g10/keyserver.c | 16 +++++++++++----- 1 files changed, 11 insertions(+), 5 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Nov 29 20:36:52 2012 From: cvs at cvs.gnupg.org (by Jussi Kivilinna) Date: Thu, 29 Nov 2012 20:36:52 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.5.0-68-g9ee9e25 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 9ee9e25f519696d509b1a5c1cc04ab0121e98a51 (commit) from 6765e0a8618000d3dc7bda035163e0708c43791b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 9ee9e25f519696d509b1a5c1cc04ab0121e98a51 Author: Jussi Kivilinna Date: Thu Nov 29 17:31:03 2012 +0200 Optimize AES-NI CTR mode. * cipher/rijndael.c [USE_AESNI] (do_aesni_ctr, do_aesni_ctr_4): Make handling of 64-bit overflow and carry conditional. Avoid generic to vector register passing of value '1'. Generate and use '-1' instead. -- We only need to handle 64-bit carry in few special cases, that happen very rarely. So move carry handling to slow-path and only detect need for carry handling on fast-path. Also avoid moving '1' from generic register to vector register, as that might be slow on some CPUs. Instead generate '-1' with SSE2 instructions and use subtraction instead of addition to increase IV. Overall this gives ~8% improvement in speed for AES CTR mode on Intel Sandy-Bridge. Signed-off-by: Jussi Kivilinna diff --git a/cipher/rijndael.c b/cipher/rijndael.c index cc7f8d6..6313ab2 100644 --- a/cipher/rijndael.c +++ b/cipher/rijndael.c @@ -1015,24 +1015,20 @@ do_aesni_ctr (const RIJNDAEL_context *ctx, asm volatile ("movdqa (%[ctr]), %%xmm0\n\t" /* xmm0, xmm2 := CTR */ "movaps %%xmm0, %%xmm2\n\t" - "mov $1, %%esi\n\t" /* xmm2++ (big-endian) */ - "movd %%esi, %%xmm1\n\t" - - "movl 12(%[ctr]), %%esi\n\t" /* load lower parts of CTR */ - "bswapl %%esi\n\t" - "movl 8(%[ctr]), %%edi\n\t" - "bswapl %%edi\n\t" + "pcmpeqd %%xmm1, %%xmm1\n\t" + "psrldq $8, %%xmm1\n\t" /* xmm1 = -1 */ "pshufb %[mask], %%xmm2\n\t" - "paddq %%xmm1, %%xmm2\n\t" + "psubq %%xmm1, %%xmm2\n\t" /* xmm2++ (big endian) */ - "addl $1, %%esi\n\t" - "adcl $0, %%edi\n\t" /* detect 64bit overflow */ - "jnc .Lno_carry%=\n\t" + /* detect if 64-bit carry handling is needed */ + "cmpl $0xffffffff, 8(%[ctr])\n\t" + "jne .Lno_carry%=\n\t" + "cmpl $0xffffffff, 12(%[ctr])\n\t" + "jne .Lno_carry%=\n\t" - /* swap upper and lower halfs */ - "pshufd $0x4e, %%xmm1, %%xmm1\n\t" - "paddq %%xmm1, %%xmm2\n\t" /* add carry to upper 64bits */ + "pslldq $8, %%xmm1\n\t" /* move lower 64-bit to high */ + "psubq %%xmm1, %%xmm2\n\t" /* add carry to upper 64bits */ ".Lno_carry%=:\n\t" @@ -1085,7 +1081,7 @@ do_aesni_ctr (const RIJNDAEL_context *ctx, [key] "r" (ctx->keyschenc), [rounds] "g" (ctx->rounds), [mask] "m" (*be_mask) - : "%esi", "%edi", "cc", "memory"); + : "cc", "memory"); #undef aesenc_xmm1_xmm0 #undef aesenclast_xmm1_xmm0 } @@ -1120,48 +1116,40 @@ do_aesni_ctr_4 (const RIJNDAEL_context *ctx, asm volatile ("movdqa (%[ctr]), %%xmm0\n\t" /* xmm0, xmm2 := CTR */ "movaps %%xmm0, %%xmm2\n\t" - "mov $1, %%esi\n\t" /* xmm1 := 1 */ - "movd %%esi, %%xmm1\n\t" - - "movl 12(%[ctr]), %%esi\n\t" /* load lower parts of CTR */ - "bswapl %%esi\n\t" - "movl 8(%[ctr]), %%edi\n\t" - "bswapl %%edi\n\t" + "pcmpeqd %%xmm1, %%xmm1\n\t" + "psrldq $8, %%xmm1\n\t" /* xmm1 = -1 */ "pshufb %[mask], %%xmm2\n\t" /* xmm2 := le(xmm2) */ - "paddq %%xmm1, %%xmm2\n\t" /* xmm2++ */ + "psubq %%xmm1, %%xmm2\n\t" /* xmm2++ */ "movaps %%xmm2, %%xmm3\n\t" /* xmm3 := xmm2 */ - "paddq %%xmm1, %%xmm3\n\t" /* xmm3++ */ + "psubq %%xmm1, %%xmm3\n\t" /* xmm3++ */ "movaps %%xmm3, %%xmm4\n\t" /* xmm4 := xmm3 */ - "paddq %%xmm1, %%xmm4\n\t" /* xmm4++ */ + "psubq %%xmm1, %%xmm4\n\t" /* xmm4++ */ "movaps %%xmm4, %%xmm5\n\t" /* xmm5 := xmm4 */ - "paddq %%xmm1, %%xmm5\n\t" /* xmm5++ */ - - /* swap upper and lower halfs */ - "pshufd $0x4e, %%xmm1, %%xmm1\n\t" - - "addl $1, %%esi\n\t" - "adcl $0, %%edi\n\t" /* detect 64bit overflow */ - "jc .Lcarry_xmm2%=\n\t" - "addl $1, %%esi\n\t" - "adcl $0, %%edi\n\t" /* detect 64bit overflow */ - "jc .Lcarry_xmm3%=\n\t" - "addl $1, %%esi\n\t" - "adcl $0, %%edi\n\t" /* detect 64bit overflow */ - "jc .Lcarry_xmm4%=\n\t" - "addl $1, %%esi\n\t" - "adcl $0, %%edi\n\t" /* detect 64bit overflow */ - "jc .Lcarry_xmm5%=\n\t" - "jmp .Lno_carry%=\n\t" - - ".Lcarry_xmm2%=:\n\t" - "paddq %%xmm1, %%xmm2\n\t" + "psubq %%xmm1, %%xmm5\n\t" /* xmm5++ */ + + /* detect if 64-bit carry handling is needed */ + "cmpl $0xffffffff, 8(%[ctr])\n\t" + "jne .Lno_carry%=\n\t" + "movl 12(%[ctr]), %%esi\n\t" + "bswapl %%esi\n\t" + "cmpl $0xfffffffc, %%esi\n\t" + "jb .Lno_carry%=\n\t" /* no carry */ + + "pslldq $8, %%xmm1\n\t" /* move lower 64-bit to high */ + "je .Lcarry_xmm5%=\n\t" /* esi == 0xfffffffc */ + "cmpl $0xfffffffe, %%esi\n\t" + "jb .Lcarry_xmm4%=\n\t" /* esi == 0xfffffffd */ + "je .Lcarry_xmm3%=\n\t" /* esi == 0xfffffffe */ + /* esi == 0xffffffff */ + + "psubq %%xmm1, %%xmm2\n\t" ".Lcarry_xmm3%=:\n\t" - "paddq %%xmm1, %%xmm3\n\t" + "psubq %%xmm1, %%xmm3\n\t" ".Lcarry_xmm4%=:\n\t" - "paddq %%xmm1, %%xmm4\n\t" + "psubq %%xmm1, %%xmm4\n\t" ".Lcarry_xmm5%=:\n\t" - "paddq %%xmm1, %%xmm5\n\t" + "psubq %%xmm1, %%xmm5\n\t" ".Lno_carry%=:\n\t" "pshufb %[mask], %%xmm2\n\t" /* xmm2 := be(xmm2) */ @@ -1170,7 +1158,7 @@ do_aesni_ctr_4 (const RIJNDAEL_context *ctx, "pshufb %[mask], %%xmm5\n\t" /* xmm5 := be(xmm5) */ "movdqa %%xmm5, (%[ctr])\n" /* Update CTR. */ - "movdqa (%[key]), %%xmm1\n\t" /* xmm1 := key[0] */ + "movdqa (%[key]), %%xmm1\n\t" /* xmm1 := key[0] */ "pxor %%xmm1, %%xmm0\n\t" /* xmm0 ^= key[0] */ "pxor %%xmm1, %%xmm2\n\t" /* xmm2 ^= key[0] */ "pxor %%xmm1, %%xmm3\n\t" /* xmm3 ^= key[0] */ @@ -1275,7 +1263,7 @@ do_aesni_ctr_4 (const RIJNDAEL_context *ctx, [key] "r" (ctx->keyschenc), [rounds] "g" (ctx->rounds), [mask] "m" (*be_mask) - : "%esi", "%edi", "cc", "memory"); + : "%esi", "cc", "memory"); #undef aesenc_xmm1_xmm0 #undef aesenc_xmm1_xmm2 #undef aesenc_xmm1_xmm3 ----------------------------------------------------------------------- Summary of changes: cipher/rijndael.c | 90 +++++++++++++++++++++++------------------------------ 1 files changed, 39 insertions(+), 51 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Thu Nov 29 20:40:40 2012 From: cvs at cvs.gnupg.org (by David Shaw) Date: Thu, 29 Nov 2012 20:40:40 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-2-0, updated. gnupg-2.0.19-41-g3d0c386 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-2-0 has been updated via 3d0c386011efcf7064ff0e7bf0be3f0c2316be67 (commit) from 978878b1be0be5bdce7b1bbc7dc9fa39ce8aa402 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 3d0c386011efcf7064ff0e7bf0be3f0c2316be67 Author: David Shaw Date: Thu Nov 29 12:00:46 2012 -0500 The keyserver search menu should honor --keyid-format * keyserver.c (print_keyrec): Honor --keyid-format when getting back full fingerprints from the keyserver (the comment in the code was correct, the code was not). diff --git a/g10/keyserver.c b/g10/keyserver.c index 90e9000..f90467c 100644 --- a/g10/keyserver.c +++ b/g10/keyserver.c @@ -1,6 +1,6 @@ /* keyserver.c - generic keyserver code * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, - * 2009 Free Software Foundation, Inc. + * 2009, 2012 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -505,21 +505,27 @@ print_keyrec(int number,struct keyrec *keyrec) break; /* However, if it gave us a long keyid, we can honor - --keyid-format */ + --keyid-format via keystr(). */ case KEYDB_SEARCH_MODE_LONG_KID: printf("key %s",keystr(keyrec->desc.u.kid)); break; + /* If it gave us a PGP 2.x fingerprint, not much we can do + beyond displaying it. */ case KEYDB_SEARCH_MODE_FPR16: printf("key "); for(i=0;i<16;i++) printf("%02X",keyrec->desc.u.fpr[i]); break; + /* If we get a modern fingerprint, we have the most + flexibility. */ case KEYDB_SEARCH_MODE_FPR20: - printf("key "); - for(i=0;i<20;i++) - printf("%02X",keyrec->desc.u.fpr[i]); + { + u32 kid[2]; + keyid_from_fingerprint(keyrec->desc.u.fpr,20,kid); + printf("key %s",keystr(kid)); + } break; default: ----------------------------------------------------------------------- Summary of changes: g10/keyserver.c | 16 +++++++++++----- 1 files changed, 11 insertions(+), 5 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Nov 29 20:40:42 2012 From: cvs at cvs.gnupg.org (by David Shaw) Date: Thu, 29 Nov 2012 20:40:42 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.0beta3-102-g7602d9e Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 7602d9e3edda99b0b65ba928eef435dab04ecd09 (commit) from 3d2da6c82163ffbc2e827abc4144dc3197ed53db (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 7602d9e3edda99b0b65ba928eef435dab04ecd09 Author: David Shaw Date: Thu Nov 29 12:00:46 2012 -0500 The keyserver search menu should honor --keyid-format * keyserver.c (print_keyrec): Honor --keyid-format when getting back full fingerprints from the keyserver (the comment in the code was correct, the code was not). diff --git a/g10/keyserver.c b/g10/keyserver.c index 0e6bcf6..0be1e3f 100644 --- a/g10/keyserver.c +++ b/g10/keyserver.c @@ -1,6 +1,6 @@ /* keyserver.c - generic keyserver code * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, - * 2009, 2011 Free Software Foundation, Inc. + * 2009, 2011, 2012 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -529,21 +529,27 @@ print_keyrec(int number,struct keyrec *keyrec) break; /* However, if it gave us a long keyid, we can honor - --keyid-format */ + --keyid-format via keystr(). */ case KEYDB_SEARCH_MODE_LONG_KID: es_printf ("key %s",keystr(keyrec->desc.u.kid)); break; + /* If it gave us a PGP 2.x fingerprint, not much we can do + beyond displaying it. */ case KEYDB_SEARCH_MODE_FPR16: es_printf ("key "); for(i=0;i<16;i++) es_printf ("%02X",keyrec->desc.u.fpr[i]); break; + /* If we get a modern fingerprint, we have the most + flexibility. */ case KEYDB_SEARCH_MODE_FPR20: - es_printf ("key "); - for(i=0;i<20;i++) - es_printf ("%02X", keyrec->desc.u.fpr[i]); + { + u32 kid[2]; + keyid_from_fingerprint(keyrec->desc.u.fpr,20,kid); + es_printf("key %s",keystr(kid)); + } break; default: ----------------------------------------------------------------------- Summary of changes: g10/keyserver.c | 16 +++++++++++----- 1 files changed, 11 insertions(+), 5 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Nov 30 19:51:44 2012 From: cvs at cvs.gnupg.org (by David Shaw) Date: Fri, 30 Nov 2012 19:51:44 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-1-4, updated. gnupg-1.4.12-20-g3ab2720 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-1-4 has been updated via 3ab272086cdd39cc982b6deccd827a3cdb804cf1 (commit) from d42dcbfa923cc2e97faf588b19c19f63c4db409d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 3ab272086cdd39cc982b6deccd827a3cdb804cf1 Author: David Shaw Date: Fri Nov 30 12:21:45 2012 -0500 Refresh sample keys * mksamplekeys: Tweak awk script to not add trailing whitespace to blank lines (makes git pre-commit hook unhappy). * samplekeys.asc: Refresh. diff --git a/doc/mksamplekeys b/doc/mksamplekeys index 23257c1..e5db52c 100755 --- a/doc/mksamplekeys +++ b/doc/mksamplekeys @@ -4,7 +4,7 @@ keys="1E42B367 4F25E3B6 5B0358A2 57548DCD 99242560 CA57AD7C B2D7795E 1CE0C630" for i in $keys; do - gpg --list-keys $i | awk ' { print " " $0 }' + gpg --list-keys $i | awk ' ( $0 != "") { print " " $0 }' done echo gpg --export-options export-minimal --export -a $keys diff --git a/doc/samplekeys.asc b/doc/samplekeys.asc index bbde937..4d16c10 100644 --- a/doc/samplekeys.asc +++ b/doc/samplekeys.asc @@ -3,27 +3,25 @@ uid Werner Koch sub 1024D/77F95F95 2011-11-02 sub 2048R/C193565B 2011-11-07 [expires: 2013-12-31] - pub 2048R/4F25E3B6 2011-01-12 [expires: 2019-12-31] uid Werner Koch (dist sig) sub 2048R/AC87C71A 2011-01-12 [expires: 2019-12-31] - pub 1024D/5B0358A2 1999-03-15 [expired: 2011-07-11] uid Werner Koch uid Werner Koch uid Werner Koch uid Werner Koch - pub 1024D/57548DCD 1998-07-07 [expired: 2005-12-31] uid Werner Koch (gnupg sig) - pub 4096R/99242560 2002-01-28 uid David M. Shaw - + sub 2048R/A1BC4FA4 2012-01-10 [expires: 2017-01-31] + sub 2048R/6F410A43 2012-01-10 [expires: 2017-01-31] pub 2048R/CA57AD7C 2004-12-06 uid PGP Global Directory Verification Key uid [jpeg image of size 3400] - + uid DNR KS1 + uid DNR-KS2 pub 1024D/B2D7795E 2001-01-04 uid Philip R. Zimmermann uid Philip R. Zimmermann @@ -31,11 +29,9 @@ uid [jpeg image of size 3457] uid Philip R. Zimmermann sub 3072g/A8E92834 2001-01-04 - pub 1024R/1CE0C630 2006-01-01 [expired: 2011-06-30] uid Werner Koch (dist sig) - -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.4.11 (GNU/Linux) @@ -421,447 +417,443 @@ AOwOoqiaEjSeKTuUKuj2DsAxahoq9fVhH6E8h1tJMYqZ1W76uKtrwIUiCjqjRCRs YOA0xCnnH98QnSdJFvHVUqIBwx/3PkOPkRUKv99Wnr9xw8ttGGssQBPeAViLCpIW jMqIYQQfEQIAIQUCOlTwWwIHABcMgBE/xzIEHSPp6mbdtQCcnbwh33TcYQAKCRDH RjY5std5Xle4AKCh1dqtFxD/BiZMqdP1eZYG8AZgTACfU7VX8NpIaGmdyzVdrSDU -o49AJae0IlBoaWxpcCBSLiBaaW1tZXJtYW5uIDxwcnpAbWl0LmVkdT6IXQQQEQIA -FQUCOlToJwULCQgHAwIZAQUbAwAAAAASCRDHRjY5std5XgdlR1BHAAEBVlEAn1ln -0wx80ns6w2sIDdmeEG+3RyqKAKCclZ5utbrXUbHS69nukJ1eWdMo47QiUGhpbGlw -IFIuIFppbW1lcm1hbm4gPHByekBhY20ub3JnPohOBBARAgAGBQI6VOi3ABIJEMdG -Njmy13leB2VHUEcAAQETyQCg5ii9gHqOjlsHGSsqkliw+Ha0MX4AoLie5O1xLkK/ -rS9J3aIp9EUkE5Ah0cx//wAADToBEAABAQAAAAAAAAAAAAAAAP/Y/+AAEEpGSUYA -AQEAAAEAAQAA/9sAQwAKBwcIBwYKCAgICwoKCw4YEA4NDQ4dFRYRGCMfJSQiHyIh -Jis3LyYpNCkhIjBBMTQ5Oz4+PiUuRElDPEg3PT47/9sAQwEKCwsODQ4cEBAcOygi -KDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7 -Ozs7/8AAEQgAkAB4AwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgME -BQYHCAkKC//EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQy -gZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RV -VldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqy -s7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/E -AB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQE -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 -u1y0utMvG0eY5ihjDREcBx/eq94H0e2meTWbxS/2d9sEZHG4DJY/TPFQ6nqNtrfi -WS9ldxat+6jPQ7QMZ/Emun8LQLp2rT6aziS3uU863f3Aww/Ln8KxVuaxs2+U29Mc -C2ndQQrSFgCMdQKswoyAMDhj1qKIM8rp8oUkfdFXxH/Q1tsYdSD94zkZPWp1RvLG -48in4ANPXncKLhYifhh+IpdmVI70P2+tPUjdimAuABnsaKZMx8sgdaKEgbP/2YhO -BBARAgAGBQI6Vo8iABIJEMdGNjmy13leB2VHUEcAAQEH0QCgkp8d7aB4RbAgGiLA -kZJhXSOB5/YAmwQyiKrwRI8m3J2gVvombn3IwM7H0czX/wAADZIBEAABAQAAAAAA -AAAAAAAAAP/Y/+AAEEpGSUYAAQEAAAEAAQAA/9sAQwAKBwcIBwYKCAgICwoKCw4Y -EA4NDQ4dFRYRGCMfJSQiHyIhJis3LyYpNCkhIjBBMTQ5Oz4+PiUuRElDPEg3PT47 -/9sAQwEKCwsODQ4cEBAcOygiKDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7 -Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7/8AAEQgAjwB1AwEiAAIRAQMRAf/EAB8AAAEF -AQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMFBQQEAAABfQEC -AwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkq -NDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqS -k5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk -5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkK -C//EALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGx -wQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFla -Y2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2 -t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQAC -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 -AQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9 -AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJico -KSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJ -ipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi -4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcI -CQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKR -obHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldY -WVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0 -tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMB -AAIRAxEAPwD2aiq1/fQabZyXdy+2KMZJrhr74s2UZK2Vm8pHRm4FaQpTqfCiZTjH -c9CoryC4+KesTNiGGKFfzqez8V+Jr9fMSUlQc5Xj+tb/AFSoleVkR7aL2PWKK8w/ -4THWrf78oLDqCKng+Jd1EQLm1SQdyvBpPCVVsrh7WJ6RRXOaF4107XJxbIrxTkZ2 -t/jXRA5rnlFxdpI0TT1QtFFFSMKKKKACiiigAooooA5j4huV8I3WD1wD+teHV9A+ -JdPh1TSjZ3BcRytyUIBGATxkH0rgn8AaQp4mvfxlT/4ivQwuIhSg1I56tOUndHni -/eFel+DdR00aasc8yxOg5z34qtB4F0B3ZJLu+Rh0+df/AIirLeB9GhOFv70Y/wBp -D/7JV1q9GrGzbJhTnB3MfXri3nv5XtceVk4I6Hmufmfk12snhTTEG3+0LzHXqn/x -FM/4QrS5FDfar0g9/MT/AOIq4YqlFJJidKbdzn/CM/leIoXLBQOpJx6V69Hr+kJH -iTVLQMOo85cj9a88uPB2mWlu08b3MjqyjbKylTlgOgUetbuk6ZFakSKpXK4+Ucfj -XFiakak+aJtTi4qzOpj1/Rpm2x6rZs3p565/nV9WV1DIwZT0IOQa54wI6nG1h7c1 -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 -ss+2NCikRwMflVUupH57Bas= -=A0Ps +o49AJae0IlBoaWxpcCBSLiBaaW1tZXJtYW5uIDxwcnpAbWl0LmVkdT6IqgQQEQIA +agUCRef5PDQUgAAAAAAgAAtwcmVmZXJyZWQtZW1haWwtZW5jb2RpbmdAcGdwLmNv +bXBhcnRpdGlvbmVkBQsJCAcDAhkBGRhsZGFwOi8va2V5c2VydmVyLnBncC5jb20F +GwMAAAAFHgEAAAAACgkQx0Y2ObLXeV5HSACgjFrFxTBOtJlEIchRGIAQkfGP40gA +n34gLcaPqvzDS+mRQEqQGEc2DKQRtCJQaGlsaXAgUi4gWmltbWVybWFubiA8cHJ6 +QGFjbS5vcmc+iJsEEBECAFsFAkXn+Tw0FIAAAAAAIAALcHJlZmVycmVkLWVtYWls +LWVuY29kaW5nQHBncC5jb21wYXJ0aXRpb25lZBkYbGRhcDovL2tleXNlcnZlci5w +Z3AuY29tBR4BAAAAAAoJEMdGNjmy13lemYkAoKcCxXB8HSiXXIxTT7mID5EXa4Sh +AKDdLTSyEKe2BPpaTITWO5iRkFENYdHMf/8AAA06ARAAAQEAAAAAAAAAAAAAAAD/ +2P/gABBKRklGAAEBAAABAAEAAP/bAEMACgcHCAcGCggICAsKCgsOGBAODQ0OHRUW +ERgjHyUkIh8iISYrNy8mKTQpISIwQTE0OTs+Pj4lLkRJQzxINz0+O//bAEMBCgsL +Dg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7 +Ozs7Ozs7Ozs7Ozs7O//AABEIAJAAeAMBIgACEQEDEQH/xAAfAAABBQEBAQEBAQAA +AAAAAAAAAQIDBAUGBwgJCgv/xAC1EAACAQMDAgQDBQUEBAAAAX0BAgMABBEFEiEx +QQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoWFxgZGiUmJygpKjQ1Njc4OTpD +REVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoOEhYaHiImKkpOUlZaXmJma +oqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4eLj5OXm5+jp6vHy +8/T19vf4+fr/xAAfAQADAQEBAQEBAQEBAAAAAAAAAQIDBAUGBwgJCgv/xAC1EQAC +AQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVi +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 +P0zxUOp6jba34lkvZXcWrfuoz0O0DGfxJrp/C0C6dq0+ms4kt7lPOt39wMMPy5/C +sVbmsbNvlNvTHAtp3UEK0hYAjHUCrMKMgDA4Y9aiiDPK6fKFJH3RV8R/0NbbGHUg +/eM5GT1qdUbyxuPIp+ADT153Ci4WIn4YfiKXZlSO9D9vrT1I3YpgLgAZ7GimTMfL +IHWihIGz/9mITgQQEQIABgUCOlaPIgASCRDHRjY5std5XgdlR1BHAAEBB9EAoJKf +He2geEWwIBoiwJGSYV0jgef2AJsEMoiq8ESPJtydoFb6Jm59yMDOx9HM1/8AAA2S +ARAAAQEAAAAAAAAAAAAAAAD/2P/gABBKRklGAAEBAAABAAEAAP/bAEMACgcHCAcG +CggICAsKCgsOGBAODQ0OHRUWERgjHyUkIh8iISYrNy8mKTQpISIwQTE0OTs+Pj4l +LkRJQzxINz0+O//bAEMBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7 +Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIAI8AdQMBIgACEQED +EQH/xAAfAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgv/xAC1EAACAQMDAgQD +BQUEBAAAAX0BAgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoW +FxgZGiUmJygpKjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5 +eoOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU +1dbX2Nna4eLj5OXm5+jp6vHy8/T19vf4+fr/xAAfAQADAQEBAQEBAQEBAAAAAAAA +AQIDBAUGBwgJCgv/xAC1EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2Fx +EyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdI +SUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Sl +pqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4 ++fr/2gAMAwEAAhEDEQA/APZqKKKACiiigArI1vxLpuhRk3Uu6XHyxL94/wCH41le +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 +9rXtgw1V1dpeyZcmUlyJUdrN28aixxPNk64oMd1omZjyclwLJ2TiqwU6IY5wWblQ +4o+fN0GHfU0qCWrD/GH7WdMDbPmiuxjiNUUgHqxaq60hxVBi38nvx2IAoV6aQQ5B +7SRTklmtjfgTymngGZLqZ8/Kvw20cV8w4ATibxpwV5pkrVfr65bn0cye/wAADVkB +EAABAQAAAAAAAAAAAAAAAP/Y/+AAEEpGSUYAAQEAAAEAAQAA/9sAQwAKBwcIBwYK +CAgICwoKCw4YEA4NDQ4dFRYRGCMfJSQiHyIhJis3LyYpNCkhIjBBMTQ5Oz4+PiUu +RElDPEg3PT47/9sAQwEKCwsODQ4cEBAcOygiKDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7 +Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7/8AAEQgAkAB4AwEiAAIRAQMR +Af/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMF +BQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYX +GBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6 +g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV +1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAAB +AgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXET +IjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJ +SlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWm +p6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5 ++v/aAAwDAQACEQMRAD8A9moqtf30Gm2cl3cvtijGSa4a++LNlGStlZvKR0ZuBWkK +U6nwomU4x3PQqK8guPinrEzYhhihX86ns/Ffia/XzElJUHOV4/rW/wBUqJXlZEe2 +i9j1iivMP+Ex1q3+/KCw6gip4PiXdREC5tUkHcrwaTwlVbK4e1iekUVzmheNdO1y +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 +K/UIN6X2/CAeQoHDpRcWLPhqVIHekxZNmOM= +=zGxu -----END PGP PUBLIC KEY BLOCK----- ----------------------------------------------------------------------- Summary of changes: doc/mksamplekeys | 2 +- doc/samplekeys.asc | 894 ++++++++++++++++++++++++++-------------------------- 2 files changed, 444 insertions(+), 452 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Nov 30 20:07:52 2012 From: cvs at cvs.gnupg.org (by David Shaw) Date: Fri, 30 Nov 2012 20:07:52 +0100 Subject: [git] GnuPG - branch, STABLE-BRANCH-1-4, updated. gnupg-1.4.12-21-ge71dbf2 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, STABLE-BRANCH-1-4 has been updated via e71dbf244a2b6e7edcca37ac9544000f0629de0e (commit) from 3ab272086cdd39cc982b6deccd827a3cdb804cf1 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e71dbf244a2b6e7edcca37ac9544000f0629de0e Author: David Shaw Date: Fri Nov 30 12:39:05 2012 -0500 Fix mksamplekeys awk to not leave out the whitespace altogether diff --git a/doc/mksamplekeys b/doc/mksamplekeys index e5db52c..9c2b596 100755 --- a/doc/mksamplekeys +++ b/doc/mksamplekeys @@ -4,9 +4,7 @@ keys="1E42B367 4F25E3B6 5B0358A2 57548DCD 99242560 CA57AD7C B2D7795E 1CE0C630" for i in $keys; do - gpg --list-keys $i | awk ' ( $0 != "") { print " " $0 }' + gpg --list-keys $i | awk '{ if ( $0 != "") print " " $0; else print $0; }' done echo gpg --export-options export-minimal --export -a $keys - - diff --git a/doc/samplekeys.asc b/doc/samplekeys.asc index 4d16c10..a6ea4cb 100644 --- a/doc/samplekeys.asc +++ b/doc/samplekeys.asc @@ -3,25 +3,31 @@ uid Werner Koch sub 1024D/77F95F95 2011-11-02 sub 2048R/C193565B 2011-11-07 [expires: 2013-12-31] + pub 2048R/4F25E3B6 2011-01-12 [expires: 2019-12-31] uid Werner Koch (dist sig) sub 2048R/AC87C71A 2011-01-12 [expires: 2019-12-31] + pub 1024D/5B0358A2 1999-03-15 [expired: 2011-07-11] uid Werner Koch uid Werner Koch uid Werner Koch uid Werner Koch + pub 1024D/57548DCD 1998-07-07 [expired: 2005-12-31] uid Werner Koch (gnupg sig) + pub 4096R/99242560 2002-01-28 uid David M. Shaw sub 2048R/A1BC4FA4 2012-01-10 [expires: 2017-01-31] sub 2048R/6F410A43 2012-01-10 [expires: 2017-01-31] + pub 2048R/CA57AD7C 2004-12-06 uid PGP Global Directory Verification Key uid [jpeg image of size 3400] uid DNR KS1 uid DNR-KS2 + pub 1024D/B2D7795E 2001-01-04 uid Philip R. Zimmermann uid Philip R. Zimmermann @@ -29,9 +35,11 @@ uid [jpeg image of size 3457] uid Philip R. Zimmermann sub 3072g/A8E92834 2001-01-04 + pub 1024R/1CE0C630 2006-01-01 [expired: 2011-06-30] uid Werner Koch (dist sig) + -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.4.11 (GNU/Linux) ----------------------------------------------------------------------- Summary of changes: doc/mksamplekeys | 4 +--- doc/samplekeys.asc | 8 ++++++++ 2 files changed, 9 insertions(+), 3 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Nov 30 20:16:22 2012 From: cvs at cvs.gnupg.org (by David Shaw) Date: Fri, 30 Nov 2012 20:16:22 +0100 Subject: [git] GnuPG - branch, master, updated. gnupg-2.1.0beta3-104-gb8eb2ab Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via b8eb2ab56971a309353ae2682bc6ef1357e9ac53 (commit) via 3f8ad564674431b4c0c6cff259f02248c80a6ef9 (commit) from 7602d9e3edda99b0b65ba928eef435dab04ecd09 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b8eb2ab56971a309353ae2682bc6ef1357e9ac53 Author: David Shaw Date: Fri Nov 30 12:47:49 2012 -0500 Refresh sample keys diff --git a/doc/samplekeys.asc b/doc/samplekeys.asc index 241b013..034af39 100644 --- a/doc/samplekeys.asc +++ b/doc/samplekeys.asc @@ -1,21 +1,38 @@ - pub 1024D/5B0358A2 1999-03-15 [expired: 2009-07-11] + pub 2048D/1E42B367 2007-12-31 [expires: 2018-12-31] uid Werner Koch uid Werner Koch - uid Werner Koch - uid Werner Koch - - pub 1024D/57548DCD 1998-07-07 [expired: 2005-12-31] - uid Werner Koch (gnupg sig) - + sub 2048R/C193565B 2011-11-07 [expires: 2013-12-31] + sub 1024D/77F95F95 2011-11-02 + pub 4096R/99242560 2002-01-28 uid David M. Shaw sub 2048R/A1BC4FA4 2012-01-10 [expires: 2017-01-31] sub 2048R/6F410A43 2012-01-10 [expires: 2017-01-31] - - pub 2048R/CA57AD7C 2004-12-06 - uid PGP Global Directory Verification Key - uid [jpeg image of size 3400] - + + pub 1024D/87978569 1999-05-13 + uid Marcus Brinkmann + uid Marcus Brinkmann + uid Marcus Brinkmann + uid Marcus Brinkmann + uid Marcus Brinkmann + sub 1024R/08AEA692 2006-04-14 + sub 1024R/FCD2A293 2006-04-14 + sub 1024R/233A942F 2006-04-14 + sub 2048g/C3AF90C1 1999-05-13 + + pub 2048R/4F25E3B6 2011-01-12 [expires: 2019-12-31] + uid Werner Koch (dist sig) + sub 2048R/AC87C71A 2011-01-12 [expires: 2019-12-31] + + pub 1024D/5B0358A2 1999-03-15 [expired: 2011-07-11] + uid Werner Koch + uid Werner Koch + uid Werner Koch + uid Werner Koch + + pub 1024D/57548DCD 1998-07-07 [expired: 2005-12-31] + uid Werner Koch (gnupg sig) + pub 1024D/B2D7795E 2001-01-04 uid Philip R. Zimmermann uid Philip R. Zimmermann @@ -23,10 +40,10 @@ uid [jpeg image of size 3457] uid Philip R. Zimmermann sub 3072g/A8E92834 2001-01-04 - + pub 1024R/1CE0C630 2006-01-01 [expired: 2011-06-30] uid Werner Koch (dist sig) - + -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.4.11 (GNU/Linux) @@ -40,17 +57,17 @@ qnNnlVZBBu3U+e1qfQwLQjHu0WX4Z2q00DKpWLThGv7Loh5NKi6OfTbMhfHoevCA zQnmA/wKc6J8GqthENThKXxZaei3Ep0t+PlBmbUzuAYCXZhI6/0KyD6emyQ7LYIa Pv9qEfMkMLhxicG0v/AAwOCBRKS3bkqc6wAYaO0bjUHJvem3HkWPux82t83+6YPy RnVjm/mwt0uEyKSvt7Md2DVrO3lEcKRkRHiYuf0nonPhl5Rs5bQaV2VybmVyIEtv -Y2ggPHdrQGdudXBnLm9yZz6IawQTEQIAIwIXgAIZAQUJE2uL/wUCQllAcgULBwoD -AgMVAgMDFgIBAh4BABIHZUdQRwABAQkQXeJJllsDWKI6xwCfV3paxYsk7KQmrtOU -xNmZb004OQoAn3uq9imOpgxqsXhXaLfz5IqZu5O7tBxXZXJuZXIgS29jaCA8d2tA -ZzEwY29kZS5jb20+iGMEExECACMCGwMCHgECF4AFCRNri/8FAkJZQHoFCwcKAwID -FQIDAxYCAQAKCRBd4kmWWwNYouXsAJ9nbkvbiJZvNlzwBL98x7YB+u9fsgCfXE6v -Hv6DJk7Eh9CY+Gcdn6kCG8i0C1dlcm5lciBLb2NoiGMEExECABsFAjbtSOoFCQzJ -fIADCwoDAxUDAgMWAgECF4AAEgkQXeJJllsDWKIHZUdQRwABAbXWAJ9SCW0ieOpL -7AY6vF+OIaMmw2ZW1gCgkto0eWfgpjAuVg6jXqR1wHt2pQO0HVdlcm5lciBLb2No -IDx3ZXJuZXJAZnNmZS5vcmc+iGMEExECACMCGwMFCRNri/8CHgECF4AFAkJZQHoF -CwcKAwIDFQIDAxYCAQAKCRBd4kmWWwNYovxpAJ0ftTtETxhK8aKfIok/+43wNbQA -SwCfSFCPuVKTNHpv4JJ79feDCtfxxLG5AaIEQF3aTxEEAP9SgfIbIPL6BQ1nqobl +Y2ggPHdrQGdudXBnLm9yZz6IawQTEQIAIwIXgAIZAQULBwoDAgMVAgMDFgIBAh4B +BQJGtcWFBQkXLil/ABIHZUdQRwABAQkQXeJJllsDWKJBTACfQI8TnuVIxE88u2na +pOMyUfoWZSMAn2t47LUMuyDEHRcYvEBiP/SRVvsrtBxXZXJuZXIgS29jaCA8d2tA +ZzEwY29kZS5jb20+iGMEExECACMCGwMCHgECF4AFCwcKAwIDFQIDAxYCAQUCRrXF +kQUJFy4pfwAKCRBd4kmWWwNYomksAJ4q+Lv3fDvzDJl4JcOmzWHPsPg2QQCdHcj5 +DwCCM7YnRLiE58ApHdrg11S0C1dlcm5lciBLb2NoiGMEExECABsDCwoDAxUDAgMW +AgECF4AFAka1xZEFCRcuKX8AEgdlR1BHAAEBCRBd4kmWWwNYokHUAKCKSLq+i1yH +rG8ZXqJRk+d4SyanGwCeKFwqqRr3tbae+m4iK+EcyY+BR2a0HVdlcm5lciBLb2No +IDx3ZXJuZXJAZnNmZS5vcmc+iGMEExECACMCGwMCHgECF4AFCwcKAwIDFQIDAxYC +AQUCRrXFkQUJFy4pfwAKCRBd4kmWWwNYomC9AKCOTnRhGus67gV2k+8K2SwytYDq +VQCfcaEJKu8EBd0sx3F024GX/RNwnZq5AaIEQF3aTxEEAP9SgfIbIPL6BQ1nqobl sTYoiwWPL48uBZPjkDfy8XsVR5V9aRQlggC4x4/MD3Ip5AUgReI7PcHnp4m3vcVL XPl+/7i7hAwd84iKzgN8I8VW0EevflcNm7nbWEnpjaGxJWFbhSLI1DmqnafoU8nZ gGp2QoE+flgGDd559C3SiHRTAKDbqgS3EDhTbwfS+bAhW5Xi8/2CPwP9HueeuW9M @@ -62,379 +79,842 @@ iB5fp/SqUpn++77TAArXqsfHbmlnwcuU1EAD/i7CEhxLBYS1N77hwxL8DWCqjpi+ dlo8aJH2UIZRRIvtiJcEGBECAA8CGwIFCQcbVgAFAkR1rB0AUkcgBBkRAgAGBQJE dawTAAoJEGB4TpQBClft2RMAn1XiL/bC9hByZInCJTaCd8WS8kYCAKCfpAWwLIxk fwAeD/RI+2p00nQfvAkQXeJJllsDWKKx7QCguc4/HiEs64Ey5p6Yihy67X8E0YsA -nRXMFdXVP7ww8uldljPiD1TgyurpuQELBEBd2ykBCADRKFS0lZw/2MawS97P3nVy -t2FF9XWb8si7T9Jgl+NRF93uqUOIC15s3u5SVPcwdIhoG04wYKHTLKhyBAjFp4az -fLmiIBDDp37DY3SAtJT6TsgULR+yFkXbRvuIOU5N/0WxzrK6JJwlFVEyaPX7zmWV -KMCj+SMj2FrmltuVS0aCf0io3n97bUAvuU3dgjTFoHqW4017smfbE4VMwnLYi3/1 -SS9s0ysKM6Px5yEM3oQiOW/9pS48wSFfs3lXi8N1BikgPdU5FFA+5BGSUhxyFf+l -qdjwcByBC7LT3dCrFeWQOL0UeVh6wG48O63j8jue7mfTm+559uXnD/J65PiHcZTn -AAYpiE8EGBECAA8FAkBd2ykCGwwFCQNY7wAACgkQXeJJllsDWKIS1gCgoJ2z4OnA -0dVt7ZM/PeAsKXA0KFUAn3AV3yuZKX4WHw5Pnf5sLmF5LUkluQELBEO4FiIBCADR -WoeCwf4lVIJQahM7ytFRvPMrkSZQy072/I6/4QPKsaHI+HnoB8PjTmBpyBDLK8Y6 -Of3Y1hNb77xe+m2g+8Wq/BUKHvUi1F+xzszpnixtMr+QOiy6U7kCJA6fGvq0qmzr -XGcv5rXpGvWwyZfymTLW4X2WKgNL8bhODy0uJ9ZR/fhjE7nnIHgIboSnBAUPHCsI -9BFumsbU8FKsKJCOBqziHEyDHbix7uP6ByYslH2tUw9WdQU8Yzo2mWojghXpjE7U -T0tAb4QNTdwurLgiEIH5umsM43elr1/2nd06KigQX+NR4MqytR+28JtEEKvULwJZ -pmExs4B+OB4x8l+6Lc0/AAYpiE8EGBECAA8FAkO4FiICGwwFCQPBFYAACgkQXeJJ -llsDWKJdywCeNyRtO1/yIyiNkotYRfO5y3xuHocAnAyA4jaxa702sRs4iPR/WWJk -MgEqmQGiBDpU6CcRBADCT/tGpBu0EHpjd3G11QtkTWYnihZDBdenjYV2EvotgRZA -j5h4ewprq1u/zqzGBYpiYL/9j+5XDFcoWF24bzsUmHXsbDSiv+XEyQND1GUdx4wV -cEY5rNjkArX06XuZzObvXFXOvqRj6LskePtw3xLf5uj8jPN0Nf6YKnhfGIHRWQCg -/0UAr3hMK6zcA/egvWRGsm9dJecD/18XWekzt5JJeK3febJO/3Mwe43O6VNOxmMp -GWOYTrhivyOb/ZLgLedqX+MeXHGdGroARZ+kxYq/a9y5jNcivD+EyN+IiNDPD64r -l00FNZksx7dijD89PbIULDCtUpps2J0gk5inR+yzinf+jDyFnn5UEHI2rPFLUbXW -HJXJcp0UBACBkzDdesPjEVXZdTRTLk0sfiWEdcBM/5GpNswMlK4A7A6iqJoSNJ4p -O5Qq6PYOwDFqGir19WEfoTyHW0kxipnVbvq4q2vAhSIKOqNEJGxg4DTEKecf3xCd -J0kW8dVSogHDH/c+Q4+RFQq/31aev3HDy20YayxAE94BWIsKkhaMyohhBB8RAgAh -BQI6VPBbAgcAFwyAET/HMgQdI+nqZt21AJydvCHfdNxhAAoJEMdGNjmy13leV7gA -oKHV2q0XEP8GJkyp0/V5lgbwBmBMAJ9TtVfw2khoaZ3LNV2tINSjj0Alp7QiUGhp -bGlwIFIuIFppbW1lcm1hbm4gPHByekBtaXQuZWR1PohdBBARAgAVBQI6VOgnBQsJ -CAcDAhkBBRsDAAAAABIJEMdGNjmy13leB2VHUEcAAQFWUQCfWWfTDHzSezrDawgN -2Z4Qb7dHKooAoJyVnm61utdRsdLr2e6QnV5Z0yjjtCJQaGlsaXAgUi4gWmltbWVy -bWFubiA8cHJ6QGFjbS5vcmc+iE4EEBECAAYFAjpU6LcAEgkQx0Y2ObLXeV4HZUdQ -RwABARPJAKDmKL2Aeo6OWwcZKyqSWLD4drQxfgCguJ7k7XEuQr+tL0ndoin0RSQT -kCHRzH//AAANOgEQAAEBAAAAAAAAAAAAAAAA/9j/4AAQSkZJRgABAQAAAQABAAD/ -2wBDAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEi -MEExNDk7Pj4+JS5ESUM8SDc9Pjv/2wBDAQoLCw4NDhwQEBw7KCIoOzs7Ozs7Ozs7 -Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozv/wAARCACQ -AHgDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QA -tRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS -0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZn -aGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLD -xMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEB -AQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEE -BSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2 -Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOU -lZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn -6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDqKXFKDSEgDJOBXSeeHaoJrqKIfMwq -leanyUi/Osi4udqNLM+EUZJNNIlvsakuqjnYazbzxKlopLOHYfwqa5S/8QvOxjty -Y1z17msqWZpGAzuz1wP61LmuhrGk3udHceO9RL4gSNB6EbjVU+Ndd3YEir9UFc+n -LYC49jWhbt5UW0RIGbpyKzuzbliuhuWfjnUw377ypQv3vk2/rXVaV4o07VFCiUQz -d43P8j3rzVpnLESIgHoopZJIYIxPDg89Vb7tNSZLppnsIIYAggj1FKa4XQ/G7r5d -vexI0R4WVTgj6jpXbxyrNGskZ3IwyCD1FWncxaa3F24oNLRTJIyKKecUUwHjrWbq -l2Y/3KHk9a084HPauZu7gTXLsemeKEgkyLmuS8TaqXmNlG3yofnweprp7qdba1ln -bpGhavPH3yN5rH55DuJNKo9LF0Y3d2T2sTt+8dflPQYzk1twaJK8AeVCxfkKOMVB -o1qJLmJSPkHzH3ru4bRJlXjFc7Z2JXOBudBlIyEYAevaq8FkLRsld5J69xXpDaNC -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 -RkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKj -pKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP0 -9fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgEC -BAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLR -ChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0 -dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbH -yMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD2aiii -gAooooAKyNb8S6boUZN1Lulx8sS/eP8Ah+NZXjbxcdCt/sdjh7+UdcjES+p968fv -LyW6leaa4mmlY5kkL4AP1qXLsaQhfVnc6l8TdSncrYRRW6Zx03t/L+lYsvjjXnA8 -zUZY8nI2kr/QVzlu0b8+S2R/HvJNWFgAYuwDFuvJ/lzms2/M2UbdDrLPxlrETK51 -CRxn7sm1gfzrs9F8b2d8ix3v+jyn+Ij5T/hXkQj8gZX5hnlCMZq9YShm8vzDt7Hu -DQm0KUUz3ZHWRQ6MGU9CDkGnV5VZ6xf6FJ5qTlY8/Mh5Vh9K77QNfi1uEkJskUZI -7EeorRSuYyjY16KKKogKKKKACiiigArO17VU0XR575sFkXCKf4mPQVo1wHxXvfJ0 -yztw+N8hdh3IHA/nSew4q7PNdT1Ga9vpLi4kaaaRyWY8KDRYWCXkuG5Qc+gzWe8m -WAUYz19TW9pbGJAScZ6msJuyO2nG7NOPTrcxhAMdOmOKp3eg36OWsw0qY4x2rVgk -ynIyfrite0bKDBrBNo3aOOtvDWr3dwPPjEKDOS1dJbeFJYY/3UqKxGC5TJ/Wt+Fd -x4HNaMUSlM9yK1TbMJ2RwWo+GtXeMiaZLlByCo2mpvCOpTaDrKpdEmA/KxIwVz61 -2rR4PPWue13T4RcwXBUBWYI5A6Z6GmpNMmyasejghgCDkHkGlrD8J3ck+lfZ5m3S -WreXu/vL/Cfy/lW5XQnc5GrMKKKKYgooooAK8j+LF4ZNchtmACQQjGDySefy6V6j -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 -CwkIBwMCCgIZARkYbGRhcDovL2tleXNlcnZlci5wZ3AuY29tBRsDAAAAAxYCAQUe -AQAAAAQVCAIKAAoJEJcQuJvKV6189+YIAJ1R3QIdiqq78Epz6LO92HZVW3hfS3G8 -bOKGDwwpOgB4g6Y69p8buPItQYi3mu2kxBMMAJHCGv95Qiz9NjYxl6uYEZ1qVv3d -MbbGgw4/MmFrrFhoRCbFJa6uQs9io8MTUB10YR1xA0fL6vbs8ORIwgdLuvb5cDZq -PPn2te2DDVXV2l7JlyZSXIlR2s3bxqLHE82Trigx3WiZmPJyXAsnZOKrBTohjnBZ -uVDij583QYd9TSoJasP8YftZ0wNs+aK7GOI1RSAerFqrrSHFUGLfye/HYgChXppB -DkHtJFOSWa2N+BPKaeAZkupnz8q/DbRxXzDgBOJvGnBXmmStV+vrlufRzJ7/AAAN -WQEQAAEBAAAAAAAAAAAAAAAA/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAoHBwgH -BgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4+ -JS5ESUM8SDc9Pjv/2wBDAQoLCw4NDhwQEBw7KCIoOzs7Ozs7Ozs7Ozs7Ozs7Ozs7 -Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozv/wAARCACQAHgDASIAAhEB -AxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIE -AwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkK -FhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4 -eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT -1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAA -AAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdh -cRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZH -SElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOk -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 -=hj82 +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 +c2VydmVyLnBncC5jb20FGwMAAAAFHgEAAAAACgkQx0Y2ObLXeV5HSACgjFrFxTBO +tJlEIchRGIAQkfGP40gAn34gLcaPqvzDS+mRQEqQGEc2DKQRtCJQaGlsaXAgUi4g +WmltbWVybWFubiA8cHJ6QGFjbS5vcmc+iJsEEBECAFsFAkXn+Tw0FIAAAAAAIAAL +cHJlZmVycmVkLWVtYWlsLWVuY29kaW5nQHBncC5jb21wYXJ0aXRpb25lZBkYbGRh +cDovL2tleXNlcnZlci5wZ3AuY29tBR4BAAAAAAoJEMdGNjmy13lemYkAoKcCxXB8 +HSiXXIxTT7mID5EXa4ShAKDdLTSyEKe2BPpaTITWO5iRkFENYdHMf/8AAA06ARAA +AQEAAAAAAAAAAAAAAAD/2P/gABBKRklGAAEBAAABAAEAAP/bAEMACgcHCAcGCggI +CAsKCgsOGBAODQ0OHRUWERgjHyUkIh8iISYrNy8mKTQpISIwQTE0OTs+Pj4lLkRJ +QzxINz0+O//bAEMBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7 +Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIAJAAeAMBIgACEQEDEQH/ +xAAfAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgv/xAC1EAACAQMDAgQDBQUE +BAAAAX0BAgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoWFxgZ +GiUmJygpKjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoOE +hYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX +2Nna4eLj5OXm5+jp6vHy8/T19vf4+fr/xAAfAQADAQEBAQEBAQEBAAAAAAAAAQID +BAUGBwgJCgv/xAC1EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIy +gQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpT +VFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeo +qaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/ +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 +rT1I3YpgLgAZ7GimTMfLIHWihIGz/9mITgQQEQIABgUCOlaPIgASCRDHRjY5std5 +XgdlR1BHAAEBB9EAoJKfHe2geEWwIBoiwJGSYV0jgef2AJsEMoiq8ESPJtydoFb6 +Jm59yMDOx9HM1/8AAA2SARAAAQEAAAAAAAAAAAAAAAD/2P/gABBKRklGAAEBAAAB +AAEAAP/bAEMACgcHCAcGCggICAsKCgsOGBAODQ0OHRUWERgjHyUkIh8iISYrNy8m +KTQpISIwQTE0OTs+Pj4lLkRJQzxINz0+O//bAEMBCgsLDg0OHBAQHDsoIig7Ozs7 +Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//A +ABEIAI8AdQMBIgACEQEDEQH/xAAfAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJ +Cgv/xAC1EAACAQMDAgQDBQUEBAAAAX0BAgMABBEFEiExQQYTUWEHInEUMoGRoQgj +QrHBFVLR8CQzYnKCCQoWFxgZGiUmJygpKjQ1Njc4OTpDREVGR0hJSlNUVVZXWFla +Y2RlZmdoaWpzdHV2d3h5eoOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3 +uLm6wsPExcbHyMnK0tPU1dbX2Nna4eLj5OXm5+jp6vHy8/T19vf4+fr/xAAfAQAD +AQEBAQEBAQEBAAAAAAAAAQIDBAUGBwgJCgv/xAC1EQACAQIEBAMEBwUEBAABAncA +AQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYn +KCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeI +iYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri +4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEAAhEDEQA/APZqKKKACiiigArI1vxLpuhR +k3Uu6XHyxL94/wCH41leNvFx0K3+x2OHv5R1yMRL6n3rx+8vJbqV5priaaVjmSQv +gA/WpcuxpCF9WdzqXxN1KdythFFbpnHTe38v6Viy+ONecDzNRljycjaSv9BXOW7R +vz5LZH8e8k1YWABi7AMW68n+XOazb8zZRt0Oss/GWsRMrnUJHGfuybWB/Ouz0Xxv +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 +b25lZBkYbGRhcDovL2tleXNlcnZlci5wZ3AuY29tBR4BAAAAAAoJEMdGNjmy13le +vlgAoMqGHGUHYglUc1q0ONVSbBqREwqgAKDm0Wb8gOEgOc4LMyrMUjFQDE+9ibQt +UGhpbGlwIFIuIFppbW1lcm1hbm4gPHByekBwaGlsemltbWVybWFubi5jb20+iKEE +EBECAGEFAkXn+Tw0FIAAAAAAIAALcHJlZmVycmVkLWVtYWlsLWVuY29kaW5nQHBn +cC5jb21wYXJ0aXRpb25lZAULCQgHAxkYbGRhcDovL2tleXNlcnZlci5wZ3AuY29t +BR4BAAAAAAoJEMdGNjmy13leaBkAni74iLTyTIzFwexRyQIQaKO3Gda9AKDIot/K +YfOdMe8YD4f5Di2KsiAnR7kDDQQ6VOgnEAwAzB13VyQ4SuLE8OiOE2eXTpITYfbb +6yUOF/32mPfIfHmwch04dfv2wXPEgxEmK0Ngw+Po1gr9oSgmC66prrNlD6IAUwGg +fNaroxIe+g8qzh90hE/K8xfzpEDp19J3tkItAjbBJstoXp18mAkKjX4t7eRdefXU +kk+bGI78KqdLfDL2Qle3CH8IF3KiutapQvMF6PlTETlPtvFuuUs4INoBp1ajFOmP +QFXz0AfGy0OplK33TGSGSfgMg71l6RfUodNQ+PVZX9x2Uk89PY3bzpnhV5JZzf24 +rnRPxfx2vIPFRzBhznzJZv8V+bv9kV7HAarTW56NoKVyOtQa8L9GAFgr5fSI/VhO +SdvNILSd5JEHNmszbDgNRR0PfIizHHxbLY7288kjwEPwpVsYjY67VYy4XTjTNP18 +F1dDox0YbN4zISy1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6ypUM2Zafq9AKUJsC +RtMIPWakXUGfnHy9iUsiGSa6q6Jew1XpTDJvAAICDACNUV4K2PS6h574Z3NaBsIQ +e5jkVO48MSohjC6s29CjPhlU79cQIYWmBpuNfwroZ6zltyz6Y2Fm65V0IfvVicR7 +zvFFCOhahMuk1cr+Qp936OMEq9sLZGxTjClgwrHGS7YpMSZrEC7bpOmERjo4F/n5 +YmCHJCH8QzCOc9+80gjVEsHiJVABrC8yykjKL5x1V/PSArE4QtMLbkBPGmQYOw8b +x6jCHoO43QjUzbqRfBMHZqWVJyoIIZCp+n13XM4+NO/cDVsZ8bjch0LIOyMrT85n +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 +/CAeQoHDpRcWLPhqVIHekxZNmOM= +=K9om -----END PGP PUBLIC KEY BLOCK----- commit 3f8ad564674431b4c0c6cff259f02248c80a6ef9 Author: David Shaw Date: Fri Nov 30 12:43:34 2012 -0500 Adjust awk to not add trailing whitespace. * mksamplekeys: Tweak awk script to not add trailing whitespace to blank lines (makes git pre-commit hook unhappy) diff --git a/doc/mksamplekeys b/doc/mksamplekeys index bb04cec..cd56b21 100755 --- a/doc/mksamplekeys +++ b/doc/mksamplekeys @@ -1,11 +1,10 @@ #/bin/sh # Generate a samplekeys.asc -keys='1E42B367 99242560 87978569 - 4F25E3B6 5B0358A2 57548DCD B2D7795E 1CE0C630' +keys='1E42B367 99242560 87978569 4F25E3B6 5B0358A2 57548DCD B2D7795E 1CE0C630' for i in $keys; do - gpg --list-keys $i | awk ' { print " " $0 }' + gpg --list-keys $i | awk '{ if ( $0 != "") print " " $0; else print $0; }' done echo gpg --export-options export-minimal --export -a $keys ----------------------------------------------------------------------- Summary of changes: doc/mksamplekeys | 5 +- doc/samplekeys.asc | 1280 ++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 882 insertions(+), 403 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org