Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

crypto: rsassa-pkcs1 - Avoid copying hash prefix

When constructing the EMSA-PKCS1-v1_5 padding for the sign operation,
a buffer for the padding is allocated and the Full Hash Prefix is copied
into it. The padding is then passed to the RSA decrypt operation as an
sglist entry which is succeeded by a second sglist entry for the hash.

Actually copying the hash prefix around is completely unnecessary.
It can simply be referenced from a third sglist entry which sits
in-between the padding and the digest.

Signed-off-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Lukas Wunner and committed by
Herbert Xu
778206d8 5e00481b

+10 -8
+10 -8
crypto/rsassa-pkcs1.c
··· 153 153 struct rsassa_pkcs1_ctx *ctx = crypto_sig_ctx(tfm); 154 154 unsigned int child_reqsize = crypto_akcipher_reqsize(ctx->child); 155 155 struct akcipher_request *child_req __free(kfree_sensitive) = NULL; 156 - struct scatterlist in_sg[2], out_sg; 156 + struct scatterlist in_sg[3], out_sg; 157 157 struct crypto_wait cwait; 158 158 unsigned int pad_len; 159 159 unsigned int ps_end; ··· 173 173 if (slen + hash_prefix->size > ctx->key_size - 11) 174 174 return -EOVERFLOW; 175 175 176 - child_req = kmalloc(sizeof(*child_req) + child_reqsize + 177 - ctx->key_size - 1 - slen, GFP_KERNEL); 176 + pad_len = ctx->key_size - slen - hash_prefix->size - 1; 177 + 178 + child_req = kmalloc(sizeof(*child_req) + child_reqsize + pad_len, 179 + GFP_KERNEL); 178 180 if (!child_req) 179 181 return -ENOMEM; 180 182 181 183 /* RFC 8017 sec 8.2.1 step 1 - EMSA-PKCS1-v1_5 encoding generation */ 182 184 in_buf = (u8 *)(child_req + 1) + child_reqsize; 183 - ps_end = ctx->key_size - hash_prefix->size - slen - 2; 185 + ps_end = pad_len - 1; 184 186 in_buf[0] = 0x01; 185 187 memset(in_buf + 1, 0xff, ps_end - 1); 186 188 in_buf[ps_end] = 0x00; 187 - memcpy(in_buf + ps_end + 1, hash_prefix->data, hash_prefix->size); 188 189 189 190 /* RFC 8017 sec 8.2.1 step 2 - RSA signature */ 190 191 crypto_init_wait(&cwait); 191 - sg_init_table(in_sg, 2); 192 - sg_set_buf(&in_sg[0], in_buf, ctx->key_size - 1 - slen); 193 - sg_set_buf(&in_sg[1], src, slen); 192 + sg_init_table(in_sg, 3); 193 + sg_set_buf(&in_sg[0], in_buf, pad_len); 194 + sg_set_buf(&in_sg[1], hash_prefix->data, hash_prefix->size); 195 + sg_set_buf(&in_sg[2], src, slen); 194 196 sg_init_one(&out_sg, dst, dlen); 195 197 akcipher_request_set_tfm(child_req, ctx->child); 196 198 akcipher_request_set_crypt(child_req, in_sg, &out_sg,