mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 17:38:00 +00:00
Add an IV argument to aes_{en,de}crypt_pubkey.
No functional change: currently, the IV passed in is always zero (except in the test suite). But this prepares to change that in a future revision of the key file format.
This commit is contained in:
parent
609502b04b
commit
c61158aa34
6
ssh.h
6
ssh.h
@ -1321,8 +1321,10 @@ void des3_decrypt_pubkey_ossh(const void *key, const void *iv,
|
|||||||
void *blk, int len);
|
void *blk, int len);
|
||||||
void des3_encrypt_pubkey_ossh(const void *key, const void *iv,
|
void des3_encrypt_pubkey_ossh(const void *key, const void *iv,
|
||||||
void *blk, int len);
|
void *blk, int len);
|
||||||
void aes256_encrypt_pubkey(const void *key, void *blk, int len);
|
void aes256_encrypt_pubkey(const void *key, const void *iv,
|
||||||
void aes256_decrypt_pubkey(const void *key, void *blk, int len);
|
void *blk, int len);
|
||||||
|
void aes256_decrypt_pubkey(const void *key, const void *iv,
|
||||||
|
void *blk, int len);
|
||||||
|
|
||||||
void des_encrypt_xdmauth(const void *key, void *blk, int len);
|
void des_encrypt_xdmauth(const void *key, void *blk, int len);
|
||||||
void des_decrypt_xdmauth(const void *key, void *blk, int len);
|
void des_decrypt_xdmauth(const void *key, void *blk, int len);
|
||||||
|
@ -11,30 +11,28 @@
|
|||||||
|
|
||||||
#include "ssh.h"
|
#include "ssh.h"
|
||||||
|
|
||||||
static ssh_cipher *aes256_pubkey_cipher(const void *key)
|
static ssh_cipher *aes256_pubkey_cipher(const void *key, const void *iv)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* PuTTY's own .PPK format for SSH-2 private key files is
|
* PuTTY's own .PPK format for SSH-2 private key files is
|
||||||
* encrypted with 256-bit AES in CBC mode.
|
* encrypted with 256-bit AES in CBC mode.
|
||||||
*/
|
*/
|
||||||
char iv[16];
|
|
||||||
memset(iv, 0, 16);
|
|
||||||
ssh_cipher *cipher = ssh_cipher_new(&ssh_aes256_cbc);
|
ssh_cipher *cipher = ssh_cipher_new(&ssh_aes256_cbc);
|
||||||
ssh_cipher_setkey(cipher, key);
|
ssh_cipher_setkey(cipher, key);
|
||||||
ssh_cipher_setiv(cipher, iv);
|
ssh_cipher_setiv(cipher, iv);
|
||||||
return cipher;
|
return cipher;
|
||||||
}
|
}
|
||||||
|
|
||||||
void aes256_encrypt_pubkey(const void *key, void *blk, int len)
|
void aes256_encrypt_pubkey(const void *key, const void *iv, void *blk, int len)
|
||||||
{
|
{
|
||||||
ssh_cipher *c = aes256_pubkey_cipher(key);
|
ssh_cipher *c = aes256_pubkey_cipher(key, iv);
|
||||||
ssh_cipher_encrypt(c, blk, len);
|
ssh_cipher_encrypt(c, blk, len);
|
||||||
ssh_cipher_free(c);
|
ssh_cipher_free(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void aes256_decrypt_pubkey(const void *key, void *blk, int len)
|
void aes256_decrypt_pubkey(const void *key, const void *iv, void *blk, int len)
|
||||||
{
|
{
|
||||||
ssh_cipher *c = aes256_pubkey_cipher(key);
|
ssh_cipher *c = aes256_pubkey_cipher(key, iv);
|
||||||
ssh_cipher_decrypt(c, blk, len);
|
ssh_cipher_decrypt(c, blk, len);
|
||||||
ssh_cipher_free(c);
|
ssh_cipher_free(c);
|
||||||
}
|
}
|
||||||
|
@ -608,6 +608,8 @@ static int userkey_parse_line_counter(const char *text)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const unsigned char zero_iv[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
||||||
|
|
||||||
ssh2_userkey *ppk_load_s(BinarySource *src, const char *passphrase,
|
ssh2_userkey *ppk_load_s(BinarySource *src, const char *passphrase,
|
||||||
const char **errorstr)
|
const char **errorstr)
|
||||||
{
|
{
|
||||||
@ -729,7 +731,8 @@ ssh2_userkey *ppk_load_s(BinarySource *src, const char *passphrase,
|
|||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
ssh2_ppk_derivekey(ptrlen_from_asciz(passphrase), key);
|
ssh2_ppk_derivekey(ptrlen_from_asciz(passphrase), key);
|
||||||
aes256_decrypt_pubkey(key, private_blob->u, private_blob->len);
|
aes256_decrypt_pubkey(key, zero_iv,
|
||||||
|
private_blob->u, private_blob->len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1323,7 +1326,8 @@ strbuf *ppk_save_sb(ssh2_userkey *key, const char *passphrase)
|
|||||||
unsigned char key[40];
|
unsigned char key[40];
|
||||||
|
|
||||||
ssh2_ppk_derivekey(ptrlen_from_asciz(passphrase), key);
|
ssh2_ppk_derivekey(ptrlen_from_asciz(passphrase), key);
|
||||||
aes256_encrypt_pubkey(key, priv_blob_encrypted, priv_encrypted_len);
|
aes256_encrypt_pubkey(key, zero_iv,
|
||||||
|
priv_blob_encrypted, priv_encrypted_len);
|
||||||
|
|
||||||
smemclr(key, sizeof(key));
|
smemclr(key, sizeof(key));
|
||||||
}
|
}
|
||||||
|
@ -1410,11 +1410,20 @@ class crypt(MyTestBase):
|
|||||||
p = b'three AES blocks, or six DES, of arbitrary input'
|
p = b'three AES blocks, or six DES, of arbitrary input'
|
||||||
|
|
||||||
k = b'thirty-two-byte aes-256 test key'
|
k = b'thirty-two-byte aes-256 test key'
|
||||||
|
iv = b'\0' * 16
|
||||||
c = unhex('7b112d00c0fc95bc13fcdacfd43281bf'
|
c = unhex('7b112d00c0fc95bc13fcdacfd43281bf'
|
||||||
'de9389db1bbcfde79d59a303d41fd2eb'
|
'de9389db1bbcfde79d59a303d41fd2eb'
|
||||||
'0955c9477ae4ee3a4d6c1fbe474c0ef6')
|
'0955c9477ae4ee3a4d6c1fbe474c0ef6')
|
||||||
self.assertEqualBin(aes256_encrypt_pubkey(k, p), c)
|
self.assertEqualBin(aes256_encrypt_pubkey(k, iv, p), c)
|
||||||
self.assertEqualBin(aes256_decrypt_pubkey(k, c), p)
|
self.assertEqualBin(aes256_decrypt_pubkey(k, iv, c), p)
|
||||||
|
|
||||||
|
# same k as in the previous case
|
||||||
|
iv = unhex('0102030405060708090a0b0c0d0e0f10')
|
||||||
|
c = unhex('9e9c8a91b739677b834397bdd8e70c05'
|
||||||
|
'c3e2cf6cce68d376d798a59848621c6d'
|
||||||
|
'42b9e7101260a438daadd7b742875a36')
|
||||||
|
self.assertEqualBin(aes256_encrypt_pubkey(k, iv, p), c)
|
||||||
|
self.assertEqualBin(aes256_decrypt_pubkey(k, iv, c), p)
|
||||||
|
|
||||||
k = b'3des with keys distinct.'
|
k = b'3des with keys distinct.'
|
||||||
iv = b'randomIV'
|
iv = b'randomIV'
|
||||||
|
12
testcrypt.c
12
testcrypt.c
@ -1029,28 +1029,32 @@ strbuf *des3_decrypt_pubkey_ossh_wrapper(ptrlen key, ptrlen iv, ptrlen data)
|
|||||||
}
|
}
|
||||||
#define des3_decrypt_pubkey_ossh des3_decrypt_pubkey_ossh_wrapper
|
#define des3_decrypt_pubkey_ossh des3_decrypt_pubkey_ossh_wrapper
|
||||||
|
|
||||||
strbuf *aes256_encrypt_pubkey_wrapper(ptrlen key, ptrlen data)
|
strbuf *aes256_encrypt_pubkey_wrapper(ptrlen key, ptrlen iv, ptrlen data)
|
||||||
{
|
{
|
||||||
if (key.len != 32)
|
if (key.len != 32)
|
||||||
fatal_error("aes256_encrypt_pubkey: key must be 32 bytes long");
|
fatal_error("aes256_encrypt_pubkey: key must be 32 bytes long");
|
||||||
|
if (iv.len != 16)
|
||||||
|
fatal_error("aes256_encrypt_pubkey: iv must be 16 bytes long");
|
||||||
if (data.len % 16 != 0)
|
if (data.len % 16 != 0)
|
||||||
fatal_error("aes256_encrypt_pubkey: data must be a multiple of 16 bytes");
|
fatal_error("aes256_encrypt_pubkey: data must be a multiple of 16 bytes");
|
||||||
strbuf *sb = strbuf_new();
|
strbuf *sb = strbuf_new();
|
||||||
put_datapl(sb, data);
|
put_datapl(sb, data);
|
||||||
aes256_encrypt_pubkey(key.ptr, sb->u, sb->len);
|
aes256_encrypt_pubkey(key.ptr, iv.ptr, sb->u, sb->len);
|
||||||
return sb;
|
return sb;
|
||||||
}
|
}
|
||||||
#define aes256_encrypt_pubkey aes256_encrypt_pubkey_wrapper
|
#define aes256_encrypt_pubkey aes256_encrypt_pubkey_wrapper
|
||||||
|
|
||||||
strbuf *aes256_decrypt_pubkey_wrapper(ptrlen key, ptrlen data)
|
strbuf *aes256_decrypt_pubkey_wrapper(ptrlen key, ptrlen iv, ptrlen data)
|
||||||
{
|
{
|
||||||
if (key.len != 32)
|
if (key.len != 32)
|
||||||
fatal_error("aes256_decrypt_pubkey: key must be 32 bytes long");
|
fatal_error("aes256_decrypt_pubkey: key must be 32 bytes long");
|
||||||
|
if (iv.len != 16)
|
||||||
|
fatal_error("aes256_encrypt_pubkey: iv must be 16 bytes long");
|
||||||
if (data.len % 16 != 0)
|
if (data.len % 16 != 0)
|
||||||
fatal_error("aes256_decrypt_pubkey: data must be a multiple of 16 bytes");
|
fatal_error("aes256_decrypt_pubkey: data must be a multiple of 16 bytes");
|
||||||
strbuf *sb = strbuf_new();
|
strbuf *sb = strbuf_new();
|
||||||
put_datapl(sb, data);
|
put_datapl(sb, data);
|
||||||
aes256_decrypt_pubkey(key.ptr, sb->u, sb->len);
|
aes256_decrypt_pubkey(key.ptr, iv.ptr, sb->u, sb->len);
|
||||||
return sb;
|
return sb;
|
||||||
}
|
}
|
||||||
#define aes256_decrypt_pubkey aes256_decrypt_pubkey_wrapper
|
#define aes256_decrypt_pubkey aes256_decrypt_pubkey_wrapper
|
||||||
|
@ -299,8 +299,8 @@ FUNC2(val_string, des3_encrypt_pubkey, val_string_ptrlen, val_string_ptrlen)
|
|||||||
FUNC2(val_string, des3_decrypt_pubkey, val_string_ptrlen, val_string_ptrlen)
|
FUNC2(val_string, des3_decrypt_pubkey, val_string_ptrlen, val_string_ptrlen)
|
||||||
FUNC3(val_string, des3_encrypt_pubkey_ossh, val_string_ptrlen, val_string_ptrlen, val_string_ptrlen)
|
FUNC3(val_string, des3_encrypt_pubkey_ossh, val_string_ptrlen, val_string_ptrlen, val_string_ptrlen)
|
||||||
FUNC3(val_string, des3_decrypt_pubkey_ossh, val_string_ptrlen, val_string_ptrlen, val_string_ptrlen)
|
FUNC3(val_string, des3_decrypt_pubkey_ossh, val_string_ptrlen, val_string_ptrlen, val_string_ptrlen)
|
||||||
FUNC2(val_string, aes256_encrypt_pubkey, val_string_ptrlen, val_string_ptrlen)
|
FUNC3(val_string, aes256_encrypt_pubkey, val_string_ptrlen, val_string_ptrlen, val_string_ptrlen)
|
||||||
FUNC2(val_string, aes256_decrypt_pubkey, val_string_ptrlen, val_string_ptrlen)
|
FUNC3(val_string, aes256_decrypt_pubkey, val_string_ptrlen, val_string_ptrlen, val_string_ptrlen)
|
||||||
FUNC1(uint, crc32_rfc1662, val_string_ptrlen)
|
FUNC1(uint, crc32_rfc1662, val_string_ptrlen)
|
||||||
FUNC1(uint, crc32_ssh1, val_string_ptrlen)
|
FUNC1(uint, crc32_ssh1, val_string_ptrlen)
|
||||||
FUNC2(uint, crc32_update, uint, val_string_ptrlen)
|
FUNC2(uint, crc32_update, uint, val_string_ptrlen)
|
||||||
|
Loading…
Reference in New Issue
Block a user