Quantcast
Channel: Seguridad Agile
Viewing all 264 articles
Browse latest View live

OWASP Latam Tour 2019

$
0
0

Me perdí el comienzo y el final por logística laboral y familiar, pero pude asistir a tres charlas aparte de dar la mía.

Soy un tanto reacio a estar contando lo que los mismos autores pueden contar, así que sólo cuento lo mínimo y alguna opinión de haberla. 
Muchas gracias a  Andrés, Martín y la nueva organización por confiarme ese rato.

La primera charla fue la de Miguel Summer Elias (http://www.informaticalegal.com.ar/) que suele dar explicaciones claras y amenas y esta vez no fue la excepción. Tuvo la innovación de usar una tela touch, con la cual podía controlar con la mano y el audio la presentación ;-)

Luego la mía, "Forzando brutalmente MD5...", que originalmente eran cuatro de cinco charlas, tratándose de calcular MD5 con CPU, SIMD, multicore, supercomputadora y GPGPU.
La última, de un modo radicalmente distinto y que es la que realmente me interesa, la tengo elaborada, me falta implementar el código y trata de hacer lo mismo con FPGA.
Había presentado CPU y SIMD en H4CK3D 2018 pero ahora se le ha hecho largo en nombre, "Forzando brutalmente MD5 con CPU, SIMD, threads, forks, supercomputadora y GPU". Dos días antes caí en cuenta que debió llamarse "Forzando brutalmente MD5 con computadoras" y la última "Forzando brutalmente MD5 sin computadoras".

Primero hice un breve resumen de hashing, para que sirve, la implementación de MD5, optimizaciones como las que menciono más abajo como "mías", la descripción de cada caso, caminos fallidos y teniendo 40 minutos medio que algunas cosas quedaron muy superficiales, otras se cayeron y alguna me la olvidé.

Lo que me han dado ganas de hacer y lo intentaré, es un análisis cuantitivo en tres dimensiones:

  • pasar de CPU a SIMD que son dos casos
  • optimización de compilador que son dos casos
  • optimizaciones mías, como padding fijo, hardcodeo de constantes y loop unroll

Esto último podría ser considerando las ocho combinaciones o quizas cinco asi:

  • padding fijo
  • padding fijo + constantes
  • padding fijo + loop unroll
  • padding fijo + constantes + loop unroll 

Me quedarian entonces 32 o 16 combinaciones, tedioso pero factible.

Para el año pasado cuando estaba por mostrar en el trabajo la parte de GPGPU,  Andrés me había ofrecido acceso a su minador pero se fué de vacaciones y no llegó a configurarme el acceso, lo cual fué una suerte para mí, pues no mucho después, mientras él monitoreaba remotamente el consumo halló 0 Watts. Fué a fijarse y los aislantes de los cables de alimentación se habían fundido, si hubiera ocurrido mientras yo la usaba... Más suerte para Andrés que no tuvo un incendio.


Luego Leandro Mantovani nos contó como utilizar unos logs de certificados TLS como alerta temprana para detectar sitios vulnerables, muy ingenioso

Finalmente, nuevamente suerte en relación a Andrés, su charla la dió en el slot previo, si no me la hubiese perdido. Fue una muy buen ensayo para... BlackHat! ¡qué capo!



La agenda y los links, ...


https://www.owasp.org/index.php/LatamTour2019#tab=ARGENTINA_-_Buenos_Aires


...la presentación, ...


https://www.owasp.org/images/d/d5/Forzando_Brutalmente_MD5_con_computadoras_-_OWASP_2019_-_Carlos_Pantelides.pdf


...las cifras a medio cocinar, ...


https://www.owasp.org/images/5/53/Forzando_Brutalmente_MD5_con_computadoras_-_Cifras_-_OWASP_2019_-_Carlos_Pantelides.pdf


...las entradas en este blog y ...


https://seguridad-agile.blogspot.com/p/indice.html#md5


...el código.

https://github.com/cpantel/Forzando-Brutalmente-MD5

 


Introduction to Packet Tracer Mobile

$
0
0

En una materia que estoy cursando, hemos visto Packet Tracer, una herramienta de simulación y entrenamiento de Cisco. He hallado dos capacitaciones online disponibles, Introduction to Packet Tracer y Packet Tracer Mobile

Para ver la calidad sin invertir mucho tiempo, elegí la mobile de dos horas en lugar de la otra de diez horas. Pero, necesito un celular y el mío no me sirve, en parte por que no le quiero meter basura y en parte no le entra, ya que es minúsculo.

Escarbando en un cajón hallé uno medio roto que me habían regalado, un LGP712, que tenía Android 4.1.x y Packet Tracer necesita 4.2.x, así que hacer el upgrade.


Crónica de resolución de dependencias


Esta sección es optativa y nada tiene que ver con el curso, si no con actualizar un celular primitivo a la versión apropiada de sistema operativo, podés mirar los dibujitos y saltar a al resumen o al curso, que finalmente ha sido una excusa para investigar otras cosas, he utilizado mucho más tiempo en esto que en el curso en sí.

Hallé un firmware 4.4.x y tras averiguar un poquito, hay que usar una herramienta específica y cargar unos drivers . Como no sé si tienen bichitos:

  • me busqué una imagen de máquina virtual
  • le copié todos los archivos
  • extraje la herramienta
  • puse en esa carpeta el firmware
  • conecté el celular (devices->USB-> LGE LG-p712)


  • ejecuté la herramienta y
  • seguí las instrucciones que dicen poner 
    • "CDMA"
    • "DIAG" 
    • y darle a "CSE Flash"

pues estoy reemplazando por un firmware distinto.






Por las dudas, cuando abrió el diálogo final, le pedí "Read Phone Information" y me dijo que no hallaba el puerto, mmh, debí haber tomado el curso largo...



Supongamos que es algo de permisos, vamos como root.

El problema es que no se puede ejecutar como root así nomás, por que si hacés

sudo VBoxManage startvm "maquina"

no la halla en el perfil de root, entonces hay que exportarla

VBoxManage export "maquina" -o lg.ova

y luego importarla

sudo --login VBoxManage import /home/usuario/log.ova

Ojo con el --login, si no lo ponés usa el home del usuario con que invocaste. No estoy seguro que falle si no, pero prefiero no arriesgar.

Al final de todo hay que recordar limpiar el desastre, o sea, borrar lg.ova y /root/VirtualBox VM

Volviendo al camino, ahora si podemos hacer

sudo --login VBoxManage startvm "maquina"


Fail....

Conectando a USB 2.0 en lugar de USB 3.0, Fail...



Salteando pasos, al darle a START directamente, se abre una subaplicación con país Corea, pero se puede elegir idioma inglés. Esta falla pues no puede comunicarse con el dispositivo.



Hallé una página con firmwares, que ofrecía uno de Uruguay, pero lleva a una pesadilla de scammers, nunca al download, hora de dormir.




Luego, al día siguiente, me queda un poco nebuloso lo que hice, quizo conectarse a algún sitio, pero no lo halló, comprobé que no es por falta de conectividad de red.





En algún momento se puso en "emergency mode" y ahí lo perdí la primera vez, pero luego estuve atento a reconectar cada vez que se desconectaba, puse unas reglas pero no sé si llegaron a hacer efecto.





Y finalmente, tras cuarenta minutos de reintentos, coronados con un glorioso "la aplicación ha dejado de funcionar", tengo Android 4.4.2, ¡já!

Lo siguiente es instalar el programa, pero no tengo ganas de meter mis credenciales para conectar al Store, así que pretendo obtener el .apk que debe haberse bajado para una tablet según cuento más adelante.

No puedo abrir una terminal para ejecutar un find, por suerte averigüé que aunque mi Desktop Manager no sabe cómo hacerlo, se puede hallar el punto de montaje, está cerca de

/run/user/1000/gvfs/mtp:....

1000 es el número de tu usuario, se consigue de varias maneras, una es id.

/run/user/$(id --user)/gvfs/



No estaba...

¿En qué situación me hallo? En que no quiero poner mis credenciales de gmail en un firmware que no sé de dónde salió.

Necesito una extensión para bajarlo en un navegador, pero no sé si esa extensión tiene bichito. APKCombo y APKDownloader para Firefox servirían, pero me piden cosas como:

  • Access your data for all websites
  • Access browser tabs

Puedo usar un downloader que no sé si le va a meter bichito, pero ni me importa, pues no tengo nada en ese celular y luego le mando un factory reset y recuerdo siempre que puede estar embichado. Hay downloaders pero

  • http://apkleecher.com/, no me trae lo que quiero
  • https://apk-dl.com/, ronda de scammers
  • https://www.apkturbo.com, pero recién cuando 
    • Your download is starting. If it doesn't start, please click here.

El hash 7451b22367376e9d22d9d02c149a1492 no aparece en ningún lado como malo, virustotal dice que está ok


Resumen de actualización de firmware


  • USB 2.0 está ok
  • Usuario no root está ok
  • Quizás debe haber conectividad
  • Hay que estar atento a reconectar en el gestor de dispositivos
  • Quizás las reglas ayuden
  • Hay que probar varias, muchas veces
  • Mejor sería no hacer desde una virtual


En algún momento antes de que se destrabara la comunicación con el dispositivo, tomé otro enfoque, que fué, ¿pará qué querría esta app en un celular, donde no se puede ver nada? Recordé que tengo por ahí dos tablets, en realidad una sola, pues la más grande tiene el conector roto y por más que se lo reemplacé no lo hice bien, más tarea para otro día.

En la que sí funciona, la instalación falló diciendo que no podía bajar los archivos, pero lo dijo después de haberlos bajado. Miré los mensajes negativos en el store, pero eran todos diciendo que no arrancaba, fallaba despues de arrancar o que se veía mal, losers, dice que es para una pantalla grande...

Copié el apk, lo instalé y salvo que se vé miserablemente chiquito y lento, parece todo ok, mañana seguiré.




Por fín, el curso...

No olvidemos que hay dos componentes en juego, el curso online y la app.


La navegación del curso no es muy fluida, si avanzás o retrocedés usando las flechas internas, se rompe Flash a veces.


La parte de simulación, los PDU, los escenarios me resulta un poco difícil de asimilar con la interfaz tan limitada, tuve que complementarlo usando la aplicación de escritorio.

Me sirvió como primer acercamiento.

Con respecto a la aplicación, si se me permite:


Muy bueno el detalle de que no se le pueden poner o sacar componentes a los dispositivos sin apagarlos.


Ya había leido quejas de que se usa un teclado propio en lugar del provisto por el sistema operativo. Error capa 8, en tu teclado podrías tener letras y símbolos que no corresponden a lo que el dispositivo espera, está ok así.

Tambien la falta de zoom, evidentemente esas personas son nativas mobile y quizás no entienden la adaptación, pues la aplicación permite pinch sobre la zona de trabajo, no sobre la interfaz ni en la vista física, pero no se puede reclamar, dice que hay que usar una pantalla grande, sorry.


Finalmente, hay un examen razonable, la mitad de las preguntas son irrelevantes para mi como si la aplicación es equivalente a la de desktop o si hace falta determinadas cuentas para usar o usar completamente.

Para obtener el certificado, va a netacad y en el curso terminado dice "Get Certificate", le decís quién querés que firme y te dá un pdf.




Introduction to Packet Tracer

$
0
0
Habiendo visto que Packet Tracer Mobile era aceptable, me propuse ver por que Packet Tracer dura cinco veces más tiempo.

Dejando de lado que la usabilidad de la aplicación Desktop es grosera y esperablemente superior a la mobile, los contenidos del curso son mucho más amenos y profundos. Más allá de lo que digan o den a entender las descripciones de los cursos, el de Mobile sólo sirve para quien ya hizo el Desktop y quiere hacer una adaptación rápida a Mobile.

Si no sabés nada de networking y programación, el curso está ok, pero te vas a quedar sin aprovechar varias cosas. Si sí sabés, al final es una fiesta cuando le metés código en javascript o python a componentes que podés crear y configurar. Me aleja de mi camino de aprendizaje ponerme a explorar a fondo, el tiempo es un bien escaso.


Algunos comentarios disociados:

Ojo con borrar en la vista física, si borrás lo el contenedor que contiene lo lógico, parece que no hay undo. O quizás hay un solo nivel.

Detallecito, en linux no funciona alt-click para cambiar el estado de objetos, como apretar un botón o abrir una puerta.

Muy bonita la vista física para motivar y gamificar, pero es eye candy. Está muy buena para hacer las animaciones de un curso de networking.

El señor relator se muy simpático, o al menos su voz y su AWESOME!s

Las preguntas y respuestas, bue, son como siempre en este tipo de exámenes. No me imagino respondiéndolas en una certificación, por ejemplo que pregunten cuál es el iconito de un archivo .pka. Otras, como cuál es la imagen del botón de un cierto comando, mostrándola aislada no es lo mismo que te muestren toda la botonera, hay cosas que uno recuerda mecánicamente.

Otra cosita que me ofende es que el examen dice que si salís de la GUI sin salvar perdés los cambios, que es tal como aprendiste hasta ese momento. Sin embargo, en el capítulo siguiente se introduce el Home Gateway para IoT, que no tiene botón de salvar en la GUI. Cuandó hice el CCNA hace mucho, pasaba lo mismo, una red clase C tenía 256 nodos disponibles hasta que la clase siguiente eran 254. En lugar de decirte de una 254 y dos reservados, luego se verá para qué, te tratan como si fueras una pieza de equipamiento, una memoria donde primero escribís algo y luego lo parcheás y eso me molesta.

De todos modos, recomiendo este curso


Como entender y lidiar con XDC files en Vivado 2018.2

$
0
0
En esta entrada relato el camino un tanto sinuoso de comprensión de que es un archivo XDC que he seguido.

Siguiendo los tutoriales de Vivado, que son muy claros, llegué a la parte de los constraints, los archivos XDC que dicen como se van a conectar las patitas del FPGA con los periféricos de la placa que tengas, en mi caso Nexys-4 DDR. Si, en la página dice "retired". Entre que la pedí y llegó, eso pasó.

Previamente, había comenzado con información específica de la placa que tengo, de seguir vos este camino con otra placa, tendrías que adaptarte.

En el paso 6 del tutorial dice de bajarte el zip de constraints, pero preferí pegarle al repo:

git clone https://github.com/Digilent/digilent-xdc

Este es el momento en que uno debería leer la documentación para comprender que es un XDC, pero como siempre elegí arrojarme contra los archivos a ver que se puede comprender y dejar el manual para más tarde, esto es lo que hice y me funcionó bastante bien, me las puede arreglar con la adaptación de proyectos ISE a Vivado, lo que implica algo de uso de los XDC pues hay que recrearlos a partir de los UCF y de las interfaces del top module. Esto lo mostraré en Para estudiar Programming FPGAs: Getting Started with Verilog, cuando termine.


Volviendo, hay varios proyectos de ejempo y de ahí obtuve los links a los demos y en cada uno a los repos:

Los cloné:

git clone https://github.com/Digilent/Nexys-4-DDR-GPIO.git
git clone https://github.com/Digilent/Nexys-4-DDR-Keyboard.git
git clone https://github.com/Digilent/Nexys-4-DDR-OOB
git clone https://github.com/Digilent/Nexys-4-DDR-XADC.git


Busqué los XDC:

find Nexys-4-DDR-* -iname "*xdc"

Nexys-4-DDR-GPIO/src/constraints/Nexys4DDR_Master.xdc
Nexys-4-DDR-Keyboard/src/constraints/Nexys4DDR_Master.xdc
Nexys-4-DDR-OOB/src/constraints/Nexys4DDR_C.xdc
Nexys-4-DDR-XADC/src/constraints/Nexys4DDR_Master.xdc


Y a jugar con kdiff3 o tu herramienta de comparación preferida.

A mi me gusta esta:

kdiff3 Nexys-4-DDR-GPIO/src/constraints/Nexys4DDR_Master.xdc \
       Nexys-4-DDR-XADC/src/constraints/Nexys4DDR_Master.xdc \
       Nexys-4-DDR-Keyboard/src/constraints/Nexys4DDR_Master.xdc

Comparé entonces entre los cuatro proyectos y contra digilent-xdc y pensé que por algún perverso motivo, en los get_ports los nombres cambian. Luego encontré que responde a un motivo muy sencillo: son los nombres que se le dan en los módulos a los pines, pueden venir de un diseño genérico, de otra placa, no hay manera que esos nombres sean los mismos en distintos proyectos.

Esto es el proyecto de GPIO vs el XDC virgen, en los botones cambian los nombres y en los pines de los 7 segmentos, además cambia el tipo.




Lo que dice luego es que más allá de des/comentar no es recomendado cambiar nada al menos del clock.

El proyecto más interesante es el OOB, pues toca casi todos los periféricos.



Dejando un poco de lado la exploración, que a mi me gusta y sirve pues es divertida y me hace hallar muchas preguntas que luego la documentación me responde, he aquí lo que he aprendido en la documentación:

En una CPU y cualquier integrado "común", los pines tienen funcionalidad fijas: uno es clock(), otro es IO y así.

 
By Bill Bertram - Own work, CC BY 2.5, https://commons.wikimedia.org/w/index.php?curid=473063

En un microcontrolador, que contiene una CPU y algunos periféricos, suele haber alguna manera de asignar a un pin una función. No es que a cualquier pin a cualquier función, si no a cada pin alguna función y cada función se puede conectar a algunos pines.

En esta imagen sacada del documento que hizo Éric Pernía, se puede apreciar que cada pin, la segunda columna, que en la primera columna dice donde hallarla en el zócalo de expansión de ponchos, tiene detallado a la derecha las distintas funciones que puede cumplir:

El resto de los diagramas del proyecto CIAA están aquí.

Por ejemplo, LCD1 se puede usar como LCD1, GPIO, etc. USB0_DM como... USB0_DM, pero eso es porque no llega hasta el chip si no que va a un dispositivo en particular.


Una FPGA puede mapear casi cualquier cosa que tenga adentro a casi cualquier pin y digo "casi" por las dudas para no decir "todo".


Pero, la FPGA está físicamente soldada a una placa entonces sus pines ya están fijados a ciertos cirtuitos electrónicos físicos inamovibles. Eso nos regresa a la situación de la CPU.

El XDC tiene entonces ese mapeo y lo provée el fabricante de la placa.

A fines prácticos:

set_property -dict { PACKAGE_PIN H17 IOSTANDARD LVCMOS33 } [get_ports { running_led }]; 

#IO_L18P_T2_A24_15 Sch=led[0]

PACKAGE_PIN: dice cuál pin físico es, no habría que tocar.

IOSTANDARD: tiene que ver con características electrónicas, setea a LVCMOS33, que es GPIO.

Para el pmod JXADC tiene IOSTANDARD LVDS, entiendo son entradas analógicas.

get_ports: dice como se va a llamar y es lo único que los básicos como yo podemos modificar.


El comentario es útil dejarlo para saber cual era el nombre original.

En Zynq, que es un chip con un microcontrolador y una FPGA, mmh, ahí la cosa se debe complicar, cuando llegue agregaré acá o en otra entrada.

Tambien quedará para el futuro el clock:

set_property -dict { PACKAGE_PIN E3    IOSTANDARD LVCMOS33 } [get_ports { CLK }];
                                                                          #IO_L12P_T1_MRCC_35 Sch=clk100mhz
create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports { CLK }];



A fines más prácticos, el modo de usarlo que he destilado es:

  • Tener el archivo, por ejemplo en mi caso Nexys-4-DDR-Master.xdc en algún lugar accesible, con permisos 644.
  • Crear el proyecto
  • Copiarlo y cambiarle los permisos a 664.
  • Ajustar
¿Por qué el asuntito de los permisos? Por que si al agregarlo al proyecto desde Vivado te equivocás y no le ponés "copiar", te puede quedar referenciado a tu archivo común y cuando lo modifiques rompes los otros proyectos que puedan tener el mismo defecto. Le pasó a un amigo y yo te cuento.

Germinómetro con sAPI del firmware v3

$
0
0
Necesitaba medir humedad y temperatura para un trabajo práctico escolar y recordé que puedo hacerme un sensor, qué loco, ¿no?




Busqué la edu-ciaa-nxp, el dht-11 y el poncho educativo por el display lcd, me bajé el Firmware V3 que Eric muy recientemente ha publicado y adelante:

git clone https://github.com/ciaa/firmware_v3.git

Temperatura y humedad



Ando medio raro, leí las instrucciones ANTES de fallar.

Tambien un poco vago, llamé

make board_select board_program


Eligiendo la placa y el path, examples/c/sapi/dht11_temp_humidity, para que me cree board.mk

Hice el export para que encuentre el compilador y lo de siempre...


export PATH=$PATH:....

make

make download

miniterm.py /dev/ttyUSB0 115200

Y anda.


Display


Parecido, la ruta es examples/c/sapi/lcd/gpio y no hace falta redefinir la placa y no sólo anda, sino que ya dice "Temp y Hum", parece que la estación meteorológica es el nuevo blinky.

Integración


Tomé el medidor, aunque pudo haber sido el del lcd y le transferí lo que necesitaba del lcd, que era la inicialización, el caracter de grados y lcdGoToXY(), lcdSendStringRaw(), etc. Metí las mediciones con un sprintf() en los buffers de entrada de lcdSendStringRaw() y listo, anda.

Finalmente lo saqué todo a mi repo y en el repo del firmware_v3 puse un symlink al mío, seleccioné el programa y lo habitual:

mkdir projects
cd projects
ln -s ../../../cpantel/Germinometro
cd ..
make select_program
make clean && make && make download

No, no tan fácil, a make select_program no le gustó el symlink:

Error: this script only work with paths inside repository folder.
If you want to use a path outside repository folder please change program.mk manualy.


Y como me había llevado sólo una hora llegar hasta acá, moví el proyecto a la carpeta al lado de los ejemplos y listo.



El sistema completo


Ya me supera un poco poner una tarjeta SD para registrar las mediciones y ponerle una pila, ponerlo en hora, así que le conecté una netbook y por puerto serial, que ya me lo había dado el primer ejemplo, las mando a un txt con un timestamp


miniterm.py /dev/ttyUSB2 115200 \
| while read LINE; do \
  TS=$(date "+%Y-%m-%d %H:%M:%S");\
  echo $TS $LINE; \
done \
| tee --append log.txt

Le pido a miniterm.py o tu programa favorito tal que puedas colgarte de su STDOUT que lea cada linea, le antepongo un timestamp y lo tiro a la pantalla y a un archivo en modo concatenación.

El código en github.

Nota de color


Me confundí al comienzo y me estaba compilando el ejemplo por default, que muestra "LED apagado" en el serial.

Para diagnosticar mis amigos fueron
  • buscar strings en el ejecutable para comprobar que se estuviera grabando
  • git grep con el texto de lo que estaba viendo en el serial
  • borrar .gitignore para ver que está tocando el proceso de compilación, lo recuperás con:

    git checkout .gitignore

Preguntar bien para aprender

$
0
0
Como esta es la... ya perdí la cuenta de las veces que me ha ocurrido, ha llegado el momento de compartirlo.


Tenía una duda de verilog que tenía que ver con que se estaba usando un vector como clock de un módulo y no lograba comprenderlo bien. Entonces me preparé como otras tantas veces para preguntar en el foro de embebidos:

Mi disciplina en estos casos y lo que quiero compartir es que cada vez que voy a hacer una pregunta, intento "hacer bien los deberes", esto es, evitar que alguien me conteste "hiciste esta obviedad?" o "mandá la salida de tal operación".

Para eso escribo la pregunta y voy completando todo lo que se me ocurre que alguien me reclamaría, lo cual me obliga a ir explorando muchas ramificaciones, algunas útiles y otras no tanto, de un modo u otro aprendiendo.

Asi que puse la pregunta, copié el código, quité de éste todo lo que estorbaba y esta es la primer versión del mail que no mandé, te propongo que intentés darte cuenta, si sabés algo de Verilog, claro, cual es la respuesta:

Hola

Mirando un ejemplo que tengo de un PWM he hallado que aparentemente un posedge de un vector corresponde a su overflow o algo así, ¿es así?


Este es el código en cuestión, quitándole todo lo que me pareció superfluo.

   module pwm_test(
   ...
   );
   reg [6:0] prescaler = 0; // CLK freq / 128 / 256 = 1.5kHz
                            // depende del reloj de la placa

   pwm p(.pwm_clk (prescaler[6]), ......);

   always @(posedge CLK)
   begin
      prescaler <= prescaler + 1;
     ...
   end

El otro módulo

   module pwm(
      input pwm_clk,
      ...
   );

   always @(posedge pwm_clk)
   .....

Gracias y saludos


¿Listo?

Busqué "verilog posedge of a vector" y me llevó una conversación donde dice que:

A posedge on (|vec) ?  Actually the standard says that [pos|neg]edge tests only the least significant bit of the vector.
Algo encaminado estoy, pero es lo contrario a los resultados, si fuera el LSB, la frecuencia sería la mitad del clock, no? ¿50 MHz en lugar de 391kHz?



Chiquito dice que la frecuencia es 391kHz


Todavía estoy intentando entender exactamente como funciona, eso lo relataré en un próximo post, pero mientras, mantengámonos en la pregunta de la relación entre posedge y un vector.

Para aclarar las cosas tanto para mí como para quien leyera, marqué con negrita el vector en los dos módulos y ahí hallé la respuesta que marco en rojo:

Se está usando el MSB del prescaler de 7 bits, encontré y entendí la respuesta a mi pregunta.



reg [6:0] prescaler = 0; // CLK freq / 128 / 256 = 1.5kHz
                         // depende del reloj de la placa

pwm p(.pwm_clk (prescaler[6]), ......);

always @(posedge CLK)
begin
  prescaler<= prescaler + 1;
  ....
end

------------------------
module pwm(
    input pwm_clk,
   ...
);

always @(posedge pwm_clk)
.....


Aunque estas son cosas muy personales, recomiendo este método, pues muchas veces en el foro hay preguntas tipo "no puedo leer el acelerómetro con la sAPI"  que hacen que quien quiera contestar tenga que empezar a escarbar para poder responder.


Está claro que quien pregunta puede estar muy perdido, pero intentar esto, si no llevarte a la solución, puede mejorar bastante la conversación.

En alguna conversación Alejandro me dijo "Gracias Carlos, siempre me contestás a mis post, te debo tener harto". Para nada, es la misma actitud, ponerse en el lugar del otro pero para aprender.


El código completo está en github y corresponde a la adaptación que estoy haciendo a una nexys4ddr de los ejemplos de un libro cuyo código está en github tambien.



Tres dimensiones extra en la evaluación de vulnerabilidades

$
0
0
Esta entrada es una actualización y extensión de algo que escribí hace rato. No quiero repetir lo que ya había dicho, pero como es bastante largo, haré un resumen. En el artículo original entro en mucho más detalle y agrego unas interminables reflexiones.

El tema es que en las fórmulas que suelo ver hay dimensiones como:

  • Cercanía al objetivo (CVSS v3)
  • Impacto de Confidencialidad, Integridad y Disponibilidad (todas).
  • Facilidad/complejidad/costo/reproducibilidad del ataque (DREAD)
  • Interacción con usuarios (CVSS v3)

En particular DREAD contempla "usuarios afectados", pero en términos cuantitativos. La primera dimensión que me resultaba interesante es entonces "tipo de usuario afectado", que apunta a la calidad. No en términos de cambio de permisos, escalamiento, eso ya lo tiene de algún modo CVSS v3 con "Scope". Me refiero a que no es lo mismo comprometer a un cliente, un empleado raso, un adminstrador de sistemas, un director. Dependiendo del objetivo y el tipo de persona afectado puede producirse fuga de información, transferencias de dinero, acceso a planes estratégico.

De algún modo está en "environmental" de CVSS v3, pero no produce un texto acompañante más expresivo tipo:

"La vulnerabilidad permite tomar el control de los nodos bajo Plan 9, que es lo que usan los administradores de sistemas".

La segunda tiene que ver con la responsabilidad: es algo mío o de un tercero. ¿Es una mala configuración mía o estoy usando una librería o componente fallado? ¿Es en mi sistema o en el sistema del cliente? En el caso de XSS, quizás el navegador es tan viejo que no puedo protegerlo completamente.

Otro ejemplo es uso repetido de credenciales por parte de los usuarios en distintos sistemas. Por más que yo le pida una credencial fuerte y limite los intentos, no tengo casi control, salvo pedir regeneración periódica, que si mal no interpreto el NIST no está del todo de acuerdo. Fijate que dice:


"Do not require that memorized secrets be changed arbitrarily (e.g., periodically) unless there is a user request or evidence of authenticator compromise."

La nueva


La tercera es "quién reporta" tiene que ver el tratamiento hacia quien ha efectuado y comunicado el hallazgo.



Si descubro la vulnerabilidad yo mismo, no pasa nada, no es público que yo tenga esa vulnerabilidad, no tengo que dar una respuesta por fuera del circuito o procedimiento de resolución.

Si esta vulnerabilidad figura en un boletín o en CVSS por que se trata de un componente ajeno, si es público que la tengo, pues al atacante le alcanza con saber que tengo el componente.

Si es por resultado de un Pentest y es propia, estamos entre pares. Seguimos dentro del contrato. Me tengo que ocupar sin duda pues si el Pentest la encontró en un sistema productivo, un atacante probablemente tambien lo haga.

Queda el caso de que un usuario o investigador independiente reporte, que es muy distinto y marca el máximo valor de esta dimensión, que puede tener muy importantes implicancias de impacto de imagen, daño reputacional.


Con un poco de suerte, el investigador independiente se puede manejar con Responsible Disclosure: tenés este problema, confirmalo y decime cuando lo vas a arreglar para darte tiempo antes de hacerlo público.

El usuario simplemente avisa y si no se le da respuesta quizás insista, quizás se olvide o quizás difunda en una red social "avisé y no me dieron respuesta o no lo arreglaron" y eso produce daño reputacional, aunque la vulnerabilidad haya sido un falso positivo.



Estas dimensiones o la visión que propongo quizás sea un poco menos "científicas" de algún modo, pues son menos cuantificable. Pero me parece que es un agregado más práctico, más de oficio. De todos modos no es un reemplazo, es una extensión al análisis.



Para estudiar Programming FPGAs: Getting Started with Verilog

$
0
0
Esta es la adaptación a Vivado/Nexys 4 DDR de los ejemplos del libro, escrito por Simon Monk que adquirí básicamente como introducción a Verilog tal que pudiera leer en el transporte público, pues necesito aún aprender Verilog para implementar Forzando Brutalmente MD5 Sin Computadoras en una Parallella y el ejemplo que quiero extender está en Verilog.



Como introducción a Verilog es muy liviana, termina y me digo ¿qué puedo hacer que no sea portar los ejemplos?

Son muy prácticos e interesantes, aparte de los típicos contadores y decodificadores de siete segmentos, tiene PWM, audio y vga, muy copado.

Comparando con [Free Range VHDL], se queda muy corto en los contenidos y la profundidad, pero le pasa por encima con la práctica, pues FR es agnóstico a la plataforma y no explica como sintetizar ni simular.

Los ejemplos son para tres placas que no tengo ni voy a tener, así que me dí la tarea de adaptarlos y ejecutarlos en la que sí tengo, una Nexys 4 DDR (Artix 7) y en lugar de usar ISE, usar Vivado 2018.2.

En teoría lo único que tendría que hacer es adaptar los clocks y las UCF, o sea, los archivitos que dicen a que patitas se conectan lo que se haya programado. En la práctica, hay un poco más. Y al interactuar con hardware externo un poco de debug no viene mal.


Lo bueno de este proceso es que me sirvió para:
  • fijar el flujo de trabajo en Vivado.
  • comprender los constraints files.
  • asimilar Verilog, del cual no sé casi nada.

Si te interesa reproducirlo, quizás te convenga dejar de leer y tampoco mirar el código en github.

Apliqué esta práctica tambien a otros cursos online que iré publicando.

Manos a la obra


git clone https://github.com/simonmonk/prog_fpgas.git


Comencé con el contador del capítulo 3. Me generó un reporte donde dice que el part name no es soportado y que los UCF (el archivo de constraints) no le sirve y que no entiende Schematics y como convertirlo a algo compatible usando ISE , que es la versión previa a Vivado.

Como me desvía mucho de mis intereses actuales, a saltear ejemplos hasta hallar Verilog.

 

Contador del capítulo 4



Según lo esperado,  hay que adaptar el target, ajustar el XDC y darle para adelante.

El target:
  • Project Manager->
  • Settings->
  • Project settings->
  • General->
  • Project Device->
  • Boards->
  • Nexys-4-DDR
El XDC:

  • Project Manager->
  • Add Sources->
  • Add or create constraints->
  • github/digilent/digilent-xdc/Nexys-4-DDR-Master.xdc

Adaptar los get_ports a la interfaz:

module counter(
    input BTNC,              // Clock en el original
    output reg [3:0] Q
    );


Habilitar los pines en XDC:



## LEDs

set_property -dict { PACKAGE_PIN H17 IOSTANDARD LVCMOS33 } [get_ports { Q[0] }];

                                                #IO_L18P_T2_A24_15 Sch=led[0]

set_property -dict { PACKAGE_PIN K15 IOSTANDARD LVCMOS33 } [get_ports { Q[1] }];

                                                #IO_L24P_T3_RS1_15 Sch=led[1]

set_property -dict { PACKAGE_PIN J13 IOSTANDARD LVCMOS33 } [get_ports { Q[2] }];

                                                #IO_L17N_T2_A25_15 Sch=led[2]

set_property -dict { PACKAGE_PIN N14 IOSTANDARD LVCMOS33 } [get_ports { Q[3] }];

                                                #IO_L8P_T1_D11_14 Sch=led[3]


##Buttons
set_property -dict { PACKAGE_PIN N17 IOSTANDARD LVCMOS33 } [get_ports { BTNC }];
                                                #IO_L9P_T1_DQS_14 Sch=btnc

Al hacer la implementación, me dijo:

[Place 30-574] Poor placement for routing between an IO pin and BUFG. If this sub optimal condition is acceptable for this design, you may use the CLOCK_DEDICATED_ROUTE constraint in the .xdc file to demote this message to a WARNING. However, the use of this override is highly discouraged. These examples can be used directly in the .xdc file to override this clock rule.
    < set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets BTNC_IBUF] >

    BTNC_IBUF_inst (IBUF.O) is locked to IOB_X0Y82
     and BTNC_IBUF_BUFG_inst (BUFG.I) is provisionally placed by clockplacer on BUFGCTRL_X0Y0


Parece que no le gusta que le pongan en el reloj cosas que no son del reloj. Seguí las instrucciones (el set property...) y todo ok.

 set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets BTNC_IBUF];


Nota de color



Durante un momento estuve confundido y en lugar de conectar el botón conecté el clock,

## Clock signal
set_property -dict { PACKAGE_PIN E3 IOSTANDARD LVCMOS33 } [get_ports { Clock }];

                                               #IO_L12P_T1_MRCC_35 Sch=clk100mhz

create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports {Clock}];




Podía tomar dos caminos:

Aprender a manejarme con todo lo de los clocks, agregado a la deuda, o hacer más ancho el contador y fué más ancho, pero aún con


output reg [15:0] Q

y en el XDC:

descomentar y renombrar Q[4] a Q[7],

el problema es que con el reloj a 100 MHz, aun con un contador de 16 bits (65536), la frecuencia más baja es 1525 Hz, obviamente inapreciable sin instrumental. Luego entendí que el "Clock" estaba provisto por apretar un botoncito.

 

Siete segmentos del capítulo 5

 

Hay un prescaler que no ajusté al número apropiado tal que haga refresco a 1kHz, deber estar haciéndolo a algo bastante más alto, en otra oportunidad diagnosticaré y corregiré.

Como mi placa tiene 8 digitos contra los 3 o 4 de las del libro, para mejorar la estética, habilité todos los dígitos propagando las centenas a la izquierda, no tenía ganas de apretar mil veces el botoncito ni modificar mucho el ejemplo tal que otro botón sumara de a diez y otro de a cien. Estuve varias horas dando vueltas por que no funcionaba hasta que me di cuenta que unos wires no estaban bien por el ancho y fundamentalmente por unos warnings que decían que habían patitas sin usar.


Cuenta regresiva del capítulo 6


Como usa componentes ya modificados en el ejemplo del contador, primero hice la adaptación tal como viene y luego le apliqué el cambio, que es usar los ocho dígitos.




kdiff3 papilio/ch06_countdown_timer/src/timer.v \
       elbert2/ch06_countdown_timer/src/timer.v \
       mojo/ch06_countdown_timer/src/timer.v


PWM del capítulo 7


No pude postergar más el asunto de la frecuencia, ya que el próximo ejemplo usa este para interactuar con un componente externo.

Adelantándome un poco pero sin hacer trampa, tras adaptar el PWM a mi placa, para el servo hay que meter un pulso así:

Stefan Tauner [CC BY-SA 3.0 (https://creativecommons.org/licenses/by-sa/3.0)]

Y en el ejemplo hay cualquier cosa, ya que es de PWM en general, más considerando la disparidad de clocks de las placas involucradas:
  • Elbert2      12 MHz
  • Papillo One  32 MHz
  • Mojo         50 MHz
  • Nexys4 DDR  100 MHz

Como siempre, te recomiendo te detengas, hagas tus pruebas y regreses.

Tablita útil para los que no estamos todo el día con esto


Hay tres caminos, uno es pensar y calcular, el otro medir y el otro mirar fijo los ejemplos y sus diferencias, tambien llamado ingeniería inversa.


Voy a tomar los tres caminos y los voy a mezclar.

Pensar y calcular


Primero hay que comprender el código:

  reg [7:0] duty = 0;
  reg [6:0] prescaler = 0; // CLK freq / 128 / 256 = 1.5

  always @(posedge CLK)
  begin

    prescaler <= prescaler + 1;
    // esto indica el ancho del pulso
    if (s_up)
      duty <= duty + 5;
    if (s_dn)
      duty <= duty - 5;

  end


  pwm p(.pwm_clk (prescaler[6]), .duty (duty),...);

 y el módulo pwm

  reg [7:0] count = 0; 

  always @(posedge pwm_clk) ; // pwm_clk <= prescaler
  begin
    count <= count + 1;
    PWM_PIN <= (count < duty);

  end


No lo termino de entender, así que a...

Medir



Para medir repliqué la salida del PWM del led a uno pin de un pmod y tambien el pwm_clk y de ahí al osciloscopio.

Volver a pensar y calcular


La frecuencia es 391 kHz, que es 100MHz dividido 256, si lo divido otra vez, tengo 1.527 kHz, con lo cual llego al ejemplo.

Para avanzar hacia el servo, lo que tengo no sirve pues no estoy respetando los límites y lo modifico sin mirar el siguiente ejemplo o paso al siguiente ejemplo... ok, versiono el ejemplo con valores equivalentes e intento hacer el servo y si fallo me copio.

Hay unos dibujitos muy lindos de pwm en el manual de referencia.

 

Mi intento de servo del capítulo 7


Pensé, primero tengo que lograr un período de 20 ms, tras algunas pruebas, quedé cerca y las aproveché para aprender como parametrizar un módulo, muy útil y sencillo:

En la interfaz del módulo se define un parameter con un valor default,

  module pwm #( 
    parameter DUTYWIDTH  = 8
  ) (
    input pwm_clk,
    input [DUTYWIDTH - 1:0] duty,
    output reg PWM_led,
    output reg PWM_pin,
    output reg PWM_CLK_pin
  );


que puede ser reemplazado en la instanciación desde el parent:

  parameter DUTYWIDTH = 8;
  pwm #(.DUTYWIDTH(DUTYWIDTH)) p(.pwm_clk


Luego pensé que si debe variar entre 1 y 2 ms el pulso, hacen falta algunos && en los ifs de variación:

  if (s_up && duty < DUTYHIGH )
  begin
    duty <= duty + DUTYSTEP;
  end
  if (s_dn && duty >= DUTYLOW)
  begin
    duty <= duty - DUTYSTEP;
  end 


Finalmente, como no estaba en 20ms de período si no en 21ms, en lugar de dejar que el contador del prescaler diera toda la vuelta, le puse un tope:

  if (prescaler > PRESCALER_MAX )
    prescaler <= 0;


El código completo acá y listo, a comparar con el libro.

 

Servo del capítulo 7

 

Un poco decepcionante, no hay ningún control del ancho del pulso.

Tomé la de Mojo por el clock múltiplo (50MHz), así que de una me arrancó con un periodo del doble, 10ms.


Pensé que con multiplicar por dos el prescaler se arreglaría pero no, así que miré las implementaciones de las otras placas:

 find . -iname servo_tester.v | xargs kdiff3
 find . -iname tester.v | xargs kdiff3



Interesante es que usa parámetros posicionales:

  servo #(100) (...

preferí nombrarlos

  servo #(.CLK_F(100)) (...

y aunque el libro menciona el parameter, no explica como reemplazarlo en synthesis time.

Además puse el valor inicial de pulse_len en 1000 en lugar de 500 y está ok, salvo la falta de límites.




Si mirás bien los kdiff3s anteriores, vas a ver que cada placa no tiene parámetros distintos si no código distinto, mmh, me parece que me quedo con mi implementación, tengo dudas de si pasarle el prescaler al módulo o conservarlo afuera.



Abajo a la izquierda el servo se mueve mientras arriba al centro cambia el ancho del pulso.

Capítulo 8 WAV Player


A diferencia del ejemplo de la Nexys4DDR, el libro no usa la memoria RAM sino la memoria de la FPGA, que ahorita no recuerdo el nombre, pero ya aparecerá... block memory. Tampoco usa el audio output sino un mero GPIO.

Lo adapté tal como está, el objetivo de esta experiencia es sólo hacerlo andar, no entrar en cambios drásticos.

Usé el ejemplo de Mojo, que es la más power.

La lectura en "memoria" del audio le agrega a la síntesis cinco minutos.

Asombrosamente, anda.

Capítulo 9 VGA básico


Esta es la interfaz del módulo:

  input CLK,
  output HS,
  output VS,
  output [2:0] RED,
  output [2:0] GREEN,
  output [1:0] BLUE


Este es el .UCF del Papillo One:

  NET "CLK" LOC = P89; #32MHz
  # Outputs
  NET "HS" LOC = P83;
  NET "VS" LOC = P85;
  NET "RED[0]" LOC = P61;
  NET "RED[1]" LOC = P58;
  NET "RED[2]" LOC = P54;
  NET "GREEN[0]" LOC = P68;
  NET "GREEN[1]" LOC = P66;
  NET "GREEN[2]" LOC = P63;
  NET "BLUE[0]" LOC = P78;
  NET "BLUE[1]" LOC = P71;



Y esto es lo que hay en el XDC:


#... [get_ports { VGA_R[0] }]; #IO_L8N_T1_AD14N_35 Sch=vga_r[0]
#... [get_ports { VGA_R[1] }]; #IO_L7N_T1_AD6N_35 Sch=vga_r[1]
#... [get_ports { VGA_R[2] }]; #IO_L1N_T0_AD4N_35 Sch=vga_r[2]
#... [get_ports { VGA_R[3] }]; #IO_L8P_T1_AD14P_35 Sch=vga_r[3]
#... [get_ports { VGA_G[0] }]; #IO_L1P_T0_AD4P_35 Sch=vga_g[0]
#... [get_ports { VGA_G[1] }]; #IO_L3N_T0_DQS_AD5N_35 Sch=vga_g[1]
#... [get_ports { VGA_G[2] }]; #IO_L2N_T0_AD12N_35 Sch=vga_g[2]
#... [get_ports { VGA_G[3] }]; #IO_L3P_T0_DQS_AD5P_35 Sch=vga_g[3]
#... [get_ports { VGA_B[0] }]; #IO_L2P_T0_AD12P_35 Sch=vga_b[0]
#... [get_ports { VGA_B[1] }]; #IO_L4N_T0_35 Sch=vga_b[1]
#... [get_ports { VGA_B[2] }]; #IO_L6N_T0_VREF_35 Sch=vga_b[2]
#... [get_ports { VGA_B[3] }]; #IO_L4P_T0_35 Sch=vga_b[3]
#... [get_ports { VGA_HS }]; #IO_L4P_T0_15 Sch=vga_hs
#... [get_ports { VGA_VS }]; #IO_L3N_T0_DQS_AD1N_15 Sch=vga_vs


Mete miedo, es la primera vez en mi vida que voy a conectar a un monitor algo que no sea una placa de video. No hay que dejarse acobardar.

...[get_ports { RED[0] }]; #IO_L8N_T1_AD14N_35 Sch=vga_r[0]
...[get_ports { RED[1] }]; #IO_L7N_T1_AD6N_35 Sch=vga_r[1]

...[get_ports { RED[2] }]; #IO_L1N_T0_AD4N_35 Sch=vga_r[2]

...[get_ports { GREEN[0] }]; #IO_L1P_T0_AD4P_35 Sch=vga_g[0]
...[get_ports { GREEN[1] }]; #IO_L3N_T0_DQS_AD5N_35 Sch=vga_g[1]
...[get_ports { GREEN[2] }]; #IO_L2N_T0_AD12N_35 Sch=vga_g[2]

...[get_ports { BLUE[0] }]; #IO_L2P_T0_AD12P_35 Sch=vga_b[0]
...[get_ports { BLUE[1] }]; #IO_L4N_T0_35 Sch=vga_b[1]

...[get_ports { HS }]; #IO_L4P_T0_15 Sch=vga_hs
...[get_ports { VS }]; #IO_L3N_T0_DQS_AD1N_15 Sch=vga_vs


Fiel a lo que había aprendido con respecto a los nombres, adapté el XDC. Obviamente sintetizó, implementó y generó de una pero está el asunto del reloj, recuerdo haber escuchado hace muchos años a monitores VGA sometidos a resoluciones extremas y luego romperse. Tengo dos caminos:

  • Conectar a un monitor descartable, difícil, el que tengo no sé que tan mal anda y sería una pena romperlo.
  • Desde una placa de video generar la misma resolucion, medirlo y comparar.

Lo segundo sin ninguna duda es más educativo, pero tambien es más trabajo, voy a reventar primero el monitor que ya está dañado.

De un modo u otro es útil releer en el libro lo que dice de como ajustar los timings según el clock de cada placa, lo que me lleva al tercer camino:

  • Comprender los timings y medir el HS y VS a ver si son apropiados sin conectar el monitor.

Para ello dupliqué las señales en el PMOD, tengo un VS de 230 Hz y HS de 120KHz:


En amarillo el HS 119 kHz antes del ajuste



En cyan VS 232 Hz antes del ajuste



Empíricamente dividí el clock por cuatro a ver si me queda en 57.5 e intuyo que HS debería ser eso por 500, un poco menos de 30 kHz, perfecto!


En amarillo HS 30 kHz




En cyan VS 57.8 Hz



Funcionando. Si, son alfileres con cabeza los que uso para las puntas.

Lo que sigue es cuesta abajo... pero en algún momento debería sentarme a hacer bien las cuentas y usar otras resoluciones correctamente, quedará para otra entrada.

Capítulo 9 VGA memoria

 

Este, al igual que el del wav levanta la info de block memory, pero en lugar de tirarla al audio, va a VGA

El módulo vga.v es el mismo que el anterior, vga_mem.v tiene agregado los probes y declaré explícitamente un wire blank que no estaba.

Ufa, es una bandera inglesa, me guardo la foto.

Capítulo 9 VGA juego

Nada, más de lo mismo, sólo hay que conectar los pines y anda, más o menos, menos que más. Habría que toquetear los tiempos y centrar bien la pantalla, va a la deuda.



Resumiendo


El procedimiento para migrar los ejemplos del libro es:
  • Crear un nuevo proyecto
  • Elegir board/device 
  • Copiar los verilogs y agregarlos al proyecto
  • Agregar XDC y adaptarlo mirando fijo la interfaz del top module y los .ucf
    • Pines
    • Reloj 
  • Pelearse con lo que haya que pelear
    • la adaptación al clock
  • Run Synthesis
  • Volver a pelearse con lo que haya que pelear
  • Run Implementation
  • Volver a pelearse con lo que haya que pelear
  • Generate Bitstream
  • Conectar los accesorios de hardware necesarios
  • Hardware Manager
  • Auto Connect
  • Program Device
Es horrible el tiempo que tarda, no bien pueda voy a aprender a distribuir la carga vía red.

Reitero que el código está en github.

Deudas  

Estos son algunos de los temas que no resolví para no salirme del rumbo, que era sólo portar los ejemplos, en algún momento saldaré mi deuda y se reflejará en futuras entradas.
  • Usar distintos clockings.
  • Comprender y usar el audio jack. 
  • Calibrar las medidas de VGA.
  • Comprender los timings de VGA para usar otras resoluciones.
  • Adaptación eléctrica del servo, no termina de girar los 90°.
  • Distribuir la carga del proceso de build.





H4CK3D 2019 - The missing pieces

$
0
0

Otra vez en H4CK3D, gracias a Javier Vallejos y Fabián Portantier de Securetia y a la UP


Cuesta trabajar y asistir a todo el evento, pero pude verla a Yamila Levalle (@ylevalle) exponer algo muy razonable: los SIEMs tienen que estar correctamente desarrollados y configurados, no dejan de ser aplicaciones, que fué lo que mostró en... Blackhat usa 2019 qué capa!

Tambien a Diego Bruno y Jorge Martín Vila, mostrando OSINT relacionado a lavado de dinero, les costó meter todo el tema en el tiempo asignado, jiji.

Finalmente Gerardo D'onofrio expuso la herramienta EJBCA, para certificados, muy interesante. Y ahí me tuve que ir y no pude volver.

El nerd de Schrödinger...


Con respecto a lo que yo expuse, ha sido rara la experiencia, normalmente todo el mundo siempre te dice que salió bien, nadie que mal.

Tambien suelen haber fallas técnicas y no técnicas, como una OWASP hace mucho en la que estando a punto de mostrar un ataque, no pude encontrar el archivo pese a tener la ruta escrita delante de mis ojos. Fallas técnicas que me hayan ocurrido a mi no recuerdo pero si a otras personas.

Esta vez hubo una falla técnica de origen humano. En una de las partes de SDR con gqrx iba a escuchar una radio y el audio de un canal de TV, pero no tenía audio. Esta ausencia m hizo desistir de mostrar la transmisión de radio con un adaptador USB-VGA.

Eso en realidad fue el impacto de la falla, que fue que el battery pack se apagara y que no recordara que eso podía ocurrir, la falla humana original.


Pienso que actué correctamente al no ponerme a diagnosticar la falla, que como siempre ocurre es ínfima, pese a los resultados espectaculares.

Tambien hubo otra falla leve, al intenter leer la banda magnética el lector estaba lejos de la antena y otra que en lugar de leer el controlador de la alarma de una asistente debí haber traido uno del que ya tuviera identificada la frecuencia.

Estas fallas que me persiguirán en mis pesadillas hasta el fin de los tiempos, bajaron un poco el nivel técnico pero tembien me obligaron a hacerla más entretenida. No hubo menos información, faltaron pruebas, no es lo mismo decir que esa franja naranja es el audio que escucharlo.



Ahora, las missing pieces.



Lector mental

 

El componente es mindwave mobile, no el dos:

https://store.neurosky.com/

El programa:

git clone https://github.com/robintibor/python-mindwave.git

Hay que ejecutar primero blueman-manager




Me encantaría explorar la API, pero tiene baja prioridad, vuelve al cajón del futuro.



Sintonizando


Esta fue la parte sin audio, usando un receptor de DVB-T
 

Esta es una radio común:



Y esto el audio del canal 13:





La captura de pasar la banda magnética, no ha vuelto a dejar trazas pese a que puse la antena bien cerca.

La alarma del auto, las franjas:




Saquen sus teléfonos



Mientras me divertía un poco a costa de los asistentes, mostré un artefacto que había levantado de un volquete unos días antes cerca del trabajo. Es parte de una central inteligentísima de fines de los ochenta, HABIMAT HT-X.


http://www.aeby-tec.ch/htx/






Tiene un 68k y en el medio esa cosa roja y blanca es un eprom con ventanita montado en un adaptador, muy bueno, todo de alta calidad, las roscas de los tornillos en el plástico son de bronce, este equipo tiene como treinta años y se abrió con un soplo, mirá el destornillador que usé por que era lo que tenía a mano, normalmente busco algo con mango más grande para poder hacer fuerza.





Separada la pantalla, que es lo que más me interesa, en un primer examen no pude identificar el modelo.


Ver lo que hay en el chip o descifrar el protocolo de la pantalla son ambos muy buenos ejercicios, pero por el momento van al cajón del futuro, a menos que cambie de idea en un impulso repentino.


USB VGA


Vale poco y con este programita anda, con un delay de tres o cuatro segundos:


git clone git://git.osmocom.org/osmo-fl2k

sudo apt install libusb-1.0-0-dev
mkdir build
cd build/
cmake ../ -DINSTALL_UDEV_RULES=ON
make -j 5
sudo make install
sudo ldconfig
sudo udevadm control -R
sudo udevadm trigger
sudo apt install sox pv






Hay que obtener el nombre de lo que se está escuchando:


pacmd list-sources | grep name | grep monitor
    name: <alsa_output.pci-0000_00_1f.3.analog-stereo.monitor>



y usarlo

 


pacat -r -d alsa_output.pci-0000_00_1f.3.analog-stereo.monitor |\
sox -t raw -r 44100 -e signed-integer -L -b 16 -c 2 - -c 1 -e signed-integer -b 16 -t raw - \
biquad 4.76963 -2.98129 0 1 0.788833 0 sinc -15k loudness 5 | \
fl2k_fm - -s 130e6 -c 35e6 -i 44100



Probablemente sacado de https://www.rtl-sdr.com/setting-up-and-testing-osmo-fl2k/


SDR

 

En general para SDR, que fué lo anterior, los componentes que usé no son muy útiles, si realmente fuera a estudiar, investigar o trabajar algo de SDR usaría algo como HackRF One. que es un poco carita, u$s 315 y mucho peor en ML, u$s 365 usado o u$s 750 nuevo.

El juego del cálculo distribuido seguro


Lo dejo aparte en... pronto...

Las claves compartidas


Gracias a que la charla es para una hora, mis varios extravíos no previstos y la participación de la audiencia, esto quedó afuera, pero la idea es sencilla:


Si queremos que de un grupo de personas hagan falta al menos dos para destrabar algo que está con una clave, repartimos entre las personas puntos de una función. El sistema autenticador conoce la función pero no sabe a que altura está, la clave real es la intersección de esa función con el eje Y.

¿Querés más personas necesarias? Aumentás el grado.



Fin



Si te interesa algún detalle extra, preguntás.



Diagnostico de HTTP Headers con Polymer y Node Express dentro de TLS

$
0
0

El Problema

Estoy haciendo una miserable aplicacioncita con Polymer del lado del cliente y Node Express como API, siendo servidas de distintas URLs, ambas con TLS.

Al intentar agregar un Custom HTTP Header en lugar de ver un:

api_1 | { connection: 'upgrade',
api_1 |   host: 'api.techu.example',
api_1 |   'user-agent': 'Mozilla/5.0 ...Firefox/57.0',
api_1 |   accept: 'text/html,application....9,*/*;q=0.8',
api_1 |   'accept-language': 'en-US,en;q=0.5',
api_1 |   'accept-encoding': 'gzip, deflate, br',
api_1 |   'access-control-request-method': 'GET',
api_1 |   'access-control-request-headers': 'content-type',

api_1 |   'X-Practitioner-Auth': '2',
api_1 |   origin: 'https://www.techu.example' }



veo


api_1 | { connection: 'upgrade',
api_1 |   host: 'api.techu.example',
api_1 |   'user-agent': 'Mozilla/5.0 ...Firefox/57.0',
api_1 |   accept: 'text/html,application....*;q=0.8',
api_1 |   'accept-language': 'en-US,en;q=0.5',
api_1 |   'accept-encoding': 'gzip, deflate, br',
api_1 |   'access-control-request-method': 'GET',
api_1 |  'access-control-request-headers': 'content-type,x-practitioner-auth'
api_1 |   origin: 'https://www.techu.example' }



y un 

NetworkError: A network error occurred

en la consola del browser.



Como no entiendo en absoluto por qué esta ocurriendo esto, quiero descartar capas intermedias, quiero ver el tráfico de red, pero está con TLS.


No me interesa tanto mostrar la solución al problema que es CORS sino el camino seguido, centrándome en la dificultad de que haya TLS de por medio.


Alcance y consideraciones


Tengo la clave privada del servidor pues estoy en un ambiente de test y yo generé las CAs.


Tuve suerte, la ciphersuite que acordaron el servidor y el cliente es descifrable por wireshark. Según leí por ahí, hay ciertas combinaciones que lo son y otras que no. Hay maneras de forzarla.

Linux Mint 19.x.

Para variar, no sé casi nada de Polymer, Node, CORS, pero se parece a cosas que he aprendido y olvidado varias veces.


Instalar wireshark 


sudo apt install wireshark-qt

Cuando pregunta si permitir a usuarios comunes capturar en modo promiscuo, decile que si.

Luego hay que agregar el usuario al grupo y reiniciar la sesión.

sudo addgroup practitioner wireshark

Configurar el browser


Pedile al browser que deje disponibles las claves de sesión en un archivo:


SSLKEYLOGFILE=/home/practitioner/sslkeylog.log firefox


Para un launcher es parecido:


Si lo estás editando



Si lo estás creando





Una vez arrancado el browser, hay que identificar en que interfaz capturar. Podés usar ANY, pero estando con Docker mejor ser más especìfico. Sospecho que localhost es el lugar, pero comprobémoslo generando tráfico:


Tráfico en localhost y algunas interfaces de Docker


Localhost ok.


Luego hay que pedirle a wireshark que mire el archivo del browser:


(Pre)-Master-Secret log filename


y las private del sitio o sitios, yo tengo API y www, claro, si este problema se trata de algo de cross domain...



Private Keys



Mejor vaciar la cache, cerrar y volver a abrir el browser, para que no esté lleno de 304 y que agarre toda la sesión TLS.




Si tuviste éxito, vas a ver una solapita abajo que dice "Decrypted SSL"

No están de más algunos filtros como:

tcp.port == 443 && ssl.record.length > 66

La primera parte es para sacarse de encima lo que no es TLS, pero sólo si tenés la certeza que tu tráfico es sólo TLS.

Para tener esa certeza tendrías que activar en el servidor HSTS


La segunda es para eliminar los keep alives y otra información administrativa del canal. No hallé o al menos no busqué mucho como filtrar dentro del tráfico TLS, por ejemplo si quisieras sólo los GET, frame matches xxx no anda. No digo que no haya.

Con "Follow HTTP Stream" se pone mucho más amigable



Me apoyé en varias fuentes, fundamentalmente https://packetpushers.net/using-wireshark-to-decode-ssltls-packets/, donde hay más detalles relativos a las ciphersuites soportadas y como ajustarlas.

A diagnosticar

El encabezado sale "mal" desde el browser, no es problema de la API.



¿Qué estoy haciendo en el browser? Hago lo natural:


request.setRequestHeader('X-Practitioner-Auth', 'tok');

¿Qué hay de malo con eso?

Leyendo https://www.html5rocks.com/en/tutorials/cors/inferí que el problema probablemente viene por el preflight fallido de CORS, que es ese OPTIONS sin GET posterior.

O sea que lo que puse en amarillo en realidad está ok, no me había dado cuenta que era en OPTIONS.... mejor no voy a decir nada por que no sé bien, aunque lo haya arreglado.



Supuse que la falla era tener en el middleware:


app.use(function(req,res,next) {
  res.setHeader('Access-Control-Allow-Origin','https://www.techu.example');
  res.setHeader('Access-Control-Allow-Headers','Content-Type');
  next();
});


en lugar de

app.use(function(req,res,next) {
  res.setHeader('Access-Control-Allow-Origin','https://www.techu.example');
  res.setHeader('Access-Control-Allow-Headers','Content-Type','X-Practitioner-Auth');
  next();
});



Pero no, no anda ni a palos. Despues de muchas vueltas llegué a que hay que usar CORS y listo:

npm install cors 

y en la API

const cors = require('cors');
var corsOptions = {
  origin: ['https://www.techu.example'],
  allowedHeaders: ['Content-Type', 'Autorization']
}

app.use(cors(corsOptions));


Un poco de CORS:







Juegos de cálculo seguro distribuido

$
0
0
En ECI 2018 hubo un curso de cripto donde mostraron varias maneras de que un grupo de adversarios puedan ejecutar cálculos con información que tienen sin compartirla, por ejemplo, empresas pueden calcular promedio de fraudes  sin que ninguna revele sus cifras.

Para mostrarlo de modo intuitivo tanto para charlas internas en el trabajo como para H4CKED 2019, he desarrollado dos juegos que paso a compartir.


En ambos casos se supone que la transmisión es completamente secreta.

Con azar

La idea es que hacemos una ronda de personas, donde la primera toma su número y le suma otro al azar, guardando ambos en secreto. El resultado se lo pasa a la siguiente participante, que le suma su número y así hasta dar la ronda completa. La primera persona le resta el número al azar a lo obtenido y tiene la sumatoria de todas las participantes, que ya puede compartir. Cualquiera divide por la cantidad de participantes y ya tenemos el promedio que queríamos.






La debilidad de este algoritmo es que cualquier par de participantes separadas por una sola persona puede atacar a esta, pues saben el valor de entrada y el de salida, cuya resta es el valor de la víctima.


Con descomposición

Una mejor versión invulnerable al ataque anterior consiste en que cada participante descompone su valor en tantos sumandos al azar como participantes hayan y envía uno a cada participantes. Cada participante toma los sumandos recibidos, los suma y comparte el resultado. Estos resultados se suman, se divide por la cantidad de participantes y nuevamente tenemos el promedio que buscábamos.








El escenario de ataque factible para este caso es que todas las participantes menos una se pongan de acuerdo para atacar a esa. Sabiendo el total, se le resta el acumulado por las atacantes y tenemos el valor de la víctima.

Multiplicación


Tambien se puede multiplicar de esta manera, con factores, salvo que si alguien tiene un cero, al menos una participante va a saberlo. Quizás habría que agregar algunas rondas de intercambio, pero para un juego ya se complica innecesariamente.

En el caso del primer juego, se puede multiplicar un cero cerca del comienzo es más identificable que al final.


Otras maneras


Hay otras maneras pero no son tan intuitivas, al menos para quienes no sabemos más que matemáticas básicas, así que no son candidatas para juegos didácticos como estos. Tampoco sé si resuelven el problema del cero en la multiplicación.

Acá tenés las tarjetas por si querés jugar







Cambiando de grupo sin reiniciar sesión

$
0
0
¿Te ha pasado que acabás de instalar un programa que accede a hardware y te dice que para poder usarlo tenés que reiniciar a la windows viejo?

Algunas situaciones pueden ser VirtualBox para conectarle los USB, wireshark para acceder a las interfaces sin ser root, acceso al puerto serial y quizás al scanner.

Lo que ocurre es que necesitás pertenencia a un grupo, no es algo que se aplique así no más, hay varias maneras:

Reiniciar la sesión

Es lo que no queríamos hacer, pero si eres tan gallina, es lo tuyo.

Iniciar una nueva sesión

Artera comadreja, ok, no cerraste la sesión y te abrís una al lado con otro usuario. Te dejo de ejercicio fijarte si podés iniciar dos sesiones de XWindows del mismo usuario.

"Iniciar" una nueva sesión

¡Es la opción correcta! Una vez que estás en el grupo con, por ejemplo, addgroup, hacés su --login USER y estás adentro




Esto es para esta terminal, en las otras aplicaciones seguís afuera, pero desde esta terminal podés abrir el programa que acabás de instalar.

Unirte al grupo


Esta opción es medio rara, no la usa nadie y consiste en que a un grupo se le puede dar una clave con gpasswd, que queda en /etc/gshadow, igual que /etc/shadow, luego haces newgrp.



Ejemplo de acceso a la carpeta de USB de VirtualBox:


Esta tambien es para la terminal y te dejo como ejercicio fijarte si altera a las aplicaciones ya abiertas.

Resultado


Este es el comportamiento para acceder a USB desde VirtualBox

Primero no estás en el grupo vboxusers.


La VM arranca todo bien, pero cuando le querés conectar algo...







De cualquiera de las maneras, una vez que estás en vboxusers


Podés conectarle lo que haya en USB



Siempre...


...es mejor tomar una de estas acciones y evitar como la plaga usar sudo, pues está vez te va a funcionar, pero la próxima que hagas login, quizás te creó archivos en tu home con permisos de root y vas a tener que limpiar el desastre.

Además siempre que puedas ejecutar algo sin ser root (ni sudo) es más seguro pues tenés una defensa adicional frente a un ataque, que es que obligás a quien te ataca a escalar privilegios.

Fijate que ni mencioné la posibilidad de hacer login como root. Es de adolescentes, sentir el poder, la adrenalina. Pero una vez que aprendiste a usar *nix, madurás y sólo usás tu poder cuando hace realmente falta.


Ejemplo de rescate de memoria de cámara

$
0
0
Un pariente borró accidentalmente sus fotos y videos de una cámara que encima tiene rota la tapita de las pilas, detallo acá lo hecho para restaurarlas:

El camino fácil


Primero, obtener una imagen de la memoria, hay que insertarla y ver que dice dmesg cómo encontrarla:

[69.899754] sd 8:0:0:0: [sdb] 7741440 512-byte logical blocks: (3.96 GB/3.69 GiB)
[69.906898] sdb: sdb1


Para ser estrictamente forenses, debimos haber desactivado el automount, para evitar cualquier escritura sobre el disco, en particular en Mint Mate me parece que con

gsettings set org.mate.meda-handling automount false

ya estamos. Recordá que si el disco se monta automáticamente, se hace read write y algo toca, aunque en este caso no debería hacer diferencia.

Luego con fdisk explorarla, por curiosidad y costumbre:


$> sudo fdisk /dev/sdb -l
Disk /dev/sdb: 3,7 GiB, 3963617280 bytes, 7741440 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00000000

Device     Boot Start     End Sectors  Size Id Type
/dev/sdb1        8192 7741439 7733248  3,7G  b W95 FAT3
2

Otro motivo para no tomar la imagen hubiese sido estar recuperando información de un almacenamiento mayor al espacio disponible.

Para buscar lo borrado, el programa photorec ha resultado muy efectivo,

sudo apt install testdisk

Puede trabajar directamente sobre la memoria con sudo o sobre la imagen, mejor sobre la imagen, de paso no le damos sudo.

photorec sd.img

Con sudo seguramente hubiese mostrado la sd.


Hay que elegir si revisar todo el disco o la partición que encuentra, en este caso la partición. Si se hubiera borrado la tabla de particiones... whole disk.


Hay que elegir el formato, en este caso sabemos


 Elegimos que busque en toda la partición


 Y finalmente donde dejar lo rescatado




En el caso de esta vieja Kodak, recuperó imágenes y videos como esperábamos y además unos xmls, .ini y sqlite que como no aportan nada los ignoré.

Las fotos que comienzan con f son fotos, las que comienzan con t son previews.

Para ver el resultado, en Mint y parecidos con abrir la primera imagen se puede ver con el visor y luego pasar a modo galería o ir avanzando con la flecha. Como detalle de calidad se pueden rotar las imágenes que lo necesiten y al salir de visor ofrecerá guardar

Como no estaba seguro del orden, ejecuté el siguiente script que extrae la fecha de la metadata y compone un nuevo nombre:



Pongo una imagen en lugar de texto en parte por que se vé mas lindo, en parte por mala gente así tenés que tipear, lo cual te ayuda a familiarizarte con bash.


Con respecto a videos rotados, se pueden corregir con:


ffmpeg -i f0316864.avi -vf "transpose=2"  fixed.avi


o mejor aún con:


mencoder -vf rotate=2 f0316864.avi -oac copy -of lavf -lavfopts format=mpeg4 -ovc lavc -lavcopts vcodec=mpeg4 -o fixed2.avi


que conserva la calidad. El format y el vcodec dependeran del formato del video.

He visto recomendado usar avidemux pero ya teniendo ffmpeg y memcoder instalados, preferí no seguir instalando cosas. Quizás avidemux resuelva automáticamente lo del formato.

El camino difícil


No me gustan mucho los hubiese, seguramente, hubiera, supongo que dejé  más arriba, así que borré la tabla de particiones de la sd y trabajé directamente sobre ésta, para recorrer el camino de sudo y la falta de espacio.

Mirando más arriba la salida de fdisk dice que la partición empieza en 8192 * 512 y mirando lo primero que encontré, la tabla de particiones está bien al comienzo.



sudo dd if=/dev/zero bs=1024 count=1 of=/dev/sdb

Ojo que si te equivocás con of podés perder el disco. Si me dedicara a esto probablemente siempre usaría una virtual o una máquina de descarte. Si te equivocás con count o bs lo suficiente, te metés con los datos, por ello es mejor trabajar sobre la imagen previamente obtenida, pero no olvidemos que esto es un ejercicio, nunca necesitaríamos borrar la tabla de particiones.

Tampoco uses if=/dev/null, ya que como input no te da nada y nada escribe, necesitás ceros.




sudo photorec /dev/sdb



Si no le decís explícitamente la ruta, te muestra lo que haya.




Le dás Search, Other... (me faltó la captura y ya me aburrí)



 y anda otra vez.




Detalles de terminación


Además, la cámara estaba un poco rota, la tapita no cerraba por que volaron las muesquitas en la bisagra y en la punta contraria.



Lo bueno es que tiene para atornillar, sólo hay que hallar la pieza apropiada y el tornillo apropiado para no usar cinta adhesiva, para algo llevo años juntando tornillos y todo tipo de basura, como un perfil de aluminio de mosquitero:




Los comandos acá utilizados y otros de utilidad los comparto en github.

Para estudiar Free Range VHDL

$
0
0
Estas son los recursos de los que me he servido para estudiar y practicar el fantástico libro Free Range VHDL, que se puede comprar, se puede bajar mediante un formulario que no me anduvo o se puede generar el pdf a partir del latex:

$ sudo apt get latex-full
$ git clone https://github.com/fabriziotappero/Free-Range-VHDL-book.git 
$ cd Free-Range-VHDL-book
$ chmod 755 clean compile
$ ./compile

latex-full es un poco drástico y son 3.5 GB, seguro que hay una opción más óptima o sudo apt remove latex-full al terminar.


El libro no explica como sintetizar ni simular ni generar el bitstream ni programar el dispositivo.

Sintetizar


Probé primero con gvhdl pues está en los repos de la distribución, pero no andaban bien y el Colo me señaló esta conversación y me recomendó ghdl:




$ sudo apt install gnat-5                    ;# 100 MB

$ git clone https://github.com/ghdl/ghdl.git ;# 110 MB
$ cd ghdl
$ git checkout -b v0.36

$ mkdir build
$ cd build
$ ../configure
$ make
$ sudo make install


<nota de color>

El tener que crear el directorio build es medio chancho y se debe a que no está versionado. Hay al menos dos maneras de versionar una carpeta "vacía" en git:


$ touch build/.gitkeep 
$ git add build

o esta un poco más retorcida pero indudablemente más completa, pues si te olvidás de hacer un clean lo que haya adentro no te aparece. Un .gitignore dentro de la carpeta con este contenido:

*
!.gitignore


</nota de color>



Luego es tan sencillo como


$ ghdl -a hello_world.vhdl
$ ghdl -e hello_world
$ ghdl -r hello_world


Que en nada se va a manifestar a menos que usés std.textio o generés waveforms.

Con respecto a los nombres, -e y -r usan el nombre de la entity que haya dentro del vhdl.


Las manifestaciones pueden ser por stdout o volcar las señales a un archivo que entienda gtkwave.

STDOUT

Hay que usar una libreria llamada textio. Luego, se escriben en una variable valores con formato y eventualmente se vuelcan en stdout:


Mensajes a stdout



Además de write() existen hwrite(), owrite() y brite() que imprimen en hexa, octal y binario pero no me los entiende mi ghdl, pese a que están en el código. Son los que hacen falta para imprimir los vectores.

Tambien se puede imprimir a archivos, pero ni lo probé, no sé si intentaré solucionarlo, lo veré cuando explore más a fondo el tema de simulación.

Lo mejor que hallé es https://lauri.võsandi.com/hdl/ghdl.html

Cuidado que --help no dá todas las opciones que si están en las migajas de más abajo.



Waveform


$ sudo apt install gtkwave

Luego, en teoría, si tomás el ejemplo del lauri:

$ ghdl -a full_adder.vhd full_adder_testbench.vhd

$ ghdl -e full_adder_testbench
$ ghdl -r full_adder_testbench \
               --vcd=out.vcd \
               --fst=out.fst \
               --wave=out.wave

deberías poder usar gtkwave, pero pese a lo que dice la documentación, gtkwave no entiende out.wave. Además, los otros dos archivos, aunque son válidos y proveen información de los pines, no hay datos. O eso pensé, luego miré http://enos.itcollege.ee/~vpesonen/lisa/lab_example.html
y aunque no lo dice, logré deducir que hay que pedirle:


  1. elegir un componente en la jerarquía
  2. elegir un pin o bus en las señales
  3. append/insert/replace



Había pensado subir mis resultados de los ejercicios del libro y mis propios ejercicios a github, pero me distraje con otro libro, asi que lo que está es algo muy incompleto.

Lamentablemente no sólo me distraje con ese libro si no con todo mi proyecto de Forzando Brutalmente MD5 y perdí contacto con VHDL, en algún  momento cuando necesite, retomaré.

Para poder hacer todo esto tuve que seguir las migajas:

https://ghdl.readthedocs.io/en/latest/
https://ghdl.readthedocs.io/en/latest/building/Building.html
https://ghdl.readthedocs.io/en/latest/building/mcode/GNULinux-GNAT.html
https://ghdl.readthedocs.io/en/latest/using/Simulation.html
https://vhdlguide.wordpress.com/2017/09/22/textio/

La conversación previamente mencionada me llevó a este interesante documento, http://qucs.sourceforge.net/docs/tutorial/digital.pdf

Rescatando un touchpad

$
0
0


Hallé tirado el cadáver vandalizado de una Toshiba Satellite a la que le quedaba la pantalla (b140xw0 v.8), el mother, el cooler, el chip wifi (Atheros AR5B95 Wireless Network Adapter con conector mini-pcie), los mini speakers, seguro que hay una flash por ahí que no pude encontrar y el touchpad, Synaptics 920-001019-02 rev A:



Foto tomada de algún foro ruso


Primero lamenté haber tirado el circuito que había entre el touchpad y el mother, pues me había parecido que sólo le agregaba los botones físicos. Luego, cuando ví esta foto me confundí, pensé... no sé qué pensé.

http://3.bp.blogspot.com/-P5Ez1B_MFrg/UPKVd_DeK_I/AAAAAAAAB6o/dzUWOPNjT_s/s1600/synaptic-apple-mag-g3-2_v1.PNG


Ahí me dí cuenta que esas letras amarillas estan asociadas los pines del chip y no a los test points o al conector,


Tambien me sobran cables con respecto al conector DIN, entonces reflexioné:

¿Y si 4 y 5, botón derecho e izquierdo no son salidas si no entradas al dispositivo? Eso sería razonable, en caso contrario la interfaz del lado de la computadora debería entender por un lado los mensajes del mouse y por otro los botones.

Lo que debe ocurrir es que el chip lee 4 y 5 los codifica en PS/2 data como corresponde.

Seguro que en la documentación está pero siendo un auténtico programador, cuanto más tarde en leerla ¡¡mejor!!



Ayuda que esté en Amazon como un componente aislado, pues entonces no hay dependencias intermedias.



En lo más parecido a una datasheet que hallé dice que puede ser PS/2, ADB o serial, apostaré a PS/2, respaldado por la mención en esta conversación.



Con el tester y comparando con esa datashit hice este mapeo, parece bastante compatible con esto:





pin mini din 6testpointpin chipcomentario
1 +5vT20 T2244
2 dataT103spoiler: clock
3 clkT112spoiler: data
4 switchT67
5 switchT76
6 groundT2345


Esto está respaldado por GIMP, usando pencil tool + shift. Intenté con Fuzzy Select pero la imagen no tiene la suficiente calidad.





Me ofende que con respecto al otro chip estén invertidos data y clk, igual no sé si son los mismos chips...



¿Cómo sigo? ¿Le adapto un conector mini DIN 6 y lo conecto a una PC vieja? ¿Tán fácil? Ni tanto, quizás tendría que cargarle el driver del synaptic, si no me sale nunca voy a estar seguro del motivo de la falla.

El problema es que si mirás el mapeo más arriba, Data y Clock están invertidos, no tengo documentación confiable, tengo que distinguir probando cuál es cada uno.  En las menciones a T10 y T11 en esta conversación todo parece confirmar que el pin chip 2 es data y el 3 clock, tambien en esta y esta, así que será el primer intento.


Le tendría que dar power, clock y mirar que aparece en data, que es el Camino Correcto Más Difícil Pero Más Cierto. Tengo que poner Cierto y no Seguro por que Seguro me transmite una seguridad en todo aspecto y lo más seguro es que queme algo, mejor Cierto como cercano a la Verdad.

Pero, en los programas que hay en esos links y recuerdo en el pdf, hay un protocolo a seguir, me parece improbable que por el simple hecho de darle corriente y clock aparezca algo en data, igual quizás pueda confirmar el pinout.


Los 5v me condenan a usar arduino en lugar de edu-ciaa-nxp. De paso puedo probar que funcione la conexión a PS/2 con algún dispositivo así no tengo dos incógnitas a la vez.


Arduino PS/2 a teclado o mouse


Como tengo un teensy, sigo los pasos para instalar teensyduino, que consiste en bajarse Arduino IDE e instalar, tomando nota de la ruta, bajar el instalador de teensyduino, aplicar udev rules, ejecutar el instalador de teensyduino para ver que versiones de Arduino IDE soporta. En este momento soporta 1.8.10 que es la última, ijuu!!


Next, next, los next que hagan falta y darle la ruta que recordaste antes.

Por las dudas un blinky primero: ejecutar la IDE, elegir teensy2.0++ como target, buscar el ejemplo de blinky, elegir pin 6 como led, si no baja el programa de una, configurar asi:

  • usb type: serial
  • cpu speed 16 Mhz
  • port: /dev/ttyACM0 serial (teensy 2++)
  • programmer: avr isp o avr isp mkii, tira un error pero funciona...



Luego hay que bajar y copiar las librerías de PS/2 en

~/bin/arduino-1.8.10/libraries


Conectarle un mouse y ver que anda con el ejemplo.


Por suerte tengo un cajón lleno de porquerías, por ejemplo este adaptador de un montón de cosas, incluido mini din 6 pines:


(1) Data, (3) Ground, (4) 5v, (5) Clock


Tuve que usar un teclado pues parece que tiré todos los mouses PS/2 que tenía.


Usé el ejemplo ./libraries/ps2/examples/ps2_kbd/ps2_kbd.pde con

// pin 3 data
// pin 5 clock
// kdbd(clock, data)
PS2 kbd(5,3)


Separé los pines para poder meter las puntas del osciloscopio, muy bonito, otro día exploraré el encoding.

No presté atención a qué tecla oprimí, sólo sé que 71 F0 71 vino por el serial monitor



Arduino PS/2 a touchpad


Como seguimos sin saber cual es clock y cual es data, le voy a poner una resistencia de 4k7 en serie a ver que pasa.


No pasa nada, ni al derecho ni al revés, pruebo sin resistencias:




Lo que cambié con respecto al ejemplo fue ajustar los pines en

./libraries/ps2/examples/ps2_mouse/

// pin 3 data
// pin 5 clock
// kdbd(clock, data)
PS2 mouse(5,3);


y este if para que el monitor no se llene de basura:

   // send the data back up
  if (mx != 0 || my != 0 ) {
    Serial.print(mstat, BIN);
    Serial.print("\tX=");
    Serial.print(mx, DEC);
    Serial.print("\tY=");
    Serial.print(my, DEC);
    Serial.println();
  }


Listo, anda, a otra cosa, algún día lo conectaré a algo. Dos fotitos más para quienes prefieren dibujitos a leer:



 El detalle de los cables y los puntos de soldado en los TP




El sensor pegado a la tapa de una caja de tarjetas



Identificando versiones de programas

$
0
0
Supongamos que tengo que hallar versiones viejas de programas en una red y no puedo ejecutar:
 

$ programa --version

pues no puedo entrar a cada máquina, aunque si puedo ver su sistema de archivos. Tampoco hay un gestor de aplicaciones al cual consultar, incluso pueden haber programas instalados sin el uso de un usuario privilegiado, como puede ser un portable o compilado localmente.




Supongamos que tenemos el ejecutable identificado, como ejemplo usaré chrome.


En linux Mint y supongo Ubuntus está en:

/opt/google/chrome/chrome

En windows lo he hallado en lugares como:


C:\Program Files (x86)\Google\Chrome\Application\
C:\Users\XXXXX\AppData\Local\Google\Chrome\Application\


Primero hay que tener varias versiones identificadas:

chrome.lin.78.0.3904.97
chromium-browser.lin.65.0.3325.181
chrome.win32.24.0.1312.57
chrome.win.44.0.2403.155
 

chrome.win.51.0.2704.84
chrome.win.57.0.2987.133
chrome.win.62.0.3202.75 
chrome.win.78.0.3904.97

Las de linux se obtienen descomprimiento el deb que se consigue en  

http://security.ubuntu.com/ubuntu/pool/universe/c/chromium-browser/

¡Qué féo ese http sin la s!

Con grep vamos viendo si esos números están almacenados. 


$ grep 3904 chrome.*
Binary file chrome.lin.78.0.3904.97 matches
Binary file chrome.win.78.0.3904.97 matches

con -a le decimos a grep que los tome como archivos de texto pese a que son binarios. De pado limitamos el contexto de match con -o y con ".{32}".

$ grep -a -o '.\{32\}78\.0\.3904\.97.\{32\}' chrome.*

chrome.lin.78.0.3904.97:brtc/pc/peer_connection.cc:609778.0.3904.97id-smime-mod-ets-eSigPolicy-97
 
chrome.win.78.0.3904.97:test-child-processvvmodule78.0.3904.97GCM Store
 
chrome.win.78.0.3904.97:mblyIdentity type="win32" name="78.0.3904.97" version="78.0.3904.97" languag

Mmmm, ese último me gustó, probemos con algo más específico y sin -o



$ grep -a 'version="78.0.3904.97"' chrome.*
chrome.win.78.0.3904.97:<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"><dependency><dependentAssembly><assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"></assemblyIdentity></dependentAssembly></dependency><dependency><dependentAssembly><assemblyIdentity type="win32" name="78.0.3904.97" version="78.0.3904.97" language="*"></assemblyIdentity></dependentAssembly></dependency><trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"><security><requestedPrivileges><requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel></requestedPrivileges></security></trustInfo><compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"><application><supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"></supportedOS><supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"></supportedOS><supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"></supportedOS><supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"></supportedOS><supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"></supportedOS></application></compatibility></assembly>( ;J�=I�=I�?L�@L�AM�BM�DP�AN�L]�DO�BO�CO�DP�EQ�FR�DR�GR�GS�OwdHT�IT�IU�Qo�IV�LW�Q\�Wb�[� [� >e�@e�]� ?f�[� \� >f�@g�]� ]�8]� Z�#^� _�[]� _� _� _� a�(`� `� a� b� b� c� ��Ie�!g�)��Jd�!��L��Mi�)Su�n�/��YZ�A��[��^P��J��O��<��?���ç�Ĩ�ĩ�Ū>��������D���Ѱ[��E��@���ձA��B��A��B��C��@��A��B��C��D��E��R��S��������������hhhhhhhhhhhhhhhhhhhhhh BQUhhhhhhhhhh FZYWhhhhhhh,&&#")TZY\hhhhh-**((>9E[ZYXhhhh//.@VJJRS[ZYhhh2113dC:7Af`[Z]hh455+L<::7Jc[Z]hh;60 L=<::Jb`[^hh;8 PD=<Cgaa_]hhh'
 
Me gusta cada vez más, quedémonos con la parte interesante de ese xml con identación para mejorar la lectura:

<assembly ...
   <assemblyIdentity
      type="win32"
      name="78.0.3904.97"
      version="78.0.3904.97"
      language="*"
   >
   </assemblyIdentity>
...
</assembly>

Y repitamos para las otras versiones con un nuevo grep ajustado:


$ grep -a -o "<assemblyIdentity type=\"win32\" name=\".\{16\}" chrom*
chrome.win.44.0.2403.155:<assemblyIdentity type="win32" name="44.0.2403.155" v
chrome.win.51.0.2704.84:<assemblyIdentity type="win32" name="51.0.2704.84" versio
chrome.win.57.0.2987.133:<assemblyIdentity type="win32" name="Microsoft.Window
chrome.win.57.0.2987.133:<assemblyIdentity type="win32" name="57.0.2987.133" v
chrome.win.62.0.3202.75:<assemblyIdentity type="win32" name="Microsoft.Window
chrome.win.62.0.3202.75:<assemblyIdentity type="win32" name="62.0.3202.75" ve
chrome.win.78.0.3904.97:<assemblyIdentity type="win32" name="Microsoft.Window
chrome.win.78.0.3904.97:<assemblyIdentity type="win32" name="78.0.3904.97" ve


Se me cayó linux, luego vemos. Para windows con esta regla ya estamos:

  • Si tiene información de versión
  • Y esa información no coincide con la versión que deseo

Dicho en yara:


rule ChromeWin
{
  strings:
    $version   = "<assemblyIdentity type=\"win32\" name=\""
    $version78 = "<assemblyIdentity type=\"win32\" name=\"78."
  condition:
    $version and not $version78
}

y su ejecución:

$ yara ruleChrome.yara .
ChromeNot78 ./chrome.win.51.0.2704.84
ChromeNot78 ./chrome.win.44.0.2403.155
ChromeNot78 ./chrome.win.57.0.2987.133
ChromeNot78 ./chrome.win.62.0.3202.75

Y así tenemos un modo que aunque dependiente del programa es independiente de las versiones menores y revisiones para identificarla estáticamente. Tambien pudimos usar un hash, pero hace falta identificar todos los casos.

Si sólo dejamos $version78, igual funciona, pero si hay otros programas los halla tambien.

Uh, uh, qué difícil, no? 

Quizás con linux suframos un poco más, veamos que tenemos:

$ grep -a -o ".\{16\}65.0.3325.181.\{16\}"chromium-browser.lin.65.0.3325.181
lurl_template65.0.3325.181BREAKPAD_DUMP_L

$ grep -a -o ".\{16\}78.0.3904.97.\{16\}" chrome.lin.78.0.3904.97

nection.cc:609778.0.3904.97id-smime-mod-e
 
Está en el medio de la nada, ni siquiera es un null terminated string, nos puede servir hallar en que section se encuentra, comenzando por el offset en el archivo:


$ hexdump -C chrome.lin.78.0.3904.97 | grep 3904
01039040  2f 76 69 64 65 6f 5f 62  69 74 72 61 74 65 5f 61  |/video_bitrate_a|
010db670 37 38 2e 30 2e 33 39 30  34 2e 39 37 00 69 64 2d  |78.0.3904.97.id-|
01139040  64 65 66 69 6e 65 64 2e  00 72 65 71 75 69 72 65  |defined..require|

Ahora hay que buscar donde cae el offset 010db670, tiene que estar en la zona amarilla, en realidad en la sección anterior a la valor inmediatamente mayor.
 
$ readelf -S --wide chrome.lin.78.0.3904.97
There are 38 section headers, starting at offset 0x91713c8:

Section Headers:
[Nr] Name              Type      Address    Off    Size   Flg
[ 0]                   NULL      00000000  000000  000000  
[ 1] .interp           PROGBITS  000002e0  0002e0  00001c   A
[ 2] .note.ABI-tag     NOTE      000002fc  0002fc  000020   A

[ 3] .note.gnu.build-id NOTE     0000031c  00031c  000024   A
[ 4] .dynsym           DYNSYM    00000340  000340  009ab0   A
[ 5] .gnu.version      VERSYM    00009df0  009df0  000ce4   A
[ 6] .gnu.version_r    VERNEED   0000aad4  00aad4  0003b0   A
[ 7] .gnu.hash         GNU_HASH  0000ae88  00ae88  0001dc   A
[ 8] .dynstr           STRTAB    0000b064  00b064  007ab9   A
[ 9] .rela.dyn         RELA      00012b20  012b20  e16a68   A
[10] .rela.plt         RELA      00e29588  e29588  009210   A
[11] .rodata           PROGBITS  00e32800  e32800  c047bf AMS
[12] protected_memory  PROGBITS  01a36fc0 1a36fc0  0001f8   A

[13] .gcc_except_table PROGBITS  01a371b8 1a371b8  001aac   A
[14] .eh_frame_hdr     PROGBITS  01a38c64 1a38c64  007c44   A
[15] .eh_frame         PROGBITS  01a408a8 1a408a8  01c464   A
[16] .text             PROGBITS  01a5d000 1a5d000 7028912  AX
[17] .init             PROGBITS  08a85914 8a85914  000017  AX
[18] .fini             PROGBITS  08a8592c 8a8592c  000009  AX
[19] malloc_hook       PROGBITS  08a85940 8a85940  000556  AX
...

Key to Flags:
 W (write), A (alloc), X (execute), M (merge), 

 S (strings), l (large),  I (info), L (link order),
 G (group), T (TLS), E (exclude), x (unknown),
 O (extra OS processing required),
 o (OS specific), p (processor specific)

Lo cual es razonable pues hasta donde entiendo los strings como este en .rodata deben estar.


$ objdump -s -j .rodata chrome.lin.78.0.3904.97 \
 | grep 3904 -A 2 -B 2 

10db650 62727463 2f70632f 70656572 5f636f6e  brtc/pc/peer_con
10db660 6e656374 696f6e2e 63633a36 30393700  nection.cc:6097.
10db670 37382e30 2e333930 342e39370069642d  78.0.3904.97.id-
10db680 736d696d 652d6d6f 642d6574 732d6553  smime-mod-ets-eS
10db690 6967506f 6c696379 2d393700 69642d73  igPolicy-97.id-s


más arriba cuando había dicho ni siquiera es un null terminated string me equivoqué, ahí está clarito el null.
Pero esto seguro cambia de versión en versión.

$ objdump -s -j .rodata chromium-browser.lin.65.0.3325.181 \
 | grep 65\.0\.3325 -A 2 -B 2

6d32960 00636872 6f6d6500 7469746c 65007465  .chrome.title.te
6d32970 78740075 726c0075 726c5f74 656d706c  xt.url.url_templ
6d32980 61746500 0036352e 302e3333 32352e31 ate..65.0.3325.1
6d32990 38310042 5245414b 5041445f 44554d50  81.BREAKPAD_DUMP
6d329a0 5f4c4f43 4154494f 4e005061 796d656e  _LOCATION.Paymen



Ok, quizás buscando un string de cuatro enteros separados por puntos entre dos nulos funcione... demasiado, trae toda dirección IP



$ grep -a -o -P \
 "\x00[1-9][0-9]*\.[0-9]+\.[0-9]+\.[0-9]+\x00" \
  chromium-browser.lin.65.0.3325.181  \
  chrome.lin.78.0.3904.97

chromium-browser.lin.65.0.3325.181:6.5.254.41
chromium-browser.lin.65.0.3325.181:65.0.3325.181
chromium-browser.lin.65.0.3325.181:239.255.255.250
chromium-browser.lin.65.0.3325.181:127.0.0.1
chrome.lin.78.0.3904.97:78.0.3904.97
chrome.lin.78.0.3904.97:7.8.279.23
chrome.lin.78.0.3904.97:4.10.1582.1
chrome.lin.78.0.3904.97:127.0.0.1
chrome.lin.78.0.3904.97:224.0.0.251
chrome.lin.78.0.3904.97:239.255.255.250
chrome.lin.78.0.3904.97:127.0.0.1

¡Qué problema! El orden no significa nada, sólo podríamso descartar algunas IPs muy evidentes como  127.0.0.1 y 239.255.255.250,pero nos empieza a obligar a tener una lista de versiones más estrictas.

No es tan terrible. para cada programa candidato, obtenemos la lista de strings potenciales y si alguna coincide con versiones correctas o incorrectas. 

Esta parte de linux ha sido para practicar lo aprendido en el libro Practical Binary Analysis, cuya reseña en pocas semanas publicaré.



Para estudiar Hardware Security

$
0
0

Estas son mis notas y actividades relacionadas con la atenta lectura y práctica parcial del libro Hardware Security: A Hands-on Learning Approach, que he leido en septiembre de 2019 y practico en la medida de lo posible ante cada oportunidad.




En el sitio hay un área docente y en mi calidad de autoinstruido, una condición simultánea de alumno/docente, quise acceder al material docente, recibiendo la respuesta:

Please use the student zone to access materials


Tambien pregunté cómo obtener un Ha-Ha board, que el libro dice hay proveedores pero en Internet no hay, sin respuesta.

Ya empezamos mal, a Stroustrup una vez le pregunté o señalé algo del libro Programming: Principles and Programming using C++ y si no él, al menos hubo alguien que se hizo pasar por él de modo extremadamente convincente y me contestó. Si esta gente con el libro recién editado no... bueno, como dijo Jonathan Swift:


Si una persona me mantiene a distancia, 
me consuela que también ella se mantiene.


Como este libro lo compré vía Amazon pude comentarlo, tomaré mi camino.


Crítica



Con respecto al libro, me ha resultado increiblemente bueno aunque objetivamente quizás no lo sea tanto, paso a explicar:


Cada tema generalmente se explica como si no hubieras leido los otros capítulos, lo cuál para mí está muy bueno, esa repetición genera un refuerzo y repaso. Hay una suerte de auto contención que de no estar, el libro tendría fácil la mitad de las páginas.


Tambien hay un cierta "desconexión", por ejemplo en la página XXX se menciona "como vimos en tal sección" remitiéndose a YYY, cuando era el tema de la sección anterior. Lamentablemente los valores de XXX e YYY los confié a mi memoria en el momento de leerlo, pero no funcionó.

Así que si sabés poco como yo, el libro es fantástico, si ya sabés algo, tiene mucho relleno, pero relleno útil, como que no tenés que estar buscando mucho las dependencias de un tema.



En síntesis, aunque es un muy buen libro, no cumple con "a hands-on learning approach" ya que no es posible hacer los ejercicios por falta de los enunciados.

A not so hands-on learning approach


A falta del Ha-Ha board y que no puedo acceder a los enunciados o guías de ejercicios, había considerado instructivo realizar una suerte de, más que ingeniería reversa, un acto de adivinación y me había propuesto hacer varios de los ejercicios en la medida que pudiera descubrir de qué se trata sin el enunciado.

Pero como tengo muchas otras cosas igual o más interesantes y urgentes que hacer, tuve que cambiar de enfoque y lo que he decidido es embeber en mis actividades el libro.

O sea, cada vez que haga algo que pueda relacionar con los ejercicios, lo registraré a continuación.



  • Rescantando un touchpad
  • Usando un touchpad (en construcción)
  • Método de entrenamiento de (de)soldado (en construcción)
  • Hardware Malware (planificado)
  • etc...

VGA Rendering de simulación FPGA

$
0
0
Mientras estudiaba "Designing Video Game Hardware in Verilog" me hallé con que tenía que diagnosticar por que no funcionaban bien mis adaptaciones del código provisto a la Nexys 4 DDR que tengo con los ejemplos correspondientes a VGA (o mi doble adaptación a VGA por ser CRT).

Para no tener que pasar por todo el prolongado ciclo de modificar, sintetizar, implementar, generar el bitstream, burn it y tener que sacar el trasero de la silla para decirle al monitor que tome la entrada VGA en lugar del HDMI me hice un programita en TCL/TK que toma la salida de la simulación y me hace el render de las señales.

La verdad es que por lo valioso en términos educativos de este proyecto ni me molesté en ver si alguien ya lo había hecho, quizás por fin haya logrado aportar algo realmente útil. Mientras escribo esto veo que Xilinx tiene un repo de scripts para Vivado pero no llego a ver rápido si hay manera de ganarse una ventana dentro de la IDE, así que quedará para la Caja del Futuro.


En términos más formales:

El objetivo es hacer el render de una señal VGA generada probablemente por una simulación de un diseño Verilog o VHDL.

Los historias de usuario vienen a ser, "como usuario quiero que..."
  • Haga render de un frame
  • Haga render de varios frames consecutivos
  • Haga render de un frame  en "tiempo real", o sea, a medida que el simulador emita los datos
  • Haga render de varios frames consecutivos en "tiempo real"
  • Ajuste automático de resolución (640 x 480 la actual) 
  • Que entienda archivos standard tipo VCD
  • Que se pueda avanzar y retroceder
  • Que se pueda avanzar y retroceder usando el dispositivo ShuttleProV2


En verde lo que hice, no creo que avance con el resto pues esto es sólo un medio para lo que realmente quiero y no quiero que me distraiga.


Dado que hace muchos años trabajé con TCL/TK y me gustó y además Vivado usa TCL, más vale que empiece a recuperarlo, decidí usarlo para esta actividad.


En la carpeta "evolucion" dejé registrada la... evolución de mi acercamiento al problema, desde generar un patrón programáticamente en TCL/TK, pasando por mostrar las hsyncs y vsyncs, leer de un archivo, de STDIN y que finalmente funcione.

Los ejemplos 01_* a 04_* son los de "calibración", los restantes ya toman la salida de la simulación.





Entre las versiones 05_patternFromFile.tcl y 06_single_frame.tcl las diferencias significativas son:



  • Abstracción: en lugar de string index por todos lados, procs.
  • Lectura por STDIN
  • update para ver el rendering en tiempo real
  • y está bien alineado

La diferencia con la versión final, render.tcl es el multiframe


Con respecto a la salida de la simulación, primero investigué y no hay manera sencilla de acceder a lo generado pues está en una base de datos de formato desconocido para mi, así que opté por usar $strobe en el testbench con algo parecido a esto:



always @(negedge clock)
   $strobe("%b %b %b #%h%h%h", clock, hsync, sync, R, G, B);


Hay que generar el color tal que lo entienda TK o hacer una función adaptadora, opté por lo primero, mirá el código.


Podría quitar el clock ya que siempre es cero.

La simulación debe correr durante unos 8 ms para tener un frame completo entre vsyncs.




Me gustaría agregar colores distintos para las zonas no visibles que ahora está en negro y se confunde con la barra negra de la derecha, pero por ahora esto me sirve.


Es bastante lento, no me puse a optimizar, ni sé si se puede, de mis motivos originales sólo cumplo con no levantarme de la silla para cambiar la entrada del monitor.

Hay otra ventaja, la posibilidad de ver un sólo frame de una secuencia, que dependiendo del circuito real quizás no se pueda en la FPGA sin agregar lógica.




El video está fuertemente editado para que sólo se vea lo esencial de la interacción y el primer frame que no se muestra por no tener VSync está omitido, luego es tiempo real en una AMD A10-7700K Radeon R7.

Tambien corresponde a la versión de un solo frame, sin la simpática rayita blanca que muestra donde está dibujando, indispensable para multi frame.

El código en github

Esta es la captura de la última versión, con la simpática rayita y los límites de lo visible enmarcados en verde:




Para estudiar The Zynq Book

$
0
0

Es un libro muy atado al producto... claro, se llama The Zynq Book, alguien en los comentarios de algún sitio que reclama por ello, pero ¿qué esperabas? Dice "con la colaboración de Xilinx" en la tapa.

Se puede obtener gratis, probablemente en http://www.zynqbook.com/download-book.php.



Tiene el problema de un fuerte sabor a marketing, muchas veces dice lo flexible, óptimo y adaptable que es Zynq. Luego hay un montón de información que es de algún modo genérica. Si tuviera la mitad de lo genérico y el cuádruple de lo de Zynq como para mantener la cantidad de páginas, hubiese sido excelente. La realidad es que a mi no me quedaron claras cosas como si el componente ethernet se puede acceder directamente desde la PL.

Lo bueno es que no explica nada de VHDL/Verilog/C/Assembly, supone que ya sabés.

Lo malo es que hay varios lugares donde se dan explicaciones de conceptos donde hubiese estado bueno un ejemplito en VHDL/Verilog.

Intel tiene algo parecido, con nombres como Arria, Stratix y Cyclone.

En apariencia, este tipo de SoC facilita esta evolución: de programar una CPU y diseñar hardware por separado a diseñar un sistema y con la ayuda de la herramienta implementar algunas partes en hardware y otras en software.

La idea es que lo simple y paralelizable va al hardware, lo complicado se queda en la CPU.


La verdad es que sea usando este tipo de SoC o los componentes separados no hace diferencia desde el punto de vista de la programación, incluso estoy seguro que el libro dice que lo que hagas en C/C++/SystemC sólo se va a ejecutar en un softcore, no es que generás código y la herramienta elige si ponerlo en los cores ARM. O al menos así era en 2014, tengo el "libro siguiente", motivo por el cual leí este pese a la mala crítica, quizás haya cambiado.

Me quedo con la idea de que el objetivo es hacer aceleradores para ser utilizados desde las CPU ARM, pero simplificando el diseño en la PL.


Zynq te permite desarrollar cosas que yo al menos no podría pues no tengo el conocimiento para interconectar una fpga con una cpu. Algo parecido a pasar de un micro + memoria(ram/rom) + uart a un microcontrolador que ya tiene todo adentro y sólo hay que configurar o ni eso.

De todos modos yo no puedo hacer nada con un zynq, necesito una Parallella, PYNQ o equivalente donde todo el hardware ya esté resuelto.

Los "ok" son relativos, para alguien que tiene experiencia de cada tema quizás estén de sobra, pero para mi siempre es un buen repaso.

  • 1 Intro ok
  • 2 Detalles hardware ok
  • 3 Detalles software, aplica a cualquier otro FPGA, ok
  • 4 Criterios de elección, ok
  • 5 Humo, completamente en vano
  • 6 Zedboard, ok para quien la tiene
  • 7 En vano
  • 8 Ejercicio
  • 9 Arquitectura de harware, modo superficial y adaptados a la arquitectura, ok
  • 10 Más detalles hardware, lo anterior aplicado a zynq, ok
  • 11 Más detalles software, aplica a cualquier otro FPGA, ok
  • 12 Ejercicio
  • 13 - 15 HLS, aplicable a cualquier FPGA, ok
  • 16 Ejercicio
  • 17 Ejercicio
  • 18 IP ok
  • 19 AXI ok
  • 20 Ejercicio
  • 21 Sistemas operativos ok
  • 22 - 24 Linux ok


Se complementa con unos tutoriales que están en http://www.zynqbook.com/download-tuts.html

Lo que me he propuesto es adaptar a mis placas PYNQ-Z2 ahora y algún día Parallella la experiencia desarrollada en los ejemplos prácticos.

Ejercicios

 

Te recomiendo que saltées esta parte y vayas directo a las conclusiones, a menos que estés siguiendo los tutoriales y te trabes, quizás algo te ayude.

Tambien si tenés una Zed o Zybo. En caso de otras placas, quizás quizás te sirva mirar por arriba lo que hice.


Estos son los pasos tomados de The_Zynq_Book_Tutorials_Aug_15.pdf, utilizando primero Vivado 2015.4, luego pasé a 2018.2 debido a que no vé la placa PYNQ.

Los dos primeros ejercicios consisten en pegarle unos IPs al Zynq y ejecutar un programa baremetal para prender los leds, luego leer los push buttons generando interrupciones y finalmente incorporar un timer, todo esto con AXI.

El tercero es de optimización, es un tanto avanzado para los básicos como yo, lo entiendo pero me dificultaría aplicarlo, pese a haber transitado el uso de PIPELINE en Forzando Brutalmente MD5.

El cuarto es crear tus propios IP, para usarlos en el quinto.


Todo versionado en github pero mal versionado pues está sin el .gitingore y además moví los ejercicios uno a tres así que no deben andar ni a palos, es más por backup que por proceso de desarrollo.



Exercise 1, First Designs on Zynq


Exercise 1A Creating a First IP Integrator Design


Registro los pasos tipo machete para futura referencia, te conviene seguir el tutorial, va todo igual salvo que hay que elegir la placa PYNQ.



Agregar la PYNQ a Vivado, con ayuda de https://pynq.readthedocs.io/en/v2.5/overlay_design_methodology/board_settings.html

dice que

<Xilinx installation directory>\Vivado\<version>\data\boards

y ahi hay dos carpetas, va en boards_files

Acá está la descripción para Vivado y acá el XDC


  • Create New Project
  • Elegir el board

Exercise 1B Creating a Zynq System in Vivado (2018.2)


  • Create Block Design (IP INTEGRATOR -> ...)
  • Add IP -> ZYNQ7 Processing System (Diagram -> ...)
  • Run Block Automation -> Apply Board Preset
  • Add IP -> GPIO (Diagram -> Add IP -> AXI GPIO)
  • Run Connection Automation -> S_AXI
  • Run Connection Automation - leds_4bits
  • File -> Save Block Design
  • Toos -> Validate Design
  • Windows -> sources
  • botón derecho -> Create HDL Wrapper
  • Generate Bitstream
  • Open Implemented Design
  • File -> Export -> Export Hardware -> include bitstream
  • File -> Launch SDK

Exercise 1C Creating a Software Application in the SDK

en particular en Import se usa lo de

The_Zynq_Book_Tutorial_Sources_Aug_15.zip,

la diferencia entre zybo y zed es el ancho de los leds, como PYNQ es 4 igual que Zybo, usé Zybo


kdiff3  zybo/first_zynq_design/LED_test_tut_1C.c zedboard/first_zynq_design/LED_test_tut_1C.c siempre ayuda para estos casos.

  • File -> New -> Application Project
  • Next -> Empty Application
  • Project Explorer -> el proyecto -> src -> Import -> ....
  • Xilinx Tools -> Program FPGA
  • Project Explorer -> el proyecto -> Run As -> Launch on Hardware

¡Anda!, ¡¡¡no lo puedo creer!!!




Exercise 2, Next Steps in Zynq SoC Design

2A-C Expanding the Basic IP Integrator Design

Podría continuar sobre el ejercicio 1 o empezar de cero, mejor para fijar los conocimientos. Las instrucciones ya están adaptadas a Vivado 2018.2


Es todo igual pero hay que agregar un AXI-GPIO extra y conectarle los botones.

Luego

  • Doble click axi_gpio_0 -> IP Configuration -> enable interrupt
  • Doble click processing_system_7 -> Page Navigator -> Interrupts -> 
    • Check Fabric Interrupts
    • Check Pl-PS Interrupt Ports -> IRQ_F2P[15:0]
  • Block Design -> Diagram -> connect
    • axi_gpio_0/ip2intc_irpt
    • processing_system_7/IRQ_F2P[0:0]
  • File -> Save Block Design
  • Tools -> Validate Block Design
y volvemos al caminito normal

  • Project Manager -> Sources -> right click on design -> Create HDL wrapper
  • Generate bitstream
  • (paciencia)
  • Open Implemented Design
  • File -> Export Hardware -> include bitstream
  • File -> Launch SDK
  • File -> New -> Application Project -> empty application
  • import...
  • Program FPGA
  • Y vuelve a andar, increible


    Exercise2D Adding a Further Interrupt Source


    Nada nuevo, sólo agregar un axi timer con la novedad de que hay que conectarlo a mano usando el IP concat, al pasar al SDK eliminar el proyecto e importar lo nuevo, interrupt_counter_tut_2D.c. Como me olvidé de versionar y taggear hasta el paso anterior, en mi código quedó con esta última versión.


    Exercise 3 Designing With Vivado HLS


    Exercise 3A Creating Projects in Vivado HLS

    Van los pasos macheteados

    • Copiar sources/hls a tu workspace
    • Create New Project, con Project Location -> lo anterior
    • Add Files (Design Files) -> matrix_mult.cpp, matrix_mult.h
      • Top Function -> matrix_mult
    • Add Files (Testbench Files) -> matrix_mult_test.cpp
    • Solution Configuration
      • Clock Period -> 5
      • Boards -> elegí board
    • Close HLS
    • Open HLS Command Prompt
    • cd hasta tut3A
    • Otra vez kdiff3 al rescate, pues dice que ejecutes run_hls_zed.tcl o run_hls_zybo.tcl. La diferencia es part. De algún modo te enteras que es xc7z020clg400-1, con lo cual creás un run_hls_pynq.tcl 
    • vivado_hls -f run_hls_pynq.tcl
    • vivado_hls -p matrix_multlplier

    Exercise 3B Design Optimisation in Vivado HLS

    Lo que se hace es probar distintas soluciones de optimización hasta que alguna sea factible por timing.

    • Run C Simulation
    • C Synthesis
    • C/RTL Co-simulation -> VHDL
    • Project -> New Solution
      • Acá hay un problema con Part, no ve los boards, tuve que ponerle vía Part el correcto, xc7z020clg400-1
    • Select matrix_mult.cpp
    • Directives -> punto de inserción -> Insert Directive -> PIPELINE / ARRAY RESHAPE
    • C Synthesis 
      • Va a ir fallando según "punto de inserción" y la directiva que se use
    • Project -> Compare Reports -> Seleccionar los últimos y comparar...

    Exercise 3C Interface Synthesis

    • cd tut3C
    • copiar run_hls_pynq.tcl de tut3A
    • vivado_hls -f run_hls_pynq.tcl
    • vivado_hls -p matrix_mult_prj
    • mirar el summary de la interface

    Exercise 4 IP Creation

    Exercise 4A Creating IP in HDL

    • Create New Project
      • no olvides poner VHDL como lenguaje que yo siempre me olvidé, esta vez sí hace diferencia
    • Tools -> Create and Package New IP
      • Create a new AXI4 peripheral 
      • Create Peripheral -> Edit IP
      •  se abrirá otra instancia
    •  Open led_controller_v1_0_S00_AXI.vhd
      • Agregar los ports de Zybo por el ancho de 4 bits
      • File -> Save
    • Open led_controller_v1_0.vhd
      • algo parecido

      • Package IP - led_controller
        • Customization Parameters
          • Merge changes from Customization Parameters Wizard
        • Ports and Interfaces -> check está ok
        • Review and Package -> edit packaging settings
        • Automatic behaviour, enable all (but Include source project archive in 2018.2)
        • Re-Package IP

        • Volver al proyecto original 
        • IP Integrator -> Create Block Design
          • Diagram -> Add IP -> led_controller
          • LEDs_out -> Right click -> Make external (ahi pone out_0)

        Tip salvador para 2018.2, le pone al pin el nombre LEDs_out_0, hay que cambiarlo por LEDs_out
          • Add IP -> zynq7 processing system
          • Run Block Automation
          • Run Connection Automation
          • Tools -> Validate
        • Project Manager -> Sources -> Design Sources -> led_test_system -> Create HLD Wrapper 


        • Add Sources -> Constraints -> Create -> XDC -> pynq-z2_v1.0.xdc
        • Y acá hay que buscar en el XDC que bajamos en algún momento los nombres de los pines correspondientes a los leds:


        set_property PACKAGE_PIN R14   [get_ports { LEDs_out[0] }]
        set_property IOSTANDARD LVCMOS33  [get_ports { LEDs_out[0] }]

        set_property PACKAGE_PIN P14   [get_ports { LEDs_out[1] }]
        set_property IOSTANDARD LVCMOS33 [get_ports { LEDs_out[1] }]

        set_property PACKAGE_PIN N16   [get_ports { LEDs_out[2] }]
        set_property IOSTANDARD LVCMOS33 [get_ports { LEDs_out[2] }]

        set_property PACKAGE_PIN M14   [get_ports { LEDs_out[3] }]
        set_property IOSTANDARD LVCMOS33 [get_ports { LEDs_out[3] }]


        • Generate Bitstream
        • Open Implemented Design
        • File -> Export -> Export Hardware -> Include Bitstream
        • File -> Launch SDK

        • Luego en el SDK
        • File -> New -> Application Project
        • Empty Application
        • Xilinx Tool -> Repositories -> New
        • ip_repo -> led_controller (lo creado antes)
        • system.mss -> modify this BSP's Settings -> drivers -> led_controller
        • Project Explorer -> src -> import -> file system -> zybo -> led_controller
        Aqui falla por undefined referencie to Xil_Out32, se corrige agregando a led_controller_test_tut_4A.c

        #include "xil_io.h"

        Sigamos
        • Xilinx -> Program FPGA
        • SDK Teminal -> Connect 
          • /dev/ttyUSB1 (o lo que haya)
        • Project Explorer -> Right Click -> Rus As -> Launch on Hardware(GDB)

        Listo...

        Exercise 4B Creating IP in MathWorks HDL Coder

         
        Este implica usar MatLab, todo bien pero me aleja demasiado de mis propósitos, quizás algún día si me sobra tiempo lo haga. O eso es lo que había pensado hasta que ví que en la última parte hace falta lo generado por esta, así que a bajar el Matlab DEMO por 30 días.



        • Copiá la carpeta hdl_coder_lms a donde te guste
        • Dice que configures HDL Toolpath, no sé por qué con ISE, le puse directo Vivado:


        hdlsetuptoolpath('ToolName', 'Xilinx Vivado', 'ToolPath', '/Xilinx/Vivado/2018.2/bin/vivado')

        No dijo que estuviera mal, pero tampoco todo lo que el tutorial

        • Cambía al directorio de trabajo donde copiaste hdl_coder_lms
        • abrí lms.slx 
        • El mirar adentro es opcional
        • No pude hallar "HDL Code -> HDL workflow Advisor", pero si que yendo a Get Add-ons, buscar "hdl code", get trial  y un sales representative te contactará. 
        Nuevamente se abre un nuevo mundo enorme y muy interesante de exploración que me alejan de mi propósito que es lograr un cierto dominio sobre Zynq y Vivado, lo siento Matlab, hasta aquí llegué.




        Exercise 4C Creating IP in Vivado HLS

         

        Este ejercicio al igual que el 3 me queda un poco grande
        • Abrir Vivado HLS
        • Create New Project
          • Add Files -> nco.cpp
          • Top Function ->nco
          • Add Test Files -> nco_tb.cpp
          • Part Selection -> usar part ya que no hay board
        • Ver *.cpp
        • Cambiar outfile a algo que te sirva
        • Run simulation
          • mirá el output
        • Seleccioná nco.cpp
        • Directive
          • Insertar todas las mencionadas
        • Run C Synthesis
        • Export RTL
        Y en teoría esto sirve para el próximo
         

        Exercise 5 Adventures with IP Integrator

        Estos ejercicios integran lo anterior y dependen de generar un IP con Matlab que tal como relato arriba no pude lograr por motivos no técnicos.
         

        Conclusiones


        Pese a el problemita con Matlab, los ejercicios salvan al libro, si no sabés nada, tendrías que leer el libro, si sabés algo salteando los capítulos no ok y si sabés bastante quizás los ejercicios no te alcancen.

        Los ejercicios en realidad son guías, si usas las versiones correctas y las placas consideradas sólo practicás recetas, quizás te cierre algún aprendizaje de la lectura del libro.



        Para estudiar The Zynq MPSoC Book

        $
        0
        0
        La lectura de este libro ha sido resultado de una serie de afortunados errores.

        Tengo algo de interés en PYNQ y en ZYNQ debido a tener un a Parallella, ví el título, no sé qué zynq, pynq, machine learning y no estaba tan caro, lo comencé a leer y mencionó que estaría bueno leer antes The Zynq Book lo estudié y volví a esto. De haber leido primero TZB sin tener ya en papel este no lo hubiese leido pues TZB no me pareció nada maravilloso y segundas partes suelen ser malas.

        Ese sí hubiese sido un error, The Zynq MPSoC Book parece haber sido escrito tras asimilar las críticas al primero y aunque tiene bastante de humo marketinero, la proporción es menor y los contenidos no sé muy bien si son muy superiores y más claros o la lectura de TZB me dejó en mejores condiciones.

        La parte marketing incluso es útil, aprendés cosas como que un cuadróptero tiene dos hélices girando para un lado y dos para el otro y eso le permite rotar, ja!

        La diferencia entre un Zynq y un Zynq MPSoC es enorme:

        • Dos cores de 32 -> cuatro cores de 64 para aplicaciones genéricas (APU).
        • FPGA Artix-7 -> FPGA Kintex-7
          • 35k-106k -> 157k-555k Flip Flops
          • 17k-53k ->  78k-277k LUTs
          • 28k-85k -> 125k-444k Logic Cells
          • 60-140 -> 265-755 36Kb Block RAM
          • 2M-5Mb -> 9M-26Mb Block RAM
          • 80-220 -> 400-2000 DSPs
        • Dos cores RealTime (RPU).
        • Graphics Processing Unit (GPU).
        • Video Codec Unit (VCU).
        • Configuration Security Unit (CSU) (*)
        • Platform Management Unit (PMU)(*) 
        Desde RPU para abajo, es terreno de MPSoC.


        CSU y PMU tienen cada una tres MicroBlazes en silicio ejecutándose en modo
        CSU se encarga del boot seguro de los procesadores.



        Las descripciones y explicaciones relacionadas a como se comunican y arrancan todos estos componentes es extremadamente educativa, me ha ayudado a avanzar en la comprensión de cómo funcionan en general las computadoras.

        Se explica SDx, aparentemente en los últimos cinco años la cosa ha evolucionado. La idea es que vos escribís tu programa en C/C++ y SDx analiza el código y busca oportunidades de pasar secciones a la FPGA y su interfaz.

        Lo que me había quedado de TZB es que este proceso estaba a cargo tuyo.


        Con respecto a la GPU y VCU se menciona que existen, pero luego nada, no recuerdo ninguna mención, lo cual es una pena pues son un tercio de la diferencia con Zynq pelado. Igual podríamos decir que como es algo común, no especial como CSU y PMU, a los cuales se los explica muy bien.


        Con respecto a ML, no respeta la proporción del título, es muy superficial, se citan ejemplos externos.

        A diferencia de TZB no hay una práctica propuesta, pero uno estos días veré de instanciar los ejemplos de PYNQ-Z1 a PYNQ-Z2.




        Se baja gratis de https://www.zynq-mpsoc-book.com/


        Conclusiones


        Vale la pena leerlo y si tenés tiempo antes leer y practicar TZB.
        Viewing all 264 articles
        Browse latest View live