int aes_cypher(void *out, const void *in, uint32_t size, const void *iv, const void *key, uint32_t keysize, int mode, int encrypt) { int res = OK; if (size % 16) { return -EINVAL; } aes_lock(); res = aes_setup_mr(keysize, mode & AES_MODE_MASK, encrypt); if (res) { aes_unlock(); return res; } aes_memcpy((void *)SAM_AES_KEYWR, key, keysize); if (iv) { aes_memcpy((void *)SAM_AES_IVR, iv, AES_BLOCK_SIZE); } while (size) { if ((mode & AES_MODE_MAC) == 0) { aes_encryptblock(out, in); out = (char *)out + AES_BLOCK_SIZE; } else if (size == AES_BLOCK_SIZE) { aes_encryptblock(out, in); } else { aes_encryptblock(NULL, in); } in = (char *)in + AES_BLOCK_SIZE; size -= AES_BLOCK_SIZE; } aes_unlock(); return res; }
int aes_cypher(void *out, const void *in, uint32_t size, const void *iv, const void *key, uint32_t keysize, int mode, int encrypt) { int ret = OK; if ((size & (AES_BLOCK_SIZE-1)) != 0) { return -EINVAL; } if (keysize != 16) { return -EINVAL; } ret = sem_wait(&aes_lock); if (ret < 0) { return ret; } /* AES must be disabled before changing mode, key or IV. */ aes_enable(false); ret = aes_setup_cr(mode, encrypt); if (ret < 0) { goto out; } aes_setkey(key, keysize); if (iv) { aes_setiv(iv); } aes_enable(true); while (size) { aes_encryptblock(out, in); out = (uint8_t *)out + AES_BLOCK_SIZE; in = (uint8_t *)in + AES_BLOCK_SIZE; size -= AES_BLOCK_SIZE; } aes_enable(false); out: sem_post(&aes_lock); return ret; }