El predictor de branca és un component crític de les arquitectures de CPU modernes dissenyades per millorar el rendiment especulant la direcció de les instruccions de la branca (per exemple, declaracions if-else) abans que es resolguin. Aquesta especulació permet a la CPU recuperar i executar instruccions al llarg del camí previst, reduint així la latència percebuda i millorant el rendiment global. Tanmateix, aquesta optimització del rendiment introdueix vulnerabilitats potencials que es poden explotar en atacs de temporització de la CPU, especialment en el context de filtrar informació sensible.
La predicció de branques funciona mantenint un historial dels resultats de les branques i utilitzant aquest historial per predir futures branques. Quan es troba una instrucció de branca, el predictor utilitza aquestes dades històriques per endevinar si es prendrà la branca o no. Si la predicció és correcta, la CPU continua amb l'execució sense interrupcions. Si és incorrecte, la CPU ha de retrocedir i executar el camí correcte, la qual cosa comporta una penalització de rendiment. Aquesta sanció, encara que petita, pot ser mesurada i explotada pels atacants.
Els atacants poden manipular el predictor de branques per crear una diferència de temps mesurable entre les branques predites correctament i incorrectament. Aquesta diferència es pot utilitzar per inferir la ruta d'execució d'un programa, que pot, al seu torn, revelar informació sensible. Un dels exemples més coneguts d'aquest atac és la vulnerabilitat Spectre, que aprofita l'execució especulativa i la predicció de branques per accedir a ubicacions de memòria no autoritzades.
En un atac d'espectre típic, l'atacant primer entrena el predictor de branques per seguir un patró específic. Aquesta fase d'entrenament consisteix a executar una seqüència d'instruccions de branca que condicionen el predictor per fer una predicció determinada. Un cop entrenat el predictor, l'atacant executa un segment de codi de víctima que inclou una branca que depèn de dades secretes. Si el predictor fa una predicció incorrecta basada en l'entrenament de l'atacant, la CPU executarà de manera especulativa instruccions que accedeixen a la memòria en funció de les dades secretes. Tot i que aquestes instruccions especulatives es descarten finalment, deixen rastres a la memòria cau de la CPU.
Aleshores, l'atacant pot mesurar els temps d'accés a diferents ubicacions de memòria per determinar a quines dades s'ha accedit especulativament. Aquesta tècnica, coneguda com a atac de temps de memòria cau, permet a l'atacant inferir les dades secretes en funció de les diferències de temps observades. Els passos clau en aquest atac són:
1. Formació del predictor de branca: L'atacant executa una seqüència controlada d'instruccions que influeixen en l'estat del predictor de branques. Per exemple, executar repetidament una instrucció de branca amb un resultat coherent (p. ex., sempre pres) condiciona el predictor a esperar aquest resultat en futures execucions.
2. Activació de l'execució especulativa: L'atacant executa el codi de la víctima amb una instrucció de branca que depèn de dades secretes. A causa de l'entrenament previ de l'atacant, el predictor de branques executa de manera especulativa el camí equivocat, que implica accedir a la memòria en funció de les dades secretes.
3. Mesura dels temps d'accés a la memòria cau: Després de l'execució especulativa, l'atacant mesura el temps que triga a accedir a ubicacions de memòria específiques. Els temps d'accés més ràpids indiquen que les dades estan presents a la memòria cau, la qual cosa implica que s'ha accedit de manera especulativa. Mitjançant l'anàlisi d'aquests temps, l'atacant pot inferir les dades secretes.
Per il·lustrar-ho amb un exemple concret, considereu un escenari on les dades secretes determinen l'índex d'accés a una matriu dins d'una branca. L'atacant primer entrena el predictor de branca perquè assumeixi una direcció de branca determinada. Quan s'executa el codi de la víctima, el predictor de branca executa de manera especulativa l'accés a la matriu en funció de la direcció entrenada. Si l'especulació implica accedir a un element de matriu concret, es carrega la línia de memòria cau corresponent. Aleshores, l'atacant pot realitzar una sèrie d'accessos de memòria cronometrats per determinar quines línies de memòria cau es carreguen, deduint així l'índex secret.
Mitigació d'aquests atacs implica diverses estratègies. Les solucions basades en maquinari inclouen millorar l'aïllament entre les vies d'execució especulatives i no especulatives i garantir que l'execució especulativa no afecti els recursos compartits com la memòria cau. Les solucions basades en programari impliquen tècniques com la inserció d'instruccions de "tanca" per evitar l'execució especulativa més enllà de determinats punts del codi, o l'ús de pràctiques de programació en temps constant per garantir que el temps d'execució no depengui de dades secretes.
La complexitat i la sofisticació dels atacs de temps basats en predictors de branques subratllen la necessitat d'investigació i desenvolupament continus tant en seguretat de maquinari com de programari. A mesura que les arquitectures de CPU continuen evolucionant, també ho han de fer les estratègies per protegir-se d'aquestes i altres formes d'atac de canal lateral.
Altres preguntes i respostes recents sobre Atacs de temporització de la CPU:
- Quins són alguns dels reptes i inconvenients que implica la implementació de mitigacions de maquinari i programari contra els atacs de temps mentre es manté el rendiment del sistema?
- Com pot ajudar la programació en temps constant a mitigar el risc d'atacs de cronometratge en algorismes criptogràfics?
- Què és l'execució especulativa i com contribueix a la vulnerabilitat dels processadors moderns a atacs de temporització com Spectre?
- Com els atacs de temporització exploten les variacions en el temps d'execució per inferir informació sensible d'un sistema?
- Què és un atac de temps?