summaryrefslogtreecommitdiffstats
path: root/cipher.c
diff options
context:
space:
mode:
Diffstat (limited to 'cipher.c')
-rw-r--r--cipher.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/cipher.c b/cipher.c
index 9e8f42f5..5ddf819c 100644
--- a/cipher.c
+++ b/cipher.c
@@ -541,3 +541,43 @@ evp_rijndael(void)
#endif
return (&rijndal_cbc);
}
+
+/*
+ * Exports an IV from the CipherContext required to export the key
+ * state back from the unprivileged child to the privileged parent
+ * process.
+ */
+
+void
+cipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len)
+{
+ Cipher *c = cc->cipher;
+ u_char *civ = NULL;
+ int evplen;
+
+ switch (c->number) {
+ case SSH_CIPHER_SSH2:
+ evplen = EVP_CIPHER_CTX_iv_length(&cc->evp);
+ if (evplen == 0)
+ return;
+ if (evplen != len)
+ fatal("%s: wrong iv length %d != %d", __FUNCTION__,
+ evplen, len);
+
+ if (strncmp(c->name, "aes", 3) == 0) {
+ struct ssh_rijndael_ctx *aesc;
+
+ aesc = EVP_CIPHER_CTX_get_app_data(&cc->evp);
+ if (aesc == NULL)
+ fatal("ssh_rijndael_cbc: no context");
+ civ = aesc->r_iv;
+ } else {
+ civ = cc->evp.iv;
+ }
+ break;
+ default:
+ fatal("%s: bad cipher %d", __FUNCTION__, c->number);
+ }
+ memcpy(iv, civ, len);
+}
+