qemu

Форк
0
/
akcipher-nettle.c.inc 
451 строка · 13.1 Кб
1
/*
2
 * QEMU Crypto akcipher algorithms
3
 *
4
 * Copyright (c) 2022 Bytedance
5
 * Author: lei he <helei.sig11@bytedance.com>
6
 *
7
 * This library is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * This library is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19
 *
20
 */
21

22
#include <nettle/rsa.h>
23

24
#include "qemu/osdep.h"
25
#include "qemu/host-utils.h"
26
#include "crypto/akcipher.h"
27
#include "crypto/random.h"
28
#include "qapi/error.h"
29
#include "sysemu/cryptodev.h"
30
#include "rsakey.h"
31

32
typedef struct QCryptoNettleRSA {
33
    QCryptoAkCipher akcipher;
34
    struct rsa_public_key pub;
35
    struct rsa_private_key priv;
36
    QCryptoRSAPaddingAlgorithm padding_alg;
37
    QCryptoHashAlgorithm hash_alg;
38
} QCryptoNettleRSA;
39

40
static void qcrypto_nettle_rsa_free(QCryptoAkCipher *akcipher)
41
{
42
    QCryptoNettleRSA *rsa = (QCryptoNettleRSA *)akcipher;
43
    if (!rsa) {
44
        return;
45
    }
46

47
    rsa_public_key_clear(&rsa->pub);
48
    rsa_private_key_clear(&rsa->priv);
49
    g_free(rsa);
50
}
51

52
static QCryptoAkCipher *qcrypto_nettle_rsa_new(
53
    const QCryptoAkCipherOptionsRSA *opt,
54
    QCryptoAkCipherKeyType type,
55
    const uint8_t *key,  size_t keylen,
56
    Error **errp);
57

58
QCryptoAkCipher *qcrypto_akcipher_new(const QCryptoAkCipherOptions *opts,
59
                                      QCryptoAkCipherKeyType type,
60
                                      const uint8_t *key, size_t keylen,
61
                                      Error **errp)
62
{
63
    switch (opts->alg) {
64
    case QCRYPTO_AKCIPHER_ALG_RSA:
65
        return qcrypto_nettle_rsa_new(&opts->u.rsa, type, key, keylen, errp);
66

67
    default:
68
        error_setg(errp, "Unsupported algorithm: %u", opts->alg);
69
        return NULL;
70
    }
71

72
    return NULL;
73
}
74

75
static void qcrypto_nettle_rsa_set_akcipher_size(QCryptoAkCipher *akcipher,
76
                                                 int key_size)
77
{
78
    akcipher->max_plaintext_len = key_size;
79
    akcipher->max_ciphertext_len = key_size;
80
    akcipher->max_signature_len = key_size;
81
    akcipher->max_dgst_len = key_size;
82
}
83

84
static int qcrypt_nettle_parse_rsa_private_key(QCryptoNettleRSA *rsa,
85
                                               const uint8_t *key,
86
                                               size_t keylen,
87
                                               Error **errp)
88
{
89
    g_autoptr(QCryptoAkCipherRSAKey) rsa_key = qcrypto_akcipher_rsakey_parse(
90
        QCRYPTO_AKCIPHER_KEY_TYPE_PRIVATE, key, keylen, errp);
91

92
    if (!rsa_key) {
93
        return -1;
94
    }
95

96
    nettle_mpz_init_set_str_256_u(rsa->pub.n, rsa_key->n.len, rsa_key->n.data);
97
    nettle_mpz_init_set_str_256_u(rsa->pub.e, rsa_key->e.len, rsa_key->e.data);
98
    nettle_mpz_init_set_str_256_u(rsa->priv.d, rsa_key->d.len, rsa_key->d.data);
99
    nettle_mpz_init_set_str_256_u(rsa->priv.p, rsa_key->p.len, rsa_key->p.data);
100
    nettle_mpz_init_set_str_256_u(rsa->priv.q, rsa_key->q.len, rsa_key->q.data);
101
    nettle_mpz_init_set_str_256_u(rsa->priv.a, rsa_key->dp.len,
102
                                  rsa_key->dp.data);
103
    nettle_mpz_init_set_str_256_u(rsa->priv.b, rsa_key->dq.len,
104
                                  rsa_key->dq.data);
105
    nettle_mpz_init_set_str_256_u(rsa->priv.c, rsa_key->u.len, rsa_key->u.data);
106

107
    if (!rsa_public_key_prepare(&rsa->pub)) {
108
        error_setg(errp, "Failed to check RSA key");
109
        return -1;
110
    }
111

112
    /**
113
     * Since in the kernel's unit test, the p, q, a, b, c of some
114
     * private keys is 0, only the simplest length check is done here
115
     */
116
    if (rsa_key->p.len > 1 &&
117
        rsa_key->q.len > 1 &&
118
        rsa_key->dp.len > 1 &&
119
        rsa_key->dq.len > 1 &&
120
        rsa_key->u.len > 1) {
121
        if (!rsa_private_key_prepare(&rsa->priv)) {
122
            error_setg(errp, "Failed to check RSA key");
123
            return -1;
124
        }
125
    } else {
126
        rsa->priv.size = rsa->pub.size;
127
    }
128
    qcrypto_nettle_rsa_set_akcipher_size(
129
        (QCryptoAkCipher *)rsa, rsa->priv.size);
130

131
    return 0;
132
}
133

134
static int qcrypt_nettle_parse_rsa_public_key(QCryptoNettleRSA *rsa,
135
                                              const uint8_t *key,
136
                                              size_t keylen,
137
                                              Error **errp)
138
{
139
    g_autoptr(QCryptoAkCipherRSAKey) rsa_key = qcrypto_akcipher_rsakey_parse(
140
        QCRYPTO_AKCIPHER_KEY_TYPE_PUBLIC, key, keylen, errp);
141

142
    if (!rsa_key) {
143
        return -1;
144
    }
145
    nettle_mpz_init_set_str_256_u(rsa->pub.n, rsa_key->n.len, rsa_key->n.data);
146
    nettle_mpz_init_set_str_256_u(rsa->pub.e, rsa_key->e.len, rsa_key->e.data);
147

148
    if (!rsa_public_key_prepare(&rsa->pub)) {
149
        error_setg(errp, "Failed to check RSA key");
150
        return -1;
151
    }
152
    qcrypto_nettle_rsa_set_akcipher_size(
153
        (QCryptoAkCipher *)rsa, rsa->pub.size);
154

155
    return 0;
156
}
157

158
static void wrap_nettle_random_func(void *ctx, size_t len, uint8_t *out)
159
{
160
    qcrypto_random_bytes(out, len, &error_abort);
161
}
162

163
static int qcrypto_nettle_rsa_encrypt(QCryptoAkCipher *akcipher,
164
                                      const void *data, size_t data_len,
165
                                      void *enc, size_t enc_len,
166
                                      Error **errp)
167
{
168

169
    QCryptoNettleRSA *rsa = (QCryptoNettleRSA *)akcipher;
170
    mpz_t c;
171
    int ret = -1;
172

173
    if (data_len > rsa->pub.size) {
174
        error_setg(errp, "Plaintext length %zu is greater than key size: %zu",
175
                   data_len, rsa->pub.size);
176
        return ret;
177
    }
178

179
    if (enc_len < rsa->pub.size) {
180
        error_setg(errp, "Ciphertext buffer length %zu is less than "
181
                         "key size: %zu", enc_len, rsa->pub.size);
182
        return ret;
183
    }
184

185
    /* Nettle do not support RSA encryption without any padding */
186
    switch (rsa->padding_alg) {
187
    case QCRYPTO_RSA_PADDING_ALG_RAW:
188
        error_setg(errp, "RSA with raw padding is not supported");
189
        break;
190

191
    case QCRYPTO_RSA_PADDING_ALG_PKCS1:
192
        mpz_init(c);
193
        if (rsa_encrypt(&rsa->pub, NULL, wrap_nettle_random_func,
194
                        data_len, (uint8_t *)data, c) != 1) {
195
            error_setg(errp, "Failed to encrypt");
196
        } else {
197
            nettle_mpz_get_str_256(enc_len, (uint8_t *)enc, c);
198
            ret = nettle_mpz_sizeinbase_256_u(c);
199
        }
200
        mpz_clear(c);
201
        break;
202

203
    default:
204
        error_setg(errp, "Unknown padding");
205
    }
206

207
    return ret;
208
}
209

210
static int qcrypto_nettle_rsa_decrypt(QCryptoAkCipher *akcipher,
211
                                      const void *enc, size_t enc_len,
212
                                      void *data, size_t data_len,
213
                                      Error **errp)
214
{
215
    QCryptoNettleRSA *rsa = (QCryptoNettleRSA *)akcipher;
216
    mpz_t c;
217
    int ret = -1;
218

219
    if (enc_len > rsa->priv.size) {
220
        error_setg(errp, "Ciphertext length %zu is greater than key size: %zu",
221
                   enc_len, rsa->priv.size);
222
        return ret;
223
    }
224

225
    switch (rsa->padding_alg) {
226
    case QCRYPTO_RSA_PADDING_ALG_RAW:
227
        error_setg(errp, "RSA with raw padding is not supported");
228
        break;
229

230
    case QCRYPTO_RSA_PADDING_ALG_PKCS1:
231
        nettle_mpz_init_set_str_256_u(c, enc_len, enc);
232
        if (!rsa_decrypt(&rsa->priv, &data_len, (uint8_t *)data, c)) {
233
            error_setg(errp, "Failed to decrypt");
234
        } else {
235
            ret = data_len;
236
        }
237

238
        mpz_clear(c);
239
        break;
240

241
    default:
242
        error_setg(errp, "Unknown padding algorithm: %d", rsa->padding_alg);
243
    }
244

245
    return ret;
246
}
247

248
static int qcrypto_nettle_rsa_sign(QCryptoAkCipher *akcipher,
249
                                   const void *data, size_t data_len,
250
                                   void *sig, size_t sig_len, Error **errp)
251
{
252
    QCryptoNettleRSA *rsa = (QCryptoNettleRSA *)akcipher;
253
    int ret = -1, rv;
254
    mpz_t s;
255

256
    /**
257
     * The RSA algorithm cannot be used for signature/verification
258
     * without padding.
259
     */
260
    if (rsa->padding_alg == QCRYPTO_RSA_PADDING_ALG_RAW) {
261
        error_setg(errp, "Try to make signature without padding");
262
        return ret;
263
    }
264

265
    if (data_len > rsa->priv.size) {
266
        error_setg(errp, "Data length %zu is greater than key size: %zu",
267
                   data_len, rsa->priv.size);
268
        return ret;
269
    }
270

271
    if (sig_len < rsa->priv.size) {
272
        error_setg(errp, "Signature buffer length %zu is less than "
273
                         "key size: %zu", sig_len, rsa->priv.size);
274
        return ret;
275
    }
276

277
    mpz_init(s);
278
    switch (rsa->hash_alg) {
279
    case QCRYPTO_HASH_ALG_MD5:
280
        rv = rsa_md5_sign_digest(&rsa->priv, data, s);
281
        break;
282

283
    case QCRYPTO_HASH_ALG_SHA1:
284
        rv = rsa_sha1_sign_digest(&rsa->priv, data, s);
285
        break;
286

287
    case QCRYPTO_HASH_ALG_SHA256:
288
        rv = rsa_sha256_sign_digest(&rsa->priv, data, s);
289
        break;
290

291
    case QCRYPTO_HASH_ALG_SHA512:
292
        rv = rsa_sha512_sign_digest(&rsa->priv, data, s);
293
        break;
294

295
    default:
296
        error_setg(errp, "Unknown hash algorithm: %d", rsa->hash_alg);
297
        goto cleanup;
298
    }
299

300
    if (rv != 1) {
301
        error_setg(errp, "Failed to make signature");
302
        goto cleanup;
303
    }
304
    nettle_mpz_get_str_256(sig_len, (uint8_t *)sig, s);
305
    ret = nettle_mpz_sizeinbase_256_u(s);
306

307
cleanup:
308
    mpz_clear(s);
309

310
    return ret;
311
}
312

313
static int qcrypto_nettle_rsa_verify(QCryptoAkCipher *akcipher,
314
                                     const void *sig, size_t sig_len,
315
                                     const void *data, size_t data_len,
316
                                     Error **errp)
317
{
318
    QCryptoNettleRSA *rsa = (QCryptoNettleRSA *)akcipher;
319

320
    int ret = -1, rv;
321
    mpz_t s;
322

323
    /**
324
     * The RSA algorithm cannot be used for signature/verification
325
     * without padding.
326
     */
327
    if (rsa->padding_alg == QCRYPTO_RSA_PADDING_ALG_RAW) {
328
        error_setg(errp, "Try to verify signature without padding");
329
        return ret;
330
    }
331
    if (data_len > rsa->pub.size) {
332
        error_setg(errp, "Data length %zu is greater than key size: %zu",
333
                   data_len, rsa->pub.size);
334
        return ret;
335
    }
336
    if (sig_len < rsa->pub.size) {
337
        error_setg(errp, "Signature length %zu is greater than key size: %zu",
338
                   sig_len, rsa->pub.size);
339
        return ret;
340
    }
341

342
    nettle_mpz_init_set_str_256_u(s, sig_len, sig);
343
    switch (rsa->hash_alg) {
344
    case QCRYPTO_HASH_ALG_MD5:
345
        rv = rsa_md5_verify_digest(&rsa->pub, data, s);
346
        break;
347

348
    case QCRYPTO_HASH_ALG_SHA1:
349
        rv = rsa_sha1_verify_digest(&rsa->pub, data, s);
350
        break;
351

352
    case QCRYPTO_HASH_ALG_SHA256:
353
        rv = rsa_sha256_verify_digest(&rsa->pub, data, s);
354
        break;
355

356
    case QCRYPTO_HASH_ALG_SHA512:
357
        rv = rsa_sha512_verify_digest(&rsa->pub, data, s);
358
        break;
359

360
    default:
361
        error_setg(errp, "Unsupported hash algorithm: %d", rsa->hash_alg);
362
        goto cleanup;
363
    }
364

365
    if (rv != 1) {
366
        error_setg(errp, "Failed to verify signature");
367
        goto cleanup;
368
    }
369
    ret = 0;
370

371
cleanup:
372
    mpz_clear(s);
373

374
    return ret;
375
}
376

377
QCryptoAkCipherDriver nettle_rsa = {
378
    .encrypt = qcrypto_nettle_rsa_encrypt,
379
    .decrypt = qcrypto_nettle_rsa_decrypt,
380
    .sign = qcrypto_nettle_rsa_sign,
381
    .verify = qcrypto_nettle_rsa_verify,
382
    .free = qcrypto_nettle_rsa_free,
383
};
384

385
static QCryptoAkCipher *qcrypto_nettle_rsa_new(
386
    const QCryptoAkCipherOptionsRSA *opt,
387
    QCryptoAkCipherKeyType type,
388
    const uint8_t *key, size_t keylen,
389
    Error **errp)
390
{
391
    QCryptoNettleRSA *rsa = g_new0(QCryptoNettleRSA, 1);
392

393
    rsa->padding_alg = opt->padding_alg;
394
    rsa->hash_alg = opt->hash_alg;
395
    rsa->akcipher.driver = &nettle_rsa;
396
    rsa_public_key_init(&rsa->pub);
397
    rsa_private_key_init(&rsa->priv);
398

399
    switch (type) {
400
    case QCRYPTO_AKCIPHER_KEY_TYPE_PRIVATE:
401
        if (qcrypt_nettle_parse_rsa_private_key(rsa, key, keylen, errp) != 0) {
402
            goto error;
403
        }
404
        break;
405

406
    case QCRYPTO_AKCIPHER_KEY_TYPE_PUBLIC:
407
        if (qcrypt_nettle_parse_rsa_public_key(rsa, key, keylen, errp) != 0) {
408
            goto error;
409
        }
410
        break;
411

412
    default:
413
        error_setg(errp, "Unknown akcipher key type %d", type);
414
        goto error;
415
    }
416

417
    return (QCryptoAkCipher *)rsa;
418

419
error:
420
    qcrypto_nettle_rsa_free((QCryptoAkCipher *)rsa);
421
    return NULL;
422
}
423

424

425
bool qcrypto_akcipher_supports(QCryptoAkCipherOptions *opts)
426
{
427
    switch (opts->alg) {
428
    case QCRYPTO_AKCIPHER_ALG_RSA:
429
        switch (opts->u.rsa.padding_alg) {
430
        case QCRYPTO_RSA_PADDING_ALG_PKCS1:
431
            switch (opts->u.rsa.hash_alg) {
432
            case QCRYPTO_HASH_ALG_MD5:
433
            case QCRYPTO_HASH_ALG_SHA1:
434
            case QCRYPTO_HASH_ALG_SHA256:
435
            case QCRYPTO_HASH_ALG_SHA512:
436
                return true;
437

438
            default:
439
                return false;
440
            }
441

442
        case QCRYPTO_RSA_PADDING_ALG_RAW:
443
        default:
444
            return false;
445
        }
446
        break;
447

448
    default:
449
        return false;
450
    }
451
}
452

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.