Changeset View
Changeset View
Standalone View
Standalone View
sys/opencrypto/cryptosoft.c
/* $OpenBSD: cryptosoft.c,v 1.35 2002/04/26 08:43:50 deraadt Exp $ */ | /* $OpenBSD: cryptosoft.c,v 1.35 2002/04/26 08:43:50 deraadt Exp $ */ | ||||
/*- | /*- | ||||
* The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu) | * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu) | ||||
* Copyright (c) 2002-2006 Sam Leffler, Errno Consulting | * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting | ||||
* | * | ||||
* This code was written by Angelos D. Keromytis in Athens, Greece, in | * This code was written by Angelos D. Keromytis in Athens, Greece, in | ||||
* February 2000. Network Security Technologies Inc. (NSTI) kindly | * February 2000. Network Security Technologies Inc. (NSTI) kindly | ||||
* supported the development of this code. | * supported the development of this code. | ||||
* | * | ||||
* Copyright (c) 2000, 2001 Angelos D. Keromytis | * Copyright (c) 2000, 2001 Angelos D. Keromytis | ||||
* Copyright (c) 2014 The FreeBSD Foundation | * Copyright (c) 2014-2021 The FreeBSD Foundation | ||||
* All rights reserved. | * All rights reserved. | ||||
* | * | ||||
* Portions of this software were developed by John-Mark Gurney | * Portions of this software were developed by John-Mark Gurney | ||||
* under sponsorship of the FreeBSD Foundation and | * under sponsorship of the FreeBSD Foundation and | ||||
* Rubicon Communications, LLC (Netgate). | * Rubicon Communications, LLC (Netgate). | ||||
* | * | ||||
* Portions of this software were developed by Ararat River | |||||
* Consulting, LLC under sponsorship of the FreeBSD Foundation. | |||||
* | |||||
* Permission to use, copy, and modify this software with or without fee | * Permission to use, copy, and modify this software with or without fee | ||||
* is hereby granted, provided that this entire notice is included in | * is hereby granted, provided that this entire notice is included in | ||||
* all source code copies of any software which is or includes a copy or | * all source code copies of any software which is or includes a copy or | ||||
* modification of this software. | * modification of this software. | ||||
* | * | ||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR | * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR | ||||
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY | * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY | ||||
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE | * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE | ||||
▲ Show 20 Lines • Show All 74 Lines • ▼ Show 20 Lines | |||||
swcr_encdec(struct swcr_session *ses, struct cryptop *crp) | swcr_encdec(struct swcr_session *ses, struct cryptop *crp) | ||||
{ | { | ||||
unsigned char iv[EALG_MAX_BLOCK_LEN], blk[EALG_MAX_BLOCK_LEN]; | unsigned char iv[EALG_MAX_BLOCK_LEN], blk[EALG_MAX_BLOCK_LEN]; | ||||
unsigned char *ivp, *nivp, iv2[EALG_MAX_BLOCK_LEN]; | unsigned char *ivp, *nivp, iv2[EALG_MAX_BLOCK_LEN]; | ||||
const struct crypto_session_params *csp; | const struct crypto_session_params *csp; | ||||
const struct enc_xform *exf; | const struct enc_xform *exf; | ||||
struct swcr_encdec *sw; | struct swcr_encdec *sw; | ||||
size_t inlen, outlen; | size_t inlen, outlen; | ||||
int i, blks, ivlen, resid; | int i, blks, resid; | ||||
struct crypto_buffer_cursor cc_in, cc_out; | struct crypto_buffer_cursor cc_in, cc_out; | ||||
const unsigned char *inblk; | const unsigned char *inblk; | ||||
unsigned char *outblk; | unsigned char *outblk; | ||||
int error; | int error; | ||||
bool encrypting; | bool encrypting; | ||||
error = 0; | error = 0; | ||||
sw = &ses->swcr_encdec; | sw = &ses->swcr_encdec; | ||||
exf = sw->sw_exf; | exf = sw->sw_exf; | ||||
ivlen = exf->ivsize; | csp = crypto_get_params(crp->crp_session); | ||||
if (exf->native_blocksize == 0) { | if (exf->native_blocksize == 0) { | ||||
/* Check for non-padded data */ | /* Check for non-padded data */ | ||||
if ((crp->crp_payload_length % exf->blocksize) != 0) | if ((crp->crp_payload_length % exf->blocksize) != 0) | ||||
return (EINVAL); | return (EINVAL); | ||||
blks = exf->blocksize; | blks = exf->blocksize; | ||||
} else | } else | ||||
blks = exf->native_blocksize; | blks = exf->native_blocksize; | ||||
if (exf == &enc_xform_aes_icm && | if (exf == &enc_xform_aes_icm && | ||||
(crp->crp_flags & CRYPTO_F_IV_SEPARATE) == 0) | (crp->crp_flags & CRYPTO_F_IV_SEPARATE) == 0) | ||||
return (EINVAL); | return (EINVAL); | ||||
if (crp->crp_cipher_key != NULL) { | if (crp->crp_cipher_key != NULL) { | ||||
csp = crypto_get_params(crp->crp_session); | |||||
error = exf->setkey(sw->sw_kschedule, | error = exf->setkey(sw->sw_kschedule, | ||||
crp->crp_cipher_key, csp->csp_cipher_klen); | crp->crp_cipher_key, csp->csp_cipher_klen); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
} | } | ||||
crypto_read_iv(crp, iv); | crypto_read_iv(crp, iv); | ||||
if (exf->reinit) { | if (exf->reinit) { | ||||
/* | /* | ||||
* xforms that provide a reinit method perform all IV | * xforms that provide a reinit method perform all IV | ||||
* handling themselves. | * handling themselves. | ||||
*/ | */ | ||||
exf->reinit(sw->sw_kschedule, iv); | exf->reinit(sw->sw_kschedule, iv, csp->csp_ivlen); | ||||
} | } | ||||
ivp = iv; | ivp = iv; | ||||
crypto_cursor_init(&cc_in, &crp->crp_buf); | crypto_cursor_init(&cc_in, &crp->crp_buf); | ||||
crypto_cursor_advance(&cc_in, crp->crp_payload_start); | crypto_cursor_advance(&cc_in, crp->crp_payload_start); | ||||
inblk = crypto_cursor_segment(&cc_in, &inlen); | inblk = crypto_cursor_segment(&cc_in, &inlen); | ||||
if (CRYPTO_HAS_OUTPUT_BUFFER(crp)) { | if (CRYPTO_HAS_OUTPUT_BUFFER(crp)) { | ||||
▲ Show 20 Lines • Show All 370 Lines • ▼ Show 20 Lines | if (resid > 0) { | ||||
crypto_cursor_copydata(&cc_in, resid, blk); | crypto_cursor_copydata(&cc_in, resid, blk); | ||||
axf->Update(&ctx, blk, blksz); | axf->Update(&ctx, blk, blksz); | ||||
} | } | ||||
} | } | ||||
if (crp->crp_cipher_key != NULL) | if (crp->crp_cipher_key != NULL) | ||||
exf->setkey(swe->sw_kschedule, crp->crp_cipher_key, | exf->setkey(swe->sw_kschedule, crp->crp_cipher_key, | ||||
crypto_get_params(crp->crp_session)->csp_cipher_klen); | crypto_get_params(crp->crp_session)->csp_cipher_klen); | ||||
exf->reinit(swe->sw_kschedule, iv); | exf->reinit(swe->sw_kschedule, iv, ivlen); | ||||
/* Do encryption with MAC */ | /* Do encryption with MAC */ | ||||
crypto_cursor_init(&cc_in, &crp->crp_buf); | crypto_cursor_init(&cc_in, &crp->crp_buf); | ||||
crypto_cursor_advance(&cc_in, crp->crp_payload_start); | crypto_cursor_advance(&cc_in, crp->crp_payload_start); | ||||
if (CRYPTO_HAS_OUTPUT_BUFFER(crp)) { | if (CRYPTO_HAS_OUTPUT_BUFFER(crp)) { | ||||
crypto_cursor_init(&cc_out, &crp->crp_obuf); | crypto_cursor_init(&cc_out, &crp->crp_obuf); | ||||
crypto_cursor_advance(&cc_out, crp->crp_payload_output_start); | crypto_cursor_advance(&cc_out, crp->crp_payload_output_start); | ||||
} else | } else | ||||
▲ Show 20 Lines • Show All 202 Lines • ▼ Show 20 Lines | else | ||||
error = crypto_apply(crp, crp->crp_aad_start, | error = crypto_apply(crp, crp->crp_aad_start, | ||||
crp->crp_aad_length, axf->Update, &ctx); | crp->crp_aad_length, axf->Update, &ctx); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
if (crp->crp_cipher_key != NULL) | if (crp->crp_cipher_key != NULL) | ||||
exf->setkey(swe->sw_kschedule, crp->crp_cipher_key, | exf->setkey(swe->sw_kschedule, crp->crp_cipher_key, | ||||
crypto_get_params(crp->crp_session)->csp_cipher_klen); | crypto_get_params(crp->crp_session)->csp_cipher_klen); | ||||
exf->reinit(swe->sw_kschedule, iv); | exf->reinit(swe->sw_kschedule, iv, ivlen); | ||||
/* Do encryption/decryption with MAC */ | /* Do encryption/decryption with MAC */ | ||||
crypto_cursor_init(&cc_in, &crp->crp_buf); | crypto_cursor_init(&cc_in, &crp->crp_buf); | ||||
crypto_cursor_advance(&cc_in, crp->crp_payload_start); | crypto_cursor_advance(&cc_in, crp->crp_payload_start); | ||||
if (CRYPTO_HAS_OUTPUT_BUFFER(crp)) { | if (CRYPTO_HAS_OUTPUT_BUFFER(crp)) { | ||||
crypto_cursor_init(&cc_out, &crp->crp_obuf); | crypto_cursor_init(&cc_out, &crp->crp_obuf); | ||||
crypto_cursor_advance(&cc_out, crp->crp_payload_output_start); | crypto_cursor_advance(&cc_out, crp->crp_payload_output_start); | ||||
} else | } else | ||||
▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | if (!CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) { | ||||
r = timingsafe_bcmp(tag, tag2, swa->sw_mlen); | r = timingsafe_bcmp(tag, tag2, swa->sw_mlen); | ||||
explicit_bzero(tag2, sizeof(tag2)); | explicit_bzero(tag2, sizeof(tag2)); | ||||
if (r != 0) { | if (r != 0) { | ||||
error = EBADMSG; | error = EBADMSG; | ||||
goto out; | goto out; | ||||
} | } | ||||
/* tag matches, decrypt data */ | /* tag matches, decrypt data */ | ||||
exf->reinit(swe->sw_kschedule, iv); | exf->reinit(swe->sw_kschedule, iv, ivlen); | ||||
crypto_cursor_init(&cc_in, &crp->crp_buf); | crypto_cursor_init(&cc_in, &crp->crp_buf); | ||||
crypto_cursor_advance(&cc_in, crp->crp_payload_start); | crypto_cursor_advance(&cc_in, crp->crp_payload_start); | ||||
for (resid = crp->crp_payload_length; resid > blksz; | for (resid = crp->crp_payload_length; resid > blksz; | ||||
resid -= blksz) { | resid -= blksz) { | ||||
inblk = crypto_cursor_segment(&cc_in, &len); | inblk = crypto_cursor_segment(&cc_in, &len); | ||||
if (len < blksz) { | if (len < blksz) { | ||||
crypto_cursor_copydata(&cc_in, blksz, blk); | crypto_cursor_copydata(&cc_in, blksz, blk); | ||||
inblk = blk; | inblk = blk; | ||||
▲ Show 20 Lines • Show All 74 Lines • ▼ Show 20 Lines | if (crp->crp_aad_length % 16 != 0) { | ||||
/* padding1 */ | /* padding1 */ | ||||
memset(blk, 0, 16); | memset(blk, 0, 16); | ||||
axf->Update(&ctx, blk, 16 - crp->crp_aad_length % 16); | axf->Update(&ctx, blk, 16 - crp->crp_aad_length % 16); | ||||
} | } | ||||
if (crp->crp_cipher_key != NULL) | if (crp->crp_cipher_key != NULL) | ||||
exf->setkey(swe->sw_kschedule, crp->crp_cipher_key, | exf->setkey(swe->sw_kschedule, crp->crp_cipher_key, | ||||
csp->csp_cipher_klen); | csp->csp_cipher_klen); | ||||
exf->reinit(swe->sw_kschedule, crp->crp_iv); | exf->reinit(swe->sw_kschedule, crp->crp_iv, csp->csp_ivlen); | ||||
/* Do encryption with MAC */ | /* Do encryption with MAC */ | ||||
crypto_cursor_init(&cc_in, &crp->crp_buf); | crypto_cursor_init(&cc_in, &crp->crp_buf); | ||||
crypto_cursor_advance(&cc_in, crp->crp_payload_start); | crypto_cursor_advance(&cc_in, crp->crp_payload_start); | ||||
if (CRYPTO_HAS_OUTPUT_BUFFER(crp)) { | if (CRYPTO_HAS_OUTPUT_BUFFER(crp)) { | ||||
crypto_cursor_init(&cc_out, &crp->crp_obuf); | crypto_cursor_init(&cc_out, &crp->crp_obuf); | ||||
crypto_cursor_advance(&cc_out, crp->crp_payload_output_start); | crypto_cursor_advance(&cc_out, crp->crp_payload_output_start); | ||||
} else | } else | ||||
▲ Show 20 Lines • Show All 778 Lines • Show Last 20 Lines |