Compilazione cie-middleware-linux su Raspberry Pi

Ciao tutti.
Spero di esser così fortunato da trovare qualcuno della community che abbia affrontato il problema.

Il mio obiettivo è quello di replicare i due progetti che ho realizzato Raspberry Pi – Un esempio di applicazione della TS-CNS e Raspberry Pi e Smart Card Mifare Classic 1K: Realizzare un sistema di accesso utilizzando la CIE.

Per usare la CIE siamo purtroppo obbligati a usare il cie-middleware (in questo caso la versione linux) , al contrario della CNS e TS-CNS per cui è possibile usare i tool solitamente distribuiti con Linux, in questo caso OpenSC.

Mi sono avventurato a compilare il cie-middleware-linux direttamente sul mio Raspberry Pi 4 (con Rasperry Pi OS 64bit) cercando di seguire la scarna documentazione, senza però alcun risultato. Ho scritto diverse issue in merito e putroppo non ho ricevuto nessuna risposta ad oggi.

Ho abbandonato il progetto di developers italia e seguito il fork di Gianluca Boiano (GitHub - M0Rf30/cie-middleware-linux at main) che ha fatto un ottimo lavoro di ristrutturazione del progetto che finalmente é possibile compilare da linea di comando, senza dover usare Eclipse.

Sull’architettura ARM ho dovuto ricompilare due librerie (che sul progetto originale “includono in forma statica”), podofo e cryptopp di cui non sono disponibili direttamente i binari per ARM.

Dopo aver ricompilato le due librerie e installate, sono riuscito a eseguire con successo la compilazione del cie-middleware-linux sul Raspberry Pi, ottenendo in questo modo il modulo PCKS#11 libcie-pkcs11.so, che poi è l’unico che mi serve. L’applicazione Java CIE non mi è utile, la procedura di associazione posso farla benissimo a linea di comando (con un semplice programmino). Su questo aspetto non capisco perché OOTB abbiano reso possibile l’associazione della CIE solo attraverso il programma CIEID (Java) che via JNI richiama la funzione nativa AbilitaCIE.

Dopo aver quindi installato sul mio Raspberry Pi il middleware-linux, ho compilato il programma di test (che forse non tutti conoscono), TestCIE utilizzando il comando g++ -o TestCIE TestCIE.cpp UUCByteArray.cpp -ldl -g .

Il comando TestCIE dispone di una test suite composta da ben 14 test di vario tipo eseguiti sulla CIE. Ho eseguito il programma che con mia grande sorpresa è partito, purtroppo all’esecuzione del primo test è fallito.

A seguire mostro lo stacktrace completo dell’errore, ottenuto grazie al gdb e al fatto di aver usato il flag -g che aggiunge i simboli di debug. Il problema accade nel momento in cui va a caricare la libreria libcie-pkcs11.so tramite la dlopen e cerca di utilizzare la una delle funzioni della libreria CryptoPP.

Load Module libcie-pkcs11.so
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/aarch64-linux-gnu/libthread_db.so.1".

Program received signal SIGILL, Illegal instruction.
0x0000007ff734dde8 in CryptoPP::CPU_ProbePMULL() () from /lib/aarch64-linux-gnu/libcrypto++.so.8
(gdb) bt
#0  0x0000007ff734dde8 in CryptoPP::CPU_ProbePMULL() () from /lib/aarch64-linux-gnu/libcrypto++.so.8
#1  0x0000007ff7261848 in CryptoPP::DetectArmFeatures() () from /lib/aarch64-linux-gnu/libcrypto++.so.8
#2  0x0000007ff7fdac9c in call_init (l=<optimized out>, argc=argc@entry=1, argv=argv@entry=0x7ffffff3f8, env=env@entry=0x7ffffff408) at dl-init.c:72
#3  0x0000007ff7fdada4 in call_init (env=0x7ffffff408, argv=0x7ffffff3f8, argc=1, l=<optimized out>) at dl-init.c:30
#4  _dl_init (main_map=0x555557f5e0, argc=1, argv=0x7ffffff3f8, env=0x7ffffff408) at dl-init.c:119
#5  0x0000007ff7d55b14 in __GI__dl_catch_exception (exception=0x0, operate=0x7ff7fde130 <call_dl_init>, args=0x7fffffe510) at dl-error-skeleton.c:182
#6  0x0000007ff7fded28 in dl_open_worker (a=a@entry=0x7fffffe760) at dl-open.c:758
#7  0x0000007ff7d55ab4 in __GI__dl_catch_exception (exception=0x7fffffe748, operate=0x7ff7fde9b0 <dl_open_worker>, args=0x7fffffe760) at dl-error-skeleton.c:208
#8  0x0000007ff7fde610 in _dl_open (file=0x5555559900 "libcie-pkcs11.so", mode=-2147483647, caller_dlopen=0x5555554460 <main(int, char**)+608>, nsid=-2, argc=1, argv=0x7ffffff3f8, env=0x7ffffff408) at dl-open.c:837
#9  0x0000007ff7fb9264 in dlopen_doit (a=a@entry=0x7fffffea18) at dlopen.c:66
#10 0x0000007ff7d55ab4 in __GI__dl_catch_exception (exception=exception@entry=0x7fffffe9a0, operate=0x7ff7fb9200 <dlopen_doit>, args=0x7fffffea18) at dl-error-skeleton.c:208
#11 0x0000007ff7d55b80 in __GI__dl_catch_error (objname=0x7ff7fcb0c8 <last_result+16>, errstring=0x7ff7fcb0d0 <last_result+24>, mallocedp=0x7ff7fcb0c0 <last_result+8>, operate=<optimized out>, args=<optimized out>)
    at dl-error-skeleton.c:227
#12 0x0000007ff7fb9b10 in _dlerror_run (operate=operate@entry=0x7ff7fb9200 <dlopen_doit>, args=args@entry=0x7fffffea18) at dlerror.c:170
#13 0x0000007ff7fb9304 in __dlopen (file=<optimized out>, mode=<optimized out>) at dlopen.c:87
#14 0x0000005555554460 in main (argc=1, argv=0x7ffffff3f8) at TestCIE.cpp:794
(gdb)

L’immagine a seguire è proprio l’output a fronte dell’esecuzione del primo test previsto dal programma TestCIE.

Spero di essere stato chiaro nell’esposizione del mio obiettivo e del problema che ho incontrato e che mi piacerebbe risolvere.

Prima di mettere di “persona personalmente”, le mani in pasta al problema, chiedo a voi se avete riscontrato questo problema o avete avuto questa necessità, e chiedo anche ai manutentori di questo progetto di fare uno sforzo per rispondere alle richieste di aiuto.

Grazie.

3 Mi Piace

Mah, non riuscirò mai a capire come funziona Github. Il fork di cui parli non è segnato tra i branches. Chissà quanti altri ce ne sono…
modifica: Ho capito, bastava cliccare su 12 forks

L’errore che riscontri sembra collegato a libcrypto++, non al software CIE. Io uso Devuan, che è pure Debian-based, e ho installato libcrypto++-dev:amd64. Secondo Debian, la versione ARM esiste.

Io ho compilato il middleware usando un orrido script messo assieme seguendo le indicazioni per Eclipse e un po’ di buon senso. Se a qualcuno interessa:

#! /bin/sh
#
# Tentative script to allow compilation without Eclipse.
# Must be launched from the project base directory.

PROJ_DIR=$(pwd)
CIEPKI_DIR=$PROJ_DIR/cie-pkcs11
CIESDK_DIR=$PROJ_DIR/cie_sign_sdk
TARGET_DIR=$PROJ_DIR/Debug

INCLUDE="-I/usr/include/PCSC -I$CIEPKI_DIR/Util -I$CIEPKI_DIR/PKCS11"

GOPT="-D__STDC_LIB_EXT1__ -O0 -g3 -Wall -c -fmessage-length=0 -fPIC -pthread"

# Set NO_DEP to use native libraries
if [ -z "$NO_DEP" ]; then
	DEPENDENCIES="-L$CIESDK_DIR/Dependencies/zlib
	 -L$CIESDK_DIR/Dependencies/openssl
	 -L$CIESDK_DIR/Dependencies/libiconv
	 -L$CIESDK_DIR/Dependencies/libpng
	 -L$CIEPKI_DIR
	 -L$CIEPKI_DIR/Sign
	 -L$CIESDK_DIR/Dependencies/bzip2
	 -L$CIESDK_DIR/Dependencies/fontconfig
	 -L$CIESDK_DIR/Dependencies/freetype
	 -L$CIESDK_DIR/Dependencies/libcurl
	 -L$CIESDK_DIR/Dependencies/libxml2
	 -L$CIESDK_DIR/Dependencies/podofo"

	LIBS="-lcryptopp -lssl -lfontconfig -lcurl -lbz2 -lfreetype -lpng16 -lz -lcie_sign_sdk -lcrypto -lpcsclite -lxml2 -lpodofo"
else
	unset DEPENDENCIES
	GOPT="-DDEFINE_CFuncCallInfo $GOPT"
	LIBS="-Wl,-Bstatic -lcrypto++ -Wl,-Bdynamic -lpcsclite -lxml2 -lcrypto"
fi


if cd $TARGET_DIR; then
	ALL_OBJ=""
	for src in $(find ../cie-pkcs11 -type f -name \*.cpp); do
		failed=1
		obj=$(echo $src| sed -e 's/^\.\.\///' -e 's/.cpp$/.o/')
		mkdir -p $(dirname $obj) || break
		echo "Compile $src"
		g++ $INCLUDE $GOPT -o $obj $src || break
		ALL_OBJ="$ALL_OBJ $obj"
		failed=0
	done

	if [ $failed = 0 ]; then
		echo "Linking with $LIBS"
		g++ $DEPENDENCIES -Xlinker --allow-multiple-definition -Xlinker --undefined=EVP_idea_cbc -Xlinker --undefined=TLS_client_method -Xlinker --undefined=curl_global_init -Xlinker --undefined=png_get_valid -Xlinker --undefined=FcInitLoadConfigAndFonts -shared -pthread -o libcie-pkcs11.so $ALL_OBJ $LIBS && echo "Link ok"
	fi
fi

(Per usare NO_DEP, sostituire #if 0 con #if DEFINE_CFuncCallInfo.)
correzione: per il link aggiunto -lcrypto.

1 Mi Piace

Grazie per la tua risposta. Io ho infatti installato la versione per ARM di libcrypto. Deve esserci qualche problema nella chiamata dal software di TestCIE.

Quello che hai postato fa riferimento al sistema Raspberry Pi (ARM) o su normale PC x86?

Io ho provato solo su amd64. Ho aggiunto l’ennesimo fork con queste due modifiche… Per ora i test funzionano, ma non riesco a fare login su FireFox (ho un bug aperto per questo.)

Noto qualche differenza nei link, non so quanto rilevanti:

  • Da qualche parte ho letto che cryptopp dev’essere linkato statico. Nello script qui sopra uso -Wl,-Bstatic -lcrypto++
  • Ho corretto lo stesso script, aggiungendo -lcrypto.
  • Per compilare il test devo mettere -pthread: g++ -g -W -O0 -o TestCIE -pthread TestCIE.cpp UUCByteArray.cpp -ldl . Sennò crasha subito.

Grazie Alessandro.
Analizzando più a fondo le caratteristiche del processore ARM utilizzato dal Raspberry Pi 4, il BCM2835, su questa versione non sono presenti le caratteristiche crittografiche hardware richieste, come in questo caso PMULL/PMULL2. A seguire l’output del comando lscpu.

Andando a leggere il datasheet dell’[ARM Cortex-A72](file:///Users/antonio.musarra/Downloads/cortex_a72_mpcore_trm_100095_0003_06_en.pdf) è evidenziato in una nota, che le funzionalità del motore crittografico sono incluse solo sotto specifica licenza.

Grazie.

Architecture:                    aarch64
CPU op-mode(s):                  32-bit, 64-bit
Byte Order:                      Little Endian
CPU(s):                          4
On-line CPU(s) list:             0-3
Thread(s) per core:              1
Core(s) per socket:              4
Socket(s):                       1
Vendor ID:                       ARM
Model:                           3
Model name:                      Cortex-A72
Stepping:                        r0p3
CPU max MHz:                     1800.0000
CPU min MHz:                     600.0000
BogoMIPS:                        108.00
Vulnerability Itlb multihit:     Not affected
Vulnerability L1tf:              Not affected
Vulnerability Mds:               Not affected
Vulnerability Meltdown:          Not affected
Vulnerability Spec store bypass: Vulnerable
Vulnerability Spectre v1:        Mitigation; __user pointer sanitization
Vulnerability Spectre v2:        Vulnerable
Vulnerability Srbds:             Not affected
Vulnerability Tsx async abort:   Not affected
Flags:                           fp asimd evtstrm crc32 cpuid