Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F115687732
D24906.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D24906.diff
View Options
Index: head/share/man/man7/crypto.7
===================================================================
--- head/share/man/man7/crypto.7
+++ head/share/man/man7/crypto.7
@@ -27,7 +27,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd May 3, 2020
+.Dd May 22, 2020
.Dt CRYPTO 7
.Os
.Sh NAME
@@ -82,7 +82,7 @@
.It IV size :
16
.It Block size :
-1 (aesni), 16 (software)
+1
.It Key size :
16, 24 or 32
.El
Index: head/sys/crypto/chacha20/chacha-sw.c
===================================================================
--- head/sys/crypto/chacha20/chacha-sw.c
+++ head/sys/crypto/chacha20/chacha-sw.c
@@ -28,11 +28,11 @@
chacha20_xform_crypt(void *ctx, const uint8_t *in, uint8_t *out)
{
- chacha_encrypt_bytes(ctx, in, out, 1);
+ chacha_encrypt_bytes(ctx, in, out, CHACHA_BLOCKLEN);
}
static void
-chacha20_xform_crypt_multi(void *ctx, const uint8_t *in, uint8_t *out,
+chacha20_xform_crypt_last(void *ctx, const uint8_t *in, uint8_t *out,
size_t len)
{
@@ -44,6 +44,7 @@
.name = "chacha20",
.ctxsize = sizeof(struct chacha_ctx),
.blocksize = 1,
+ .native_blocksize = CHACHA_BLOCKLEN,
.ivsize = CHACHA_NONCELEN + CHACHA_CTRLEN,
.minkey = CHACHA_MINKEYLEN,
.maxkey = 32,
@@ -51,6 +52,6 @@
.decrypt = chacha20_xform_crypt,
.setkey = chacha20_xform_setkey,
.reinit = chacha20_xform_reinit,
- .encrypt_multi = chacha20_xform_crypt_multi,
- .decrypt_multi = chacha20_xform_crypt_multi,
+ .encrypt_last = chacha20_xform_crypt_last,
+ .decrypt_last = chacha20_xform_crypt_last,
};
Index: head/sys/opencrypto/cryptosoft.c
===================================================================
--- head/sys/opencrypto/cryptosoft.c
+++ head/sys/opencrypto/cryptosoft.c
@@ -117,13 +117,17 @@
sw = &ses->swcr_encdec;
exf = sw->sw_exf;
- blks = exf->blocksize;
ivlen = exf->ivsize;
- /* Check for non-padded data */
- if ((crp->crp_payload_length % blks) != 0)
- return EINVAL;
+ if (exf->native_blocksize == 0) {
+ /* Check for non-padded data */
+ if ((crp->crp_payload_length % exf->blocksize) != 0)
+ return (EINVAL);
+ blks = exf->blocksize;
+ } else
+ blks = exf->native_blocksize;
+
if (exf == &enc_xform_aes_icm &&
(crp->crp_flags & CRYPTO_F_IV_SEPARATE) == 0)
return (EINVAL);
@@ -182,7 +186,7 @@
i = crp->crp_payload_length;
encrypting = CRYPTO_OP_IS_ENCRYPT(crp->crp_op);
- while (i > 0) {
+ while (i >= blks) {
/*
* If there's insufficient data at the end of
* an iovec, we have to do some copying.
@@ -249,31 +253,18 @@
break;
}
- while (uio->uio_iov[ind].iov_len >= k + blks && i > 0) {
+ while (uio->uio_iov[ind].iov_len >= k + blks && i >= blks) {
uint8_t *idat;
- size_t nb, rem;
- nb = blks;
- rem = MIN((size_t)i,
- uio->uio_iov[ind].iov_len - (size_t)k);
idat = (uint8_t *)uio->uio_iov[ind].iov_base + k;
if (exf->reinit) {
- if (encrypting && exf->encrypt_multi == NULL)
+ if (encrypting)
exf->encrypt(sw->sw_kschedule,
idat, idat);
- else if (encrypting) {
- nb = rounddown(rem, blks);
- exf->encrypt_multi(sw->sw_kschedule,
- idat, idat, nb);
- } else if (exf->decrypt_multi == NULL)
+ else
exf->decrypt(sw->sw_kschedule,
idat, idat);
- else {
- nb = rounddown(rem, blks);
- exf->decrypt_multi(sw->sw_kschedule,
- idat, idat, nb);
- }
} else if (encrypting) {
/* XOR with previous block/IV */
for (j = 0; j < blks; j++)
@@ -298,9 +289,9 @@
ivp = nivp;
}
- count += nb;
- k += nb;
- i -= nb;
+ count += blks;
+ k += blks;
+ i -= blks;
}
/*
@@ -319,6 +310,25 @@
}
}
+ /* Handle trailing partial block for stream ciphers. */
+ if (i > 0) {
+ KASSERT(exf->native_blocksize != 0,
+ ("%s: partial block of %d bytes for cipher %s",
+ __func__, i, exf->name));
+ KASSERT(exf->reinit != NULL,
+ ("%s: partial block cipher %s without reinit hook",
+ __func__, exf->name));
+ KASSERT(i < blks, ("%s: partial block too big", __func__));
+
+ cuio_copydata(uio, count, i, blk);
+ if (encrypting) {
+ exf->encrypt_last(sw->sw_kschedule, blk, blk, i);
+ } else {
+ exf->decrypt_last(sw->sw_kschedule, blk, blk, i);
+ }
+ cuio_copyback(uio, count, i, blk);
+ }
+
out:
if (iovalloc)
free(iov, M_CRYPTO_DATA);
@@ -512,6 +522,8 @@
swe = &ses->swcr_encdec;
exf = swe->sw_exf;
+ KASSERT(axf->blocksize == exf->native_blocksize,
+ ("%s: blocksize mismatch", __func__));
if ((crp->crp_flags & CRYPTO_F_IV_SEPARATE) == 0)
return (EINVAL);
@@ -665,6 +677,8 @@
swe = &ses->swcr_encdec;
exf = swe->sw_exf;
+ KASSERT(axf->blocksize == exf->native_blocksize,
+ ("%s: blocksize mismatch", __func__));
if ((crp->crp_flags & CRYPTO_F_IV_SEPARATE) == 0)
return (EINVAL);
Index: head/sys/opencrypto/xform_aes_icm.c
===================================================================
--- head/sys/opencrypto/xform_aes_icm.c
+++ head/sys/opencrypto/xform_aes_icm.c
@@ -54,6 +54,7 @@
static int aes_icm_setkey(void *, const uint8_t *, int);
static void aes_icm_crypt(void *, const uint8_t *, uint8_t *);
+static void aes_icm_crypt_last(void *, const uint8_t *, uint8_t *, size_t);
static void aes_icm_reinit(void *, const uint8_t *);
static void aes_gcm_reinit(void *, const uint8_t *);
static void aes_ccm_reinit(void *, const uint8_t *);
@@ -63,7 +64,8 @@
.type = CRYPTO_AES_ICM,
.name = "AES-ICM",
.ctxsize = sizeof(struct aes_icm_ctx),
- .blocksize = AES_BLOCK_LEN,
+ .blocksize = 1,
+ .native_blocksize = AES_BLOCK_LEN,
.ivsize = AES_BLOCK_LEN,
.minkey = AES_MIN_KEY,
.maxkey = AES_MAX_KEY,
@@ -71,13 +73,16 @@
.decrypt = aes_icm_crypt,
.setkey = aes_icm_setkey,
.reinit = aes_icm_reinit,
+ .encrypt_last = aes_icm_crypt_last,
+ .decrypt_last = aes_icm_crypt_last,
};
struct enc_xform enc_xform_aes_nist_gcm = {
.type = CRYPTO_AES_NIST_GCM_16,
.name = "AES-GCM",
.ctxsize = sizeof(struct aes_icm_ctx),
- .blocksize = AES_ICM_BLOCK_LEN,
+ .blocksize = 1,
+ .native_blocksize = AES_BLOCK_LEN,
.ivsize = AES_GCM_IV_LEN,
.minkey = AES_MIN_KEY,
.maxkey = AES_MAX_KEY,
@@ -85,18 +90,24 @@
.decrypt = aes_icm_crypt,
.setkey = aes_icm_setkey,
.reinit = aes_gcm_reinit,
+ .encrypt_last = aes_icm_crypt_last,
+ .decrypt_last = aes_icm_crypt_last,
};
struct enc_xform enc_xform_ccm = {
.type = CRYPTO_AES_CCM_16,
.name = "AES-CCM",
.ctxsize = sizeof(struct aes_icm_ctx),
- .blocksize = AES_ICM_BLOCK_LEN, .ivsize = AES_CCM_IV_LEN,
+ .blocksize = 1,
+ .native_blocksize = AES_BLOCK_LEN,
+ .ivsize = AES_CCM_IV_LEN,
.minkey = AES_MIN_KEY, .maxkey = AES_MAX_KEY,
.encrypt = aes_icm_crypt,
.decrypt = aes_icm_crypt,
.setkey = aes_icm_setkey,
.reinit = aes_ccm_reinit,
+ .encrypt_last = aes_icm_crypt_last,
+ .decrypt_last = aes_icm_crypt_last,
};
/*
@@ -143,20 +154,30 @@
aes_icm_crypt(void *key, const uint8_t *in, uint8_t *out)
{
struct aes_icm_ctx *ctx;
- uint8_t keystream[AESICM_BLOCKSIZE];
int i;
ctx = key;
- rijndaelEncrypt(ctx->ac_ek, ctx->ac_nr, ctx->ac_block, keystream);
- for (i = 0; i < AESICM_BLOCKSIZE; i++)
- out[i] = in[i] ^ keystream[i];
- explicit_bzero(keystream, sizeof(keystream));
+ aes_icm_crypt_last(key, in, out, AESICM_BLOCKSIZE);
/* increment counter */
for (i = AESICM_BLOCKSIZE - 1;
i >= 0; i--)
if (++ctx->ac_block[i]) /* continue on overflow */
break;
+}
+
+static void
+aes_icm_crypt_last(void *key, const uint8_t *in, uint8_t *out, size_t len)
+{
+ struct aes_icm_ctx *ctx;
+ uint8_t keystream[AESICM_BLOCKSIZE];
+ int i;
+
+ ctx = key;
+ rijndaelEncrypt(ctx->ac_ek, ctx->ac_nr, ctx->ac_block, keystream);
+ for (i = 0; i < len; i++)
+ out[i] = in[i] ^ keystream[i];
+ explicit_bzero(keystream, sizeof(keystream));
}
static int
Index: head/sys/opencrypto/xform_enc.h
===================================================================
--- head/sys/opencrypto/xform_enc.h
+++ head/sys/opencrypto/xform_enc.h
@@ -51,20 +51,25 @@
char *name;
size_t ctxsize;
u_int16_t blocksize; /* Required input block size -- 1 for stream ciphers. */
+ uint16_t native_blocksize; /* Used for stream ciphers. */
u_int16_t ivsize;
u_int16_t minkey, maxkey;
+
+ /*
+ * Encrypt/decrypt a single block. For stream ciphers this
+ * encrypts/decrypts a single "native" block.
+ */
void (*encrypt) (void *, const uint8_t *, uint8_t *);
void (*decrypt) (void *, const uint8_t *, uint8_t *);
int (*setkey) (void *, const uint8_t *, int len);
void (*reinit) (void *, const u_int8_t *);
+
/*
- * Encrypt/decrypt 1+ blocks of input -- total size is 'len' bytes.
- * Len is guaranteed to be a multiple of the defined 'blocksize'.
- * Optional interface -- most useful for stream ciphers with a small
- * blocksize (1).
+ * For stream ciphers, encrypt/decrypt the final partial block
+ * of 'len' bytes.
*/
- void (*encrypt_multi) (void *, const uint8_t *, uint8_t *, size_t len);
- void (*decrypt_multi) (void *, const uint8_t *, uint8_t *, size_t len);
+ void (*encrypt_last) (void *, const uint8_t *, uint8_t *, size_t len);
+ void (*decrypt_last) (void *, const uint8_t *, uint8_t *, size_t len);
};
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Apr 28, 4:00 AM (15 h, 54 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17824291
Default Alt Text
D24906.diff (8 KB)
Attached To
Mode
D24906: Improve support for stream ciphers in the software encryption interface.
Attached
Detach File
Event Timeline
Log In to Comment