* [PATCH 0/2] crytpo: rsa - use mpi sgl helpers
@ 2015-09-23 22:48 Tadeusz Struk
2015-09-23 22:48 ` [PATCH 1/2] lib/mpi: Add " Tadeusz Struk
2015-09-23 22:49 ` [PATCH 2/2] crytpo: rsa - use mpi slg helpers to import and export data Tadeusz Struk
0 siblings, 2 replies; 3+ messages in thread
From: Tadeusz Struk @ 2015-09-23 22:48 UTC (permalink / raw)
To: herbert; +Cc: linux-crypto, tadeusz.struk
This series introduces new mpi helpers to read from and
write to an sgl without a need of using an intermediate
flat buffer.
First patch adds helpers to mpi library.
Second patch changes rsa implementation to use the new
functions.
This is an incremental patch series on top of these two:
https://patchwork.kernel.org/patch/7241041/
https://patchwork.kernel.org/patch/7241051/
A simple test for the new helpers can be found here:
https://github.com/tstruk/mpi_sgl_test/blob/master/test.c
---
Tadeusz Struk (2):
lib/mpi: Add mpi sgl helpers
crytpo: rsa - use mpi slg helpers to import and export data
crypto/rsa.c | 110 ++----------------------------
include/linux/mpi.h | 4 +
lib/mpi/mpicoder.c | 186 +++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 198 insertions(+), 102 deletions(-)
--
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH 1/2] lib/mpi: Add mpi sgl helpers
2015-09-23 22:48 [PATCH 0/2] crytpo: rsa - use mpi sgl helpers Tadeusz Struk
@ 2015-09-23 22:48 ` Tadeusz Struk
2015-09-23 22:49 ` [PATCH 2/2] crytpo: rsa - use mpi slg helpers to import and export data Tadeusz Struk
1 sibling, 0 replies; 3+ messages in thread
From: Tadeusz Struk @ 2015-09-23 22:48 UTC (permalink / raw)
To: herbert; +Cc: linux-crypto, tadeusz.struk
Add mpi_read_raw_from_sgl and mpi_write_to_sgl helpers.
Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
---
include/linux/mpi.h | 4 +
lib/mpi/mpicoder.c | 189 +++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 193 insertions(+)
diff --git a/include/linux/mpi.h b/include/linux/mpi.h
index 641b7d6..68278b3 100644
--- a/include/linux/mpi.h
+++ b/include/linux/mpi.h
@@ -31,6 +31,7 @@
#define G10_MPI_H
#include <linux/types.h>
+#include <linux/scatterlist.h>
/* DSI defines */
@@ -78,6 +79,7 @@ void mpi_swap(MPI a, MPI b);
MPI do_encode_md(const void *sha_buffer, unsigned nbits);
MPI mpi_read_raw_data(const void *xbuffer, size_t nbytes);
MPI mpi_read_from_buffer(const void *buffer, unsigned *ret_nread);
+MPI mpi_read_raw_from_sgl(struct scatterlist *sgl);
int mpi_fromstr(MPI val, const char *str);
u32 mpi_get_keyid(MPI a, u32 *keyid);
void *mpi_get_buffer(MPI a, unsigned *nbytes, int *sign);
@@ -85,6 +87,8 @@ int mpi_read_buffer(MPI a, uint8_t *buf, unsigned buf_len, unsigned *nbytes,
int *sign);
void *mpi_get_secure_buffer(MPI a, unsigned *nbytes, int *sign);
int mpi_set_buffer(MPI a, const void *buffer, unsigned nbytes, int sign);
+int mpi_write_to_sgl(MPI a, struct scatterlist *sg, unsigned *nbytes,
+ int *sign);
#define log_mpidump g10_log_mpidump
diff --git a/lib/mpi/mpicoder.c b/lib/mpi/mpicoder.c
index 95c52a9..455a59a 100644
--- a/lib/mpi/mpicoder.c
+++ b/lib/mpi/mpicoder.c
@@ -319,3 +319,192 @@ int mpi_set_buffer(MPI a, const void *xbuffer, unsigned nbytes, int sign)
return 0;
}
EXPORT_SYMBOL_GPL(mpi_set_buffer);
+
+/**
+ * mpi_write_to_sgl() - Funnction exports MPI to an sgl (msb first)
+ *
+ * This function works in the same way as the mpi_read_buffer, but it
+ * takes an sgl instead of u8 * buf.
+ *
+ * @a: a multi precision integer
+ * @sgl: scatterlist to write to. Needs to be at least
+ * mpi_get_size(a) long.
+ * @nbytes: receives the actual length of the data written.
+ * @sign: if not NULL, it will be set to the sign of a.
+ *
+ * Return: 0 on success or error code in case of error
+ */
+int mpi_write_to_sgl(MPI a, struct scatterlist *sgl, unsigned *nbytes,
+ int *sign)
+{
+ u8 *p, *p2;
+ mpi_limb_t alimb, alimb2;
+ unsigned int n = mpi_get_size(a), sglen = sg_len(sgl);
+ int i, x, y = 0, lzeros = 0, buf_len;
+
+ if (sglen < n || !nbytes)
+ return -EINVAL;
+
+ if (sign)
+ *sign = a->sign;
+
+ p = (void *)&a->d[a->nlimbs] - 1;
+
+ for (i = a->nlimbs * sizeof(alimb) - 1; i >= 0; i--, p--) {
+ if (!*p)
+ lzeros++;
+ else
+ break;
+ }
+
+ *nbytes = n - lzeros;
+ buf_len = sgl->length;
+ p2 = sg_virt(sgl);
+
+ for (i = a->nlimbs - 1; i >= 0; i--) {
+ alimb = a->d[i];
+ p = (u8 *)&alimb2;
+#if BYTES_PER_MPI_LIMB == 4
+ *p++ = alimb >> 24;
+ *p++ = alimb >> 16;
+ *p++ = alimb >> 8;
+ *p++ = alimb;
+#elif BYTES_PER_MPI_LIMB == 8
+ *p++ = alimb >> 56;
+ *p++ = alimb >> 48;
+ *p++ = alimb >> 40;
+ *p++ = alimb >> 32;
+ *p++ = alimb >> 24;
+ *p++ = alimb >> 16;
+ *p++ = alimb >> 8;
+ *p++ = alimb;
+#else
+#error please implement for this limb size.
+#endif
+ if (lzeros > 0) {
+ if (lzeros >= sizeof(alimb)) {
+ p -= sizeof(alimb);
+ continue;
+ } else {
+ mpi_limb_t *limb1 = (void *)p - sizeof(alimb);
+ mpi_limb_t *limb2 = (void *)p - sizeof(alimb)
+ + lzeros;
+ *limb1 = *limb2;
+ p -= lzeros;
+ y = lzeros;
+ }
+ lzeros -= sizeof(alimb);
+ }
+
+ p = p - (sizeof(alimb) - y);
+
+ for (x = 0; x < sizeof(alimb) - y; x++) {
+ if (!buf_len) {
+ sgl = sg_next(sgl);
+ buf_len = sgl->length;
+ p2 = sg_virt(sgl);
+ }
+ *p2++ = *p++;
+ buf_len--;
+ }
+ y = 0;
+ }
+ return 0;
+}
+EXPORT_SYMBOL_GPL(mpi_write_to_sgl);
+
+/*
+ * mpi_read_raw_from_sgl() - Function allocates an MPI and populates it with
+ * data from the sgl
+ *
+ * This function works in the same way as the mpi_read_raw_data, but it
+ * takes an sgl instead of void * buffer. i.e. it allocates
+ * a new MPI and reads the content of the sgl to the MPI.
+ *
+ * @sgl: scatterlist to read from
+ *
+ * Return: Pointer to a new MPI or NULL on error
+ */
+MPI mpi_read_raw_from_sgl(struct scatterlist *sgl)
+{
+ struct scatterlist *sg;
+ int x, i, j, z, lzeros, ents;
+ unsigned int nbits, nlimbs, nbytes;
+ mpi_limb_t a;
+ MPI val = NULL;
+
+ lzeros = 0;
+ ents = sg_nents(sgl);
+ for_each_sg(sgl, sg, ents, i) {
+ const u8 *buff = sg_virt(sg);
+ int len = sg->length;
+
+ while (len-- && !*buff++)
+ lzeros++;
+
+ if (len && *buff)
+ break;
+
+ ents--;
+ lzeros = 0;
+ }
+
+ sgl = sg;
+
+ if (!ents)
+ nbytes = 0;
+ else
+ nbytes = sg_len(sgl) - lzeros;
+
+ nbits = nbytes * 8;
+ if (nbits > MAX_EXTERN_MPI_BITS) {
+ pr_info("MPI: mpi too large (%u bits)\n", nbits);
+ return NULL;
+ }
+
+ if (nbytes > 0)
+ nbits -= count_leading_zeros(*(u8 *)(sg_virt(sgl) + lzeros));
+ else
+ nbits = 0;
+
+ nlimbs = DIV_ROUND_UP(nbytes, BYTES_PER_MPI_LIMB);
+ val = mpi_alloc(nlimbs);
+ if (!val)
+ return NULL;
+
+ val->nbits = nbits;
+ val->sign = 0;
+ val->nlimbs = nlimbs;
+
+ if (nbytes <= 0)
+ return val;
+
+ j = nlimbs - 1;
+ a = 0;
+ z = 0;
+ x = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
+ x %= BYTES_PER_MPI_LIMB;
+
+ for_each_sg(sgl, sg, ents, i) {
+ const u8 *buffer = sg_virt(sg) + lzeros;
+ int len = sg->length - lzeros;
+ int buf_shift = x;
+
+ if (sg_is_last(sg) && (len % BYTES_PER_MPI_LIMB))
+ len += BYTES_PER_MPI_LIMB - (len % BYTES_PER_MPI_LIMB);
+
+ for (;x < len + buf_shift; x++) {
+ a <<= 8;
+ a |= *buffer++;
+ if (((z + x + 1) % BYTES_PER_MPI_LIMB) == 0) {
+ val->d[j--] = a;
+ a = 0;
+ }
+ }
+ z += x;
+ x = 0;
+ lzeros = 0;
+ }
+ return val;
+}
+EXPORT_SYMBOL_GPL(mpi_read_raw_from_sgl);
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH 2/2] crytpo: rsa - use mpi slg helpers to import and export data
2015-09-23 22:48 [PATCH 0/2] crytpo: rsa - use mpi sgl helpers Tadeusz Struk
2015-09-23 22:48 ` [PATCH 1/2] lib/mpi: Add " Tadeusz Struk
@ 2015-09-23 22:49 ` Tadeusz Struk
1 sibling, 0 replies; 3+ messages in thread
From: Tadeusz Struk @ 2015-09-23 22:49 UTC (permalink / raw)
To: herbert; +Cc: linux-crypto, tadeusz.struk
Use the new mpi_write_to_sgl and mpi_read_raw_from_sgl helpers
to import and export data.
Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
---
crypto/rsa.c | 127 +++++-----------------------------------------------------
1 file changed, 12 insertions(+), 115 deletions(-)
diff --git a/crypto/rsa.c b/crypto/rsa.c
index df81bbf..ce293d3 100644
--- a/crypto/rsa.c
+++ b/crypto/rsa.c
@@ -13,7 +13,6 @@
#include <crypto/internal/rsa.h>
#include <crypto/internal/akcipher.h>
#include <crypto/akcipher.h>
-#include <crypto/scatterwalk.h>
/*
* RSAEP function [RFC3447 sec 5.1.1]
@@ -100,18 +99,7 @@ static int rsa_enc(struct akcipher_request *req)
}
ret = -ENOMEM;
- if (sg_is_last(req->src)) {
- m = mpi_read_raw_data(sg_virt(req->src), src_len);
- } else {
- void *ptr = kmalloc(src_len, GFP_KERNEL);
-
- if (!ptr)
- goto err_free_c;
-
- scatterwalk_map_and_copy(ptr, req->src, 0, src_len, 0);
- m = mpi_read_raw_data(ptr, src_len);
- kfree(ptr);
- }
+ m = mpi_read_raw_from_sgl(req->src);
if (!m)
goto err_free_c;
@@ -119,26 +107,12 @@ static int rsa_enc(struct akcipher_request *req)
if (ret)
goto err_free_m;
- if (sg_is_last(req->dst)) {
- ret = mpi_read_buffer(c, sg_virt(req->dst), dst_len,
- &req->out_len, &sign);
- } else {
- void *ptr = kmalloc(dst_len, GFP_KERNEL);
-
- if (!ptr)
- goto err_free_m;
-
- ret = mpi_read_buffer(c, ptr, dst_len, &req->out_len, &sign);
- scatterwalk_map_and_copy(ptr, req->dst, 0, dst_len, 1);
- kfree(ptr);
- }
+ ret = mpi_write_to_sgl(c, req->dst, &req->out_len, &sign);
if (ret)
goto err_free_m;
- if (sign < 0) {
+ if (sign < 0)
ret = -EBADMSG;
- goto err_free_m;
- }
err_free_m:
mpi_free(m);
@@ -171,18 +145,7 @@ static int rsa_dec(struct akcipher_request *req)
}
ret = -ENOMEM;
- if (sg_is_last(req->src)) {
- c = mpi_read_raw_data(sg_virt(req->src), src_len);
- } else {
- void *ptr = kmalloc(src_len, GFP_KERNEL);
-
- if (!ptr)
- goto err_free_m;
-
- scatterwalk_map_and_copy(ptr, req->src, 0, src_len, 0);
- c = mpi_read_raw_data(ptr, src_len);
- kfree(ptr);
- }
+ c = mpi_read_raw_from_sgl(req->src);
if (!c)
goto err_free_m;
@@ -190,27 +153,12 @@ static int rsa_dec(struct akcipher_request *req)
if (ret)
goto err_free_c;
- if (sg_is_last(req->dst)) {
- ret = mpi_read_buffer(m, sg_virt(req->dst), dst_len,
- &req->out_len, &sign);
- } else {
- void *ptr = kmalloc(dst_len, GFP_KERNEL);
-
- if (!ptr)
- goto err_free_c;
-
- ret = mpi_read_buffer(m, ptr, dst_len, &req->out_len, &sign);
- scatterwalk_map_and_copy(ptr, req->dst, 0, dst_len, 1);
- kfree(ptr);
- }
+ ret = mpi_write_to_sgl(m, req->dst, &req->out_len, &sign);
if (ret)
goto err_free_c;
- if (sign < 0) {
+ if (sign < 0)
ret = -EBADMSG;
- goto err_free_c;
- }
-
err_free_c:
mpi_free(c);
err_free_m:
@@ -242,19 +190,7 @@ static int rsa_sign(struct akcipher_request *req)
}
ret = -ENOMEM;
- if (sg_is_last(req->src)) {
- m = mpi_read_raw_data(sg_virt(req->src), src_len);
- } else {
- void *ptr = kmalloc(src_len, GFP_KERNEL);
-
- if (!ptr)
- goto err_free_s;
-
- scatterwalk_map_and_copy(ptr, req->src, 0, src_len, 0);
- m = mpi_read_raw_data(ptr, src_len);
- kfree(ptr);
-
- }
+ m = mpi_read_raw_from_sgl(req->src);
if (!m)
goto err_free_s;
@@ -262,26 +198,12 @@ static int rsa_sign(struct akcipher_request *req)
if (ret)
goto err_free_m;
- if (sg_is_last(req->dst)) {
- ret = mpi_read_buffer(s, sg_virt(req->dst), dst_len,
- &req->out_len, &sign);
- } else {
- void *ptr = kmalloc(dst_len, GFP_KERNEL);
-
- if (!ptr)
- goto err_free_m;
-
- ret = mpi_read_buffer(s, ptr, dst_len, &req->out_len, &sign);
- scatterwalk_map_and_copy(ptr, req->dst, 0, dst_len, 1);
- kfree(ptr);
- }
+ ret = mpi_write_to_sgl(s, req->dst, &req->out_len, &sign);
if (ret)
goto err_free_m;
- if (sign < 0) {
+ if (sign < 0)
ret = -EBADMSG;
- goto err_free_m;
- }
err_free_m:
mpi_free(m);
@@ -314,18 +236,7 @@ static int rsa_verify(struct akcipher_request *req)
}
ret = -ENOMEM;
- if (sg_is_last(req->src)) {
- s = mpi_read_raw_data(sg_virt(req->src), src_len);
- } else {
- void *ptr = kmalloc(src_len, GFP_KERNEL);
-
- if (!ptr)
- goto err_free_m;
-
- scatterwalk_map_and_copy(ptr, req->src, 0, src_len, 0);
- s = mpi_read_raw_data(ptr, src_len);
- kfree(ptr);
- }
+ s = mpi_read_raw_from_sgl(req->src);
if (!s) {
ret = -ENOMEM;
goto err_free_m;
@@ -335,26 +246,12 @@ static int rsa_verify(struct akcipher_request *req)
if (ret)
goto err_free_s;
- if (sg_is_last(req->dst)) {
- ret = mpi_read_buffer(m, sg_virt(req->dst), dst_len,
- &req->out_len, &sign);
- } else {
- void *ptr = kmalloc(dst_len, GFP_KERNEL);
-
- if (!ptr)
- goto err_free_s;
-
- ret = mpi_read_buffer(m, ptr, dst_len, &req->out_len, &sign);
- scatterwalk_map_and_copy(ptr, req->dst, 0, dst_len, 1);
- kfree(ptr);
- }
+ ret = mpi_write_to_sgl(m, req->dst, &req->out_len, &sign);
if (ret)
goto err_free_s;
- if (sign < 0) {
+ if (sign < 0)
ret = -EBADMSG;
- goto err_free_s;
- }
err_free_s:
mpi_free(s);
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2015-09-23 22:50 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-09-23 22:48 [PATCH 0/2] crytpo: rsa - use mpi sgl helpers Tadeusz Struk
2015-09-23 22:48 ` [PATCH 1/2] lib/mpi: Add " Tadeusz Struk
2015-09-23 22:49 ` [PATCH 2/2] crytpo: rsa - use mpi slg helpers to import and export data Tadeusz Struk
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox