Hi, I'm fairly certain that I've found the bug.
The problem is that the gnome keyring daemon and libsecret are using very slightly different algorithms to create the private aes key used for communication over dbus. They're constructing the same dh secret, but in those cases where the secret is < 2^{1024-8}, they apply the sha256 algorithm to byte strings of different lengths, so they get different aes keys. Then everything falls apart. I attach a patch. With the patch, the error did not occur during 10,000 iterations, so it's pretty safe (probability roughly 1 - 10^{-17}) to say that it fixes the bug. I don't know enough about the various standards in cryptography, so I don't really know whether gnome-keyring (actually, libgck) or libsecret is more to blame. I chose to modify libsecret, since gnome-keyring's approach seems to be cleaner, and since libgck is probably used in many other applications, so is more likely to be correct. I also recommend changing the error message. I don't think that there's any such thing as an unencryptable secret in aes (unless it has infinite length or something). I suggest "failure in communicating with keyring daemon" or perhaps "unknown decryption failure", but would be open to other possibilities. Sincerely, Paul Vojta
--- libsecret-0.18.5/libsecret/secret-session.c.orig 2014-09-23 00:49:21.000000000 -0700 +++ libsecret-0.18.5/libsecret/secret-session.c 2017-02-28 17:49:18.032902772 -0800 @@ -149,15 +149,26 @@ #if 0 g_printerr (" lib ikm: %s\n", egg_hex_encode (ikm, n_ikm)); + g_printerr (" lib n_ikm: %lu\n", n_ikm); #endif - if (ikm == NULL) { + if (ikm == NULL || n_ikm > 128) { g_warning ("couldn't negotiate a valid AES session key"); g_free (session->path); session->path = NULL; return FALSE; } + if (n_ikm < 128) { + gchar *ikm_new = egg_secure_alloc (128); + + memset (ikm_new, 0, 128 - n_ikm); + memcpy (ikm_new + 128 - n_ikm, ikm, n_ikm); + egg_secure_free (ikm); + ikm = ikm_new; + n_ikm = 128; + } + session->n_key = 16; session->key = egg_secure_alloc (session->n_key); if (!egg_hkdf_perform ("sha256", ikm, n_ikm, NULL, 0, NULL, 0, @@ -441,7 +452,7 @@ if (!pkcs7_unpad_bytes_in_place (padded, &n_padded)) { egg_secure_clear (padded, n_padded); egg_secure_free (padded); - g_message ("received an invalid or unencryptable secret"); + g_message ("failure in communicating with keyring daemon"); return FALSE; }