Annotation of embedaddon/strongswan/src/libstrongswan/plugins/aesni/aesni_cbc.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (C) 2015 Martin Willi
        !             3:  * Copyright (C) 2015 revosec AG
        !             4:  *
        !             5:  * This program is free software; you can redistribute it and/or modify it
        !             6:  * under the terms of the GNU General Public License as published by the
        !             7:  * Free Software Foundation; either version 2 of the License, or (at your
        !             8:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
        !             9:  *
        !            10:  * This program is distributed in the hope that it will be useful, but
        !            11:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
        !            12:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
        !            13:  * for more details.
        !            14:  */
        !            15: 
        !            16: #include "aesni_cbc.h"
        !            17: #include "aesni_key.h"
        !            18: 
        !            19: /**
        !            20:  * Pipeline parallelism we use for CBC decryption
        !            21:  */
        !            22: #define CBC_DECRYPT_PARALLELISM 4
        !            23: 
        !            24: typedef struct private_aesni_cbc_t private_aesni_cbc_t;
        !            25: 
        !            26: /**
        !            27:  * CBC en/decryption method type
        !            28:  */
        !            29: typedef void (*aesni_cbc_fn_t)(aesni_key_t*, u_int, u_char*, u_char*, u_char*);
        !            30: 
        !            31: /**
        !            32:  * Private data of an aesni_cbc_t object.
        !            33:  */
        !            34: struct private_aesni_cbc_t {
        !            35: 
        !            36:        /**
        !            37:         * Public aesni_cbc_t interface.
        !            38:         */
        !            39:        aesni_cbc_t public;
        !            40: 
        !            41:        /**
        !            42:         * Key size
        !            43:         */
        !            44:        u_int key_size;
        !            45: 
        !            46:        /**
        !            47:         * Encryption key schedule
        !            48:         */
        !            49:        aesni_key_t *ekey;
        !            50: 
        !            51:        /**
        !            52:         * Decryption key schedule
        !            53:         */
        !            54:        aesni_key_t *dkey;
        !            55: 
        !            56:        /**
        !            57:         * Encryption method
        !            58:         */
        !            59:        aesni_cbc_fn_t encrypt;
        !            60: 
        !            61:        /**
        !            62:         * Decryption method
        !            63:         */
        !            64:        aesni_cbc_fn_t decrypt;
        !            65: };
        !            66: 
        !            67: /**
        !            68:  * AES-128 CBC encryption
        !            69:  */
        !            70: static void encrypt_cbc128(aesni_key_t *key, u_int blocks, u_char *in,
        !            71:                                                   u_char *iv, u_char *out)
        !            72: {
        !            73:        __m128i *ks, t, fb, *bi, *bo;
        !            74:        int i;
        !            75: 
        !            76:        ks = key->schedule;
        !            77:        bi = (__m128i*)in;
        !            78:        bo = (__m128i*)out;
        !            79: 
        !            80:        fb = _mm_loadu_si128((__m128i*)iv);
        !            81:        for (i = 0; i < blocks; i++)
        !            82:        {
        !            83:                t = _mm_loadu_si128(bi + i);
        !            84:                fb = _mm_xor_si128(t, fb);
        !            85:                fb = _mm_xor_si128(fb, ks[0]);
        !            86: 
        !            87:                fb = _mm_aesenc_si128(fb, ks[1]);
        !            88:                fb = _mm_aesenc_si128(fb, ks[2]);
        !            89:                fb = _mm_aesenc_si128(fb, ks[3]);
        !            90:                fb = _mm_aesenc_si128(fb, ks[4]);
        !            91:                fb = _mm_aesenc_si128(fb, ks[5]);
        !            92:                fb = _mm_aesenc_si128(fb, ks[6]);
        !            93:                fb = _mm_aesenc_si128(fb, ks[7]);
        !            94:                fb = _mm_aesenc_si128(fb, ks[8]);
        !            95:                fb = _mm_aesenc_si128(fb, ks[9]);
        !            96: 
        !            97:                fb = _mm_aesenclast_si128(fb, ks[10]);
        !            98:                _mm_storeu_si128(bo + i, fb);
        !            99:        }
        !           100: }
        !           101: 
        !           102: /**
        !           103:  * AES-128 CBC decryption
        !           104:  */
        !           105: static void decrypt_cbc128(aesni_key_t *key, u_int blocks, u_char *in,
        !           106:                                                   u_char *iv, u_char *out)
        !           107: {
        !           108:        __m128i *ks, last, *bi, *bo;
        !           109:        __m128i t1, t2, t3, t4;
        !           110:        __m128i f1, f2, f3, f4;
        !           111:        u_int i, pblocks;
        !           112: 
        !           113:        ks = key->schedule;
        !           114:        bi = (__m128i*)in;
        !           115:        bo = (__m128i*)out;
        !           116:        pblocks = blocks - (blocks % CBC_DECRYPT_PARALLELISM);
        !           117: 
        !           118:        f1 = _mm_loadu_si128((__m128i*)iv);
        !           119: 
        !           120:        for (i = 0; i < pblocks; i += CBC_DECRYPT_PARALLELISM)
        !           121:        {
        !           122:                t1 = _mm_loadu_si128(bi + i + 0);
        !           123:                t2 = _mm_loadu_si128(bi + i + 1);
        !           124:                t3 = _mm_loadu_si128(bi + i + 2);
        !           125:                t4 = _mm_loadu_si128(bi + i + 3);
        !           126: 
        !           127:                f2 = t1;
        !           128:                f3 = t2;
        !           129:                f4 = t3;
        !           130:                last = t4;
        !           131: 
        !           132:                t1 = _mm_xor_si128(t1, ks[0]);
        !           133:                t2 = _mm_xor_si128(t2, ks[0]);
        !           134:                t3 = _mm_xor_si128(t3, ks[0]);
        !           135:                t4 = _mm_xor_si128(t4, ks[0]);
        !           136: 
        !           137:                t1 = _mm_aesdec_si128(t1, ks[1]);
        !           138:                t2 = _mm_aesdec_si128(t2, ks[1]);
        !           139:                t3 = _mm_aesdec_si128(t3, ks[1]);
        !           140:                t4 = _mm_aesdec_si128(t4, ks[1]);
        !           141:                t1 = _mm_aesdec_si128(t1, ks[2]);
        !           142:                t2 = _mm_aesdec_si128(t2, ks[2]);
        !           143:                t3 = _mm_aesdec_si128(t3, ks[2]);
        !           144:                t4 = _mm_aesdec_si128(t4, ks[2]);
        !           145:                t1 = _mm_aesdec_si128(t1, ks[3]);
        !           146:                t2 = _mm_aesdec_si128(t2, ks[3]);
        !           147:                t3 = _mm_aesdec_si128(t3, ks[3]);
        !           148:                t4 = _mm_aesdec_si128(t4, ks[3]);
        !           149:                t1 = _mm_aesdec_si128(t1, ks[4]);
        !           150:                t2 = _mm_aesdec_si128(t2, ks[4]);
        !           151:                t3 = _mm_aesdec_si128(t3, ks[4]);
        !           152:                t4 = _mm_aesdec_si128(t4, ks[4]);
        !           153:                t1 = _mm_aesdec_si128(t1, ks[5]);
        !           154:                t2 = _mm_aesdec_si128(t2, ks[5]);
        !           155:                t3 = _mm_aesdec_si128(t3, ks[5]);
        !           156:                t4 = _mm_aesdec_si128(t4, ks[5]);
        !           157:                t1 = _mm_aesdec_si128(t1, ks[6]);
        !           158:                t2 = _mm_aesdec_si128(t2, ks[6]);
        !           159:                t3 = _mm_aesdec_si128(t3, ks[6]);
        !           160:                t4 = _mm_aesdec_si128(t4, ks[6]);
        !           161:                t1 = _mm_aesdec_si128(t1, ks[7]);
        !           162:                t2 = _mm_aesdec_si128(t2, ks[7]);
        !           163:                t3 = _mm_aesdec_si128(t3, ks[7]);
        !           164:                t4 = _mm_aesdec_si128(t4, ks[7]);
        !           165:                t1 = _mm_aesdec_si128(t1, ks[8]);
        !           166:                t2 = _mm_aesdec_si128(t2, ks[8]);
        !           167:                t3 = _mm_aesdec_si128(t3, ks[8]);
        !           168:                t4 = _mm_aesdec_si128(t4, ks[8]);
        !           169:                t1 = _mm_aesdec_si128(t1, ks[9]);
        !           170:                t2 = _mm_aesdec_si128(t2, ks[9]);
        !           171:                t3 = _mm_aesdec_si128(t3, ks[9]);
        !           172:                t4 = _mm_aesdec_si128(t4, ks[9]);
        !           173: 
        !           174:                t1 = _mm_aesdeclast_si128(t1, ks[10]);
        !           175:                t2 = _mm_aesdeclast_si128(t2, ks[10]);
        !           176:                t3 = _mm_aesdeclast_si128(t3, ks[10]);
        !           177:                t4 = _mm_aesdeclast_si128(t4, ks[10]);
        !           178:                t1 = _mm_xor_si128(t1, f1);
        !           179:                t2 = _mm_xor_si128(t2, f2);
        !           180:                t3 = _mm_xor_si128(t3, f3);
        !           181:                t4 = _mm_xor_si128(t4, f4);
        !           182:                _mm_storeu_si128(bo + i + 0, t1);
        !           183:                _mm_storeu_si128(bo + i + 1, t2);
        !           184:                _mm_storeu_si128(bo + i + 2, t3);
        !           185:                _mm_storeu_si128(bo + i + 3, t4);
        !           186:                f1 = last;
        !           187:        }
        !           188: 
        !           189:        for (i = pblocks; i < blocks; i++)
        !           190:        {
        !           191:                last = _mm_loadu_si128(bi + i);
        !           192:                t1 = _mm_xor_si128(last, ks[0]);
        !           193: 
        !           194:                t1 = _mm_aesdec_si128(t1, ks[1]);
        !           195:                t1 = _mm_aesdec_si128(t1, ks[2]);
        !           196:                t1 = _mm_aesdec_si128(t1, ks[3]);
        !           197:                t1 = _mm_aesdec_si128(t1, ks[4]);
        !           198:                t1 = _mm_aesdec_si128(t1, ks[5]);
        !           199:                t1 = _mm_aesdec_si128(t1, ks[6]);
        !           200:                t1 = _mm_aesdec_si128(t1, ks[7]);
        !           201:                t1 = _mm_aesdec_si128(t1, ks[8]);
        !           202:                t1 = _mm_aesdec_si128(t1, ks[9]);
        !           203: 
        !           204:                t1 = _mm_aesdeclast_si128(t1, ks[10]);
        !           205:                t1 = _mm_xor_si128(t1, f1);
        !           206:                _mm_storeu_si128(bo + i, t1);
        !           207:                f1 = last;
        !           208:        }
        !           209: }
        !           210: 
        !           211: /**
        !           212:  * AES-192 CBC encryption
        !           213:  */
        !           214: static void encrypt_cbc192(aesni_key_t *key, u_int blocks, u_char *in,
        !           215:                                                   u_char *iv, u_char *out)
        !           216: {
        !           217:        __m128i *ks, t, fb, *bi, *bo;
        !           218:        int i;
        !           219: 
        !           220:        ks = key->schedule;
        !           221:        bi = (__m128i*)in;
        !           222:        bo = (__m128i*)out;
        !           223: 
        !           224:        fb = _mm_loadu_si128((__m128i*)iv);
        !           225:        for (i = 0; i < blocks; i++)
        !           226:        {
        !           227:                t = _mm_loadu_si128(bi + i);
        !           228:                fb = _mm_xor_si128(t, fb);
        !           229:                fb = _mm_xor_si128(fb, ks[0]);
        !           230: 
        !           231:                fb = _mm_aesenc_si128(fb, ks[1]);
        !           232:                fb = _mm_aesenc_si128(fb, ks[2]);
        !           233:                fb = _mm_aesenc_si128(fb, ks[3]);
        !           234:                fb = _mm_aesenc_si128(fb, ks[4]);
        !           235:                fb = _mm_aesenc_si128(fb, ks[5]);
        !           236:                fb = _mm_aesenc_si128(fb, ks[6]);
        !           237:                fb = _mm_aesenc_si128(fb, ks[7]);
        !           238:                fb = _mm_aesenc_si128(fb, ks[8]);
        !           239:                fb = _mm_aesenc_si128(fb, ks[9]);
        !           240:                fb = _mm_aesenc_si128(fb, ks[10]);
        !           241:                fb = _mm_aesenc_si128(fb, ks[11]);
        !           242: 
        !           243:                fb = _mm_aesenclast_si128(fb, ks[12]);
        !           244:                _mm_storeu_si128(bo + i, fb);
        !           245:        }
        !           246: }
        !           247: 
        !           248: /**
        !           249:  * AES-192 CBC decryption
        !           250:  */
        !           251: static void decrypt_cbc192(aesni_key_t *key, u_int blocks, u_char *in,
        !           252:                                                   u_char *iv, u_char *out)
        !           253: {
        !           254:        __m128i *ks, last, *bi, *bo;
        !           255:        __m128i t1, t2, t3, t4;
        !           256:        __m128i f1, f2, f3, f4;
        !           257:        u_int i, pblocks;
        !           258: 
        !           259:        ks = key->schedule;
        !           260:        bi = (__m128i*)in;
        !           261:        bo = (__m128i*)out;
        !           262:        pblocks = blocks - (blocks % CBC_DECRYPT_PARALLELISM);
        !           263: 
        !           264:        f1 = _mm_loadu_si128((__m128i*)iv);
        !           265: 
        !           266:        for (i = 0; i < pblocks; i += CBC_DECRYPT_PARALLELISM)
        !           267:        {
        !           268:                t1 = _mm_loadu_si128(bi + i + 0);
        !           269:                t2 = _mm_loadu_si128(bi + i + 1);
        !           270:                t3 = _mm_loadu_si128(bi + i + 2);
        !           271:                t4 = _mm_loadu_si128(bi + i + 3);
        !           272: 
        !           273:                f2 = t1;
        !           274:                f3 = t2;
        !           275:                f4 = t3;
        !           276:                last = t4;
        !           277: 
        !           278:                t1 = _mm_xor_si128(t1, ks[0]);
        !           279:                t2 = _mm_xor_si128(t2, ks[0]);
        !           280:                t3 = _mm_xor_si128(t3, ks[0]);
        !           281:                t4 = _mm_xor_si128(t4, ks[0]);
        !           282: 
        !           283:                t1 = _mm_aesdec_si128(t1, ks[1]);
        !           284:                t2 = _mm_aesdec_si128(t2, ks[1]);
        !           285:                t3 = _mm_aesdec_si128(t3, ks[1]);
        !           286:                t4 = _mm_aesdec_si128(t4, ks[1]);
        !           287:                t1 = _mm_aesdec_si128(t1, ks[2]);
        !           288:                t2 = _mm_aesdec_si128(t2, ks[2]);
        !           289:                t3 = _mm_aesdec_si128(t3, ks[2]);
        !           290:                t4 = _mm_aesdec_si128(t4, ks[2]);
        !           291:                t1 = _mm_aesdec_si128(t1, ks[3]);
        !           292:                t2 = _mm_aesdec_si128(t2, ks[3]);
        !           293:                t3 = _mm_aesdec_si128(t3, ks[3]);
        !           294:                t4 = _mm_aesdec_si128(t4, ks[3]);
        !           295:                t1 = _mm_aesdec_si128(t1, ks[4]);
        !           296:                t2 = _mm_aesdec_si128(t2, ks[4]);
        !           297:                t3 = _mm_aesdec_si128(t3, ks[4]);
        !           298:                t4 = _mm_aesdec_si128(t4, ks[4]);
        !           299:                t1 = _mm_aesdec_si128(t1, ks[5]);
        !           300:                t2 = _mm_aesdec_si128(t2, ks[5]);
        !           301:                t3 = _mm_aesdec_si128(t3, ks[5]);
        !           302:                t4 = _mm_aesdec_si128(t4, ks[5]);
        !           303:                t1 = _mm_aesdec_si128(t1, ks[6]);
        !           304:                t2 = _mm_aesdec_si128(t2, ks[6]);
        !           305:                t3 = _mm_aesdec_si128(t3, ks[6]);
        !           306:                t4 = _mm_aesdec_si128(t4, ks[6]);
        !           307:                t1 = _mm_aesdec_si128(t1, ks[7]);
        !           308:                t2 = _mm_aesdec_si128(t2, ks[7]);
        !           309:                t3 = _mm_aesdec_si128(t3, ks[7]);
        !           310:                t4 = _mm_aesdec_si128(t4, ks[7]);
        !           311:                t1 = _mm_aesdec_si128(t1, ks[8]);
        !           312:                t2 = _mm_aesdec_si128(t2, ks[8]);
        !           313:                t3 = _mm_aesdec_si128(t3, ks[8]);
        !           314:                t4 = _mm_aesdec_si128(t4, ks[8]);
        !           315:                t1 = _mm_aesdec_si128(t1, ks[9]);
        !           316:                t2 = _mm_aesdec_si128(t2, ks[9]);
        !           317:                t3 = _mm_aesdec_si128(t3, ks[9]);
        !           318:                t4 = _mm_aesdec_si128(t4, ks[9]);
        !           319:                t1 = _mm_aesdec_si128(t1, ks[10]);
        !           320:                t2 = _mm_aesdec_si128(t2, ks[10]);
        !           321:                t3 = _mm_aesdec_si128(t3, ks[10]);
        !           322:                t4 = _mm_aesdec_si128(t4, ks[10]);
        !           323:                t1 = _mm_aesdec_si128(t1, ks[11]);
        !           324:                t2 = _mm_aesdec_si128(t2, ks[11]);
        !           325:                t3 = _mm_aesdec_si128(t3, ks[11]);
        !           326:                t4 = _mm_aesdec_si128(t4, ks[11]);
        !           327: 
        !           328:                t1 = _mm_aesdeclast_si128(t1, ks[12]);
        !           329:                t2 = _mm_aesdeclast_si128(t2, ks[12]);
        !           330:                t3 = _mm_aesdeclast_si128(t3, ks[12]);
        !           331:                t4 = _mm_aesdeclast_si128(t4, ks[12]);
        !           332:                t1 = _mm_xor_si128(t1, f1);
        !           333:                t2 = _mm_xor_si128(t2, f2);
        !           334:                t3 = _mm_xor_si128(t3, f3);
        !           335:                t4 = _mm_xor_si128(t4, f4);
        !           336:                _mm_storeu_si128(bo + i + 0, t1);
        !           337:                _mm_storeu_si128(bo + i + 1, t2);
        !           338:                _mm_storeu_si128(bo + i + 2, t3);
        !           339:                _mm_storeu_si128(bo + i + 3, t4);
        !           340:                f1 = last;
        !           341:        }
        !           342: 
        !           343:        for (i = pblocks; i < blocks; i++)
        !           344:        {
        !           345:                last = _mm_loadu_si128(bi + i);
        !           346:                t1 = _mm_xor_si128(last, ks[0]);
        !           347: 
        !           348:                t1 = _mm_aesdec_si128(t1, ks[1]);
        !           349:                t1 = _mm_aesdec_si128(t1, ks[2]);
        !           350:                t1 = _mm_aesdec_si128(t1, ks[3]);
        !           351:                t1 = _mm_aesdec_si128(t1, ks[4]);
        !           352:                t1 = _mm_aesdec_si128(t1, ks[5]);
        !           353:                t1 = _mm_aesdec_si128(t1, ks[6]);
        !           354:                t1 = _mm_aesdec_si128(t1, ks[7]);
        !           355:                t1 = _mm_aesdec_si128(t1, ks[8]);
        !           356:                t1 = _mm_aesdec_si128(t1, ks[9]);
        !           357:                t1 = _mm_aesdec_si128(t1, ks[10]);
        !           358:                t1 = _mm_aesdec_si128(t1, ks[11]);
        !           359: 
        !           360:                t1 = _mm_aesdeclast_si128(t1, ks[12]);
        !           361:                t1 = _mm_xor_si128(t1, f1);
        !           362:                _mm_storeu_si128(bo + i, t1);
        !           363:                f1 = last;
        !           364:        }
        !           365: }
        !           366: 
        !           367: /**
        !           368:  * AES-256 CBC encryption
        !           369:  */
        !           370: static void encrypt_cbc256(aesni_key_t *key, u_int blocks, u_char *in,
        !           371:                                                   u_char *iv, u_char *out)
        !           372: {
        !           373:        __m128i *ks, t, fb, *bi, *bo;
        !           374:        int i;
        !           375: 
        !           376:        ks = key->schedule;
        !           377:        bi = (__m128i*)in;
        !           378:        bo = (__m128i*)out;
        !           379: 
        !           380:        fb = _mm_loadu_si128((__m128i*)iv);
        !           381:        for (i = 0; i < blocks; i++)
        !           382:        {
        !           383:                t = _mm_loadu_si128(bi + i);
        !           384:                fb = _mm_xor_si128(t, fb);
        !           385:                fb = _mm_xor_si128(fb, ks[0]);
        !           386: 
        !           387:                fb = _mm_aesenc_si128(fb, ks[1]);
        !           388:                fb = _mm_aesenc_si128(fb, ks[2]);
        !           389:                fb = _mm_aesenc_si128(fb, ks[3]);
        !           390:                fb = _mm_aesenc_si128(fb, ks[4]);
        !           391:                fb = _mm_aesenc_si128(fb, ks[5]);
        !           392:                fb = _mm_aesenc_si128(fb, ks[6]);
        !           393:                fb = _mm_aesenc_si128(fb, ks[7]);
        !           394:                fb = _mm_aesenc_si128(fb, ks[8]);
        !           395:                fb = _mm_aesenc_si128(fb, ks[9]);
        !           396:                fb = _mm_aesenc_si128(fb, ks[10]);
        !           397:                fb = _mm_aesenc_si128(fb, ks[11]);
        !           398:                fb = _mm_aesenc_si128(fb, ks[12]);
        !           399:                fb = _mm_aesenc_si128(fb, ks[13]);
        !           400: 
        !           401:                fb = _mm_aesenclast_si128(fb, ks[14]);
        !           402:                _mm_storeu_si128(bo + i, fb);
        !           403:        }
        !           404: }
        !           405: 
        !           406: /**
        !           407:  * AES-256 CBC decryption
        !           408:  */
        !           409: static void decrypt_cbc256(aesni_key_t *key, u_int blocks, u_char *in,
        !           410:                                                   u_char *iv, u_char *out)
        !           411: {
        !           412:        __m128i *ks, last, *bi, *bo;
        !           413:        __m128i t1, t2, t3, t4;
        !           414:        __m128i f1, f2, f3, f4;
        !           415:        u_int i, pblocks;
        !           416: 
        !           417:        ks = key->schedule;
        !           418:        bi = (__m128i*)in;
        !           419:        bo = (__m128i*)out;
        !           420:        pblocks = blocks - (blocks % CBC_DECRYPT_PARALLELISM);
        !           421: 
        !           422:        f1 = _mm_loadu_si128((__m128i*)iv);
        !           423: 
        !           424:        for (i = 0; i < pblocks; i += CBC_DECRYPT_PARALLELISM)
        !           425:        {
        !           426:                t1 = _mm_loadu_si128(bi + i + 0);
        !           427:                t2 = _mm_loadu_si128(bi + i + 1);
        !           428:                t3 = _mm_loadu_si128(bi + i + 2);
        !           429:                t4 = _mm_loadu_si128(bi + i + 3);
        !           430: 
        !           431:                f2 = t1;
        !           432:                f3 = t2;
        !           433:                f4 = t3;
        !           434:                last = t4;
        !           435: 
        !           436:                t1 = _mm_xor_si128(t1, ks[0]);
        !           437:                t2 = _mm_xor_si128(t2, ks[0]);
        !           438:                t3 = _mm_xor_si128(t3, ks[0]);
        !           439:                t4 = _mm_xor_si128(t4, ks[0]);
        !           440: 
        !           441:                t1 = _mm_aesdec_si128(t1, ks[1]);
        !           442:                t2 = _mm_aesdec_si128(t2, ks[1]);
        !           443:                t3 = _mm_aesdec_si128(t3, ks[1]);
        !           444:                t4 = _mm_aesdec_si128(t4, ks[1]);
        !           445:                t1 = _mm_aesdec_si128(t1, ks[2]);
        !           446:                t2 = _mm_aesdec_si128(t2, ks[2]);
        !           447:                t3 = _mm_aesdec_si128(t3, ks[2]);
        !           448:                t4 = _mm_aesdec_si128(t4, ks[2]);
        !           449:                t1 = _mm_aesdec_si128(t1, ks[3]);
        !           450:                t2 = _mm_aesdec_si128(t2, ks[3]);
        !           451:                t3 = _mm_aesdec_si128(t3, ks[3]);
        !           452:                t4 = _mm_aesdec_si128(t4, ks[3]);
        !           453:                t1 = _mm_aesdec_si128(t1, ks[4]);
        !           454:                t2 = _mm_aesdec_si128(t2, ks[4]);
        !           455:                t3 = _mm_aesdec_si128(t3, ks[4]);
        !           456:                t4 = _mm_aesdec_si128(t4, ks[4]);
        !           457:                t1 = _mm_aesdec_si128(t1, ks[5]);
        !           458:                t2 = _mm_aesdec_si128(t2, ks[5]);
        !           459:                t3 = _mm_aesdec_si128(t3, ks[5]);
        !           460:                t4 = _mm_aesdec_si128(t4, ks[5]);
        !           461:                t1 = _mm_aesdec_si128(t1, ks[6]);
        !           462:                t2 = _mm_aesdec_si128(t2, ks[6]);
        !           463:                t3 = _mm_aesdec_si128(t3, ks[6]);
        !           464:                t4 = _mm_aesdec_si128(t4, ks[6]);
        !           465:                t1 = _mm_aesdec_si128(t1, ks[7]);
        !           466:                t2 = _mm_aesdec_si128(t2, ks[7]);
        !           467:                t3 = _mm_aesdec_si128(t3, ks[7]);
        !           468:                t4 = _mm_aesdec_si128(t4, ks[7]);
        !           469:                t1 = _mm_aesdec_si128(t1, ks[8]);
        !           470:                t2 = _mm_aesdec_si128(t2, ks[8]);
        !           471:                t3 = _mm_aesdec_si128(t3, ks[8]);
        !           472:                t4 = _mm_aesdec_si128(t4, ks[8]);
        !           473:                t1 = _mm_aesdec_si128(t1, ks[9]);
        !           474:                t2 = _mm_aesdec_si128(t2, ks[9]);
        !           475:                t3 = _mm_aesdec_si128(t3, ks[9]);
        !           476:                t4 = _mm_aesdec_si128(t4, ks[9]);
        !           477:                t1 = _mm_aesdec_si128(t1, ks[10]);
        !           478:                t2 = _mm_aesdec_si128(t2, ks[10]);
        !           479:                t3 = _mm_aesdec_si128(t3, ks[10]);
        !           480:                t4 = _mm_aesdec_si128(t4, ks[10]);
        !           481:                t1 = _mm_aesdec_si128(t1, ks[11]);
        !           482:                t2 = _mm_aesdec_si128(t2, ks[11]);
        !           483:                t3 = _mm_aesdec_si128(t3, ks[11]);
        !           484:                t4 = _mm_aesdec_si128(t4, ks[11]);
        !           485:                t1 = _mm_aesdec_si128(t1, ks[12]);
        !           486:                t2 = _mm_aesdec_si128(t2, ks[12]);
        !           487:                t3 = _mm_aesdec_si128(t3, ks[12]);
        !           488:                t4 = _mm_aesdec_si128(t4, ks[12]);
        !           489:                t1 = _mm_aesdec_si128(t1, ks[13]);
        !           490:                t2 = _mm_aesdec_si128(t2, ks[13]);
        !           491:                t3 = _mm_aesdec_si128(t3, ks[13]);
        !           492:                t4 = _mm_aesdec_si128(t4, ks[13]);
        !           493: 
        !           494:                t1 = _mm_aesdeclast_si128(t1, ks[14]);
        !           495:                t2 = _mm_aesdeclast_si128(t2, ks[14]);
        !           496:                t3 = _mm_aesdeclast_si128(t3, ks[14]);
        !           497:                t4 = _mm_aesdeclast_si128(t4, ks[14]);
        !           498:                t1 = _mm_xor_si128(t1, f1);
        !           499:                t2 = _mm_xor_si128(t2, f2);
        !           500:                t3 = _mm_xor_si128(t3, f3);
        !           501:                t4 = _mm_xor_si128(t4, f4);
        !           502:                _mm_storeu_si128(bo + i + 0, t1);
        !           503:                _mm_storeu_si128(bo + i + 1, t2);
        !           504:                _mm_storeu_si128(bo + i + 2, t3);
        !           505:                _mm_storeu_si128(bo + i + 3, t4);
        !           506:                f1 = last;
        !           507:        }
        !           508: 
        !           509:        for (i = pblocks; i < blocks; i++)
        !           510:        {
        !           511:                last = _mm_loadu_si128(bi + i);
        !           512:                t1 = _mm_xor_si128(last, ks[0]);
        !           513: 
        !           514:                t1 = _mm_aesdec_si128(t1, ks[1]);
        !           515:                t1 = _mm_aesdec_si128(t1, ks[2]);
        !           516:                t1 = _mm_aesdec_si128(t1, ks[3]);
        !           517:                t1 = _mm_aesdec_si128(t1, ks[4]);
        !           518:                t1 = _mm_aesdec_si128(t1, ks[5]);
        !           519:                t1 = _mm_aesdec_si128(t1, ks[6]);
        !           520:                t1 = _mm_aesdec_si128(t1, ks[7]);
        !           521:                t1 = _mm_aesdec_si128(t1, ks[8]);
        !           522:                t1 = _mm_aesdec_si128(t1, ks[9]);
        !           523:                t1 = _mm_aesdec_si128(t1, ks[10]);
        !           524:                t1 = _mm_aesdec_si128(t1, ks[11]);
        !           525:                t1 = _mm_aesdec_si128(t1, ks[12]);
        !           526:                t1 = _mm_aesdec_si128(t1, ks[13]);
        !           527: 
        !           528:                t1 = _mm_aesdeclast_si128(t1, ks[14]);
        !           529:                t1 = _mm_xor_si128(t1, f1);
        !           530:                _mm_storeu_si128(bo + i, t1);
        !           531:                f1 = last;
        !           532:        }
        !           533: }
        !           534: 
        !           535: /**
        !           536:  * Do inline or allocated de/encryption using key schedule
        !           537:  */
        !           538: static bool crypt(aesni_cbc_fn_t fn, aesni_key_t *key,
        !           539:                                  chunk_t data, chunk_t iv, chunk_t *out)
        !           540: {
        !           541:        u_char *buf;
        !           542: 
        !           543:        if (!key || iv.len != AES_BLOCK_SIZE || data.len % AES_BLOCK_SIZE)
        !           544:        {
        !           545:                return FALSE;
        !           546:        }
        !           547:        if (out)
        !           548:        {
        !           549:                *out = chunk_alloc(data.len);
        !           550:                buf = out->ptr;
        !           551:        }
        !           552:        else
        !           553:        {
        !           554:                buf = data.ptr;
        !           555:        }
        !           556:        fn(key, data.len / AES_BLOCK_SIZE, data.ptr, iv.ptr, buf);
        !           557:        return TRUE;
        !           558: }
        !           559: 
        !           560: METHOD(crypter_t, encrypt, bool,
        !           561:        private_aesni_cbc_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted)
        !           562: {
        !           563:        return crypt(this->encrypt, this->ekey, data, iv, encrypted);
        !           564: }
        !           565: 
        !           566: METHOD(crypter_t, decrypt, bool,
        !           567:        private_aesni_cbc_t *this, chunk_t data, chunk_t iv, chunk_t *decrypted)
        !           568: {
        !           569:        return crypt(this->decrypt, this->dkey, data, iv, decrypted);
        !           570: }
        !           571: 
        !           572: METHOD(crypter_t, get_block_size, size_t,
        !           573:        private_aesni_cbc_t *this)
        !           574: {
        !           575:        return AES_BLOCK_SIZE;
        !           576: }
        !           577: 
        !           578: METHOD(crypter_t, get_iv_size, size_t,
        !           579:        private_aesni_cbc_t *this)
        !           580: {
        !           581:        return AES_BLOCK_SIZE;
        !           582: }
        !           583: 
        !           584: METHOD(crypter_t, get_key_size, size_t,
        !           585:        private_aesni_cbc_t *this)
        !           586: {
        !           587:        return this->key_size;
        !           588: }
        !           589: 
        !           590: METHOD(crypter_t, set_key, bool,
        !           591:        private_aesni_cbc_t *this, chunk_t key)
        !           592: {
        !           593:        if (key.len != this->key_size)
        !           594:        {
        !           595:                return FALSE;
        !           596:        }
        !           597: 
        !           598:        DESTROY_IF(this->ekey);
        !           599:        DESTROY_IF(this->dkey);
        !           600: 
        !           601:        this->ekey = aesni_key_create(TRUE, key);
        !           602:        this->dkey = aesni_key_create(FALSE, key);
        !           603: 
        !           604:        return this->ekey && this->dkey;
        !           605: }
        !           606: 
        !           607: METHOD(crypter_t, destroy, void,
        !           608:        private_aesni_cbc_t *this)
        !           609: {
        !           610:        DESTROY_IF(this->ekey);
        !           611:        DESTROY_IF(this->dkey);
        !           612:        free_align(this);
        !           613: }
        !           614: 
        !           615: /**
        !           616:  * See header
        !           617:  */
        !           618: aesni_cbc_t *aesni_cbc_create(encryption_algorithm_t algo, size_t key_size)
        !           619: {
        !           620:        private_aesni_cbc_t *this;
        !           621: 
        !           622:        if (algo != ENCR_AES_CBC)
        !           623:        {
        !           624:                return NULL;
        !           625:        }
        !           626:        switch (key_size)
        !           627:        {
        !           628:                case 0:
        !           629:                        key_size = 16;
        !           630:                        break;
        !           631:                case 16:
        !           632:                case 24:
        !           633:                case 32:
        !           634:                        break;
        !           635:                default:
        !           636:                        return NULL;
        !           637:        }
        !           638: 
        !           639:        INIT_ALIGN(this, sizeof(__m128i),
        !           640:                .public = {
        !           641:                        .crypter = {
        !           642:                                .encrypt = _encrypt,
        !           643:                                .decrypt = _decrypt,
        !           644:                                .get_block_size = _get_block_size,
        !           645:                                .get_iv_size = _get_iv_size,
        !           646:                                .get_key_size = _get_key_size,
        !           647:                                .set_key = _set_key,
        !           648:                                .destroy = _destroy,
        !           649:                        },
        !           650:                },
        !           651:                .key_size = key_size,
        !           652:        );
        !           653: 
        !           654:        switch (key_size)
        !           655:        {
        !           656:                case 16:
        !           657:                        this->encrypt = encrypt_cbc128;
        !           658:                        this->decrypt = decrypt_cbc128;
        !           659:                        break;
        !           660:                case 24:
        !           661:                        this->encrypt = encrypt_cbc192;
        !           662:                        this->decrypt = decrypt_cbc192;
        !           663:                        break;
        !           664:                case 32:
        !           665:                        this->encrypt = encrypt_cbc256;
        !           666:                        this->decrypt = decrypt_cbc256;
        !           667:                        break;
        !           668:        }
        !           669: 
        !           670:        return &this->public;
        !           671: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>