Skip to content

Commit 83bee4b

Browse files
committed
crypto: replace 'des-rfb' cipher with 'des'
Currently the crypto layer exposes support for a 'des-rfb' algorithm which is just normal single-DES, with the bits in each key byte reversed. This special key munging is required by the RFB protocol password authentication mechanism. Since the crypto layer is generic shared code, it makes more sense to do the key byte munging in the VNC server code, and expose normal single-DES support. Replacing cipher 'des-rfb' by 'des' looks like an incompatible interface change, but it doesn't matter. While the QMP schema allows any QCryptoCipherAlgorithm for the 'cipher-alg' field in QCryptoBlockCreateOptionsLUKS, the code restricts what can be used at runtime. Thus the only effect is a change in error message. Original behaviour: $ qemu-img create -f luks --object secret,id=sec0,data=123 -o cipher-alg=des-rfb,key-secret=sec0 demo.luks 1G Formatting 'demo.luks', fmt=luks size=1073741824 key-secret=sec0 cipher-alg=des-rfb qemu-img: demo.luks: Algorithm 'des-rfb' not supported New behaviour: $ qemu-img create -f luks --object secret,id=sec0,data=123 -o cipher-alg=des-rfb,key-secret=sec0 demo.luks 1G Formatting 'demo.luks', fmt=luks size=1073741824 key-secret=sec0 cipher-alg=des-fish qemu-img: demo.luks: Invalid parameter 'des-rfb' Reviewed-by: Markus Armbruster <[email protected]> Reviewed-by: Eric Blake <[email protected]> Signed-off-by: Daniel P. Berrangé <[email protected]>
1 parent 6801404 commit 83bee4b

File tree

6 files changed

+47
-65
lines changed

6 files changed

+47
-65
lines changed

crypto/cipher-gcrypt.c.inc

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
2424
QCryptoCipherMode mode)
2525
{
2626
switch (alg) {
27-
case QCRYPTO_CIPHER_ALG_DES_RFB:
27+
case QCRYPTO_CIPHER_ALG_DES:
2828
case QCRYPTO_CIPHER_ALG_3DES:
2929
case QCRYPTO_CIPHER_ALG_AES_128:
3030
case QCRYPTO_CIPHER_ALG_AES_192:
@@ -186,7 +186,7 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
186186
}
187187

188188
switch (alg) {
189-
case QCRYPTO_CIPHER_ALG_DES_RFB:
189+
case QCRYPTO_CIPHER_ALG_DES:
190190
gcryalg = GCRY_CIPHER_DES;
191191
break;
192192
case QCRYPTO_CIPHER_ALG_3DES:
@@ -257,17 +257,7 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
257257
}
258258
ctx->blocksize = gcry_cipher_get_algo_blklen(gcryalg);
259259

260-
if (alg == QCRYPTO_CIPHER_ALG_DES_RFB) {
261-
/* We're using standard DES cipher from gcrypt, so we need
262-
* to munge the key so that the results are the same as the
263-
* bizarre RFB variant of DES :-)
264-
*/
265-
uint8_t *rfbkey = qcrypto_cipher_munge_des_rfb_key(key, nkey);
266-
err = gcry_cipher_setkey(ctx->handle, rfbkey, nkey);
267-
g_free(rfbkey);
268-
} else {
269-
err = gcry_cipher_setkey(ctx->handle, key, nkey);
270-
}
260+
err = gcry_cipher_setkey(ctx->handle, key, nkey);
271261
if (err != 0) {
272262
error_setg(errp, "Cannot set key: %s", gcry_strerror(err));
273263
goto error;

crypto/cipher-nettle.c.inc

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -235,11 +235,11 @@ static const struct QCryptoCipherDriver NAME##_driver_xts = { \
235235
DEFINE_XTS(NAME, TYPE, BLEN, ENCRYPT, DECRYPT)
236236

237237

238-
typedef struct QCryptoNettleDESRFB {
238+
typedef struct QCryptoNettleDES {
239239
QCryptoCipher base;
240240
struct des_ctx key;
241241
uint8_t iv[DES_BLOCK_SIZE];
242-
} QCryptoNettleDESRFB;
242+
} QCryptoNettleDES;
243243

244244
static void des_encrypt_native(const void *ctx, size_t length,
245245
uint8_t *dst, const uint8_t *src)
@@ -253,7 +253,7 @@ static void des_decrypt_native(const void *ctx, size_t length,
253253
des_decrypt(ctx, length, dst, src);
254254
}
255255

256-
DEFINE_ECB_CBC_CTR(qcrypto_nettle_des_rfb, QCryptoNettleDESRFB,
256+
DEFINE_ECB_CBC_CTR(qcrypto_nettle_des, QCryptoNettleDES,
257257
DES_BLOCK_SIZE, des_encrypt_native, des_decrypt_native)
258258

259259

@@ -431,7 +431,7 @@ bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
431431
QCryptoCipherMode mode)
432432
{
433433
switch (alg) {
434-
case QCRYPTO_CIPHER_ALG_DES_RFB:
434+
case QCRYPTO_CIPHER_ALG_DES:
435435
case QCRYPTO_CIPHER_ALG_3DES:
436436
case QCRYPTO_CIPHER_ALG_AES_128:
437437
case QCRYPTO_CIPHER_ALG_AES_192:
@@ -480,32 +480,28 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
480480
}
481481

482482
switch (alg) {
483-
case QCRYPTO_CIPHER_ALG_DES_RFB:
483+
case QCRYPTO_CIPHER_ALG_DES:
484484
{
485-
QCryptoNettleDESRFB *ctx;
485+
QCryptoNettleDES *ctx;
486486
const QCryptoCipherDriver *drv;
487-
uint8_t *rfbkey;
488487

489488
switch (mode) {
490489
case QCRYPTO_CIPHER_MODE_ECB:
491-
drv = &qcrypto_nettle_des_rfb_driver_ecb;
490+
drv = &qcrypto_nettle_des_driver_ecb;
492491
break;
493492
case QCRYPTO_CIPHER_MODE_CBC:
494-
drv = &qcrypto_nettle_des_rfb_driver_cbc;
493+
drv = &qcrypto_nettle_des_driver_cbc;
495494
break;
496495
case QCRYPTO_CIPHER_MODE_CTR:
497-
drv = &qcrypto_nettle_des_rfb_driver_ctr;
496+
drv = &qcrypto_nettle_des_driver_ctr;
498497
break;
499498
default:
500499
goto bad_cipher_mode;
501500
}
502501

503-
ctx = g_new0(QCryptoNettleDESRFB, 1);
502+
ctx = g_new0(QCryptoNettleDES, 1);
504503
ctx->base.driver = drv;
505-
506-
rfbkey = qcrypto_cipher_munge_des_rfb_key(key, nkey);
507-
des_set_key(&ctx->key, rfbkey);
508-
g_free(rfbkey);
504+
des_set_key(&ctx->key, key);
509505

510506
return &ctx->base;
511507
}

crypto/cipher.c

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ static const size_t alg_key_len[QCRYPTO_CIPHER_ALG__MAX] = {
2929
[QCRYPTO_CIPHER_ALG_AES_128] = 16,
3030
[QCRYPTO_CIPHER_ALG_AES_192] = 24,
3131
[QCRYPTO_CIPHER_ALG_AES_256] = 32,
32-
[QCRYPTO_CIPHER_ALG_DES_RFB] = 8,
32+
[QCRYPTO_CIPHER_ALG_DES] = 8,
3333
[QCRYPTO_CIPHER_ALG_3DES] = 24,
3434
[QCRYPTO_CIPHER_ALG_CAST5_128] = 16,
3535
[QCRYPTO_CIPHER_ALG_SERPENT_128] = 16,
@@ -44,7 +44,7 @@ static const size_t alg_block_len[QCRYPTO_CIPHER_ALG__MAX] = {
4444
[QCRYPTO_CIPHER_ALG_AES_128] = 16,
4545
[QCRYPTO_CIPHER_ALG_AES_192] = 16,
4646
[QCRYPTO_CIPHER_ALG_AES_256] = 16,
47-
[QCRYPTO_CIPHER_ALG_DES_RFB] = 8,
47+
[QCRYPTO_CIPHER_ALG_DES] = 8,
4848
[QCRYPTO_CIPHER_ALG_3DES] = 8,
4949
[QCRYPTO_CIPHER_ALG_CAST5_128] = 8,
5050
[QCRYPTO_CIPHER_ALG_SERPENT_128] = 16,
@@ -107,9 +107,9 @@ qcrypto_cipher_validate_key_length(QCryptoCipherAlgorithm alg,
107107
}
108108

109109
if (mode == QCRYPTO_CIPHER_MODE_XTS) {
110-
if (alg == QCRYPTO_CIPHER_ALG_DES_RFB
111-
|| alg == QCRYPTO_CIPHER_ALG_3DES) {
112-
error_setg(errp, "XTS mode not compatible with DES-RFB/3DES");
110+
if (alg == QCRYPTO_CIPHER_ALG_DES ||
111+
alg == QCRYPTO_CIPHER_ALG_3DES) {
112+
error_setg(errp, "XTS mode not compatible with DES/3DES");
113113
return false;
114114
}
115115
if (nkey % 2) {
@@ -132,24 +132,6 @@ qcrypto_cipher_validate_key_length(QCryptoCipherAlgorithm alg,
132132
return true;
133133
}
134134

135-
#if defined(CONFIG_GCRYPT) || defined(CONFIG_NETTLE)
136-
static uint8_t *
137-
qcrypto_cipher_munge_des_rfb_key(const uint8_t *key,
138-
size_t nkey)
139-
{
140-
uint8_t *ret = g_new0(uint8_t, nkey);
141-
size_t i;
142-
for (i = 0; i < nkey; i++) {
143-
uint8_t r = key[i];
144-
r = (r & 0xf0) >> 4 | (r & 0x0f) << 4;
145-
r = (r & 0xcc) >> 2 | (r & 0x33) << 2;
146-
r = (r & 0xaa) >> 1 | (r & 0x55) << 1;
147-
ret[i] = r;
148-
}
149-
return ret;
150-
}
151-
#endif /* CONFIG_GCRYPT || CONFIG_NETTLE */
152-
153135
#ifdef CONFIG_GCRYPT
154136
#include "cipher-gcrypt.c.inc"
155137
#elif defined CONFIG_NETTLE

qapi/crypto.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
# @aes-128: AES with 128 bit / 16 byte keys
6767
# @aes-192: AES with 192 bit / 24 byte keys
6868
# @aes-256: AES with 256 bit / 32 byte keys
69-
# @des-rfb: RFB specific variant of single DES. Do not use except in VNC.
69+
# @des: DES with 56 bit / 8 byte keys. Do not use except in VNC. (since 6.1)
7070
# @3des: 3DES(EDE) with 192 bit / 24 byte keys (since 2.9)
7171
# @cast5-128: Cast5 with 128 bit / 16 byte keys
7272
# @serpent-128: Serpent with 128 bit / 16 byte keys
@@ -80,7 +80,7 @@
8080
{ 'enum': 'QCryptoCipherAlgorithm',
8181
'prefix': 'QCRYPTO_CIPHER_ALG',
8282
'data': ['aes-128', 'aes-192', 'aes-256',
83-
'des-rfb', '3des',
83+
'des', '3des',
8484
'cast5-128',
8585
'serpent-128', 'serpent-192', 'serpent-256',
8686
'twofish-128', 'twofish-192', 'twofish-256']}

tests/unit/test-crypto-cipher.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -155,28 +155,28 @@ static QCryptoCipherTestData test_data[] = {
155155
* in single AES block, and gives identical
156156
* ciphertext in ECB and CBC modes
157157
*/
158-
.path = "/crypto/cipher/des-rfb-ecb-56-one-block",
159-
.alg = QCRYPTO_CIPHER_ALG_DES_RFB,
158+
.path = "/crypto/cipher/des-ecb-56-one-block",
159+
.alg = QCRYPTO_CIPHER_ALG_DES,
160160
.mode = QCRYPTO_CIPHER_MODE_ECB,
161-
.key = "0123456789abcdef",
161+
.key = "80c4a2e691d5b3f7",
162162
.plaintext = "70617373776f7264",
163163
.ciphertext = "73fa80b66134e403",
164164
},
165165
{
166166
/* See previous comment */
167-
.path = "/crypto/cipher/des-rfb-cbc-56-one-block",
168-
.alg = QCRYPTO_CIPHER_ALG_DES_RFB,
167+
.path = "/crypto/cipher/des-cbc-56-one-block",
168+
.alg = QCRYPTO_CIPHER_ALG_DES,
169169
.mode = QCRYPTO_CIPHER_MODE_CBC,
170-
.key = "0123456789abcdef",
170+
.key = "80c4a2e691d5b3f7",
171171
.iv = "0000000000000000",
172172
.plaintext = "70617373776f7264",
173173
.ciphertext = "73fa80b66134e403",
174174
},
175175
{
176-
.path = "/crypto/cipher/des-rfb-ecb-56",
177-
.alg = QCRYPTO_CIPHER_ALG_DES_RFB,
176+
.path = "/crypto/cipher/des-ecb-56",
177+
.alg = QCRYPTO_CIPHER_ALG_DES,
178178
.mode = QCRYPTO_CIPHER_MODE_ECB,
179-
.key = "0123456789abcdef",
179+
.key = "80c4a2e691d5b3f7",
180180
.plaintext =
181181
"6bc1bee22e409f96e93d7e117393172a"
182182
"ae2d8a571e03ac9c9eb76fac45af8e51"

ui/vnc.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2733,6 +2733,19 @@ static void authentication_failed(VncState *vs)
27332733
vnc_client_error(vs);
27342734
}
27352735

2736+
static void
2737+
vnc_munge_des_rfb_key(unsigned char *key, size_t nkey)
2738+
{
2739+
size_t i;
2740+
for (i = 0; i < nkey; i++) {
2741+
uint8_t r = key[i];
2742+
r = (r & 0xf0) >> 4 | (r & 0x0f) << 4;
2743+
r = (r & 0xcc) >> 2 | (r & 0x33) << 2;
2744+
r = (r & 0xaa) >> 1 | (r & 0x55) << 1;
2745+
key[i] = r;
2746+
}
2747+
}
2748+
27362749
static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
27372750
{
27382751
unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
@@ -2757,9 +2770,10 @@ static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
27572770
pwlen = strlen(vs->vd->password);
27582771
for (i=0; i<sizeof(key); i++)
27592772
key[i] = i<pwlen ? vs->vd->password[i] : 0;
2773+
vnc_munge_des_rfb_key(key, sizeof(key));
27602774

27612775
cipher = qcrypto_cipher_new(
2762-
QCRYPTO_CIPHER_ALG_DES_RFB,
2776+
QCRYPTO_CIPHER_ALG_DES,
27632777
QCRYPTO_CIPHER_MODE_ECB,
27642778
key, G_N_ELEMENTS(key),
27652779
&err);
@@ -4045,9 +4059,9 @@ void vnc_display_open(const char *id, Error **errp)
40454059
goto fail;
40464060
}
40474061
if (!qcrypto_cipher_supports(
4048-
QCRYPTO_CIPHER_ALG_DES_RFB, QCRYPTO_CIPHER_MODE_ECB)) {
4062+
QCRYPTO_CIPHER_ALG_DES, QCRYPTO_CIPHER_MODE_ECB)) {
40494063
error_setg(errp,
4050-
"Cipher backend does not support DES RFB algorithm");
4064+
"Cipher backend does not support DES algorithm");
40514065
goto fail;
40524066
}
40534067
}

0 commit comments

Comments
 (0)