Está en la página 1de 72

historias de la cripta

twitter tag: #cripta

Javi Moreno

ESCENARIO

FALLOS EN CIFRADOS

FALLOS QUE DESMONTAN UN SISTEMA COMPLETO

FALLOS CON CRIPTOGRAFA DE CLAVE PBLICA

FALLOS EN FIRMAS

FALLOS EN LA PROTECCIN DE LA INTEGRIDAD

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. [Ya casi] nadie implementa sus algoritmos. Disponemos de muchas libreras de bajo nivel.
OpenSSL Java crypto API Microsoft CryptoAPI

ESCENARIO

Pero la realidad es otra

Extremadamente frgil.
Especialmente la criptografa de clave pblica.

(adems lo debe revisar otro)

Cuando falla algo falla todo.

ESCENARIO

Revisar el cdigo cuesta mucho ms que desarrollarlo.

Para no implementar criptografa


Solucin simple Si no puedes, usa una librera de alto nivel: No uses directamente las de bajo nivel:
SSL para las comunicaciones GPG para el resto

GPGME, keyzcar, u otras comerciales

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

ESCENARIO

Piensa mal y acertars

uso de MAC para firmar descifrar una firma para comprobarla confusin de trminos

Confusiones evidentes

Seguridad basada en usar SALTs


seguridad por oscuridad la clave es muy grande lo le en un blog

ESCENARIO

Argumentos que defienden lo no estndar

Piensa mal y acertars

Cifrado de varios bloques con RSA Insistencia en mantener los IVs secretos Uso de diagramas que no vienen del estndar
Criptografa y Javascript no tiene sentido! Dispones SSL en el cliente y en el servidor

Y una de las mejores:

ESCENARIO

Un pequeo detalle que lo derrumba todo

ESCENARIO

fallos que desmontan un sistema completo

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

Compatiblidad hacia atrs


Tenemos un esquema antiguo

una cookie, hash SHA1 con un cifrado CBC, sin integridad lo mejoramos: HMAC, integridad se detecta una cookie antigua se migra al nuevo formato !

Lo implantamos no adecuadamente Seguir usando ambos esquemas


desgraciadamente demasiado comn

FALLOS QUE DESMONTAN UN SISTEMA COMPLETO

PRNGs no adecuados
no uses:
random (python) java.util.Random (java) System.Random (.NET)

el por defecto no es suficiente

usa:

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

creacin de claves!

Son la fortaleza de los cifrados de flujo

IVs, contadores, PIDs, entropa reducida a menos de 15bits claves comprometidas peligro de MITM tablas precalculadas RSA, DSA

El caso OpenSSL y Debian, return 4!

FALLOS QUE DESMONTAN UN SISTEMA COMPLETO

PRNGs no adecuados

el ataque DNS de Kaminsky acertar un valor con 16 bits de entropa poca entropa disponible repeticin de IVs, valores de desafios...

Relacionado, mismo concepto:

Con un servidor recin arrancado

FALLOS QUE DESMONTAN UN SISTEMA COMPLETO

PRNGs no adecuados

Mifare Classic
reconstruyeron el circuito a base de fotografas microscpicas.

Semilla 16 bits, basado en un LFSR. Valor derivado del tiempo de lectura desde el encendido.

Su RNG

FALLOS QUE DESMONTAN UN SISTEMA COMPLETO

PRNGs no adecuados
FALLOS QUE DESMONTAN UN SISTEMA COMPLETO

crypto1 Vs. crapto1

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 == Counter with CBC-MAC cifrado autenticacin tampoco se debe reusar IVs

OFB, CFB, CTR

CCM, EAX, GCM, OCB

FALLOS CIFRANDO

fallos en la proteccin de la integridad

colega, ste no es mi coche

Hashing

SHA1(data) => replay attacks

Mismo ejemplo, una cookie:

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

Usa HMAC! Problema:


granularidad, parmetros configurables

FALLOS FALLOS EN EN LA LA PROTECCIN PROTECCIN DE DE LA LA INTEGRIDAD INTEGRIDA

Hashing

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

Estndar XMLDsig. Disponible desde alto nivel.

y por qu no existe nicamente SHA1?

FALLOS EN LA PROTECCIN DE LA INTEGRIDA

Dar ms informacin de la cuenta

plaintext -> HMAC -> relleno -> cifrado CBC


padding_incorrect integrity_failure

El servidor devuelve diferentes errores

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

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?
1 Se calcula una simple exponenciacin 2 - caso correcto:
verificamos todos los datos (relleno includo)

- pero Nintendo hace:

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

FALLOS EN FRIMAS

Un ejemplo real con una firma RSA

FALLOS EN FRIMAS

Un ejemplo real con una firma RSA


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

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

FALLOS EN FRIMAS

La importancia del relleno

usando RSA directamente permitimos:


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

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

fallos usando criptografa de clave pblica

a veces muchos bits nunca sern suficientes

DSA conociendo k?
Debian! Conociendo la salida del PRNG

Revela la clave privada

r = gk mod p mod q

Firma DSA (r, s):

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

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

Con k conocido:

En realidad slo con parte de los bits de k sera posible con suficientes firmas

FALLOS USANDO CRIPTOGRAFA DE CLAVE PBLICA

Cifrar usando la clave privada?


dos firmas = clave pblica escenario: RSA, verificar actualizaciones
no tiene sentido

mantenemos la clave publica secreta


usada para descifrar actualizaciones

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

Uso de valores no adecuados

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

7 side channel

la implementacin es el enemigo del diseo

Side channel has dicho?


Hasta ahora hemos pensando en:

Servidores remotos
Nuestro ordenador

datos en la pila uso de recursos planificacin

SIDE CHANNEL

no operamos en Eventos que filtran informacin: una caja negra estados de la cache de la CPU ideal bfer de prediccin de saltos

SIDE CHANNEL

Qu ms podemos medir?

temporizacin consumo de potencias radiacin EM temperatura sonidos patrones de acceso a discos

Principalmente

SIDE CHANNEL

Incluso

Entonces?

necesitamos ser paranoicos

Veamos un par de ejemplos de ataques Pensemos en posibles protecciones

SIDE CHANNEL

Ataque de temporizacin a RSA


t_producto > t_cuadrado
Exponenciaciones modulares
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

Ej. Ataque de temporizacin a RSA


Si combinamos la temporizacin con un anlisis de potencia consumida.

SIDE CHANNEL

Anlisis de potencia

ver el path de ejecucin conocer de antemano el resultado de una comparacin

SPA (simple), observar varias medidas

ataques estadsticos diferencias de medias correlaciones relacin entre potencia y datos

SIDE CHANNEL

DPA (diferencial), muchas medidas

Anlisis de potencia

SIDE CHANNEL

Inyeccin de fallos

usando lser

provocando un fallo temporal

power glitching clock glitching introducir un fallo en un clculo variacin el camino de ejecucin

podemos:

SIDE CHANNEL

Ej. Inyeccin de fallos en RSA-CRT


Implementacin eficiente en memoria

exponenciaciones modulares de modulos ms pequeos recombinacin

s = md (mod n)

RSA firma un mensaje mediante

SIDE CHANNEL

Con un fallo en la exponenciacin obtenemos una firma una defectuosa

Ej. Inyeccin de fallos en RSA-CRT


Sin embargo RSA-CRT hace:

ss = a*s1 a*s1 := 0 (mod q) ss = b*s2 b*s2 : 0 (mod p)

Usando una firma defectuosa:

SIDE CHANNEL

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)

Ej. Inyeccin de fallos en RSA-CRT

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


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

Cmo protegernos?

Muy difcil si programamos en un lenguaje de alto nivel Mucho cuidado con optimizaciones de los compiladores Necesitamos libreras pensadas para resistir este tipo de ataques

SIDE CHANNEL

Ejemplo

y si las cadenas no tienen la misma longitud? y si la longitud es 0?

SIDE CHANNEL

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

Ejemplo

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

Fuga segn el tiempo de ejecucin

SIDE CHANNEL

if (a tmp else tmp total

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


!= b) = 1

= 0 += tmp

Ejemplo
Podramos cambiarlo por
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

Ejemplo

si es un valor criptogrfico no importa mucho (tericamente tiene una longitud conocida) si es un passwd: calcular el hash antes de comparar y si x, y negativos? realmente conocemos como funciona internamente zip()? hace previamente una comparacin de la longitud?

Solucin:

Pero deberamos seguir dudando de algunos factores:

SIDE CHANNEL

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

Cache timming attack

nos puede jugar una mala pasado el compilador?

con 1000 medidas podemos detectar 20 ns en LAN 30 ms en WAN

podramos aplicar estos conceptos via red?

SIDE CHANNEL

Fugas al acceder a claves

Evita estar copiando claves de un sitio a otro

SIDE CHANNEL

Usa exclusivamente punteros a la claves

Fugas al ejecutar saltos

Evitar saltos en decisiones importantes. Que ambos caminos:

tarden lo mismo misma estructura de instrucciones

SIDE CHANNEL

Fugas al comprobar la integridad

Cuidado al comprobar la paridad Podramos estar revelando la clave El comportamiento de los algoritmos ha de ser invariable con los datos procesados

SIDE CHANNEL

Fugas al comprobar la integridad


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

Podemos obtener la clave bit a bit

SIDE CHANNEL

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

Si sabemos que:

Fugas al comprobar la integridad

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

SIDE CHANNEL

Fugas al comprobar la integridad


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}; 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

Fugas cuando accedemos a datos

Evitad lecturas secuenciales --> usar offset aleatorio Ejemplo negativo:


memcpy( pin, buffer, 4 ); for(int i = 0, j = (rand() & 3); i < 4; i++, j = ((j+1) & 3)) buffer[j] = pin[j];

Ejemplo ms adecuado:

SIDE CHANNEL

Fugas al verificar a datos

Usar strncmp() es un error lgico pero memcmp es secuencial


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

Fugas al verificar a datos

Se podra mejorar usando un offset aleatorio.

SIDE CHANNEL

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;

Posible implementacin:

Fugas al sobreescribir datos


escribir un 0 escribir un 1

No hacerlo secuencialmente No borrar datos sobreescribiendo ceros CMOS consume en los cambios de estado Borrad con un random(), limpiad con ceros despus

SIDE CHANNEL

Defendernos de inyecciones de fallos

Pueden ser medidas implementadas en hardware pero tambin muchas son lgicas.

SIDE CHANNEL

Una inyeccin de fallos puede hasta revelar una clave.

El caso por defecto


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(); }

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

Vs.

result = yes if ( notequal) result = no

SIDE CHANNEL

Fallos en el flujo de ejecucin

shadow stack/PC comprobar el estado despus de los saltos los valores booleanos con fcilmente corrompibles escoger valores con distancia hamming mxima enmascaramiento en las medidas de potencia true = 0xc3 false = 0x3c

Verificaciones del flujo

SIDE CHANNEL

Uso de valores no triviales

Fallos en los saltos

No usar booleanos para comprobar saltos Comprobar siempre el valor para acceder a esa zona
if (conditionalValue == (byte)0xA5) // then part else if (conditionalValue == (byte)0xC3) // else part

SIDE CHANNEL

Fallos en los saltos

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


// within then part if (conditionalValue != (byte)0xA5) fail(); if (~conditionalValue != (byte)0x5A) fail();

SIDE CHANNEL

Respuesta a inyeccin de fallos


static final byte[] CONSTANT = { 0x0F, 0x1E, 0x2D, 0x3C, 0x4B, 0x5A,0x69, 0x78 }; static byte[] copied = new byte[CONSTANT.length]; 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

Respuesta a inyeccin de fallos

Incluso con el borrado de claves privadas

SIDE CHANNEL

ataques repetidos datos suficientemente sensibles

En caso de:

Necesitamos un lmite

Podramos ser paranoicos hasta el infinito


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

SIDE CHANNEL

Tenemos que plantearnos

8 conclusin

Qu nos llevamos de todo esto?

Resumen

La criptografa es frgil. Cuando falla, falla del todo. No implementes la tuya propia:
Remodela tu arquitectura SSL para comunicaciones GPG para el resto

Si de verdad no puedes

usa una librera de alto nivel cryptlib, keyzcar

Que el cdigo sea revisado por terceros 10x

SIDE CHANNEL

Javi Moreno <vierito5@gmail.com>


http://vierito.es/wordpress http://twiiter.com/vierito5 hashtag #cripta

preguntas

cambio sugus por