From fd847bfffe42cf44069354d7ef4f625994f4f9b3 Mon Sep 17 00:00:00 2001 From: Daniel Markstedt Date: Sat, 25 Apr 2026 17:58:15 +0200 Subject: [PATCH 1/5] uams: harden DHX2 key exchange and prime serialization Zero-pad the DH prime p when serializing for the wire, matching the existing treatment of g and Ma. Add error handling for all gcry_mpi_print calls when serializing g, p, and Ma in dhx2_setup. If serialization fails, bail out via the existing error path instead of using a stale nwritten value for the zero-padding logic. Inspired by bug fixes in afp-perl by Derrik Pates --- etc/uams/uams_dhx2_pam.c | 28 ++++++++++++++++++++++++---- etc/uams/uams_dhx2_passwd.c | 28 ++++++++++++++++++++++++---- 2 files changed, 48 insertions(+), 8 deletions(-) diff --git a/etc/uams/uams_dhx2_pam.c b/etc/uams/uams_dhx2_pam.c index ad599b1b4f1..b323413b875 100644 --- a/etc/uams/uams_dhx2_pam.c +++ b/etc/uams/uams_dhx2_pam.c @@ -313,8 +313,13 @@ static int dhx2_setup(void *obj, char *ibuf _U_, size_t ibuflen _U_, memcpy(rbuf, &uint16, sizeof(uint16_t)); rbuf += 2; *rbuflen += 2; + /* g is next */ - gcry_mpi_print(GCRYMPI_FMT_USG, (unsigned char *)rbuf, 4, &nwritten, g); + if (gcry_mpi_print(GCRYMPI_FMT_USG, (unsigned char *)rbuf, 4, &nwritten, + g) != 0) { + ret = AFPERR_MISC; + goto error; + } if (nwritten < 4) { memmove(rbuf + 4 - nwritten, rbuf, nwritten); @@ -328,13 +333,28 @@ static int dhx2_setup(void *obj, char *ibuf _U_, size_t ibuflen _U_, memcpy(rbuf, &uint16, sizeof(uint16_t)); rbuf += 2; *rbuflen += 2; + /* p */ - gcry_mpi_print(GCRYMPI_FMT_USG, (unsigned char *)rbuf, PRIMEBITS / 8, NULL, p); + if (gcry_mpi_print(GCRYMPI_FMT_USG, (unsigned char *)rbuf, PRIMEBITS / 8, + &nwritten, p) != 0) { + ret = AFPERR_MISC; + goto error; + } + + if (nwritten < PRIMEBITS / 8) { + memmove(rbuf + (PRIMEBITS / 8) - nwritten, rbuf, nwritten); + memset(rbuf, 0, (PRIMEBITS / 8) - nwritten); + } + rbuf += PRIMEBITS / 8; *rbuflen += PRIMEBITS / 8; + /* Ma */ - gcry_mpi_print(GCRYMPI_FMT_USG, (unsigned char *)rbuf, PRIMEBITS / 8, &nwritten, - Ma); + if (gcry_mpi_print(GCRYMPI_FMT_USG, (unsigned char *)rbuf, PRIMEBITS / 8, + &nwritten, Ma) != 0) { + ret = AFPERR_MISC; + goto error; + } if (nwritten < PRIMEBITS / 8) { memmove(rbuf + (PRIMEBITS / 8) - nwritten, rbuf, nwritten); diff --git a/etc/uams/uams_dhx2_passwd.c b/etc/uams/uams_dhx2_passwd.c index 092de77f6a5..4dd138f74fc 100644 --- a/etc/uams/uams_dhx2_passwd.c +++ b/etc/uams/uams_dhx2_passwd.c @@ -246,8 +246,13 @@ static int dhx2_setup(void *obj, char *ibuf _U_, size_t ibuflen _U_, memcpy(rbuf, &uint16, sizeof(uint16_t)); rbuf += 2; *rbuflen += 2; + /* g is next */ - gcry_mpi_print(GCRYMPI_FMT_USG, (unsigned char *)rbuf, 4, &nwritten, g); + if (gcry_mpi_print(GCRYMPI_FMT_USG, (unsigned char *)rbuf, 4, &nwritten, + g) != 0) { + ret = AFPERR_MISC; + goto error; + } if (nwritten < 4) { memmove(rbuf + 4 - nwritten, rbuf, nwritten); @@ -261,13 +266,28 @@ static int dhx2_setup(void *obj, char *ibuf _U_, size_t ibuflen _U_, memcpy(rbuf, &uint16, sizeof(uint16_t)); rbuf += 2; *rbuflen += 2; + /* p */ - gcry_mpi_print(GCRYMPI_FMT_USG, (unsigned char *)rbuf, PRIMEBITS / 8, NULL, p); + if (gcry_mpi_print(GCRYMPI_FMT_USG, (unsigned char *)rbuf, PRIMEBITS / 8, + &nwritten, p) != 0) { + ret = AFPERR_MISC; + goto error; + } + + if (nwritten < PRIMEBITS / 8) { + memmove(rbuf + (PRIMEBITS / 8) - nwritten, rbuf, nwritten); + memset(rbuf, 0, (PRIMEBITS / 8) - nwritten); + } + rbuf += PRIMEBITS / 8; *rbuflen += PRIMEBITS / 8; + /* Ma */ - gcry_mpi_print(GCRYMPI_FMT_USG, (unsigned char *)rbuf, PRIMEBITS / 8, &nwritten, - Ma); + if (gcry_mpi_print(GCRYMPI_FMT_USG, (unsigned char *)rbuf, PRIMEBITS / 8, + &nwritten, Ma) != 0) { + ret = AFPERR_MISC; + goto error; + } if (nwritten < PRIMEBITS / 8) { memmove(rbuf + (PRIMEBITS / 8) - nwritten, rbuf, nwritten); From 8bf96f588af0fd650341e6fd80a32280cadce70a Mon Sep 17 00:00:00 2001 From: Daniel Markstedt Date: Sat, 25 Apr 2026 18:13:17 +0200 Subject: [PATCH 2/5] uams: harden DHX key exchange state and key lifecycle Guard logincont and changepw against being called before the shared key K is established, preventing a NULL pointer dereference if the login step was skipped or failed. Also release K immediately after serializing it to the local key buffer, fixing a leak that left key material in memory indefinitely after authentication. Add error handling for all gcry_mpi_print calls in DHX UAMs. In the setup functions, bail out via the existing error path if serialization of K or Mb fails. In logincont and changepw, release K and return an error instead of using a stale nwritten value for the zero-padding logic. Inspired by bug fixes in afp-perl by Derrik Pates --- etc/uams/uams_dhx_pam.c | 55 ++++++++++++++++++++++++++++++++++---- etc/uams/uams_dhx_passwd.c | 42 ++++++++++++++++++++++++++--- 2 files changed, 88 insertions(+), 9 deletions(-) diff --git a/etc/uams/uams_dhx_pam.c b/etc/uams/uams_dhx_pam.c index 2f3cd0853b0..0d66c363963 100644 --- a/etc/uams/uams_dhx_pam.c +++ b/etc/uams/uams_dhx_pam.c @@ -45,6 +45,14 @@ /*! the secret key */ gcry_mpi_t K; +static void dhx_release_key(void) +{ + if (K != NULL) { + gcry_mpi_release(K); + K = NULL; + } +} + static struct passwd *dhxpwd; static uint8_t randbuf[KEYSIZE]; @@ -205,6 +213,7 @@ static int dhx_setup(void *obj, const unsigned char *ibuf, size_t ibuflen _U_, Rb = gcry_mpi_new(0); Ma = gcry_mpi_new(0); Mb = gcry_mpi_new(0); + dhx_release_key(); K = gcry_mpi_new(0); unsigned char Rb_binary[32], K_binary[16]; gcry_cipher_hd_t ctx; @@ -229,7 +238,11 @@ static int dhx_setup(void *obj, const unsigned char *ibuf, size_t ibuflen _U_, gcry_mpi_release(g); gcry_mpi_release(Ma); gcry_mpi_release(Rb); - gcry_mpi_print(GCRYMPI_FMT_USG, K_binary, sizeof(K_binary), &i, K); + + if (gcry_mpi_print(GCRYMPI_FMT_USG, K_binary, sizeof(K_binary), &i, K) != 0) { + *rbuflen = 0; + goto pam_fail; + } if (i < KEYSIZE) { memmove(K_binary + sizeof(K_binary) - i, K_binary, i); @@ -241,7 +254,11 @@ static int dhx_setup(void *obj, const unsigned char *ibuf, size_t ibuflen _U_, memcpy(rbuf, &sessid, sizeof(sessid)); rbuf += sizeof(sessid); *rbuflen += sizeof(sessid); - gcry_mpi_print(GCRYMPI_FMT_USG, rbuf, KEYSIZE, &nwritten, Mb); + + if (gcry_mpi_print(GCRYMPI_FMT_USG, rbuf, KEYSIZE, &nwritten, Mb) != 0) { + *rbuflen = 0; + goto pam_fail; + } if (nwritten < KEYSIZE) { memmove(rbuf + KEYSIZE - nwritten, rbuf, nwritten); @@ -316,7 +333,7 @@ static int dhx_setup(void *obj, const unsigned char *ibuf, size_t ibuflen _U_, gcry_cipher_close(ctx); return AFPERR_AUTHCONT; pam_fail: - gcry_mpi_release(K); + dhx_release_key(); /* Log Entry */ LOG(log_info, logtype_uams, "uams_dhx_pam.c :PAM: Fail - Cast Encryption -- %s", strerror(errno)); @@ -438,6 +455,13 @@ static int pam_logincont(void *obj, struct passwd **uam_pwd, unsigned char K_binary[16]; size_t i; *rbuflen = 0; + + /* Make sure dhx_setup actually ran and established the shared key */ + if (K == NULL) { + LOG(log_error, logtype_uams, "DHX: logincont called without completing login"); + return AFPERR_PARAM; + } + /* check for session id */ memcpy(&sessid, ibuf, sizeof(sessid)); @@ -447,6 +471,7 @@ static int pam_logincont(void *obj, struct passwd **uam_pwd, "uams_dhx_pam.c :PAM Session ID - DHXHash Mismatch -- %s", strerror(errno)); /* Log Entry */ + dhx_release_key(); return AFPERR_PARAM; } @@ -459,7 +484,12 @@ static int pam_logincont(void *obj, struct passwd **uam_pwd, hostname = NULL; } - gcry_mpi_print(GCRYMPI_FMT_USG, K_binary, sizeof(K_binary), &i, K); + if (gcry_mpi_print(GCRYMPI_FMT_USG, K_binary, sizeof(K_binary), &i, K) != 0) { + dhx_release_key(); + return AFPERR_PARAM; + } + + dhx_release_key(); if (i < KEYSIZE) { memmove(K_binary + sizeof(K_binary) - i, K_binary, i); @@ -675,6 +705,13 @@ static int pam_changepw(void *obj, unsigned char *username, /* otherwise, it's like logincont but different. */ + /* Make sure dhx_setup actually ran and established the shared key */ + if (K == NULL) { + LOG(log_error, logtype_uams, + "DHX: changepw called without completing key exchange"); + return AFPERR_PARAM; + } + /* check out the session id */ if (sessid != dhxhash(obj)) { /* Log Entry */ @@ -682,6 +719,7 @@ static int pam_changepw(void *obj, unsigned char *username, "uams_dhx_pam.c :PAM: Session ID not Equal to DHX Hash -- %s", strerror(errno)); /* Log Entry */ + dhx_release_key(); return AFPERR_PARAM; } @@ -692,10 +730,16 @@ static int pam_changepw(void *obj, unsigned char *username, LOG(log_info, logtype_uams, "uams_dhx_pam.c :PAM: Hostname Null?? -- %s", strerror(errno)); /* Log Entry */ + dhx_release_key(); return AFPERR_MISC; } - gcry_mpi_print(GCRYMPI_FMT_USG, K_binary, sizeof(K_binary), &i, K); + if (gcry_mpi_print(GCRYMPI_FMT_USG, K_binary, sizeof(K_binary), &i, K) != 0) { + dhx_release_key(); + return AFPERR_PARAM; + } + + dhx_release_key(); if (i < KEYSIZE) { memmove(K_binary + sizeof(K_binary) - i, K_binary, i); @@ -853,6 +897,7 @@ static int uam_setup(void *obj _U_, const char *path) static void uam_cleanup(void) { + dhx_release_key(); uam_unregister(UAM_SERVER_LOGIN, "DHCAST128"); uam_unregister(UAM_SERVER_CHANGEPW, "DHCAST128"); #if 0 diff --git a/etc/uams/uams_dhx_passwd.c b/etc/uams/uams_dhx_passwd.c index c7900abdce0..f6e518e10bf 100644 --- a/etc/uams/uams_dhx_passwd.c +++ b/etc/uams/uams_dhx_passwd.c @@ -44,6 +44,15 @@ /*! the secret key */ gcry_mpi_t K; + +static void dhx_release_key(void) +{ + if (K != NULL) { + gcry_mpi_release(K); + K = NULL; + } +} + static struct passwd *dhxpwd; static uint8_t randbuf[16]; @@ -78,6 +87,7 @@ static int pwd_login(void *obj, char *username, int ulen, Rb = gcry_mpi_new(0); Ma = gcry_mpi_new(0); Mb = gcry_mpi_new(0); + dhx_release_key(); K = gcry_mpi_new(0); unsigned char Rb_binary[32], K_binary[16]; gcry_cipher_hd_t ctx; @@ -128,7 +138,11 @@ static int pwd_login(void *obj, char *username, int ulen, gcry_mpi_release(g); gcry_mpi_release(Ma); gcry_mpi_release(Rb); - gcry_mpi_print(GCRYMPI_FMT_USG, K_binary, sizeof(K_binary), &i, K); + + if (gcry_mpi_print(GCRYMPI_FMT_USG, K_binary, sizeof(K_binary), &i, K) != 0) { + *rbuflen = 0; + goto passwd_fail; + } if (i < KEYSIZE) { memmove(K_binary + sizeof(K_binary) - i, K_binary, i); @@ -140,7 +154,12 @@ static int pwd_login(void *obj, char *username, int ulen, memcpy(rbuf, &sessid, sizeof(sessid)); rbuf += sizeof(sessid); *rbuflen += sizeof(sessid); - gcry_mpi_print(GCRYMPI_FMT_USG, (unsigned char *) rbuf, KEYSIZE, &nwritten, Mb); + + if (gcry_mpi_print(GCRYMPI_FMT_USG, (unsigned char *) rbuf, KEYSIZE, + &nwritten, Mb) != 0) { + *rbuflen = 0; + goto passwd_fail; + } if (nwritten < KEYSIZE) { memmove(rbuf + KEYSIZE - nwritten, rbuf, nwritten); @@ -206,7 +225,7 @@ static int pwd_login(void *obj, char *username, int ulen, gcry_cipher_close(ctx); return AFPERR_AUTHCONT; passwd_fail: - gcry_mpi_release(K); + dhx_release_key(); return AFPERR_PARAM; } @@ -306,6 +325,13 @@ static int passwd_logincont(void *obj, struct passwd **uam_pwd, char *p; int err = AFPERR_NOTAUTH; *rbuflen = 0; + + /* Make sure pwd_login actually ran and established the shared key */ + if (K == NULL) { + LOG(log_error, logtype_uams, "DHX: logincont called without completing login"); + return AFPERR_PARAM; + } + /* check for session id */ memcpy(&sessid, ibuf, sizeof(sessid)); @@ -315,11 +341,18 @@ static int passwd_logincont(void *obj, struct passwd **uam_pwd, "uams_dhx_passwd.c :passwd Session ID - DHXHash Mismatch -- %s", strerror(errno)); /* Log Entry */ + dhx_release_key(); return AFPERR_PARAM; } ibuf += sizeof(sessid); - gcry_mpi_print(GCRYMPI_FMT_USG, K_binary, sizeof(K_binary), &i, K); + + if (gcry_mpi_print(GCRYMPI_FMT_USG, K_binary, sizeof(K_binary), &i, K) != 0) { + dhx_release_key(); + return AFPERR_PARAM; + } + + dhx_release_key(); if (i < KEYSIZE) { memmove(K_binary + sizeof(K_binary) - i, K_binary, i); @@ -428,6 +461,7 @@ static int uam_setup(void *obj, const char *path) static void uam_cleanup(void) { + dhx_release_key(); uam_unregister(UAM_SERVER_LOGIN, "DHCAST128"); #if 0 uam_unregister(UAM_SERVER_PRINTAUTH, "DHCAST128"); From 3e3a9b8e26d998204e4cc6881ba750cc9524fc2e Mon Sep 17 00:00:00 2001 From: Daniel Markstedt Date: Sat, 25 Apr 2026 18:20:11 +0200 Subject: [PATCH 3/5] uams: guard SRP logincont against missing session state Check that the SRP session verifier is set before proceeding in srp_logincont, preventing a NULL pointer dereference if the login step was skipped or failed. --- etc/uams/uams_srp.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/etc/uams/uams_srp.c b/etc/uams/uams_srp.c index 30008f81842..5ff04785a70 100644 --- a/etc/uams/uams_srp.c +++ b/etc/uams/uams_srp.c @@ -628,6 +628,14 @@ static int srp_logincont(void *obj _U_, struct passwd **uam_pwd, unsigned char A_buf[SRP_NBYTES]; unsigned char K[SRP_SESSION_KEY_LEN]; *rbuflen = 0; + + /* Make sure srp_setup actually ran and established session state */ + if (session_v == NULL) { + LOG(log_error, logtype_uams, "srp_logincont: called without completing setup"); + ret = AFPERR_PARAM; + goto fail; + } + unsigned char *d = (unsigned char *)ibuf; const unsigned char *end = d + ibuflen; From 98d3e087743622094244eab225d6ac7251899c68 Mon Sep 17 00:00:00 2001 From: Daniel Markstedt Date: Mon, 24 Aug 2026 07:24:08 +0200 Subject: [PATCH 4/5] uams: clear reply length on setup failure in DHX2 --- etc/uams/uams_dhx2_pam.c | 1 + etc/uams/uams_dhx2_passwd.c | 1 + 2 files changed, 2 insertions(+) diff --git a/etc/uams/uams_dhx2_pam.c b/etc/uams/uams_dhx2_pam.c index b323413b875..83c05c14374 100644 --- a/etc/uams/uams_dhx2_pam.c +++ b/etc/uams/uams_dhx2_pam.c @@ -370,6 +370,7 @@ static int dhx2_setup(void *obj, char *ibuf _U_, size_t ibuflen _U_, gcry_mpi_release(Ma); if (ret != AFPERR_AUTHCONT) { + *rbuflen = 0; dhx2_clear_session(); } diff --git a/etc/uams/uams_dhx2_passwd.c b/etc/uams/uams_dhx2_passwd.c index 4dd138f74fc..49a9394cf43 100644 --- a/etc/uams/uams_dhx2_passwd.c +++ b/etc/uams/uams_dhx2_passwd.c @@ -304,6 +304,7 @@ static int dhx2_setup(void *obj, char *ibuf _U_, size_t ibuflen _U_, gcry_mpi_release(Ma); if (ret != AFPERR_AUTHCONT) { + *rbuflen = 0; dhx2_clear_session(); } From 37e3dd0461a0ca7ac4b26af4f5c6fb711211693f Mon Sep 17 00:00:00 2001 From: Daniel Markstedt Date: Mon, 24 Aug 2026 07:24:14 +0200 Subject: [PATCH 5/5] uams: clear abandoned DHX nonces --- etc/uams/uams_dhx_pam.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/etc/uams/uams_dhx_pam.c b/etc/uams/uams_dhx_pam.c index 0d66c363963..a8a124e7070 100644 --- a/etc/uams/uams_dhx_pam.c +++ b/etc/uams/uams_dhx_pam.c @@ -199,6 +199,8 @@ static int dhx_setup(void *obj, const unsigned char *ibuf, size_t ibuflen _U_, uint16_t sessid; size_t i; size_t nwritten; + /* A new exchange supersedes any unfinished challenge. */ + explicit_bzero(randbuf, sizeof(randbuf)); if (!gcry_check_version(UAM_NEED_LIBGCRYPT_VERSION)) { LOG(log_error, logtype_uams, @@ -334,6 +336,7 @@ static int dhx_setup(void *obj, const unsigned char *ibuf, size_t ibuflen _U_, return AFPERR_AUTHCONT; pam_fail: dhx_release_key(); + explicit_bzero(randbuf, sizeof(randbuf)); /* Log Entry */ LOG(log_info, logtype_uams, "uams_dhx_pam.c :PAM: Fail - Cast Encryption -- %s", strerror(errno)); @@ -459,6 +462,7 @@ static int pam_logincont(void *obj, struct passwd **uam_pwd, /* Make sure dhx_setup actually ran and established the shared key */ if (K == NULL) { LOG(log_error, logtype_uams, "DHX: logincont called without completing login"); + explicit_bzero(randbuf, sizeof(randbuf)); return AFPERR_PARAM; } @@ -472,6 +476,7 @@ static int pam_logincont(void *obj, struct passwd **uam_pwd, strerror(errno)); /* Log Entry */ dhx_release_key(); + explicit_bzero(randbuf, sizeof(randbuf)); return AFPERR_PARAM; } @@ -486,6 +491,7 @@ static int pam_logincont(void *obj, struct passwd **uam_pwd, if (gcry_mpi_print(GCRYMPI_FMT_USG, K_binary, sizeof(K_binary), &i, K) != 0) { dhx_release_key(); + explicit_bzero(randbuf, sizeof(randbuf)); return AFPERR_PARAM; } @@ -501,6 +507,7 @@ static int pam_logincont(void *obj, struct passwd **uam_pwd, GCRY_CIPHER_MODE_CBC, 0); if (gcry_err_code(ctxerror) != GPG_ERR_NO_ERROR) { + explicit_bzero(randbuf, sizeof(randbuf)); return AFPERR_PARAM; } @@ -508,6 +515,7 @@ static int pam_logincont(void *obj, struct passwd **uam_pwd, ctxerror = gcry_cipher_setkey(ctx, K_binary, sizeof(K_binary)); if (gcry_err_code(ctxerror) != GPG_ERR_NO_ERROR) { + explicit_bzero(randbuf, sizeof(randbuf)); return AFPERR_PARAM; } @@ -515,6 +523,7 @@ static int pam_logincont(void *obj, struct passwd **uam_pwd, ctxerror = gcry_cipher_setiv(ctx, msg3_iv, sizeof(msg3_iv)); if (gcry_err_code(ctxerror) != GPG_ERR_NO_ERROR) { + explicit_bzero(randbuf, sizeof(randbuf)); return AFPERR_PARAM; } @@ -522,6 +531,7 @@ static int pam_logincont(void *obj, struct passwd **uam_pwd, ctxerror = gcry_cipher_decrypt(ctx, rbuf, CRYPT2BUFLEN, ibuf, CRYPT2BUFLEN); if (gcry_err_code(ctxerror) != GPG_ERR_NO_ERROR) { + explicit_bzero(randbuf, sizeof(randbuf)); return AFPERR_PARAM; } @@ -690,6 +700,7 @@ static int pam_changepw(void *obj, unsigned char *username, int PAM_error; if (ibuflen < sizeof(sessid)) { + explicit_bzero(randbuf, sizeof(randbuf)); return AFPERR_PARAM; } @@ -709,6 +720,7 @@ static int pam_changepw(void *obj, unsigned char *username, if (K == NULL) { LOG(log_error, logtype_uams, "DHX: changepw called without completing key exchange"); + explicit_bzero(randbuf, sizeof(randbuf)); return AFPERR_PARAM; } @@ -720,6 +732,7 @@ static int pam_changepw(void *obj, unsigned char *username, strerror(errno)); /* Log Entry */ dhx_release_key(); + explicit_bzero(randbuf, sizeof(randbuf)); return AFPERR_PARAM; } @@ -731,11 +744,13 @@ static int pam_changepw(void *obj, unsigned char *username, strerror(errno)); /* Log Entry */ dhx_release_key(); + explicit_bzero(randbuf, sizeof(randbuf)); return AFPERR_MISC; } if (gcry_mpi_print(GCRYMPI_FMT_USG, K_binary, sizeof(K_binary), &i, K) != 0) { dhx_release_key(); + explicit_bzero(randbuf, sizeof(randbuf)); return AFPERR_PARAM; } @@ -751,6 +766,7 @@ static int pam_changepw(void *obj, unsigned char *username, GCRY_CIPHER_MODE_CBC, 0); if (gcry_err_code(ctxerror) != GPG_ERR_NO_ERROR) { + explicit_bzero(randbuf, sizeof(randbuf)); return AFPERR_PARAM; } @@ -758,6 +774,7 @@ static int pam_changepw(void *obj, unsigned char *username, ctxerror = gcry_cipher_setkey(ctx, K_binary, sizeof(K_binary)); if (gcry_err_code(ctxerror) != GPG_ERR_NO_ERROR) { + explicit_bzero(randbuf, sizeof(randbuf)); return AFPERR_PARAM; } @@ -765,6 +782,7 @@ static int pam_changepw(void *obj, unsigned char *username, ctxerror = gcry_cipher_setiv(ctx, msg3_iv, sizeof(msg3_iv)); if (gcry_err_code(ctxerror) != GPG_ERR_NO_ERROR) { + explicit_bzero(randbuf, sizeof(randbuf)); return AFPERR_PARAM; } @@ -772,6 +790,7 @@ static int pam_changepw(void *obj, unsigned char *username, ctxerror = gcry_cipher_decrypt(ctx, ibuf, CHANGEPWBUFLEN, NULL, 0); if (gcry_err_code(ctxerror) != GPG_ERR_NO_ERROR) { + explicit_bzero(randbuf, sizeof(randbuf)); return AFPERR_PARAM; }