1/* $NetBSD: slapd-sha2.c,v 1.3 2021/08/14 16:14:53 christos Exp $ */ 2 3/* $OpenLDAP$ */ 4/* This work is part of OpenLDAP Software <http://www.openldap.org/>. 5 * 6 * Copyright 2009-2021 The OpenLDAP Foundation. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted only as authorized by the OpenLDAP 11 * Public License. 12 * 13 * A copy of this license is available in the file LICENSE in the 14 * top-level directory of the distribution or, alternatively, at 15 * <http://www.OpenLDAP.org/license.html>. 16 */ 17/* ACKNOWLEDGEMENT: 18 * This work was initially developed by Jeff Turner for inclusion 19 * in OpenLDAP Software. 20 * 21 * Hash methods for passwords generation added by C��dric Delfosse. 22 * 23 * SSHA256 / SSHA384 / SSHA512 support added, and chk_sha*() replaced 24 * with libraries/liblutil/passwd.c:chk_sha1() implementation to 25 * fix a race by SATOH Fumiyasu @ OSS Technology, Inc. 26 */ 27 28#include <sys/cdefs.h> 29__RCSID("$NetBSD: slapd-sha2.c,v 1.3 2021/08/14 16:14:53 christos Exp $"); 30 31#include "portable.h" 32 33#include <ac/string.h> 34 35#include "lber_pvt.h" 36#include "lutil.h" 37#include "sha2.h" 38 39#ifdef SLAPD_SHA2_DEBUG 40#include <stdio.h> 41#endif 42 43#define SHA2_SALT_SIZE 8 44 45static int hash_ssha256( 46 const struct berval *scheme, 47 const struct berval *passwd, 48 struct berval *hash, 49 const char **text ) 50{ 51 SHA256_CTX ct; 52 unsigned char hash256[SHA256_DIGEST_LENGTH]; 53 char saltdata[SHA2_SALT_SIZE]; 54 struct berval digest; 55 struct berval salt; 56 57 digest.bv_val = (char *) hash256; 58 digest.bv_len = sizeof(hash256); 59 salt.bv_val = saltdata; 60 salt.bv_len = sizeof(saltdata); 61 62 if (lutil_entropy((unsigned char *)salt.bv_val, salt.bv_len) < 0) { 63 return LUTIL_PASSWD_ERR; 64 } 65 66 SHA256_Init(&ct); 67 SHA256_Update(&ct, (const uint8_t*)passwd->bv_val, passwd->bv_len); 68 SHA256_Update(&ct, (const uint8_t*)salt.bv_val, salt.bv_len); 69 SHA256_Final(hash256, &ct); 70 71 return lutil_passwd_string64(scheme, &digest, hash, &salt); 72} 73 74static int hash_sha256( 75 const struct berval *scheme, 76 const struct berval *passwd, 77 struct berval *hash, 78 const char **text ) 79{ 80 SHA256_CTX ct; 81 unsigned char hash256[SHA256_DIGEST_LENGTH]; 82 struct berval digest; 83 digest.bv_val = (char *) hash256; 84 digest.bv_len = sizeof(hash256); 85 86 SHA256_Init(&ct); 87 SHA256_Update(&ct, (const uint8_t*)passwd->bv_val, passwd->bv_len); 88 SHA256_Final(hash256, &ct); 89 90 return lutil_passwd_string64(scheme, &digest, hash, NULL); 91} 92 93static int hash_ssha384( 94 const struct berval *scheme, 95 const struct berval *passwd, 96 struct berval *hash, 97 const char **text ) 98{ 99 SHA384_CTX ct; 100 unsigned char hash384[SHA384_DIGEST_LENGTH]; 101 char saltdata[SHA2_SALT_SIZE]; 102 struct berval digest; 103 struct berval salt; 104 105 digest.bv_val = (char *) hash384; 106 digest.bv_len = sizeof(hash384); 107 salt.bv_val = saltdata; 108 salt.bv_len = sizeof(saltdata); 109 110 if (lutil_entropy((unsigned char *)salt.bv_val, salt.bv_len) < 0) { 111 return LUTIL_PASSWD_ERR; 112 } 113 114 SHA384_Init(&ct); 115 SHA384_Update(&ct, (const uint8_t*)passwd->bv_val, passwd->bv_len); 116 SHA384_Update(&ct, (const uint8_t*)salt.bv_val, salt.bv_len); 117 SHA384_Final(hash384, &ct); 118 119 return lutil_passwd_string64(scheme, &digest, hash, &salt); 120} 121 122static int hash_sha384( 123 const struct berval *scheme, 124 const struct berval *passwd, 125 struct berval *hash, 126 const char **text ) 127{ 128 SHA384_CTX ct; 129 unsigned char hash384[SHA384_DIGEST_LENGTH]; 130 struct berval digest; 131 digest.bv_val = (char *) hash384; 132 digest.bv_len = sizeof(hash384); 133 134 SHA384_Init(&ct); 135 SHA384_Update(&ct, (const uint8_t*)passwd->bv_val, passwd->bv_len); 136 SHA384_Final(hash384, &ct); 137 138 return lutil_passwd_string64(scheme, &digest, hash, NULL); 139} 140 141static int hash_ssha512( 142 const struct berval *scheme, 143 const struct berval *passwd, 144 struct berval *hash, 145 const char **text ) 146{ 147 SHA512_CTX ct; 148 unsigned char hash512[SHA512_DIGEST_LENGTH]; 149 char saltdata[SHA2_SALT_SIZE]; 150 struct berval digest; 151 struct berval salt; 152 153 digest.bv_val = (char *) hash512; 154 digest.bv_len = sizeof(hash512); 155 salt.bv_val = saltdata; 156 salt.bv_len = sizeof(saltdata); 157 158 if (lutil_entropy((unsigned char *)salt.bv_val, salt.bv_len) < 0) { 159 return LUTIL_PASSWD_ERR; 160 } 161 162 SHA512_Init(&ct); 163 SHA512_Update(&ct, (const uint8_t*)passwd->bv_val, passwd->bv_len); 164 SHA512_Update(&ct, (const uint8_t*)salt.bv_val, salt.bv_len); 165 SHA512_Final(hash512, &ct); 166 167 return lutil_passwd_string64(scheme, &digest, hash, &salt); 168} 169 170static int hash_sha512( 171 const struct berval *scheme, 172 const struct berval *passwd, 173 struct berval *hash, 174 const char **text ) 175{ 176 SHA512_CTX ct; 177 unsigned char hash512[SHA512_DIGEST_LENGTH]; 178 struct berval digest; 179 digest.bv_val = (char *) hash512; 180 digest.bv_len = sizeof(hash512); 181 182 SHA512_Init(&ct); 183 SHA512_Update(&ct, (const uint8_t*)passwd->bv_val, passwd->bv_len); 184 SHA512_Final(hash512, &ct); 185 186 return lutil_passwd_string64(scheme, &digest, hash, NULL); 187} 188 189#ifdef SLAPD_SHA2_DEBUG 190static void chk_sha_debug( 191 const struct berval *scheme, 192 const struct berval *passwd, 193 const struct berval *cred, 194 const char *cred_hash, 195 size_t cred_len, 196 int cmp_rc) 197{ 198 int rc; 199 struct berval cred_b64; 200 201 cred_b64.bv_len = LUTIL_BASE64_ENCODE_LEN(cred_len) + 1; 202 cred_b64.bv_val = ber_memalloc(cred_b64.bv_len + 1); 203 204 if( cred_b64.bv_val == NULL ) { 205 return; 206 } 207 208 rc = lutil_b64_ntop( 209 (unsigned char *) cred_hash, cred_len, 210 cred_b64.bv_val, cred_b64.bv_len ); 211 212 if( rc < 0 ) { 213 ber_memfree(cred_b64.bv_val); 214 return; 215 } 216 217 fprintf(stderr, "Validating password\n"); 218 fprintf(stderr, " Hash scheme:\t\t%s\n", scheme->bv_val); 219 fprintf(stderr, " Password to validate: %s\n", cred->bv_val); 220 fprintf(stderr, " Password hash:\t%s\n", cred_b64.bv_val); 221 fprintf(stderr, " Stored password hash:\t%s\n", passwd->bv_val); 222 fprintf(stderr, " Result:\t\t%s\n", cmp_rc ? "do not match" : "match"); 223 224 ber_memfree(cred_b64.bv_val); 225} 226#endif 227 228static int chk_ssha256( 229 const struct berval *scheme, /* Scheme of hashed reference password */ 230 const struct berval *passwd, /* Hashed reference password to check against */ 231 const struct berval *cred, /* user-supplied password to check */ 232 const char **text ) 233{ 234 SHA256_CTX SHAcontext; 235 unsigned char SHAdigest[SHA256_DIGEST_LENGTH]; 236 int rc; 237 unsigned char *orig_pass = NULL; 238 size_t decode_len = LUTIL_BASE64_DECODE_LEN(passwd->bv_len); 239 240 /* safety check */ 241 if (decode_len <= sizeof(SHAdigest)) { 242 return LUTIL_PASSWD_ERR; 243 } 244 245 /* base64 un-encode password */ 246 orig_pass = (unsigned char *) ber_memalloc(decode_len + 1); 247 248 if( orig_pass == NULL ) return LUTIL_PASSWD_ERR; 249 250 rc = lutil_b64_pton(passwd->bv_val, orig_pass, decode_len); 251 252 if( rc <= (int)(sizeof(SHAdigest)) ) { 253 ber_memfree(orig_pass); 254 return LUTIL_PASSWD_ERR; 255 } 256 257 /* hash credentials with salt */ 258 SHA256_Init(&SHAcontext); 259 SHA256_Update(&SHAcontext, 260 (const unsigned char *) cred->bv_val, cred->bv_len); 261 SHA256_Update(&SHAcontext, 262 (const unsigned char *) &orig_pass[sizeof(SHAdigest)], 263 rc - sizeof(SHAdigest)); 264 SHA256_Final(SHAdigest, &SHAcontext); 265 266 /* compare */ 267 rc = memcmp((char *)orig_pass, (char *)SHAdigest, sizeof(SHAdigest)); 268 ber_memfree(orig_pass); 269 return rc ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK; 270} 271 272static int chk_sha256( 273 const struct berval *scheme, /* Scheme of hashed reference password */ 274 const struct berval *passwd, /* Hashed reference password to check against */ 275 const struct berval *cred, /* user-supplied password to check */ 276 const char **text ) 277{ 278 SHA256_CTX SHAcontext; 279 unsigned char SHAdigest[SHA256_DIGEST_LENGTH]; 280 int rc; 281 unsigned char *orig_pass = NULL; 282 size_t decode_len = LUTIL_BASE64_DECODE_LEN(passwd->bv_len); 283 284 /* safety check */ 285 if (decode_len < sizeof(SHAdigest)) { 286 return LUTIL_PASSWD_ERR; 287 } 288 289 /* base64 un-encode password */ 290 orig_pass = (unsigned char *) ber_memalloc(decode_len + 1); 291 292 if( orig_pass == NULL ) return LUTIL_PASSWD_ERR; 293 294 rc = lutil_b64_pton(passwd->bv_val, orig_pass, decode_len); 295 296 if( rc != sizeof(SHAdigest) ) { 297 ber_memfree(orig_pass); 298 return LUTIL_PASSWD_ERR; 299 } 300 301 /* hash credentials with salt */ 302 SHA256_Init(&SHAcontext); 303 SHA256_Update(&SHAcontext, 304 (const unsigned char *) cred->bv_val, cred->bv_len); 305 SHA256_Final(SHAdigest, &SHAcontext); 306 307 /* compare */ 308 rc = memcmp((char *)orig_pass, (char *)SHAdigest, sizeof(SHAdigest)); 309#ifdef SLAPD_SHA2_DEBUG 310 chk_sha_debug(scheme, passwd, cred, (char *)SHAdigest, sizeof(SHAdigest), rc); 311#endif 312 ber_memfree(orig_pass); 313 return rc ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK; 314} 315 316static int chk_ssha384( 317 const struct berval *scheme, /* Scheme of hashed reference password */ 318 const struct berval *passwd, /* Hashed reference password to check against */ 319 const struct berval *cred, /* user-supplied password to check */ 320 const char **text ) 321{ 322 SHA384_CTX SHAcontext; 323 unsigned char SHAdigest[SHA384_DIGEST_LENGTH]; 324 int rc; 325 unsigned char *orig_pass = NULL; 326 size_t decode_len = LUTIL_BASE64_DECODE_LEN(passwd->bv_len); 327 328 /* safety check */ 329 if (decode_len <= sizeof(SHAdigest)) { 330 return LUTIL_PASSWD_ERR; 331 } 332 333 /* base64 un-encode password */ 334 orig_pass = (unsigned char *) ber_memalloc(decode_len + 1); 335 336 if( orig_pass == NULL ) return LUTIL_PASSWD_ERR; 337 338 rc = lutil_b64_pton(passwd->bv_val, orig_pass, decode_len); 339 340 if( rc <= (int)(sizeof(SHAdigest)) ) { 341 ber_memfree(orig_pass); 342 return LUTIL_PASSWD_ERR; 343 } 344 345 /* hash credentials with salt */ 346 SHA384_Init(&SHAcontext); 347 SHA384_Update(&SHAcontext, 348 (const unsigned char *) cred->bv_val, cred->bv_len); 349 SHA384_Update(&SHAcontext, 350 (const unsigned char *) &orig_pass[sizeof(SHAdigest)], 351 rc - sizeof(SHAdigest)); 352 SHA384_Final(SHAdigest, &SHAcontext); 353 354 /* compare */ 355 rc = memcmp((char *)orig_pass, (char *)SHAdigest, sizeof(SHAdigest)); 356 ber_memfree(orig_pass); 357 return rc ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK; 358} 359 360static int chk_sha384( 361 const struct berval *scheme, /* Scheme of hashed reference password */ 362 const struct berval *passwd, /* Hashed reference password to check against */ 363 const struct berval *cred, /* user-supplied password to check */ 364 const char **text ) 365{ 366 SHA384_CTX SHAcontext; 367 unsigned char SHAdigest[SHA384_DIGEST_LENGTH]; 368 int rc; 369 unsigned char *orig_pass = NULL; 370 size_t decode_len = LUTIL_BASE64_DECODE_LEN(passwd->bv_len); 371 372 /* safety check */ 373 if (decode_len < sizeof(SHAdigest)) { 374 return LUTIL_PASSWD_ERR; 375 } 376 377 /* base64 un-encode password */ 378 orig_pass = (unsigned char *) ber_memalloc(decode_len + 1); 379 380 if( orig_pass == NULL ) return LUTIL_PASSWD_ERR; 381 382 rc = lutil_b64_pton(passwd->bv_val, orig_pass, decode_len); 383 384 if( rc != sizeof(SHAdigest) ) { 385 ber_memfree(orig_pass); 386 return LUTIL_PASSWD_ERR; 387 } 388 389 /* hash credentials with salt */ 390 SHA384_Init(&SHAcontext); 391 SHA384_Update(&SHAcontext, 392 (const unsigned char *) cred->bv_val, cred->bv_len); 393 SHA384_Final(SHAdigest, &SHAcontext); 394 395 /* compare */ 396 rc = memcmp((char *)orig_pass, (char *)SHAdigest, sizeof(SHAdigest)); 397#ifdef SLAPD_SHA2_DEBUG 398 chk_sha_debug(scheme, passwd, cred, (char *)SHAdigest, sizeof(SHAdigest), rc); 399#endif 400 ber_memfree(orig_pass); 401 return rc ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK; 402} 403 404static int chk_ssha512( 405 const struct berval *scheme, /* Scheme of hashed reference password */ 406 const struct berval *passwd, /* Hashed reference password to check against */ 407 const struct berval *cred, /* user-supplied password to check */ 408 const char **text ) 409{ 410 SHA512_CTX SHAcontext; 411 unsigned char SHAdigest[SHA512_DIGEST_LENGTH]; 412 int rc; 413 unsigned char *orig_pass = NULL; 414 size_t decode_len = LUTIL_BASE64_DECODE_LEN(passwd->bv_len); 415 416 /* safety check */ 417 if (decode_len <= sizeof(SHAdigest)) { 418 return LUTIL_PASSWD_ERR; 419 } 420 421 /* base64 un-encode password */ 422 orig_pass = (unsigned char *) ber_memalloc(decode_len + 1); 423 424 if( orig_pass == NULL ) return LUTIL_PASSWD_ERR; 425 426 rc = lutil_b64_pton(passwd->bv_val, orig_pass, decode_len); 427 428 if( rc <= (int)(sizeof(SHAdigest)) ) { 429 ber_memfree(orig_pass); 430 return LUTIL_PASSWD_ERR; 431 } 432 433 /* hash credentials with salt */ 434 SHA512_Init(&SHAcontext); 435 SHA512_Update(&SHAcontext, 436 (const unsigned char *) cred->bv_val, cred->bv_len); 437 SHA512_Update(&SHAcontext, 438 (const unsigned char *) &orig_pass[sizeof(SHAdigest)], 439 rc - sizeof(SHAdigest)); 440 SHA512_Final(SHAdigest, &SHAcontext); 441 442 /* compare */ 443 rc = memcmp((char *)orig_pass, (char *)SHAdigest, sizeof(SHAdigest)); 444 ber_memfree(orig_pass); 445 return rc ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK; 446} 447 448static int chk_sha512( 449 const struct berval *scheme, /* Scheme of hashed reference password */ 450 const struct berval *passwd, /* Hashed reference password to check against */ 451 const struct berval *cred, /* user-supplied password to check */ 452 const char **text ) 453{ 454 SHA512_CTX SHAcontext; 455 unsigned char SHAdigest[SHA512_DIGEST_LENGTH]; 456 int rc; 457 unsigned char *orig_pass = NULL; 458 size_t decode_len = LUTIL_BASE64_DECODE_LEN(passwd->bv_len); 459 460 /* safety check */ 461 if (decode_len < sizeof(SHAdigest)) { 462 return LUTIL_PASSWD_ERR; 463 } 464 465 /* base64 un-encode password */ 466 orig_pass = (unsigned char *) ber_memalloc(decode_len + 1); 467 468 if( orig_pass == NULL ) return LUTIL_PASSWD_ERR; 469 470 rc = lutil_b64_pton(passwd->bv_val, orig_pass, decode_len); 471 472 if( rc != sizeof(SHAdigest) ) { 473 ber_memfree(orig_pass); 474 return LUTIL_PASSWD_ERR; 475 } 476 477 /* hash credentials with salt */ 478 SHA512_Init(&SHAcontext); 479 SHA512_Update(&SHAcontext, 480 (const unsigned char *) cred->bv_val, cred->bv_len); 481 SHA512_Final(SHAdigest, &SHAcontext); 482 483 /* compare */ 484 rc = memcmp((char *)orig_pass, (char *)SHAdigest, sizeof(SHAdigest)); 485#ifdef SLAPD_SHA2_DEBUG 486 chk_sha_debug(scheme, passwd, cred, (char *)SHAdigest, sizeof(SHAdigest), rc); 487#endif 488 ber_memfree(orig_pass); 489 return rc ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK; 490} 491 492const struct berval ssha256scheme = BER_BVC("{SSHA256}"); 493const struct berval sha256scheme = BER_BVC("{SHA256}"); 494const struct berval ssha384scheme = BER_BVC("{SSHA384}"); 495const struct berval sha384scheme = BER_BVC("{SHA384}"); 496const struct berval ssha512scheme = BER_BVC("{SSHA512}"); 497const struct berval sha512scheme = BER_BVC("{SHA512}"); 498 499int init_module(int argc, char *argv[]) { 500 int result = 0; 501 result = lutil_passwd_add( (struct berval *)&ssha256scheme, chk_ssha256, hash_ssha256 ); 502 if (result != 0) return result; 503 result = lutil_passwd_add( (struct berval *)&sha256scheme, chk_sha256, hash_sha256 ); 504 if (result != 0) return result; 505 result = lutil_passwd_add( (struct berval *)&ssha384scheme, chk_ssha384, hash_ssha384 ); 506 if (result != 0) return result; 507 result = lutil_passwd_add( (struct berval *)&sha384scheme, chk_sha384, hash_sha384 ); 508 if (result != 0) return result; 509 result = lutil_passwd_add( (struct berval *)&ssha512scheme, chk_ssha512, hash_ssha512 ); 510 if (result != 0) return result; 511 result = lutil_passwd_add( (struct berval *)&sha512scheme, chk_sha512, hash_sha512 ); 512 return result; 513} 514