-/* $OpenBSD: cryptosoft.c,v 1.87 2021/07/08 09:22:30 bluhm Exp $ */
+/* $OpenBSD: cryptosoft.c,v 1.88 2021/07/09 15:29:55 bluhm Exp $ */
/*
* The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
};
-struct swcr_data **swcr_sessions = NULL;
+struct swcr_list *swcr_sessions = NULL;
u_int32_t swcr_sesnum = 0;
int32_t swcr_id = -1;
u_char iv[EALG_MAX_BLOCK_LEN];
union authctx ctx;
struct cryptodesc *crd, *crda = NULL, *crde = NULL;
+ struct swcr_list *session;
struct swcr_data *sw, *swa, *swe = NULL;
const struct auth_hash *axf = NULL;
const struct enc_xform *exf = NULL;
ivlen = blksz = iskip = oskip = 0;
+ session = &swcr_sessions[crp->crp_sid & 0xffffffff];
for (i = 0; i < crp->crp_ndesc; i++) {
crd = &crp->crp_desc[i];
- for (sw = swcr_sessions[crp->crp_sid & 0xffffffff];
- sw && sw->sw_alg != crd->crd_alg;
- sw = sw->sw_next)
- ;
+ SLIST_FOREACH(sw, session, sw_next) {
+ if (sw->sw_alg == crd->crd_alg)
+ break;
+ }
if (sw == NULL)
return (EINVAL);
int
swcr_newsession(u_int32_t *sid, struct cryptoini *cri)
{
- struct swcr_data **swd;
+ struct swcr_list *session;
+ struct swcr_data *swd, *prev;
const struct auth_hash *axf;
const struct enc_xform *txf;
const struct comp_algo *cxf;
if (sid == NULL || cri == NULL)
return EINVAL;
- if (swcr_sessions) {
+ if (swcr_sessions != NULL) {
for (i = 1; i < swcr_sesnum; i++)
- if (swcr_sessions[i] == NULL)
+ if (SLIST_EMPTY(&swcr_sessions[i]))
break;
}
} else
swcr_sesnum *= 2;
- swd = mallocarray(swcr_sesnum, sizeof(struct swcr_data *),
+ session = mallocarray(swcr_sesnum, sizeof(struct swcr_list),
M_CRYPTO_DATA, M_NOWAIT | M_ZERO);
- if (swd == NULL) {
+ if (session == NULL) {
/* Reset session number */
if (swcr_sesnum == CRYPTO_SW_SESSIONS)
swcr_sesnum = 0;
/* Copy existing sessions */
if (swcr_sessions) {
- bcopy(swcr_sessions, swd,
- (swcr_sesnum / 2) * sizeof(struct swcr_data *));
+ bcopy(swcr_sessions, session,
+ (swcr_sesnum / 2) * sizeof(struct swcr_list));
free(swcr_sessions, M_CRYPTO_DATA,
- (swcr_sesnum / 2) * sizeof(struct swcr_data *));
+ (swcr_sesnum / 2) * sizeof(struct swcr_list));
}
- swcr_sessions = swd;
+ swcr_sessions = session;
}
- swd = &swcr_sessions[i];
+ session = &swcr_sessions[i];
*sid = i;
+ prev = NULL;
while (cri) {
- *swd = malloc(sizeof(struct swcr_data), M_CRYPTO_DATA,
+ swd = malloc(sizeof(struct swcr_data), M_CRYPTO_DATA,
M_NOWAIT | M_ZERO);
- if (*swd == NULL) {
+ if (swd == NULL) {
swcr_freesession(i);
return ENOBUFS;
}
+ if (prev == NULL)
+ SLIST_INSERT_HEAD(session, swd, sw_next);
+ else
+ SLIST_INSERT_AFTER(prev, swd, sw_next);
switch (cri->cri_alg) {
case CRYPTO_3DES_CBC:
goto enccommon;
case CRYPTO_AES_GMAC:
txf = &enc_xform_aes_gmac;
- (*swd)->sw_exf = txf;
+ swd->sw_exf = txf;
break;
case CRYPTO_CHACHA20_POLY1305:
txf = &enc_xform_chacha20_poly1305;
goto enccommon;
enccommon:
if (txf->ctxsize > 0) {
- (*swd)->sw_kschedule = malloc(txf->ctxsize,
+ swd->sw_kschedule = malloc(txf->ctxsize,
M_CRYPTO_DATA, M_NOWAIT | M_ZERO);
- if ((*swd)->sw_kschedule == NULL) {
+ if (swd->sw_kschedule == NULL) {
swcr_freesession(i);
return EINVAL;
}
}
- if (txf->setkey((*swd)->sw_kschedule, cri->cri_key,
+ if (txf->setkey(swd->sw_kschedule, cri->cri_key,
cri->cri_klen / 8) < 0) {
swcr_freesession(i);
return EINVAL;
}
- (*swd)->sw_exf = txf;
+ swd->sw_exf = txf;
break;
case CRYPTO_MD5_HMAC:
axf = &auth_hash_hmac_sha2_512_256;
goto authcommon;
authcommon:
- (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
+ swd->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
M_NOWAIT);
- if ((*swd)->sw_ictx == NULL) {
+ if (swd->sw_ictx == NULL) {
swcr_freesession(i);
return ENOBUFS;
}
- (*swd)->sw_octx = malloc(axf->ctxsize, M_CRYPTO_DATA,
+ swd->sw_octx = malloc(axf->ctxsize, M_CRYPTO_DATA,
M_NOWAIT);
- if ((*swd)->sw_octx == NULL) {
+ if (swd->sw_octx == NULL) {
swcr_freesession(i);
return ENOBUFS;
}
for (k = 0; k < cri->cri_klen / 8; k++)
cri->cri_key[k] ^= HMAC_IPAD_VAL;
- axf->Init((*swd)->sw_ictx);
- axf->Update((*swd)->sw_ictx, cri->cri_key,
+ axf->Init(swd->sw_ictx);
+ axf->Update(swd->sw_ictx, cri->cri_key,
cri->cri_klen / 8);
- axf->Update((*swd)->sw_ictx, hmac_ipad_buffer,
+ axf->Update(swd->sw_ictx, hmac_ipad_buffer,
axf->blocksize - (cri->cri_klen / 8));
for (k = 0; k < cri->cri_klen / 8; k++)
cri->cri_key[k] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL);
- axf->Init((*swd)->sw_octx);
- axf->Update((*swd)->sw_octx, cri->cri_key,
+ axf->Init(swd->sw_octx);
+ axf->Update(swd->sw_octx, cri->cri_key,
cri->cri_klen / 8);
- axf->Update((*swd)->sw_octx, hmac_opad_buffer,
+ axf->Update(swd->sw_octx, hmac_opad_buffer,
axf->blocksize - (cri->cri_klen / 8));
for (k = 0; k < cri->cri_klen / 8; k++)
cri->cri_key[k] ^= HMAC_OPAD_VAL;
- (*swd)->sw_axf = axf;
+ swd->sw_axf = axf;
break;
case CRYPTO_AES_128_GMAC:
axf = &auth_hash_chacha20_poly1305;
goto authenccommon;
authenccommon:
- (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
+ swd->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
M_NOWAIT);
- if ((*swd)->sw_ictx == NULL) {
+ if (swd->sw_ictx == NULL) {
swcr_freesession(i);
return ENOBUFS;
}
- axf->Init((*swd)->sw_ictx);
- axf->Setkey((*swd)->sw_ictx, cri->cri_key,
+ axf->Init(swd->sw_ictx);
+ axf->Setkey(swd->sw_ictx, cri->cri_key,
cri->cri_klen / 8);
- (*swd)->sw_axf = axf;
+ swd->sw_axf = axf;
break;
case CRYPTO_DEFLATE_COMP:
cxf = &comp_algo_deflate;
- (*swd)->sw_cxf = cxf;
+ swd->sw_cxf = cxf;
break;
case CRYPTO_ESN:
/* nothing to do */
return EINVAL;
}
- (*swd)->sw_alg = cri->cri_alg;
+ swd->sw_alg = cri->cri_alg;
cri = cri->cri_next;
- swd = &((*swd)->sw_next);
+ prev = swd;
}
return 0;
}
int
swcr_freesession(u_int64_t tid)
{
+ struct swcr_list *session;
struct swcr_data *swd;
const struct enc_xform *txf;
const struct auth_hash *axf;
u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;
if (sid > swcr_sesnum || swcr_sessions == NULL ||
- swcr_sessions[sid] == NULL)
+ SLIST_EMPTY(&swcr_sessions[sid]))
return EINVAL;
/* Silently accept and return */
if (sid == 0)
return 0;
- while ((swd = swcr_sessions[sid]) != NULL) {
- swcr_sessions[sid] = swd->sw_next;
+ session = &swcr_sessions[sid];
+ while (!SLIST_EMPTY(session)) {
+ swd = SLIST_FIRST(session);
+ SLIST_REMOVE_HEAD(session, sw_next);
switch (swd->sw_alg) {
case CRYPTO_3DES_CBC:
swcr_process(struct cryptop *crp)
{
struct cryptodesc *crd;
+ struct swcr_list *session;
struct swcr_data *sw;
u_int32_t lid;
int type;
}
lid = crp->crp_sid & 0xffffffff;
- if (lid >= swcr_sesnum || lid == 0 || swcr_sessions[lid] == NULL) {
+ if (lid >= swcr_sesnum || lid == 0 ||
+ SLIST_EMPTY(&swcr_sessions[lid])) {
crp->crp_etype = ENOENT;
goto done;
}
type = CRYPTO_BUF_IOV;
/* Go through crypto descriptors, processing as we go */
+ session = &swcr_sessions[lid];
for (i = 0; i < crp->crp_ndesc; i++) {
crd = &crp->crp_desc[i];
/*
* XXX between the various instances of an algorithm (so we can
* XXX locate the correct crypto context).
*/
- for (sw = swcr_sessions[lid];
- sw && sw->sw_alg != crd->crd_alg;
- sw = sw->sw_next)
- ;
+ SLIST_FOREACH(sw, session, sw_next) {
+ if (sw->sw_alg == crd->crd_alg)
+ break;
+ }
/* No such context ? */
if (sw == NULL) {