blog

slappasswdとopensslでsha256のハッシュ値が異なる

Published:

By nob

Category: Posts

Tags: OpenLDAP slappasswd OpenSSL GentooLinux

前提

software version
Gentoo Linux -
OpenLDAP 2.6.3
OpenSSL 3.0.11

事象

slappasswdを使ってパスワードを作成してOpenLDAPに登録したのだが認証が通らない。

原因

slappasswdとopensslで出力されるハッシュ値が異なる。

$ echo -n "abc" | openssl dgst -sha256 -binary | openssl enc -base64
ungWv48Bz+pBQUDeXa4iI7ADYaOWF3qctBD/YfIAFa0=

$ slappasswd -o module-path=/usr/lib64/openldap/openldap -o module-load=pw-sha2 -h '{sha256}' -s abc
{SHA256}Wyvqx+38PRBfZkNfDd9si6Ggf/eEIpvweskqiOtHVuw=

根本原因

slappasswdのコンパイルオプション(gccの最適化オプション)とソースコードの組み合わせの問題であるらしい。

slappasswd generating a strange password hash (SHA256 only)

Obviously we hitted with that error above a gcc-Compiler/Optimizer-Bug. The gcc-Version used on Ubuntu kinetic is 12.2.0.

We bisected the problem to the gcc-Optimizer (without any -O the error is gone). Finally: when the sha2-contrib-Module is (re-)built with the flag -fno-strict-aliasing the error goes away. This does not fix the gcc-Problem, but our ssha256-error with that particular module.

Diff:

--- a/contrib/slapd-modules/passwd/sha2/Makefile
+++ b/contrib/slapd-modules/passwd/sha2/Makefile
@@ -9,7 +9,7 @@
 LIBTOOL = $(LDAP_BUILD)/libtool
 INSTALL = /usr/bin/install
 CC = gcc
-OPT = -g -O2
+OPT = -g -O2 -fno-strict-aliasing
 DEFS =
 #DEFS = -DSLAPD_SHA2_DEBUG
 INCS = $(LDAP_INC)

Gentooのコンパイルオプションを見ると -O3 となっていた。

# grep COMMON_FLAGS /etc/portage/make.conf
COMMON_FLAGS="-march=haswell -O3 -pipe"

gcc option -f(no-)strict-aliasing

厳密な別名規約(aliasing rule)に則っているとみなすか、則っていないとみなすか。intの変数に対してshort*でアクセスするような行儀の悪いコードが無いと宣言できるなら-fstrict-aliasingにする。

#include <stdio.h>
int main(int argc, char* argv[]){
    int x = 0;
    short* p = (short*)&x;  // strict aliasing rule に則っていない
    *p = 1;                 // 例えばここで1を設定しても…
    printf("x = %d", x);    // 最適化によりこれが"x = 0"になる可能性がある
    return 0;
}

対策

コンパイルオプションの変更

# grep COMMON_FLAGS /etc/portage/make.conf
COMMON_FLAGS="-march=haswell -O2 -fno-strict-aliasing -pipe"