3 votos

¿Cómo valida la protección de dm-verity de Android los bloques con un árbol de hash?

Estoy aprendiendo sobre la protección dm-verity de Android y trato de entender cómo utiliza dm-verity de Android el árbol hash para la validación de "bloque único".

https://source.android.com/security/verifiedboot/dm-verity dice:

En lugar de ello, dm-verity verifica bloques individualmente y solo cuando cada uno es accedido. Cuando se lee en memoria, el bloque se hashea en paralelo. El hash es verificado luego en el árbol. Y dado que leer el bloque es una operación costosa, la latencia introducida por esta verificación a nivel de bloque es comparativamente nominal.

Después de que el bloque es leído y hasheado, se verifica en el árbol. Pero ¿cómo puedo verificar el hash root, cuando no he leído todos los bloques?? Solo puedo verificar la parte del árbol que he leído, y eso significa que no tengo que llegar hasta el hash root.

No entiendo por qué usamos un árbol hash. La publicación en StackOverflow dice que la razón principal para usar árboles hash es cuando se calcula el hash para cada bloque y luego para el archivo completo nuevamente, no entiendo por qué se usa aquí.

Entonces ¿cómo se implementa en realidad?? Mi suposición es que cuando el bloque se carga en la memoria, Android simplemente verifica la rama particular y el resto de los valores se toman del árbol hash precalculado. Pero luego no veo la razón para usar el árbol. Solo almacenaría los valores hash de bloque y después de leer el bloque y hashear, compararía solo el hash.

¡Editemos: Supongamos esta implementación:

  1. dividir todo el dispositivo de bloque en bloques de tamaño 4K.
  2. hashear cada bloque en particular y concatenar los hashes (crear la capa 0 de dm-verity)
  3. almacenar los hashes (capa 0) al final del dispositivo de bloque Ahora, cuando quiero verificar el bloque 4K cargado en la memoria, encuentro la posición del bloque y comparo el hash del bloque cargado con el hash almacenado.

En situaciones como esta tiene sentido usar un árbol, porque solo tienes disponible la root de Merkle, pero en Android, tenemos el árbol completo, entonces ¿por qué no usar solo la capa 0 (implementación anterior) y descartar el resto?

Y mientras escribo, creo que he llegado a una respuesta. Android almacena todo el árbol hash al final. Pero el árbol no está firmado, solo la tabla dm-verity (metadatos) que contiene el hash root. Entonces, en mi implementación, tendría que firmar toda la capa 0. Y eso probablemente sea un desperdicio de recursos, así que es mejor usar el árbol.

3voto

rascalking Puntos 1422

"Pero ¿cómo puedo verificar el hash root, si no he leído todos los bloques??"

"En esencia, las hojas del árbol son páginas que contienen valores hash; cada nivel superior en el árbol contiene hashes de los bloques debajo de él." Referencia

Ejemplo:

"Un camino de Merkle se utiliza para probar la inclusión de un elemento de datos. Un nodo puede probar que una transacción K está incluida en el bloque al producir un camino de Merkle que es solo de cuatro hashes de 32 bytes de largo (128 bytes en total). El camino consiste en los cuatro hashes (mostrados con un fondo sombreado en Un camino de Merkle utilizado para probar la inclusión de un elemento de datos) HL, HIJ, HMNOP y HABCDEFGH. Con esos cuatro hashes proporcionados como un camino de autenticación, cualquier nodo puede probar que HK (con un fondo negro en la parte inferior del diagrama) está incluido en la root de Merkle calculando cuatro hashes adicionales de pares HKL, HIJKL, HIJKLMNOP, y la root del árbol de Merkle ."árbol de Merkle Referencia

"Solo almacenaría valores hash de bloque y después de leer el bloque y hacer el hash, solo compararía el hash."

Debes recordar que los teléfonos celulares tienen una cantidad limitada de recursos. Tu forma de hacerlo requiere que leas todo el bloque y compares para verificar la validez antes. Con el árbol solo necesitas leer una parte de él para verificar la validez.

"Sin embargo, intentar verificar un dispositivo de bloque completo puede llevar un período prolongado y consumir mucha energía de un dispositivo. Los dispositivos tardarían mucho tiempo en arrancar y luego se descargarían significativamente antes de su uso." Referencia

Para ayudar con tu investigación, creo que sería importante conocer la teoría del árbol de hash. Se llama árbol de Merkle patentado por primera vez por Ralph Merkle

0 votos

De lo que entiendo además 1. El árbol de búsqueda binaria nunca se encuentra con colisiones, lo que significa que el árbol de búsqueda binaria puede garantizar que la inserción, búsqueda y eliminación se implementan en O(log(n)), lo cual es mucho más rápido que el tiempo lineal. Además, el espacio necesario por el árbol es exactamente igual al tamaño de los datos de entrada. 2. No necesitas conocer el tamaño de entrada de antemano. 3. Todos los elementos en el árbol están ordenados de manera que el recorrido en orden toma tiempo O(n). Lo cual es fundamental en cosas como contactos telefónicos que están en orden alfabético.

1 votos

Gracias. No había escuchado sobre el camino de Merkle, y ahora me queda claro cómo se validan los bloques. Sin embargo, aún no estaba seguro de por qué usan el árbol, por lo que editaré mi pregunta para aclarar lo que no entendí.

1 votos

La razón principal es seguridad. Ten en cuenta que Android se supone que es de solo lectura para el usuario. La modificación de cualquier bloque equivale a romper el hash criptográfico. dm-verity verifica los bloques individualmente y solo cuando cada uno es accedido. Cuando se lee en memoria, el bloque se hashea en paralelo. Luego se verifica el hash hacia arriba en el árbol. Y dado que la lectura del bloque es una operación tan costosa, la latencia introducida por esta verificación a nivel de bloque es comparativamente nominal.

PreguntAndroid.com

PreguntAndroid es una comunidad de usuarios de Android en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X