Skip to content

Commit 402ebec

Browse files
committed
linuxkm rsa: comments, cleanup work buffer useage.
1 parent 5410488 commit 402ebec

1 file changed

Lines changed: 91 additions & 80 deletions

File tree

linuxkm/lkcapi_rsa_glue.c

Lines changed: 91 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,6 +1031,20 @@ static int km_pkcs1_sha3_512_init(struct tfm_type *tfm)
10311031
#endif /* WOLFSSL_SHA3 */
10321032

10331033
#if !defined(LINUXKM_AKCIPHER_NO_SIGNVERIFY)
1034+
/*
1035+
* Generates a pkcs1 encoded signature.
1036+
*
1037+
* src:
1038+
* - req->src scatterlist is the digest to be encoded, padded, and signed.
1039+
* - req->src_len + encoding + min padding must be <= key_size.
1040+
*
1041+
* dst:
1042+
* - req->dst scatterlist is destination signature.
1043+
* - req->dst_len must be >= key_len size.
1044+
*
1045+
* See kernel (6.12 or earlier):
1046+
* - include/crypto/akcipher.h
1047+
*/
10341048
static int km_pkcs1pad_sign(struct akcipher_request *req)
10351049
{
10361050
struct crypto_akcipher * tfm = NULL;
@@ -1041,6 +1055,7 @@ static int km_pkcs1pad_sign(struct akcipher_request *req)
10411055
int hash_enc_len = 0;
10421056
byte * msg = NULL;
10431057
byte * sig = NULL;
1058+
byte * work_buffer = NULL;
10441059

10451060
if (req->src == NULL || req->dst == NULL) {
10461061
err = -EINVAL;
@@ -1072,22 +1087,17 @@ static int km_pkcs1pad_sign(struct akcipher_request *req)
10721087
goto pkcs1pad_sign_out;
10731088
}
10741089

1075-
/* allocate extra space for encoding. */
1076-
msg = malloc(ctx->key_len);
1077-
if (unlikely(msg == NULL)) {
1090+
work_buffer = malloc(2 * ctx->key_len);
1091+
if (unlikely(work_buffer == NULL)) {
10781092
err = -ENOMEM;
10791093
goto pkcs1pad_sign_out;
10801094
}
10811095

1082-
sig = malloc(ctx->key_len);
1083-
if (unlikely(sig == NULL)) {
1084-
err = -ENOMEM;
1085-
goto pkcs1pad_sign_out;
1086-
}
1096+
memset(work_buffer, 0, 2 * ctx->key_len);
1097+
msg = work_buffer;
1098+
sig = work_buffer + ctx->key_len;
10871099

10881100
/* copy req->src to msg */
1089-
memset(msg, 0, ctx->key_len);
1090-
memset(sig, 0, ctx->key_len);
10911101
scatterwalk_map_and_copy(msg, req->src, 0, req->src_len, 0);
10921102

10931103
/* encode message with hash oid. */
@@ -1118,8 +1128,7 @@ static int km_pkcs1pad_sign(struct akcipher_request *req)
11181128

11191129
err = 0;
11201130
pkcs1pad_sign_out:
1121-
if (msg != NULL) { free(msg); msg = NULL; }
1122-
if (sig != NULL) { free(sig); sig = NULL; }
1131+
if (work_buffer != NULL) { free(work_buffer); work_buffer = NULL; }
11231132

11241133
#ifdef WOLFKM_DEBUG_RSA
11251134
pr_info("info: exiting km_pkcs1pad_sign msg_len %d, enc_msg_len %d,"
@@ -1137,7 +1146,7 @@ static int km_pkcs1pad_sign(struct akcipher_request *req)
11371146
* - dst_len: digest
11381147
*
11391148
* dst should be null.
1140-
* See kernel:
1149+
* See kernel (6.12 or earlier):
11411150
* - include/crypto/akcipher.h
11421151
*/
11431152
static int km_pkcs1pad_verify(struct akcipher_request *req)
@@ -1153,10 +1162,11 @@ static int km_pkcs1pad_verify(struct akcipher_request *req)
11531162
int n_diff = 0;
11541163
byte * sig = NULL;
11551164
byte * msg = NULL;
1165+
byte * work_buffer = NULL;
11561166

11571167
if (req->src == NULL || req->dst != NULL) {
11581168
err = -EINVAL;
1159-
goto pkcs1_verify_out;
1169+
goto pkcs1pad_verify_out;
11601170
}
11611171

11621172
tfm = crypto_akcipher_reqtfm(req);
@@ -1168,7 +1178,7 @@ static int km_pkcs1pad_verify(struct akcipher_request *req)
11681178
if (ctx->key_len <= 0 || ctx->digest_len <= 0) {
11691179
/* invalid key state */
11701180
err = -EINVAL;
1171-
goto pkcs1_verify_out;
1181+
goto pkcs1pad_verify_out;
11721182
}
11731183

11741184
hash_enc_len = get_hash_enc_len(ctx->hash_oid);
@@ -1178,7 +1188,7 @@ static int km_pkcs1pad_verify(struct akcipher_request *req)
11781188
WOLFKM_RSA_DRIVER, hash_enc_len);
11791189
#endif /* WOLFKM_DEBUG_RSA */
11801190
err = -EINVAL;
1181-
goto pkcs1_verify_out;
1191+
goto pkcs1pad_verify_out;
11821192
}
11831193

11841194
if (msg_len != ctx->digest_len || sig_len != ctx->key_len) {
@@ -1188,25 +1198,20 @@ static int km_pkcs1pad_verify(struct akcipher_request *req)
11881198
WOLFKM_RSA_DRIVER, msg_len, ctx->digest_len);
11891199
#endif /* WOLFKM_DEBUG_RSA */
11901200
err = -EINVAL;
1191-
goto pkcs1_verify_out;
1201+
goto pkcs1pad_verify_out;
11921202
}
11931203

1194-
sig = malloc(ctx->key_len);
1195-
if (unlikely(sig == NULL)) {
1204+
work_buffer = malloc(2 * ctx->key_len);
1205+
if (unlikely(work_buffer == NULL)) {
11961206
err = -ENOMEM;
1197-
goto pkcs1_verify_out;
1207+
goto pkcs1pad_verify_out;
11981208
}
11991209

1200-
/* allocate extra space for encoding. */
1201-
msg = malloc(ctx->key_len);
1202-
if (unlikely(msg == NULL)) {
1203-
err = -ENOMEM;
1204-
goto pkcs1_verify_out;
1205-
}
1210+
memset(work_buffer, 0, 2 * ctx->key_len);
1211+
msg = work_buffer;
1212+
sig = work_buffer + ctx->key_len;
12061213

12071214
/* copy sig from req->src to sig */
1208-
memset(sig, 0, ctx->key_len);
1209-
memset(msg, 0, ctx->key_len);
12101215
scatterwalk_map_and_copy(sig, req->src, 0, sig_len, 0);
12111216

12121217
/* verify encoded message. */
@@ -1217,7 +1222,7 @@ static int km_pkcs1pad_verify(struct akcipher_request *req)
12171222
WOLFKM_RSA_DRIVER, dec_len);
12181223
#endif /* WOLFKM_DEBUG_RSA */
12191224
err = -EBADMSG;
1220-
goto pkcs1_verify_out;
1225+
goto pkcs1pad_verify_out;
12211226
}
12221227

12231228
/* reuse sig array for digest comparison */
@@ -1228,19 +1233,18 @@ static int km_pkcs1pad_verify(struct akcipher_request *req)
12281233
enc_msg_len = wc_EncodeSignature(sig, sig, msg_len, ctx->hash_oid);
12291234
if (unlikely(enc_msg_len <= 0 || enc_msg_len != dec_len)) {
12301235
err = -EINVAL;
1231-
goto pkcs1_verify_out;
1236+
goto pkcs1pad_verify_out;
12321237
}
12331238

12341239
n_diff = memcmp(sig, msg, dec_len);
12351240
if (unlikely(n_diff != 0)) {
12361241
err = -EKEYREJECTED;
1237-
goto pkcs1_verify_out;
1242+
goto pkcs1pad_verify_out;
12381243
}
12391244

12401245
err = 0;
1241-
pkcs1_verify_out:
1242-
if (msg != NULL) { free(msg); msg = NULL; }
1243-
if (sig != NULL) { free(sig); sig = NULL; }
1246+
pkcs1pad_verify_out:
1247+
if (work_buffer != NULL) { free(work_buffer); work_buffer = NULL; }
12441248

12451249
#ifdef WOLFKM_DEBUG_RSA
12461250
pr_info("info: exiting km_pkcs1pad_verify msg_len %d, enc_msg_len %d,"
@@ -1266,17 +1270,32 @@ static unsigned int km_pkcs1_key_size(struct crypto_sig *tfm)
12661270
return (unsigned int) ctx->key_len;
12671271
}
12681272

1273+
/*
1274+
* Generates a pkcs1 encoded signature.
1275+
*
1276+
* src:
1277+
* - src contains the digest to be encoded, padded, and signed.
1278+
* - slen + encoding + min padding must be <= key_size.
1279+
*
1280+
* dst:
1281+
* - dst is destination signature buffer.
1282+
* - dlen must be >= key_len size.
1283+
*
1284+
* See kernel (6.13 or later):
1285+
* - include/crypto/sig.h
1286+
*/
12691287
static int km_pkcs1_sign(struct crypto_sig *tfm,
12701288
const void *src, unsigned int slen,
12711289
void *dst, unsigned int dlen)
12721290
{
12731291
struct km_rsa_ctx * ctx = NULL;
12741292
int err = 0;
12751293
word32 sig_len = 0;
1276-
word32 enc_len = 0;
1294+
word32 enc_msg_len = 0;
12771295
int hash_enc_len = 0;
12781296
byte * msg = NULL;
1279-
byte * sig = NULL;
1297+
byte * sig = dst; /* reuse dst buffer. we will check if
1298+
* it is large enough. */
12801299

12811300
if (src == NULL || dst == NULL) {
12821301
err = -EINVAL;
@@ -1314,30 +1333,24 @@ static int km_pkcs1_sign(struct crypto_sig *tfm,
13141333
goto pkcs1_sign_out;
13151334
}
13161335

1317-
sig = malloc(ctx->key_len);
1318-
if (unlikely(sig == NULL)) {
1319-
err = -ENOMEM;
1320-
goto pkcs1_sign_out;
1321-
}
1322-
1323-
/* copy src to msg */
1336+
/* copy src to msg, and clear buffers. */
13241337
memset(msg, 0, ctx->key_len);
13251338
memset(sig, 0, ctx->key_len);
1326-
memmove(msg, src, slen);
1339+
memcpy(msg, src, slen);
13271340

13281341
/* encode message with hash oid. */
1329-
enc_len = wc_EncodeSignature(msg, msg, slen, ctx->hash_oid);
1330-
if (unlikely(enc_len <= 0)) {
1342+
enc_msg_len = wc_EncodeSignature(msg, msg, slen, ctx->hash_oid);
1343+
if (unlikely(enc_msg_len <= 0)) {
13311344
#ifdef WOLFKM_DEBUG_RSA
13321345
pr_err("error: %s: wc_EncodeSignature returned: %d\n",
1333-
WOLFKM_RSA_DRIVER, enc_len);
1346+
WOLFKM_RSA_DRIVER, enc_msg_len);
13341347
#endif /* WOLFKM_DEBUG_RSA */
13351348
err = -EINVAL;
13361349
goto pkcs1_sign_out;
13371350
}
13381351

13391352
/* sign encoded message. */
1340-
sig_len = wc_RsaSSL_Sign(msg, enc_len, sig,
1353+
sig_len = wc_RsaSSL_Sign(msg, enc_msg_len, sig,
13411354
ctx->key_len, ctx->key, &ctx->rng);
13421355
if (unlikely(sig_len != ctx->key_len)) {
13431356
#ifdef WOLFKM_DEBUG_RSA
@@ -1348,26 +1361,34 @@ static int km_pkcs1_sign(struct crypto_sig *tfm,
13481361
goto pkcs1_sign_out;
13491362
}
13501363

1351-
/* copy sig to dst */
1352-
memmove(dst, sig, ctx->key_len);
1353-
13541364
err = 0;
13551365
pkcs1_sign_out:
13561366
if (msg != NULL) { free(msg); msg = NULL; }
1357-
if (sig != NULL) { free(sig); sig = NULL; }
13581367

13591368
#ifdef WOLFKM_DEBUG_RSA
13601369
pr_info("info: exiting km_pkcs1_sign msg_len %d, enc_msg_len %d,"
1361-
" sig_len %d, err %d", slen, enc_len, sig_len, err);
1370+
" sig_len %d, err %d", slen, enc_msg_len, sig_len, err);
13621371
#endif /* WOLFKM_DEBUG_RSA */
13631372

13641373
return err;
1365-
1366-
return 0;
13671374
}
13681375

1376+
/*
1377+
* Verify a pkcs1 encoded signature.
1378+
*
1379+
* src:
1380+
* - src contains the signature.
1381+
* - slen must == key_size
1382+
*
1383+
* digest:
1384+
* - the digest that was encoded, padded, and signed previously.
1385+
* - dlen must be the correct digest len.
1386+
*
1387+
* See kernel (6.13 or later):
1388+
* - include/crypto/sig.h
1389+
*/
13691390
static int km_pkcs1_verify(struct crypto_sig *tfm,
1370-
const void *src_v, unsigned int slen,
1391+
const void *src, unsigned int slen,
13711392
const void *digest, unsigned int dlen)
13721393
{
13731394
struct km_rsa_ctx * ctx = NULL;
@@ -1378,9 +1399,9 @@ static int km_pkcs1_verify(struct crypto_sig *tfm,
13781399
word32 enc_msg_len = 0;
13791400
int hash_enc_len = 0;
13801401
int n_diff = 0;
1381-
byte * sig = NULL;
1402+
byte * enc_digest = NULL;
13821403
byte * msg = NULL;
1383-
const u8 * src = src_v;
1404+
byte * work_buffer = NULL;
13841405

13851406
if (src == NULL || digest == NULL) {
13861407
err = -EINVAL;
@@ -1418,26 +1439,18 @@ static int km_pkcs1_verify(struct crypto_sig *tfm,
14181439
goto pkcs1_verify_out;
14191440
}
14201441

1421-
sig = malloc(ctx->key_len);
1422-
if (unlikely(sig == NULL)) {
1442+
work_buffer = malloc(2 * ctx->key_len);
1443+
if (unlikely(work_buffer == NULL)) {
14231444
err = -ENOMEM;
14241445
goto pkcs1_verify_out;
14251446
}
14261447

1427-
/* allocate extra space for encoding. */
1428-
msg = malloc(ctx->key_len);
1429-
if (unlikely(msg == NULL)) {
1430-
err = -ENOMEM;
1431-
goto pkcs1_verify_out;
1432-
}
1448+
memset(work_buffer, 0, 2 * ctx->key_len);
1449+
msg = work_buffer;
1450+
enc_digest = work_buffer + ctx->key_len;
14331451

1434-
/* copy sig from src to sig */
1435-
memset(sig, 0, ctx->key_len);
1436-
memset(msg, 0, ctx->key_len);
1437-
memmove(sig, src, sig_len);
1438-
1439-
/* verify encoded message. */
1440-
dec_len = wc_RsaSSL_Verify(sig, sig_len, msg, sig_len, ctx->key);
1452+
/* verify encoded message. msg contains recovered original message. */
1453+
dec_len = wc_RsaSSL_Verify(src, sig_len, msg, sig_len, ctx->key);
14411454
if (unlikely(dec_len <= 0)) {
14421455
#ifdef WOLFKM_DEBUG_RSA
14431456
pr_err("error: %s: wc_RsaSSL_Verify returned: %d\n",
@@ -1447,18 +1460,17 @@ static int km_pkcs1_verify(struct crypto_sig *tfm,
14471460
goto pkcs1_verify_out;
14481461
}
14491462

1450-
/* reuse sig array for digest comparison */
1451-
memset(sig, 0, ctx->key_len);
1452-
memmove(sig, digest, msg_len);
1463+
memcpy(enc_digest, digest, msg_len);
14531464

14541465
/* encode digest with hash oid. */
1455-
enc_msg_len = wc_EncodeSignature(sig, sig, msg_len, ctx->hash_oid);
1466+
enc_msg_len = wc_EncodeSignature(enc_digest, enc_digest, msg_len,
1467+
ctx->hash_oid);
14561468
if (unlikely(enc_msg_len <= 0 || enc_msg_len != dec_len)) {
14571469
err = -EINVAL;
14581470
goto pkcs1_verify_out;
14591471
}
14601472

1461-
n_diff = memcmp(sig, msg, enc_msg_len);
1473+
n_diff = memcmp(enc_digest, msg, enc_msg_len);
14621474
if (unlikely(n_diff != 0)) {
14631475
#ifdef WOLFKM_DEBUG_RSA
14641476
pr_err("error: %s: recovered msg did not match digest: %d\n",
@@ -1470,8 +1482,7 @@ static int km_pkcs1_verify(struct crypto_sig *tfm,
14701482

14711483
err = 0;
14721484
pkcs1_verify_out:
1473-
if (msg != NULL) { free(msg); msg = NULL; }
1474-
if (sig != NULL) { free(sig); sig = NULL; }
1485+
if (work_buffer != NULL) { free(work_buffer); work_buffer = NULL; }
14751486

14761487
#ifdef WOLFKM_DEBUG_RSA
14771488
pr_info("info: exiting km_pkcs1_verify msg_len %d, enc_msg_len %d,"

0 commit comments

Comments
 (0)