You are on page 1of 72

historias

de la
cripta
Javi Moreno

twitter tag: #cripta

ESCENARIO

FALLOS EN CIFRADOS

FALLOS QUE DESMONTAN


UN SISTEMA COMPLETO

FALLOS CON CRIPTOGRAFA


DE CLAVE PBLICA

FALLOS EN LA PROTECCIN
DE LA INTEGRIDAD

FALLOS EN FIRMAS

SIDE CHANNEL

CONCLUSIN

1
escenario

ponindonos en situacin

Criptografa simple y atractiva


128 256 bits?
Disponible para todo el pblico
No es complicado entender lo bsico.
Disponemos de muchas libreras de bajo nivel.
OpenSSL
Java crypto API
Microsoft CryptoAPI

ESCENARIO

[Ya casi] nadie implementa sus algoritmos.

Pero la realidad es otra

Extremadamente frgil.
Revisar el cdigo cuesta mucho ms que desarrollarlo.
(adems lo debe revisar otro)

Cuando falla algo falla todo.

ESCENARIO

Especialmente la criptografa de clave pblica.

Para no implementar criptografa

Si no puedes, usa
una librera de
alto nivel:
No uses directamente las de
bajo nivel:

GPGME, keyzcar, u
otras comerciales

OpenSSL, Crypto++,
Java crypto, BouncyCastle,
.NET System.Security.Cryptography

ESCENARIO

Solucin simple

SSL para las comunicaciones


GPG para el resto

Piensa mal y acertars

Confusiones evidentes

uso de MAC para firmar


descifrar una firma para comprobarla
confusin de trminos

Argumentos que defienden lo no estndar

seguridad por oscuridad


la clave es muy grande
lo le en un blog

ESCENARIO

Seguridad basada en usar SALTs

Piensa mal y acertars

Cifrado de varios bloques con RSA


Uso de diagramas que no vienen del estndar
Y una de las mejores:

Criptografa y Javascript no tiene sentido!


Dispones SSL en el cliente y en el servidor

ESCENARIO

Insistencia en mantener los IVs secretos

ESCENARIO

Un pequeo
detalle que lo
derrumba todo

fallos que
desmontan un
sistema completo

la fortaleza de una cadena es la de su eslabn ms dbil

Tenemos un esquema antiguo

una cookie, hash SHA1


con un cifrado CBC, sin integridad
lo mejoramos: HMAC, integridad

Lo implantamos no adecuadamente

se detecta una cookie antigua


se migra al nuevo formato !

Seguir usando ambos esquemas


desgraciadamente demasiado comn

FALLOS QUE DESMONTAN UN SISTEMA COMPLETO

Compatiblidad hacia atrs

no uses:

random (python)
java.util.Random (java)
System.Random (.NET)

usa:

el por defecto
no es suficiente

random.SystemRandom (python)
java.security.SecureRandom (java)
System.Security.Cryptography.RandomNumberGenerator (.NET)

nunca:

time() ^ getpid() y sus hermanos

FALLOS QUE DESMONTAN UN SISTEMA COMPLETO

PRNGs no adecuados

indispensables
para
un sistema
criptogrfico

Son la fortaleza de los cifrados de flujo

creacin de claves!

IVs, contadores, PIDs,

El caso OpenSSL y Debian, return 4!

entropa reducida a menos de 15bits


claves comprometidas
peligro de MITM
tablas precalculadas RSA, DSA

FALLOS QUE DESMONTAN UN SISTEMA COMPLETO

PRNGs no adecuados

Relacionado, mismo concepto:

el ataque DNS de Kaminsky


acertar un valor con 16 bits de entropa

Con un servidor recin arrancado

poca entropa disponible


repeticin de IVs, valores de desafios...

FALLOS QUE DESMONTAN UN SISTEMA COMPLETO

PRNGs no adecuados

Mifare Classic
reconstruyeron el circuito a base de fotografas microscpicas.

Su RNG

Semilla 16 bits, basado en un LFSR.


Valor derivado del tiempo de lectura desde el encendido.

FALLOS QUE DESMONTAN UN SISTEMA COMPLETO

PRNGs no adecuados

crypto1 Vs. crapto1


FALLOS QUE DESMONTAN UN SISTEMA COMPLETO

PRNGs no adecuados

fallos en
cifrados
cuando no es tu propia implementacin

Modos de encadenamiento
ECB? Sin realimentacin
El tpico conocido CBC
convierten de bloque a uno flujo
sin integridad, se pueden cambiar bits
no reusar: IVs, realimentacin, contadores...

CCM, EAX, GCM, OCB

CCM == Counter with CBC-MAC


cifrado autenticacin
tampoco se debe reusar IVs

FALLOS CIFRANDO

OFB, CFB, CTR

fallos en la proteccin de la
integridad

colega, ste no es mi coche

Mismo

ejemplo, una cookie:

SHA1(data) => replay attacks

SHA1(key || data) => basado en oscuridad

Usa

HMAC!
Problema:
granularidad, parmetros configurables

FALLOS
FALLOS
ENEN
LALA
PROTECCIN
PROTECCIN
DEDE
LALA
INTEGRIDAD
INTEGRIDA

Hashing

FALLOS EN LA PROTECCIN DE LA INTEGRIDA

Hashing

<SignatureMethod Algorithm=xmldsig#hmac-sha1>
<HMACOutputLength>
160
</HMACOutputLength>
</SignatureMethod>

Estndar XMLDsig.
Disponible desde alto nivel.

y por qu
no existe
nicamente
SHA1?

plaintext -> HMAC -> relleno -> cifrado CBC


El servidor devuelve diferentes errores

padding_incorrect
integrity_failure

CBC? empezamos por el final


bruteforce en el ltimo byte

si es correcto -> integrity_failure


iteramos hacia atrs

por la boca
muere el pez

FALLOS EN LA PROTECCIN DE LA INTEGRIDA

Dar ms informacin de la cuenta

fallos en
firmas
no te han dicho que nunca firmes algo sin leerlo primero?

Un ejemplo real con una firma RSA


dnde est
el error?

2
- caso correcto:
verificamos todos los datos (relleno includo)

- pero Nintendo hace:

return (0 == strncmp(userHash, myHash, 20));

FALLOS EN FRIMAS

1
Se calcula una simple exponenciacin

FALLOS EN FRIMAS

Un ejemplo real con una firma RSA

Un ejemplo real con una firma RSA


return (0 == memcmp(userHash, myHash, 20));

FALLOS EN FRIMAS

creamos 256 mensajes ligeramente distintos, seguro que al


menos 1 hash empieza por \x00.
saltarnos la comprobacin permite:
1. software, IOS y menu de sistema

2. cambiar gran parte del bootloader

La importancia del relleno

usando RSA directamente permitimos:


ataques de parejas de texto plano/cifrado especficas.
comprobad cada byte, incluyendo el relleno.
puede ser usado en tu contra para buscar colisiones
en las firmas.

FALLOS EN FRIMAS

sig(a*b) = (siga * sigb) mod n

fallos usando
criptografa de
clave pblica

a veces muchos bits nunca sern suficientes

Debian! Conociendo la salida del PRNG


Firma DSA (r, s):

Revela
la clave
privada

r = gk mod p mod q

s = k-1 (H(m) + x*r) mod q

Con k conocido:

x = ((s*k) H(m)) * r-1 mod q

En realidad slo con parte de los bits de


k sera posible con suficientes firmas

FALLOS USANDO CRIPTOGRAFA DE CLAVE PBLICA

DSA conociendo k?

dos firmas = clave pblica


escenario: RSA, verificar actualizaciones

mantenemos la clave publica secreta


usada para descifrar actualizaciones

no tiene sentido

no podemos mantener secreta la pblica


for e in [3, 5, 7, 65537]:
n ~= gcd(sig1em1, sig2em2)
if m1e mod n == sig1:
break

FALLOS USANDO CRIPTOGRAFA DE CLAVE PBLICA

Cifrar usando la clave privada?

Son problemas matemticos que


asumen ciertas condiciones
casos particulares
claves dbiles
cambios en algunos parmetros
no permitir que sean cero
exponentes pequeos

FALLOS USANDO CRIPTOGRAFA DE CLAVE PBLICA

Uso de valores no adecuados

7
side channel

la implementacin es el enemigo del diseo

Side channel has dicho?


Hasta ahora hemos pensando en:

Servidores remotos

no
operamos en

Eventos
que
filtran
informacin:
una caja negra
estados de la cache de la CPU
ideal bfer de prediccin de saltos
datos en la pila
uso de recursos
planificacin

SIDE CHANNEL

Nuestro ordenador

SIDE CHANNEL

Qu ms podemos medir?

Principalmente

Incluso

temperatura
sonidos
patrones de acceso a discos

SIDE CHANNEL

temporizacin
consumo de potencias
radiacin EM

Entonces?

Veamos un par de ejemplos de ataques


Pensemos en posibles protecciones

SIDE CHANNEL

necesitamos ser paranoicos

Ataque de temporizacin a RSA


t_producto > t_cuadrado

s=1;while(y) {
if (y&1)
s = (s*x) mod n; y>>=1;
x = (x*x) mod n;
}

El tiempo de clculo depende del valor de la clave

SIDE CHANNEL

Exponenciaciones modulares

Ej. Ataque de temporizacin a RSA

SIDE CHANNEL

Si combinamos la temporizacin
con un anlisis de potencia consumida.

Anlisis de potencia

SPA (simple), observar varias medidas

DPA (diferencial), muchas medidas

ataques estadsticos
diferencias de medias
correlaciones
relacin entre potencia y datos

SIDE CHANNEL

ver el path de ejecucin


conocer de antemano el resultado de una comparacin

SIDE CHANNEL

Anlisis de potencia

Inyeccin de fallos

provocando un fallo temporal

usando lser

podemos:

introducir un fallo en un clculo


variacin el camino de ejecucin

SIDE CHANNEL

power glitching
clock glitching

Ej. Inyeccin de fallos en RSA-CRT


Implementacin eficiente en memoria

Con un fallo en la exponenciacin


obtenemos una firma una defectuosa

RSA firma un mensaje mediante

s = md (mod n)

SIDE CHANNEL

exponenciaciones modulares de modulos ms pequeos


recombinacin

Ej. Inyeccin de fallos en RSA-CRT

s1 = mdq (mod q)
s2 = mdp (mod p)
s = a*s1 + b*s2 (mod n) = md (mod n)
a := 0 (mod p), a := 1 (mod q)
b := 1 (mod p), b := 0 (mod q)

Usando una firma defectuosa:

ss = a*s1 a*s1 := 0 (mod q)


ss = b*s2 b*s2 : 0 (mod p)

SIDE CHANNEL

Sin embargo RSA-CRT hace:

Ej. Inyeccin de fallos en RSA-CRT

sage:
sage:
sage:
sage:
sage:
sage:

q = gcd(s1-s2,n)
p = n / q
G1 = IntegerModRing(lcm(q-1,p-1))
private_key = G1(e)^-1
G2 = IntegerModRing(n)
message = G2(encrypted)^G2(private_key)

SIDE CHANNEL

Teniendo s1, s2 (defectuosa), pub(e, n):

Cmo protegernos?

Muy difcil si programamos en un lenguaje de alto nivel


Necesitamos libreras pensadas para resistir este tipo
de ataques

SIDE CHANNEL

Mucho cuidado con optimizaciones de los compiladores

def cmp(s1, s2):


total = 0
for a, b in zip(s1, s2)
total += (a != b)
return not total

y si las cadenas no tienen la misma longitud?


y si la longitud es 0?

SIDE CHANNEL

Ejemplo

Ejemplo

Analizando la lnea total += ( a !=b )


!= b)
= 1

= 0
+= tmp

Fuga segn el tiempo de ejecucin

Una lnea de cdigo en alto nivel no tiene por qu ser atmica

SIDE CHANNEL

if (a
tmp
else
tmp
total

Ejemplo

if len(userMsg) != len(correctValue)
return false
result = 0
for x, y in zip(userMsg, correctValue)
result |= ord(x)^ord(y)
return result
Usamos xor en lugar de !=
Fuga por tiempo sobre la longitud correcta

SIDE CHANNEL

Podramos cambiarlo por

Ejemplo

Solucin:

Pero deberamos seguir dudando de algunos factores:

y si x, y negativos?
realmente conocemos como funciona internamente zip()?
hace previamente una comparacin de la longitud?

SIDE CHANNEL

si es un valor criptogrfico no importa mucho


(tericamente tiene una longitud conocida)
si es un passwd: calcular el hash antes de comparar

A otros niveles
Cache timming attack

dependiente de la microarquitectura
ver artculo de djb sobre openssl AES-256
optimizaciones fuera
auditar el cdigo compilado

podramos aplicar estos conceptos via red?

con 1000 medidas podemos detectar


20 ns en LAN
30 ms en WAN

SIDE CHANNEL

nos puede jugar una mala pasado el compilador?

Usa exclusivamente punteros a la claves


Evita estar copiando claves de un sitio a otro

SIDE CHANNEL

Fugas al acceder a claves

Fugas al ejecutar saltos

Que ambos caminos:

tarden lo mismo
misma estructura de
instrucciones

SIDE CHANNEL

Evitar saltos en
decisiones importantes.

Fugas al comprobar la integridad

Podramos estar revelando la clave


El comportamiento de los algoritmos ha de ser
invariable con los datos procesados

SIDE CHANNEL

Cuidado al comprobar la paridad

public static boolean checkParity( byte[]key, int offset){


for (int i = 0; i < DES_KEY_LEN; i++){
byte keyByte = key[i + offset];
int count = 0;
while (keyByte != 0){
// loop till no 1 bits left
if ((keyByte & 0x01) != 0)
count++;
keyByte >>>= 1; // shift right}
if ((count & 1) == 0)
return false; // not odd
}
return true; // all bytes were odd
}

SIDE CHANNEL

Fugas al comprobar la integridad

Fugas al comprobar la integridad

va de LSB a MSB
comprobar que es un 1 tarda ms que un 0

Podemos obtener la clave bit a bit

SIDE CHANNEL

Si sabemos que:

solucin?
usar una tabla de paridad
consultarla en un orden aleatorio

SIDE CHANNEL

Fugas al comprobar la integridad

Fugas al comprobar la integridad

public static boolean checkParity( byte[]key, int offset){


int r = random.nextInt() & 7; // random number 0..7
for ( int i=0, j = r; i<8; i++, j = (j+1)&7 ){
if (key[j] != odd_parity[key[j+offset]])
return false; // parity incorrect
}
return true; // all bytes were odd
}

SIDE CHANNEL

static byte odd_parity[]= {


// each table entry represents odd parity of index
1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, ..., 248, 248,
251, 251, 253, 253, 254, 254};

Fugas cuando accedemos a datos

Evitad lecturas secuenciales --> usar offset aleatorio


memcpy( pin, buffer, 4 );

Ejemplo ms adecuado:

for(int i = 0, j = (rand() & 3);


i < 4; i++, j = ((j+1) & 3))
buffer[j] = pin[j];

SIDE CHANNEL

Ejemplo negativo:

Fugas al verificar a datos

if ( strcmp( givenPasswd, storedPasswd ) != 0 )


return -1; // combo fail
if ( memcmp( givenPasswd, storedPasswd ) != 0 )
return -1; // time leak fail

Evitad todo lo secuencial

SIDE CHANNEL

Usar strncmp() es un error lgico


pero memcmp es secuencial

Fugas al verificar a datos

char* c1 = givenPasswd;
char* c2 = storedPasswd;
char error = 0;
for (; *c1 != 0 && *c2 != 0; c1++, c2++ )
error |= *c1 ^ *c2; // collect diff in error
if (error | *c1 | *c2) // fail if any not zero
return -1;
return 0;

Se podra mejorar usando un offset aleatorio.

SIDE CHANNEL

Posible implementacin:

Fugas al sobreescribir datos


escribir un 0 escribir un 1

No borrar datos sobreescribiendo ceros


CMOS consume en los cambios de estado
Borrad con un random(), limpiad con ceros despus

SIDE CHANNEL

No hacerlo secuencialmente

Una inyeccin
de fallos puede
hasta revelar
una clave.
Pueden ser medidas implementadas en hardware pero
tambin muchas son lgicas.

SIDE CHANNEL

Defendernos de inyecciones de fallos

El caso por defecto

Mismo concepto:
result = no
if ( equal )
result = yes

Vs.

result = yes
if ( notequal)
result = no

SIDE CHANNEL

switch (state) {
case STATE_INIT: processInit(apdu); break;
case STATE_PERSO: processPerso(apdu); break;
case STATE_ISSUED: processIssued(apdu); break;
case STATE_LOCKED: processLocked(apdu); break;
default: fail();
}

Fallos en el flujo de ejecucin

Verificaciones del flujo

Uso de valores no triviales

los valores booleanos con fcilmente corrompibles


escoger valores con distancia hamming mxima
enmascaramiento en las medidas de potencia
true = 0xc3
false = 0x3c

SIDE CHANNEL

shadow stack/PC
comprobar el estado despus de los saltos

Fallos en los saltos

No usar booleanos para comprobar saltos

if (conditionalValue == (byte)0xA5)
// then part
else if (conditionalValue == (byte)0xC3)
// else part

SIDE CHANNEL

Comprobar siempre el valor para acceder a esa zona

Fallos en los saltos

// within then part


if (conditionalValue != (byte)0xA5)
fail();
if (~conditionalValue != (byte)0x5A)
fail();

SIDE CHANNEL

En situaciones decisivas, haced varias veces usando una comparacin complementaria:

Respuesta a inyeccin de fallos


static final byte[] CONSTANT = { 0x0F, 0x1E, 0x2D,
0x3C, 0x4B, 0x5A,0x69, 0x78 };

public void main( Strings[] s ){


System.arraycopy( CONSTANT, 0, copied, 0, CONSTANT.
LENGTH );
private void check(){ // call this method repeteadly
for (int i = 0; i < CONSTANT.LENGTH; i++)
if (CONSTANT [i] != copied[i])
fail();
}

SIDE CHANNEL

static byte[] copied = new byte[CONSTANT.length];

Respuesta a inyeccin de fallos

ataques repetidos
datos suficientemente sensibles

Incluso con el borrado de claves privadas

SIDE CHANNEL

En caso de:

Necesitamos un lmite

Tenemos que plantearnos

hay acceso fsico?


hay negocio atacando el sistema?
hay otras zonas ms dbiles?
necesito esta inversin en seguridad?

SIDE CHANNEL

Podramos ser paranoicos hasta el infinito

8
conclusin

Qu nos llevamos de todo esto?

Resumen

No implementes la tuya propia:


Remodela tu arquitectura

Si de verdad no puedes

SSL para comunicaciones


GPG para el resto

SIDE CHANNEL

La criptografa es frgil.
Cuando falla, falla del todo.

usa una librera de alto nivel


cryptlib, keyzcar

Que el cdigo sea revisado por terceros 10x

Javi Moreno
<vierito5@gmail.com>
http://vierito.es/wordpress
http://twiiter.com/vierito5
hashtag #cripta

cambio sugus por

preguntas

You might also like