Cientificosaficionados.com

Los foros de los científicos aficionados de la red.
Fecha actual Sab Jul 04, 2020 8:02 pm

Todos los horarios son UTC [ DST ]




Nuevo tema Responder al tema  [ 6 mensajes ] 
Autor Mensaje
NotaPublicado: Mar Jun 27, 2017 10:01 am 
Desconectado
Avatar de Usuario

Registrado: Mié Sep 06, 2006 7:28 am
Mensajes: 1470
Ubicación: Alcala de Henares (Madrid, España)
País: España
Ciudad: Alcalá de Henares
Estoy metido en tres fregados simultáneos de IOT (ahora se llama así, antes solo eran redes de sensores distribuidos) y estaba buscando un algoritmo de encriptación aceptable para dispositivos embebidos (yo no pierdo de vista la seguridad de la IOT, que ya son muchos años programando..)
De momento estoy usando Arduino Uno (Atmega328) y había reciclado un DES https://es.wikipedia.org/wiki/Data_Encryption_Standard que usé en otro proyecto (librería de arduino http://spaniakos.github.io/ArduinoDES) pero como voy justo de memoria y tiempo de ciclo pensé en mejorarlo.

Valoré un AES https://es.wikipedia.org/wiki/Advanced_ ... n_Standard del que también tengo librería para arduino https://github.com/DavyLandman/AESLib pero ocupaba demasiado espacio en flash.

Entonces me encuentro la sorpresa, viendo avr-crypto-lib un listado de algoritmos para micros AVR de atmel, veo que existe uno llamado XTEA y su mejora XXTEA https://en.wikipedia.org/wiki/XXTEA muy sencillos de implementar y pensados para dispositivos embebidos!!

Después de un cortapega de la wikipedia y de machacar el teclado he dejado el algorítmo bastante óptimo para Arduino (he visto un par de librerías ya hechas pero son un calco de la publicación original y no aportan mejoras).

Un arduino Uno a 16Mhz tarda en cifrar y descifra un bloque de 64 bytes:
Con DES en modo CBC tarda 284568us y ocupa 2572 bytes de flash
Con XTEA en modo CBC tarda 11008us y ocupa 916 bytes de flash
Con XXTEA tarda 4168us y ocupa 1086 bytes de flash
O sea que es rapidísimo y pequeñito...

La KEY es de 128 bits (mejor que el DES que solo es de 56) aceptable para mi aplicación. Se conocen ataques pero se basan en usar mas de 2^59 "textos planos escogidos", también aceptable!!

El código es extremadamente sencillo, la única desventaja es que sobreescribe los datos planos con los datos encriptados:
Código:
#define DELTA 0x9E3779B9
#define MX (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((Sum^y) + (Key[(WordCount&3)^KeyIdx] ^ z)))
// =================================================================================
// Cifrador  XXTEA (Tiny Encryption Algorithm) Key = 128 bits, 16 bytes
// Blocks = bloques de 32bit, 64 bits min (Blocks = 2)
// https://en.wikipedia.org/wiki/XXTEA
// (c) Heli Tejedor, helitp@gmail.com, Junio 2017
// Licencia Creative Commons 3.0 Reconocimiento, No Comercial, Compartir Igual (CC BY-NC-SA 3.0)
// =================================================================================
void XxteaEncrypt (uint32_t *Data, uint8_t Blocks, uint32_t const Key[4])
{
  uint32_t y, z, Sum;
  uint8_t WordCount, Rounds, KeyIdx;       
  Rounds = 6 + 52/Blocks;
  Sum = 0;
  z = Data[Blocks-1];
  do
  {
    Sum += DELTA;
    KeyIdx = ((uint8_t)Sum >> 2) & 3;
    for (WordCount = 0; WordCount < Blocks-1; WordCount++)
    {
      y = Data[WordCount+1];
      z = Data[WordCount] += MX;
    }
    y = Data[0];
    z = Data[Blocks-1] += MX;
  } while (--Rounds);   
}
 
// =================================================================================
// Descrifrador  XXTEA (Tiny Encryption Algorithm) Key = 128 bits, 16 bytes
// =================================================================================
void XxteaDecrypt (uint32_t *Data, uint8_t Blocks, uint32_t const Key[4])
{       
  uint32_t y, z, Sum;       
  uint8_t WordCount, Rounds, KeyIdx;
  Rounds = 6 + 52/Blocks;
  Sum = Rounds*DELTA;
  y = Data[0];
  do
  {
    KeyIdx = (Sum >> 2) & 3;
    for (WordCount = Blocks-1; WordCount > 0; WordCount--)
    {
      z = Data[WordCount-1];
      y = Data[WordCount] -= MX;   
    }
    z = Data[Blocks-1];
    y = Data[0] -= MX;
    Sum -= DELTA;
  } while (--Rounds);
}

Para usarlo:
Código:
 
#define MYDATA 64
uint8_t Plain[MYDATA] = {"0123456789012345abcdefghijklmnopABCDEFGHIJKLMNOP-.,_:;?=)(/&%$!"};
uint8_t XteaKey[16] = {0xF3, 0xD5, 0x36, 0x32, 0x13, 0x12, 0x34, 0x56, 0xF4, 0xD5, 0xB6, 0x3F, 0x53, 0x15, 0x64, 0x56 };

XxteaEncrypt ((uint32_t*)Plain, MYDATA/4, (uint32_t*)XteaKey);
XxteaDecrypt ((uint32_t*)Plain,  MYDATA/4, (uint32_t*)XteaKey);

_________________
¡No es imposible, lo que pasa es que no sabes como hacerlo!
Aka: no es difícil si sabes como.
http://heli.xbot.es


Arriba
 Perfil  
 
NotaPublicado: Mar Jun 27, 2017 6:54 pm 
Desconectado
Avatar de Usuario

Registrado: Mié Sep 06, 2006 7:28 am
Mensajes: 1470
Ubicación: Alcala de Henares (Madrid, España)
País: España
Ciudad: Alcalá de Henares
Pues ya lo tengo corriendo en todos los nodos de prueba y es una maravilla!
Lo he portado a Teensy 3.2 (compatible con arduino) https://www.pjrc.com/teensy/teensy31.html pero con un micro Freescale MK20DX256VLH7 ARM Cortex-M4 hasta 96Mhz y también funciona perectamente.
Debido a que es un micro de 32 bits he cambiado algunas definiciones de datos para optimizar y he conseguido que, ocupando 448 bytes de programa, encripte y desencripte bloques de 64 bytes en solo 296 microsegundos a 24Mhz

Cambiando también algunas definiciones de datos en Arduino el programa ocupa 10 bytes mas (1096) pero encripta y desencripta los mismos bloques de 64 bytes 128 microsegundos mas rápido (en 4040us).

Es curioso ver como el ARM Cortex M4 ejecuta el programa 13 veces mas rápido que el AVR con solo un 50% mas de velocidad de reloj.

El código para arduino queda así:
Código:
#define DELTA 0x9E3779B9
#define MX (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((Sum^y) + (Key[(WordCount&3)^KeyIdx] ^ z)))
// =================================================================================
// Cifrador  XXTEA (Tiny Encryption Algorithm) Key = 128 bits, 16 bytes
// Blocks = bloques de 32bit, 64 bits min (Blocks = 2)
// https://en.wikipedia.org/wiki/XXTEA
// (c) Heli Tejedor, helitp@gmail.com, Junio 2017 V0.2
// Licencia Creative Commons 3.0 Reconocimiento, No Comercial, Compartir Igual (CC BY-NC-SA 3.0)
// =================================================================================
void XxteaEncrypt (uint32_t *Data, int Blocks, uint32_t const Key[4])
{
  uint32_t y, z, Sum;
  int WordCount, Rounds, KeyIdx;       
  Rounds = 6 + 52/Blocks;
  Sum = 0;
  z = Data[Blocks-1];
  do
  {
    Sum += DELTA;
    KeyIdx = ((uint8_t)Sum >> 2) & 3; // Optimizacion para ATMEGA328
    for (WordCount = 0; WordCount < Blocks-1; WordCount++)
    {
      y = Data[WordCount+1];
      z = Data[WordCount] += MX;
    }
    y = Data[0];
    z = Data[Blocks-1] += MX;
  } while (--Rounds);   
}
 
/ =================================================================================
// Descrifrador  XXTEA (Tiny Encryption Algorithm) Key = 128 bits, 16 bytes
// =================================================================================
void XxteaDecrypt (uint32_t *Data, int Blocks, uint32_t const Key[4])
{       
  uint32_t y, z, Sum;       
  uint8_t WordCount, Rounds, KeyIdx;  // Optimizaciones para ATMEGA328
  Rounds = 6 + 52/Blocks;
  Sum = Rounds*DELTA;
  y = Data[0];
  do
  {
    KeyIdx = (Sum >> 2) & 3;
    for (WordCount = Blocks-1; WordCount > 0; WordCount--)
    {
      z = Data[WordCount-1];
      y = Data[WordCount] -= MX;   
    }
    z = Data[Blocks-1];
    y = Data[0] -= MX;
    Sum -= DELTA;
  } while (--Rounds);
}

_________________
¡No es imposible, lo que pasa es que no sabes como hacerlo!
Aka: no es difícil si sabes como.
http://heli.xbot.es


Arriba
 Perfil  
 
NotaPublicado: Mar Jun 27, 2017 8:39 pm 
Desconectado

Registrado: Mar Sep 16, 2014 12:55 am
Mensajes: 931
País: españa
Ciudad: barcelona
Muy interesante.
He empezado a seguirlo pero no es nada evidente. :D


Arriba
 Perfil  
 
NotaPublicado: Mar Jun 27, 2017 10:00 pm 
Desconectado
Avatar de Usuario

Registrado: Mié Sep 06, 2006 7:28 am
Mensajes: 1470
Ubicación: Alcala de Henares (Madrid, España)
País: España
Ciudad: Alcalá de Henares
Pero si es muy facil!
Imagen

Cuando vi el flujograma pensé que no podría implementarlo, pero el ejemplo de la wikipedia es suficiente para hacerlo funcionar en un compilador moderno.
Casi todo el truco esta en el macro:
Código:
#define MX (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((Sum^y) + (Key[(WordCount&3)^KeyIdx] ^ z)))

_________________
¡No es imposible, lo que pasa es que no sabes como hacerlo!
Aka: no es difícil si sabes como.
http://heli.xbot.es


Arriba
 Perfil  
 
NotaPublicado: Mié Jul 05, 2017 10:11 am 
Desconectado
Avatar de Usuario

Registrado: Mié Sep 06, 2006 7:28 am
Mensajes: 1470
Ubicación: Alcala de Henares (Madrid, España)
País: España
Ciudad: Alcalá de Henares
Por si alguien necesita el sketch puede descargarlo aqui, junto con algunas pruebas: http://heli.xbot.es/?p=427

_________________
¡No es imposible, lo que pasa es que no sabes como hacerlo!
Aka: no es difícil si sabes como.
http://heli.xbot.es


Arriba
 Perfil  
 
NotaPublicado: Sab Jul 08, 2017 10:43 am 
Desconectado
Avatar de Usuario

Registrado: Dom Feb 11, 2007 10:16 pm
Mensajes: 4905
Ubicación: Islas Baleares, España
Interesante tema Heli, me bajaré el código, aunque mi conocimiento de los sistemas de encriptación se reduce a los llamados métodos "clásicos", de los cuales he implementado unos cuantos en Visual Basic y uno en Arduino. No obstante, todos ellos están enfocados únicamente al cifrado de textos, y no de datos a nivel general. Respecto a eso, tengo uno de estos programas instalado en un Arduino Leonardo "beetle" (el que parece un pequeño pendrive) y va de maravilla, permite claves de 64 dígitos alfanuméricos y realiza hasta 16 multicifrados sucesivos utilizando subclaves distintas, con lo cual pienso que puede ser un sistema difícil de romper (aunque nunca se sabe...).

Saludos

_________________
La VIDA sólo es energía que ha aprendido a defenderse... (Anilandro)

*** La Web de Anilandro *** http://sites.google.com/site/anilandro


Arriba
 Perfil  
 
Mostrar mensajes previos:  Ordenar por  
Nuevo tema Responder al tema  [ 6 mensajes ] 

Todos los horarios son UTC [ DST ]


¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 2 invitados


No puede abrir nuevos temas en este Foro
No puede responder a temas en este Foro
No puede editar sus mensajes en este Foro
No puede borrar sus mensajes en este Foro

Buscar:
Desarrollado por phpBB® Forum Software © phpBB Group
Traducción al español por Huan Manwë para phpbb-es.com