This is needed for the upcoming libcrypto bump. While it would be better to do error checking for EVP_Digest* (for example EVP_DigestInit* usually allocates internally), I kept the change as mechanical as possible and left that one for someone else to fix.
Index: usr.bin/snmp/usm.c =================================================================== RCS file: /cvs/src/usr.bin/snmp/usm.c,v retrieving revision 1.5 diff -u -p -r1.5 usm.c --- usr.bin/snmp/usm.c 24 Oct 2019 12:39:26 -0000 1.5 +++ usr.bin/snmp/usm.c 5 Jan 2022 09:37:40 -0000 @@ -252,7 +252,7 @@ static char * usm_crypt(const EVP_CIPHER *cipher, int do_enc, char *key, struct usm_cookie *cookie, char *serialpdu, size_t pdulen, size_t *outlen) { - EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX *ctx; size_t i; char iv[EVP_MAX_IV_LENGTH]; char *salt = (char *)&(cookie->salt); @@ -279,28 +279,34 @@ usm_crypt(const EVP_CIPHER *cipher, int return NULL; } - bzero(&ctx, sizeof(ctx)); - if (!EVP_CipherInit(&ctx, cipher, key, iv, do_enc)) + if ((ctx = EVP_CIPHER_CTX_new()) == NULL) return NULL; - EVP_CIPHER_CTX_set_padding(&ctx, do_enc); + if (!EVP_CipherInit(ctx, cipher, key, iv, do_enc)) { + EVP_CIPHER_CTX_free(ctx); + return NULL; + } + + EVP_CIPHER_CTX_set_padding(ctx, do_enc); bs = EVP_CIPHER_block_size(cipher); /* Maximum output size */ *outlen = pdulen + (bs - (pdulen % bs)); - if ((outtext = malloc(*outlen)) == NULL) + if ((outtext = malloc(*outlen)) == NULL) { + EVP_CIPHER_CTX_free(ctx); return NULL; + } - if (EVP_CipherUpdate(&ctx, outtext, &len, serialpdu, pdulen) && - EVP_CipherFinal_ex(&ctx, outtext + len, &len2)) + if (EVP_CipherUpdate(ctx, outtext, &len, serialpdu, pdulen) && + EVP_CipherFinal_ex(ctx, outtext + len, &len2)) *outlen = len + len2; else { free(outtext); outtext = NULL; } - EVP_CIPHER_CTX_cleanup(&ctx); + EVP_CIPHER_CTX_free(ctx); return outtext; } @@ -616,7 +622,7 @@ usm_setbootstime(struct snmp_sec *sec, u static char * usm_passwd2mkey(const EVP_MD *md, const char *passwd) { - EVP_MD_CTX ctx; + EVP_MD_CTX *ctx; int i, count; const u_char *pw; u_char *c; @@ -624,8 +630,9 @@ usm_passwd2mkey(const EVP_MD *md, const unsigned dlen; char *key; - bzero(&ctx, sizeof(ctx)); - EVP_DigestInit_ex(&ctx, md, NULL); + if ((ctx = EVP_MD_CTX_new()) == NULL) + return NULL; + EVP_DigestInit_ex(ctx, md, NULL); pw = (const u_char *)passwd; for (count = 0; count < 1048576; count += 64) { c = keybuf; @@ -634,10 +641,10 @@ usm_passwd2mkey(const EVP_MD *md, const pw = (const u_char *)passwd; *c++ = *pw++; } - EVP_DigestUpdate(&ctx, keybuf, 64); + EVP_DigestUpdate(ctx, keybuf, 64); } - EVP_DigestFinal_ex(&ctx, keybuf, &dlen); - EVP_MD_CTX_cleanup(&ctx); + EVP_DigestFinal_ex(ctx, keybuf, &dlen); + EVP_MD_CTX_free(ctx); if ((key = malloc(dlen)) == NULL) return NULL; @@ -648,20 +655,21 @@ usm_passwd2mkey(const EVP_MD *md, const static char * usm_mkey2lkey(struct usm_sec *usm, const EVP_MD *md, const char *mkey) { - EVP_MD_CTX ctx; + EVP_MD_CTX *ctx; u_char buf[EVP_MAX_MD_SIZE]; u_char *lkey; unsigned lklen; - bzero(&ctx, sizeof(ctx)); - EVP_DigestInit_ex(&ctx, md, NULL); + if ((ctx = EVP_MD_CTX_new()) == NULL) + return NULL; + EVP_DigestInit_ex(ctx, md, NULL); - EVP_DigestUpdate(&ctx, mkey, EVP_MD_size(md)); - EVP_DigestUpdate(&ctx, usm->engineid, usm->engineidlen); - EVP_DigestUpdate(&ctx, mkey, EVP_MD_size(md)); + EVP_DigestUpdate(ctx, mkey, EVP_MD_size(md)); + EVP_DigestUpdate(ctx, usm->engineid, usm->engineidlen); + EVP_DigestUpdate(ctx, mkey, EVP_MD_size(md)); - EVP_DigestFinal_ex(&ctx, buf, &lklen); - EVP_MD_CTX_cleanup(&ctx); + EVP_DigestFinal_ex(ctx, buf, &lklen); + EVP_MD_CTX_free(ctx); if ((lkey = malloc(lklen)) == NULL) return NULL; Index: usr.sbin/snmpd/usm.c =================================================================== RCS file: /cvs/src/usr.sbin/snmpd/usm.c,v retrieving revision 1.21 diff -u -p -r1.21 usm.c --- usr.sbin/snmpd/usm.c 1 Aug 2021 11:30:56 -0000 1.21 +++ usr.sbin/snmpd/usm.c 5 Jan 2022 09:37:53 -0000 @@ -650,7 +650,7 @@ usm_crypt(struct snmp_message *msg, u_ch int do_encrypt) { const EVP_CIPHER *cipher; - EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX *ctx; u_char *privkey; int i; u_char iv[EVP_MAX_IV_LENGTH]; @@ -683,19 +683,24 @@ usm_crypt(struct snmp_message *msg, u_ch return -1; } - if (!EVP_CipherInit(&ctx, cipher, privkey, iv, do_encrypt)) + if ((ctx = EVP_CIPHER_CTX_new()) == NULL) return -1; + if (!EVP_CipherInit(ctx, cipher, privkey, iv, do_encrypt)) { + EVP_CIPHER_CTX_free(ctx); + return -1; + } + if (!do_encrypt) - EVP_CIPHER_CTX_set_padding(&ctx, 0); + EVP_CIPHER_CTX_set_padding(ctx, 0); - if (EVP_CipherUpdate(&ctx, outbuf, &len, inbuf, inlen) && - EVP_CipherFinal_ex(&ctx, outbuf + len, &len2)) + if (EVP_CipherUpdate(ctx, outbuf, &len, inbuf, inlen) && + EVP_CipherFinal_ex(ctx, outbuf + len, &len2)) rv = len + len2; else rv = -1; - EVP_CIPHER_CTX_cleanup(&ctx); + EVP_CIPHER_CTX_free(ctx); return rv; } @@ -705,7 +710,7 @@ usm_crypt(struct snmp_message *msg, u_ch char * usm_passwd2key(const EVP_MD *md, char *passwd, int *maxlen) { - EVP_MD_CTX ctx; + EVP_MD_CTX *ctx; int i, count; u_char *pw, *c; u_char pwbuf[2 * EVP_MAX_MD_SIZE + SNMPD_MAXENGINEIDLEN]; @@ -713,7 +718,9 @@ usm_passwd2key(const EVP_MD *md, char *p unsigned dlen; char *key; - EVP_DigestInit(&ctx, md); + if ((ctx = EVP_MD_CTX_new()) == NULL) + return NULL; + EVP_DigestInit(ctx, md); pw = (u_char *)passwd; for (count = 0; count < 1048576; count += 64) { c = pwbuf; @@ -722,10 +729,10 @@ usm_passwd2key(const EVP_MD *md, char *p pw = (u_char *)passwd; *c++ = *pw++; } - EVP_DigestUpdate(&ctx, pwbuf, 64); + EVP_DigestUpdate(ctx, pwbuf, 64); } - EVP_DigestFinal(&ctx, keybuf, &dlen); - EVP_MD_CTX_cleanup(&ctx); + EVP_DigestFinal(ctx, keybuf, &dlen); + EVP_MD_CTX_free(ctx); /* Localize the key */ #ifdef DEBUG @@ -736,10 +743,10 @@ usm_passwd2key(const EVP_MD *md, char *p snmpd_env->sc_engineid_len); memcpy(pwbuf + dlen + snmpd_env->sc_engineid_len, keybuf, dlen); - EVP_DigestInit(&ctx, md); - EVP_DigestUpdate(&ctx, pwbuf, 2 * dlen + snmpd_env->sc_engineid_len); - EVP_DigestFinal(&ctx, keybuf, &dlen); - EVP_MD_CTX_cleanup(&ctx); + EVP_DigestInit(ctx, md); + EVP_DigestUpdate(ctx, pwbuf, 2 * dlen + snmpd_env->sc_engineid_len); + EVP_DigestFinal(ctx, keybuf, &dlen); + EVP_MD_CTX_free(ctx); if (*maxlen > 0 && dlen > (unsigned)*maxlen) dlen = (unsigned)*maxlen;