+
+static int chk_ssha256(
+ const struct berval *scheme, /* Scheme of hashed reference password */
+ const struct berval *passwd, /* Hashed reference password to check against */
+ const struct berval *cred, /* user-supplied password to check */
+ const char **text )
+{
+ SHA256_CTX SHAcontext;
+ unsigned char SHAdigest[SHA256_DIGEST_LENGTH];
+ int rc;
+ unsigned char *orig_pass = NULL;
+
+ /* safety check */
+ if (LUTIL_BASE64_DECODE_LEN(passwd->bv_len) <= sizeof(SHAdigest)) {
+ return LUTIL_PASSWD_ERR;
+ }
+
+ /* base64 un-encode password */
+ orig_pass = (unsigned char *) ber_memalloc( (size_t) (
+ LUTIL_BASE64_DECODE_LEN(passwd->bv_len) + 1) );
+
+ if( orig_pass == NULL ) return LUTIL_PASSWD_ERR;
+
+ rc = lutil_b64_pton(passwd->bv_val, orig_pass, passwd->bv_len);
+
+ if( rc <= sizeof(SHAdigest) ) {
+ ber_memfree(orig_pass);
+ return LUTIL_PASSWD_ERR;
+ }
+
+ /* hash credentials with salt */
+ SHA256_Init(&SHAcontext);
+ SHA256_Update(&SHAcontext,
+ (const unsigned char *) cred->bv_val, cred->bv_len);
+ SHA256_Update(&SHAcontext,
+ (const unsigned char *) &orig_pass[sizeof(SHAdigest)],
+ rc - sizeof(SHAdigest));
+ SHA256_Final(SHAdigest, &SHAcontext);
+
+ /* compare */
+ rc = memcmp((char *)orig_pass, (char *)SHAdigest, sizeof(SHAdigest));
+ ber_memfree(orig_pass);
+ return rc ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK;
+}
+
+static int chk_sha256(
+ const struct berval *scheme, /* Scheme of hashed reference password */
+ const struct berval *passwd, /* Hashed reference password to check against */
+ const struct berval *cred, /* user-supplied password to check */
+ const char **text )
+{
+ SHA256_CTX SHAcontext;
+ unsigned char SHAdigest[SHA256_DIGEST_LENGTH];
+ int rc;
+ unsigned char *orig_pass = NULL;
+
+ /* safety check */
+ if (LUTIL_BASE64_DECODE_LEN(passwd->bv_len) < sizeof(SHAdigest)) {
+ return LUTIL_PASSWD_ERR;
+ }
+
+ /* base64 un-encode password */
+ orig_pass = (unsigned char *) ber_memalloc( (size_t) (
+ LUTIL_BASE64_DECODE_LEN(passwd->bv_len) + 1) );
+
+ if( orig_pass == NULL ) return LUTIL_PASSWD_ERR;
+
+ rc = lutil_b64_pton(passwd->bv_val, orig_pass, passwd->bv_len);
+
+ if( rc != sizeof(SHAdigest) ) {
+ ber_memfree(orig_pass);
+ return LUTIL_PASSWD_ERR;
+ }
+
+ /* hash credentials with salt */
+ SHA256_Init(&SHAcontext);
+ SHA256_Update(&SHAcontext,
+ (const unsigned char *) cred->bv_val, cred->bv_len);
+ SHA256_Final(SHAdigest, &SHAcontext);
+
+ /* compare */
+ rc = memcmp((char *)orig_pass, (char *)SHAdigest, sizeof(SHAdigest));
+#ifdef SLAPD_SHA2_DEBUG
+ chk_sha_debug(scheme, passwd, cred, (char *)SHAdigest, sizeof(SHAdigest), rc);
+#endif
+ ber_memfree(orig_pass);
+ return rc ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK;
+}
+
+static int chk_ssha384(
+ const struct berval *scheme, /* Scheme of hashed reference password */
+ const struct berval *passwd, /* Hashed reference password to check against */
+ const struct berval *cred, /* user-supplied password to check */
+ const char **text )
+{
+ SHA384_CTX SHAcontext;
+ unsigned char SHAdigest[SHA384_DIGEST_LENGTH];
+ int rc;
+ unsigned char *orig_pass = NULL;
+
+ /* safety check */
+ if (LUTIL_BASE64_DECODE_LEN(passwd->bv_len) <= sizeof(SHAdigest)) {
+ return LUTIL_PASSWD_ERR;
+ }
+
+ /* base64 un-encode password */
+ orig_pass = (unsigned char *) ber_memalloc( (size_t) (
+ LUTIL_BASE64_DECODE_LEN(passwd->bv_len) + 1) );
+
+ if( orig_pass == NULL ) return LUTIL_PASSWD_ERR;
+
+ rc = lutil_b64_pton(passwd->bv_val, orig_pass, passwd->bv_len);
+
+ if( rc <= sizeof(SHAdigest) ) {
+ ber_memfree(orig_pass);
+ return LUTIL_PASSWD_ERR;
+ }
+
+ /* hash credentials with salt */
+ SHA384_Init(&SHAcontext);
+ SHA384_Update(&SHAcontext,
+ (const unsigned char *) cred->bv_val, cred->bv_len);
+ SHA384_Update(&SHAcontext,
+ (const unsigned char *) &orig_pass[sizeof(SHAdigest)],
+ rc - sizeof(SHAdigest));
+ SHA384_Final(SHAdigest, &SHAcontext);
+
+ /* compare */
+ rc = memcmp((char *)orig_pass, (char *)SHAdigest, sizeof(SHAdigest));
+ ber_memfree(orig_pass);
+ return rc ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK;