Appunti vari per criptocamere disperate. Quale piattaforma supportare? questo e’ il problema
- 1 Le foto
- 2 Canon CHDK (compatte)
- 3 Canon MagicLantern (le reflex)
- 4 Android
- 5 Fare SD Emulation
- 6 SD WiFi
- 7 Esperimenti
Le foto¶
in che qualita’ e’ necessario fare le foto?
Canon CHDK (compatte)¶
Device supportati¶
Piu’ o meno tutte le canon point-and-shoot (quindi le compatte). Si trovano abbastanza facilmente abbandonate nei cassetti (specie quelle di qualche anno fa), o si comprano a partire dagli 80 pleuri
Scrittura software¶
un po’ un casino, bisogna fare un hook sulla filewritetask e dovremmo capire come si fa.
Cose interessanti:
- chdk.wikia.com/wiki/Script_Shooting_Hoo... solo in chdk 1.3, con questo si potrebbe cifrare direttamente il raw, cercando poi di “sabotare” la scrittura del jpeg sulla sd. Fare hook sul jpeg non sembra invece possibile, al momento.
Il codice C e’ abbastanza ordinato, sembra anche semplice inserire alcune funzioni computazionalmente costose direttamente in C, e renderle chiamabili da lua.
Prove fatte¶
A610¶
Sulla a610 il firmware 1.2 e l’1.3 funzionano senza problemi, usando la revisione 100e
(la 100f
non funziona).
Per modificare il firmware ci serve preparare un sistema di build.
Toolchain¶
OK FUNZIONA
sudo debootstrap jessie criptocamera
cat <<EOF >> jessie/root/.bashrc
export PATH="/bin:/sbin:$PATH"
export PATH="/root/build-dir/arm/toolchain/bin:$PATH"
EOF
sudo chroot criptocamera /bin/bash
da dentro, fate:
aptitude install -y build-essential libmpfr-dev zlib1g-dev subversion zip
cd /root
wget 'http://pappp.net/wp-content/uploads/2013/10/chdk-gcc454.sh' -O maketutto.sh
bash maketutto.sh
svn co https://tools.assembla.com/svn/chdk/trunk chdk
make batch-zip
e quello vi fa TUTTI i firmware. Se volete fare prima fate
make PLATFORM=vostromodello PLATFORMSUB=sottocosa clean fir
tipo per me PLATFORM=a610 PLATFORMSUB=100e
Nota che se invece di fare svn checkout
fai git clone
di un repo equivalente, pare non funzionare un cazzo
Dentro bin/
vi trovate tutti gli zip pronti per essere messi nella vostra fotocamera
Il codice¶
C’e’ il github github.com/boyska/chdkripto cha fa gia’ qualcosa:
- cifra file (expost, non al momento dello scatto)
- ma solo se sono piccoli
- e le chiavi sono hardcodate
- e abbiamo rotto la
randbytes()
- ed e’ lentissimo perche’ deve fare buffer piccoli perche’ la ram scarseggia e la
crypto_box
non galleggia
comunque siamo gia’ contenti
Canon MagicLantern (le reflex)¶
Device supportati¶
Le canon che finiscono con la D
Scrittura software¶
C’e’ gia’ qualcosa:
- https://bitbucket.org/hudson/magic-lantern/src/c62e719cc9d54c6e801e5e1d97f880
cfa9ad8d8f/modules/io_crypt/?at=unified
Android¶
Device supportati¶
Tutti gli android, incluse le android-camera
AndroidCamere¶
costano >= 100 neuri e sono paragonabili a delle compatte e sono riflashabili, rootabili, ecc
nikon coolpix s800c
Scrittura software¶
Piuttosto semplice. Esempi simili:
- github.com/guardianproject/securecamera
- https://guardianproject.info/informa/
Fare SD Emulation¶
Programmarsi un chippino che si “interfacci” come se fosse SD.
A occhio, e’ un delirio vero.
Pro:
- molto yeah
- probabilmente economico
Contro: - panico vero
SD WiFi¶
Molte schede che vengono vendute come “sd+wifi” hanno linux all’interno e hanno parecchi modi per essere hackate in modo semplice. Tipicamente se si mette un autorun.sh sulla scheda SD, quello viene eseguito. Si puo’ anche modificare direttamente l’initramfs, tutto senza dover riflashare ne’ rischio di brickare.
link.autistici.org/bookmarks.php/avana/sd
Pro:
- tutte le fotocamere che supportano sdhc diventano magicamente criptocamere
- e’ gnu/linux, quindi fare modifiche e’ abbastanza semplice
- le risorse non sembrano molto scarse: 15MB di RAM libera (29MB totali), un processore armv5 dalle performance perora sconosciute
Contro:
- non costano proprio pochissimo: tipo 40$ l’una. Pero’ le PQi hanno lo slot microsd, quindi almeno sullo storage si risparmia. Inoltre si puo’ “cambiare sw” switchando scheda.
- La cifratura e’ comunque expost, quindi il dato passa non cifrato sulla scheda.
Modelli¶
- Transcend wifi
- PQi Air Card (sembra uguale alla transcend, tranne che invece di avere la memoria loro stesse, hanno lo slot microsdhc)
- Flucam (non e’ chiaro se il suo firmware e’ diverso dagli altri, l’hw pare sia lo stesso); ha un buzzer (!) e pare scaldi parecchio
secondo dei tipi sul forum di openwrt la cosa meglio e’ la pqi, ma le microsd che ti danno incluse fanno un po’ rate, quindi poi magari ce ne metti di meglio.
Cose da fare¶
- Creazione ambiente di sviluppo per armv5 (su debian c’e’ il crosscompile)
- scrittura tool di (de)cifratura asimmetrica (con libsodium o tweetnacl, sentire spartak)
- scrittura tool che monitora periodicamente in attesa di nuove foto
Accesso in scrittura¶
Occhio!
In fondo a quest articolo fanno notare che
FAT32 is not a clustered filesystem and is not safe (will loose data integrity) with concurrent access. There may be
some mechanisms being used by the card to solve this, however I have repeatedly corrupted the filesystem when writing to
it from both SD and OS. I can’t be sure that anything I’m doing will be safe any guarantee data integrity – there is a
risk you could corrupt the SD filesystem and loose all your data.
Quindi servono dei trucchetti per salvare le cose dentro la SD.
Il modo in cui il tutto funziona viene mezzo spiegato anche sul solito forum dove spiegano che c’e’ una sorta di switch sul master, la fotocamera ha priorita’, ma comunque il tutto e’ trasparente. Forse partizionare puo’ essere una soluzione? Su un post pazzesco in cui uno mette firefox su sta roba nei commenti c’e’ un tale Charles che dice che lui ha partizionato per evitare di accavallarsi, e gli e’ andato tutto bene.
curve ellittiche¶
codice di chdk¶
Si puo’ provare il vecchio tool scritto per chdkripto. Compila (anche statico), in emulazione funziona, pero’ non legge dai file: gli devi dare il messaggio come argomento!!
blobcrypt¶
Oppure direttamente blobcrypt: github.com/jedisct1/blobcrypt che dovrebbe gestire gli stream di dati assai meglio
chiavi con pochi uni¶
Idea presa dalla lista hackmeeting
Usare NTRU¶
Un tipo ad hackmeeting suggeriva ntru
Esperimenti¶
Cose fatte sul PQi AirCard:
- non e’ banale alimentarla bene: sia un cosariello usb sia il lettore sd integrato nell’eee 701 non je la fanno. Il primo proprio non batte ciglio, il secondo pare andare ma poi si spegne. Invece una fotocamera canon powershot a2600 ce la fa senza battere ciglio.
- a volte l’avvio del wifi e’ piu’ lento, ma in genere e’ rapido.
- telnetd si avvia da solo senza nemmeno fare un autorun.sh
- non c’e’ ext2 nel kernel
- quando prepari il chroot arm, occhio: qemu-arm-static deve stare dentro il chroot nello stesso path in cui sta fuori: ovvero tipicamente in
/usr/bin
Toolchain¶
E’ abbastanza comodo creare una toolchain con buildroot (manuale).
si fa cosi’:
- scarichi buildroot-2015.05 (che ad ora e’ la piu’ recente, poi magari no)
- usi il config allegato
make defconfig BR2_DEFCONFIG=/path/to/downloaded/sdwifi.config
make toolchain
e dentro output/host ti trovi la toolchain. A quel punto quando vuoi usarla fai
export PATH=/per/co/rso/output/host/usr/bin:$PATH
export CC=arm-linux-cc
buildroot¶
oltre a creare toolchain (vedi sopra) buildroot e’ anche in grado di creare interi sistemi host.
C’e’ questo coso github.com/dankrause/kcard-buildroot che funziona ma e’ fatto per le transcend, e boh alla fine non funziona.
Comunque usando la 2015.05 di buildroot mi funziona.
expat
non compila, quindi con make menuconfig lo tolgo (si trova in target packages/libraries/json+xml o qualcosa del genere)
Solo che la root cosi’ creata non riesco ancora a farla bootare (vedi sotto)
cambiare firmware¶
fino ad ora avevo sempre lavorato sul file autorun.sh
che e’ bello pero’ e’ un po’ limitante perche’ comunque ti rimane l’OS “normale” ed e’ difficile buildare cose custom, e’ tutto strippato eccetera. Allora volevo cambiare il tutto. La descrizione del sistema e’ su dmitry.gr/index.php?r=05.Projects&proj=15.%20Transcend%20WiFiSD
The bootloader (u-boot, whose sources Transcend did NOT provide) reads the ramdisk into RAM, reads the kernel into ram, and jumps to it. The sizes are hardcoded in u-boot at 0×300000 bytes (exactly 3MB). This size limitation is rather annoying, since the existing ramdisk is already quite close to the limit, and addinig much more to it will push it over. Removing things from it is also dangerous – since my goal was to not open the card physically, if it does not boot and does not get onto WiFi, there is no way to debug it. Compressing the ramdisk using better compression was not an option either. Their kernel was not built with support for bzip2 or LZMA.
We need a way to flash this thing safely and effectively. Turns out that this job is done for us. The bootloader of the card will detect on boot if four files called “image3”, “initramfs3.gz”, “mtd_jffs2.bin” and “program.bin” exist, and, if so, load and run “program.bin”, which just so happens to be a copy of u-boot (did I meantion that they did not ship the sources?). This u-boot flashes the card’s NOR flash with these three pieces: kernel, ramdisk, and the small jffs2 filesystem. The way the card works is rather curious. Almost all of the code is in the ramdisk, but the size limitation must have bit them too. One library is not: “libcrypto.so.0.9.8” – it did not fit. They unpack it (bunzip2) from the jffs2 filesystem at boot into the RAM. The jffs2 filesystem is also where the settings are stored. This actually explains why flashing new firmware erases the settings – the entire NOR flash partition is overwritten with the new image.
Un’altra cosa importante e’ il commento sul post di hackaday: hackaday.com/2013/09/19/advanced-transcend-wifi-sd-hacking-custom-kernels-x-and-firefox/#comment-1061584
che dice:
Place my files on card. wait 1 min. remove card. reinsert card. wait 6 min (very important). remove card. reinsert card. wait till “wifisd” network shows up. connect to it
Quindi su questa roba bisogna metterci QUATTRO file: bootloader (program.bin
) kernel (Image3
) robo jffs chissa’ che cazzo e’, e initramfs, che poi in realta’ contiene tipo tuto (initramfs3.gz
).
I primi 3 ci starebbero bene cosi’ come sono, ma il quarto vorremmo personalizzarlo.
Solo che in realta’ non funziona mica un cazzo. Il primo avvio e’ molto lento e in effetti fa partire la wifi WIFIV1.6
come dice il commento, di cui non so la passphrase. Aspetto molto, stacco, riattacco, e non parte NULLA.
GPG sul cosariello FUNZIONA (ma va lento)¶
Finalmente funziona. La toolchain usata (arm-unknown-linux-uclibcgnueabi) e’ stata creata da crootool-ng su archlinux. Seguira’, forse, un metodo per riprodurla.
GPG e’ stato compilato senza particolari magie, solo qualche attenzione. Scaricare gnupg 1.4.19 (cioe’ l’ultima della release 1, anche detta “classic”)
#!/bin/bash
export PATH=~/x-tools/arm-unknown-linux-uclibcgnueabi/bin/:$PATH
export CFLAGS=-static
export CXXFLAGS=-static
make clean
./configure --disable-photo-viewers --disable-ldap \
--disable-cast5 --disable-blowfish \
--disable-card-support --disable-agent-support \
--disable-finger --disable-mailto --disable-dns-srv \
--disable-gnupg-iconv \
--disable-dev-random \
--enable-asm \
--disable-idea \
--enable-cast5 \
--disable-blowfish \
--enable-aes \
--enable-twofish \
--enable-sha256 \
--enable-sha512 \
--disable-bzip2 \
--disable-exec \
--disable-photo-viewers \
--disable-keyserver-helpers \
--disable-ldap \
--disable-hkp \
--disable-finger \
--disable-dns-cert \
--disable-largefile \
--build $(gcc -dumpmachine) \
--host arm-unknown-linux-uclibcgnueabi
make -j all
A questo punto basta copiare il binario g10/gpg
e tutto dovrebbe andare. Pero’ gpg rosica un po’ perche’ su quel kernel scemo la fcntl
non funziona, e questo provoca delle attese infinite col file random_seed
. Il trucco e’ dirgli --no-random-seed-file
.
Cosi’ facendo tutto funziona MA per cifrare un file grande 1.4MB ci vogliono tipo 30 secondi. Sospettiamo sia roba di entropia, chi lo sa.
Ottimizzazioni possibili¶
Cose che forse si fanno facile:
- haveged (se il problema e’ l’entropia)
- compilare con architettura thumb
Cose che richiedono cambi piu’ grandi:
- un modulo del fs decente, cosi’ si puo’ usare
random_seed
. Richiede cambio kernel - compilare per musl oppure per glibc
Una roba minimale con le NaCL¶
Ricicciando codice scritto originariamente per chdk, proviamo a vedere quanto va veloce un programma che cifra a chiave pubblica (ma deterministico, quindi non ci sono i dubbi sull’accesso a /dev/random
).
Innanzitutto si noti che la “precomputation” non è troppo utile: essa serve soprattutto se bisogna mandare molti messaggi piccoli allo stesso destinatario, e infatti nel caso di molti file piccoli funziona bene. Ma per cifrare uno (o anche molti) file grandi non serve a molto. Comunque l’ho implementata.
Il tempo di cifratura dipende circa linearmente dalla dimensione del file.
Ottimizzazioni gcc¶
Le ottimizzazioni di gcc contano molto.
Senza ottimizzazioni, un file da 1.1MB richiede 20 secondi per essere cifrato: troppo.
Con -O2
ci mette 6.5 secondi.
Con -O3
ce ne mette 4.0.
CRISTO CI AMA
Il binario thumb (ottenuto con -mthumb
) va più lento di quello arm. Se gli dici la tua architettura precisa
(-mtune
, -march
, --param l1-cache-size
eccetera), non c’è alcun vantaggio, a volte va pure più lento.
Librerie¶
API più rapide¶
Rimanendo in tema nacl, è da capire come se la cavano le API crypto_stream_* (che pero’ forse non sono fatte per quello che dobbiamo noi, ma per fare una pnf, quindi boh)
NaCL originali¶
Inoltre bisognerebbe vedere se le ottimizzazioni fatte dalla NaCl vera (e non da tweetnacl, come facciamo ora) sono effettivamente utili alle performance.
Cross-compilare nacl e’ un po’ un bagno di sangue, perche’ lo script ./do
assume in molti punti che l’host e il target coincidano (cioe’, vuole eseguire i binari compilati per misurare quale va piu’ veloce).
Libsodium¶
Allora ho utilizzato le libsodium, che invece si crosscompilano facile:
CFLAGS=-O3 CPPFLAGS=-O3 ./configure --enable-static --enable-asm --host=arm-linux
make
Purtroppo il make check
fallisce, ma credo sia perche’ su quella macchina non posso eseguire binari arm. Settando qemu-user-static e binfmt forse si potrebbe, boh.
Passando a libsodium, il guadagno di performance è ENORME: si arriva a 0.75s per il solito file da 1.1MB!
Inoltre le libsodium hanno alcune API più intriganti (ancora da provare) tipo le sealed boxes; le sealedboxes ogni volta generano una chiave effimera, questo potrebbe sembrare lento ma i benchmark mostrano che la generazione di una chiave porta via solo 0.07 secondi, quindi ok.
Quando si passa a libsodium la differenza di performance la fa la compilazione della libreria, dopodiche’ cambiare le ottimizzazioni del programmino nostro non e’ piu’ importante.
Come smanettarci¶
Per compilare, vedi la parte sulla cross-toolchain detta più in alto. Io uso la toolchain con uclibc, ma in realtà non so perché lo faccio, forse è meglio musl? forse glibc? chi lo sa!
Per come funziona l’accesso alla memoria, è particolarmente noioso mettere i file nuovi sulla memoria. Cioè diciamo che tu sei loggato in telnet, fai una prova e non va. Sul tuo computer trovi il bug, cambi il file, vuoi copiarlo, come fai? Dopo varie prove ho visto che la cosa meglio è che sul mio computer apro un server http, e dalla shell telnet scarico i file importanti.
Ho fatto questo script chiamato getall, che non è nel Repository
#!/bin/bash
baseurl="http://192.168.1.51:8000"
wget "${baseurl}/getall" -O /mnt/sd/getall
wget "${baseurl}/autorun" -O /mnt/sd/crypta-autorun.sh
wget "${baseurl}/detector/processall" -O /mnt/sd/processall
wget "${baseurl}/cryptapult/cryptapult" -O /mnt/sd/catapult-encrypt
dove 192.168.1.151
e’ l’IP del mio computer. Io prima facevo che dal computer copiavo i file con cp, poi smontavo, montavo sul cazzariello, ma sta cosa non funziona bene, per via probabilmente di cache varie, o mille altre noie. Così vado troppo meglio.