* has been replaced incompatibly.
*/
-/* --- @key_plock@ --- *
+/* --- @key_lock@ --- *
*
- * Arguments: @const char *tag@ = tag to use for passphrase
+ * Arguments: @key_data *kt@ = destination block
* @key_data *k@ = source key data block
- * @key_data *kt@ = target key data block
+ * @const void *e@ = secret to encrypt key with
+ * @size_t esz@ = size of the secret
*
- * Returns: Zero if successful, nonzero if there was a problem.
+ * Returns: ---
*
- * Use: Locks a key by encrypting it with a passphrase.
+ * Use: Encrypts a key data block using a secret.
*/
-int key_plock(const char *tag, key_data *k, key_data *kt)
+void key_lock(key_data *kt, key_data *k, const void *e, size_t esz)
{
dstr d = DSTR_INIT;
octet b[RMD160_HASHSZ * 2];
octet *m;
size_t msz;
- char buf[256];
+ rmd160_mgfctx r;
+ blowfish_cbcctx c;
+ rmd160_mackey mk;
+ rmd160_macctx mc;
/* --- Sanity check --- */
m = (octet *)d.buf + RMD160_HASHSZ * 2;
msz = d.len - RMD160_HASHSZ * 2;
- /* --- Read the passphrase --- */
-
- if (passphrase_read(tag, PMODE_VERIFY, buf, sizeof(buf))) {
- dstr_destroy(&d);
- return (-1);
- }
-
/* --- Hash the passphrase to make a key --- */
- {
- rmd160_mgfctx r;
- rmd160_mgfkeybegin(&r);
- rmd160_mgfkeyadd(&r, d.buf, RMD160_HASHSZ);
- rmd160_mgfkeyadd(&r, buf, strlen(buf));
- rmd160_mgfencrypt(&r, 0, b, sizeof(b));
- BURN(r);
- BURN(buf);
- }
+ rmd160_mgfkeybegin(&r);
+ rmd160_mgfkeyadd(&r, d.buf, RMD160_HASHSZ);
+ rmd160_mgfkeyadd(&r, e, esz);
+ rmd160_mgfencrypt(&r, 0, b, sizeof(b));
+ BURN(r);
/* --- Encrypt the plaintext --- */
- {
- blowfish_cbcctx c;
- blowfish_cbcinit(&c, b, RMD160_HASHSZ, 0);
- blowfish_cbcencrypt(&c, m, m, msz);
- BURN(c);
- }
+ blowfish_cbcinit(&c, b, RMD160_HASHSZ, 0);
+ blowfish_cbcencrypt(&c, m, m, msz);
+ BURN(c);
/* --- MAC the ciphertext --- */
- {
- rmd160_mackey mk;
- rmd160_macctx mc;
- rmd160_hmacinit(&mk, b + RMD160_HASHSZ, RMD160_HASHSZ);
- rmd160_macinit(&mc, &mk);
- rmd160_machash(&mc, m, msz);
- rmd160_macdone(&mc, d.buf + RMD160_HASHSZ);
- BURN(mk);
- BURN(mc);
- }
+ rmd160_hmacinit(&mk, b + RMD160_HASHSZ, RMD160_HASHSZ);
+ rmd160_macinit(&mc, &mk);
+ rmd160_machash(&mc, m, msz);
+ rmd160_macdone(&mc, d.buf + RMD160_HASHSZ);
+ BURN(mk);
+ BURN(mc);
/* --- Done --- */
BURN(b);
key_encrypted(kt, d.buf, d.len);
dstr_destroy(&d);
- return (0);
}
-/* --- @key_punlock@ --- *
+/* --- @key_unlock@ --- *
*
- * Arguments: @const char *tag@ = tag to use for passphrase
+ * Arguments: @key_data *kt@ = target block
* @key_data *k@ = source key data block
- * @key_data *kt@ = target key data block
+ * @const void *e@ = secret to decrypt the block with
+ * @size_t esz@ = size of the secret
*
- * Returns: Zero if it worked, nonzero if it didn't.
+ * Returns: Zero for success, or a @KERR_@ error code.
*
- * Use: Unlocks a passphrase-locked key.
+ * Use: Unlocks a key using a secret.
*/
-int key_punlock(const char *tag, key_data *k, key_data *kt)
+int key_unlock(key_data *kt, key_data *k, const void *e, size_t esz)
{
octet b[RMD160_HASHSZ * 2];
- char buf[256];
octet *p = 0;
+ int rc;
+ rmd160_mgfctx r;
+ blowfish_cbcctx c;
+ rmd160_mackey mk;
+ rmd160_macctx mc;
size_t sz;
/* --- Sanity check --- */
/* --- Check the size --- */
if (k->u.k.sz < RMD160_HASHSZ * 2)
- return (-1);
+ return (KERR_MALFORMED);
sz = k->u.k.sz - RMD160_HASHSZ * 2;
- /* --- Fetch the passphrase --- */
-
- if (passphrase_read(tag, PMODE_READ, buf, sizeof(buf)))
- goto fail;
-
/* --- Hash the passphrase to make a key --- */
- {
- rmd160_mgfctx r;
- rmd160_mgfkeybegin(&r);
- rmd160_mgfkeyadd(&r, k->u.k.k, RMD160_HASHSZ);
- rmd160_mgfkeyadd(&r, buf, strlen(buf));
- rmd160_mgfencrypt(&r, 0, b, sizeof(b));
- BURN(r);
- BURN(buf);
- }
+ rmd160_mgfkeybegin(&r);
+ rmd160_mgfkeyadd(&r, k->u.k.k, RMD160_HASHSZ);
+ rmd160_mgfkeyadd(&r, e, esz);
+ rmd160_mgfencrypt(&r, 0, b, sizeof(b));
+ BURN(r);
/* --- Verify the MAC --- */
- {
- rmd160_mackey mk;
- rmd160_macctx mc;
- rmd160_hmacinit(&mk, b + RMD160_HASHSZ, RMD160_HASHSZ);
- rmd160_macinit(&mc, &mk);
- rmd160_machash(&mc, k->u.k.k + RMD160_HASHSZ * 2, sz);
- rmd160_macdone(&mc, b + RMD160_HASHSZ);
- if (memcmp(b + RMD160_HASHSZ, k->u.k.k + RMD160_HASHSZ,
- RMD160_HASHSZ) != 0) {
- passphrase_cancel(tag);
- goto fail;
- }
- BURN(mk);
- BURN(mc);
+ rmd160_hmacinit(&mk, b + RMD160_HASHSZ, RMD160_HASHSZ);
+ rmd160_macinit(&mc, &mk);
+ rmd160_machash(&mc, k->u.k.k + RMD160_HASHSZ * 2, sz);
+ rmd160_macdone(&mc, b + RMD160_HASHSZ);
+ if (memcmp(b + RMD160_HASHSZ, k->u.k.k + RMD160_HASHSZ,
+ RMD160_HASHSZ) != 0) {
+ rc = KERR_BADPASS;
+ goto fail;
}
+ BURN(mk);
+ BURN(mc);
/* --- Allocate a destination buffer --- */
/* --- Decrypt the key data --- */
- {
- blowfish_cbcctx c;
- blowfish_cbcinit(&c, b, RMD160_HASHSZ, 0);
- blowfish_cbcdecrypt(&c, k->u.k.k + RMD160_HASHSZ * 2, p, sz);
- BURN(c);
- }
+ blowfish_cbcinit(&c, b, RMD160_HASHSZ, 0);
+ blowfish_cbcdecrypt(&c, k->u.k.k + RMD160_HASHSZ * 2, p, sz);
+ BURN(c);
/* --- Decode the key data into the destination buffer --- */
- if (k == kt) {
+ if (k == kt)
key_destroy(k);
- passphrase_cancel(tag);
- }
- if (key_decode(p, sz, kt))
+ if (key_decode(p, sz, kt)) {
+ rc = KERR_MALFORMED;
goto fail;
+ }
/* --- Done --- */
fail:
BURN(b);
xfree(p);
- return (-1);
+ return (rc);
+}
+
+/* --- @key_plock@ --- *
+ *
+ * Arguments: @const char *tag@ = tag to use for passphrase
+ * @key_data *k@ = source key data block
+ * @key_data *kt@ = target key data block
+ *
+ * Returns: Zero if successful, a @KERR@ error code on failure.
+ *
+ * Use: Locks a key by encrypting it with a passphrase.
+ */
+
+int key_plock(const char *tag, key_data *k, key_data *kt)
+{
+ char buf[256];
+
+ if (passphrase_read(tag, PMODE_VERIFY, buf, sizeof(buf)))
+ return (KERR_IO);
+ key_lock(kt, k, buf, strlen(buf));
+ BURN(buf);
+ return (0);
+}
+
+/* --- @key_punlock@ --- *
+ *
+ * Arguments: @const char *tag@ = tag to use for passphrase
+ * @key_data *k@ = source key data block
+ * @key_data *kt@ = target key data block
+ *
+ * Returns: Zero if it worked, a @KERR_@ error code on failure.
+ *
+ * Use: Unlocks a passphrase-locked key.
+ */
+
+int key_punlock(const char *tag, key_data *k, key_data *kt)
+{
+ char buf[256];
+ int rc;
+
+ if (passphrase_read(tag, PMODE_READ, buf, sizeof(buf)))
+ return (KERR_IO);
+ rc = key_unlock(kt, k, buf, strlen(buf));
+ BURN(buf);
+ if (rc == KERR_BADPASS || k == kt)
+ passphrase_cancel(tag);
+ return (rc);
}
/*----- That's all, folks -------------------------------------------------*/