⟁ HXA πŸ‡¬πŸ‡§ EN
β”Œβ”€[ AES-Encryption ]─────────────────────────────────────────────────────────────────────────────────
β”‚ user: Alejandro Lopez Aguilar
β”” path: /linux-and-herramientas/herramientas-propias/aes-encryption/
Este codigo no se puede usar en producciΓ³n ya que es necesario remover tanto la clave hardcodeada y 
eliminar cualquier printf que muestre secretos

Definiciones iniciales

~ `WIN32_LEAN_AND_MEAN` reduce macros innecesarias del `windows.h`
~ `bcrypt.h` se usa para `BCryptGenRandom` (RNG de Windows)
~ `crypto/aes.h` es la API de tiny-aes que se usa (proporciona `AES_ctx`, `AES_init_ctx_iv`, 
`AES_CBC_encrypt_buffer`)

checkPadding
β”Œβ”€[ c ]─────────────────────────────────────────────────────────────────────────────────────────────
bool checkPadding(unsigned char payload[], size_t sizePayload) {
    return (sizePayload % 16 == 0)
               ? true
               : false;
}
└───────────────────────────────────────────────────────────────────────────────────────────────────
~ Devuelve `true` si `sizePayload` ya es mΓΊltiplo de 16 (tamaΓ±o de bloque AES), `false` si no
~ AES-CBC en tiny-aes requiere que el buffer a cifrar tenga longitud mΓΊltiplo de 16 bytes

fillPadding
β”Œβ”€[ c ]─────────────────────────────────────────────────────────────────────────────────────────────
void fillPadding(unsigned char payload[], size_t sizePayload, unsigned char **newPayload, size_t *newSize) {
    size_t size = ((sizePayload + (15)) / 16) * 16;

    unsigned char *pNewpayload = (unsigned char *) malloc(size);

    if (!pNewpayload) {
        *newPayload = NULL;
        *newSize = 0;
        return;
    }

    memcpy(pNewpayload, payload, sizePayload);

    memset(pNewpayload + sizePayload, 0x00, size - sizePayload);

    *newSize = size;
    *newPayload = pNewpayload;
}
└───────────────────────────────────────────────────────────────────────────────────────────────────
~ Calcula el siguiente mΓΊltiplo de 16 para `sizePayload`
~ Reserva `size` bytes con `malloc`
~ Copia `sizePayload` bytes desde `payload` a la nueva Γ‘rea
~ Rellena el resto con ceros (`0x00`)
~ Devuelve el puntero en `*newPayload` y tamaΓ±o en `*newSize`

encriptar
β”Œβ”€[ c ]─────────────────────────────────────────────────────────────────────────────────────────────
bool encriptar(unsigned char payload[], size_t sizePayload, unsigned char **encryptedPayload,
               size_t *encryptedPayloadSize, bool *must_free) {
    if (!encryptedPayload || !encryptedPayloadSize) return false;

    unsigned char *newPayload = NULL;
    size_t newPayloadSize;

    if (!checkPadding(payload, sizePayload)) {
        fillPadding(payload, sizePayload, &newPayload, &newPayloadSize);
        if (!newPayload) return false;
        *must_free = true;
    } else {
        newPayload = payload;
        newPayloadSize = sizePayload;
        *must_free = false;
    }

    uint8_t iv[16] = {0};
    NTSTATUS st = BCryptGenRandom(NULL, iv, sizeof iv, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
    if (st != 0) {
        puts("Error al generar el IV");
    }

    printf("IV usado:\n");
    for (int i = 0; i < 16; i++) {
        printf("0x%02X ", iv[i]);
    }

    uint8_t key[16] = "extraterrestrial";

    struct AES_ctx ctx;
    AES_init_ctx_iv(&ctx, key, iv);

    AES_CBC_encrypt_buffer(&ctx, newPayload, (uint32_t) newPayloadSize);

    *encryptedPayload = newPayload;
    *encryptedPayloadSize = newPayloadSize;

    return true;
}
└───────────────────────────────────────────────────────────────────────────────────────────────────
~ Comprueba `encryptedPayload` y `encryptedPayloadSize` no nulos. Bien evitar writes a punteros 
nulos
~ No comprueba `must_free` (se asume que es vΓ‘lido si se pasa)

A continuaciΓ³n proporciono el enlace al cΓ³digo completo en mi github

Recurso externo: abrir recurso