Print this page
5007142 Add ntohll and htonll to sys/byteorder.h
6717509 Need to use bswap/bswapq for byte swap of 64-bit integer on x32/x64
PSARC 2008/474


   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 #pragma ident   "%Z%%M% %I%     %E% SMI"
  27 
  28 #include <sys/types.h>
  29 #include <sys/systm.h>
  30 #include <sys/ddi.h>
  31 #include <sys/sysmacros.h>
  32 #include <sys/strsun.h>
  33 #include <netinet/in.h>
  34 #include <sys/crypto/spi.h>
  35 #include <modes/modes.h>
  36 #include "aes_impl.h"
  37 #ifndef _KERNEL
  38 #include <strings.h>
  39 #include <stdlib.h>
  40 #endif  /* !_KERNEL */
  41 
  42 
  43 /*
  44  * This file is derived from the file  rijndael-alg-fst.c  taken from the
  45  * "optimized C code v3.0" on the "rijndael home page"
  46  * http://www.iaik.tu-graz.ac.at/research/krypto/AES/old/~rijmen/rijndael/
  47  * pointed by the NIST web-site http://csrc.nist.gov/archive/aes/


1473          * For _LITTLE_ENDIAN machines (except AMD64), reverse every
1474          * 4 bytes in the key.  On _BIG_ENDIAN and AMD64, copy the key
1475          * without reversing bytes.
1476          * For AMD64, do not byte swap for aes_setupkeys().
1477          *
1478          * SPARCv8/v9 uses a key schedule array with 64-bit elements.
1479          * X86/AMD64  uses a key schedule array with 32-bit elements.
1480          */
1481 #ifndef AES_BYTE_SWAP
1482         if (IS_P2ALIGNED(cipherKey, sizeof (uint64_t))) {
1483                 for (i = 0, j = 0; j < keysize; i++, j += 8) {
1484                         /* LINTED: pointer alignment */
1485                         keyarr.ka64[i] = *((uint64_t *)&cipherKey[j]);
1486                 }
1487         } else {
1488                 bcopy(cipherKey, keyarr.ka32, keysize);
1489         }
1490 
1491 #else   /* byte swap */
1492         for (i = 0, j = 0; j < keysize; i++, j += 4) {
1493                 keyarr.ka32[i] = (((uint32_t)cipherKey[j] << 24) |
1494                     ((uint32_t)cipherKey[j + 1] << 16) |
1495                     ((uint32_t)cipherKey[j + 2] << 8) |
1496                     (uint32_t)cipherKey[j + 3]);
1497         }
1498 #endif
1499 
1500         aes_setupkeys(newbie, keyarr.ka32, keyBits);
1501 /* EXPORT DELETE END */
1502 }
1503 
1504 /*
1505  * Encrypt one block using AES.
1506  * Align if needed and (for x86 32-bit only) byte-swap.
1507  *
1508  * Parameters:
1509  * ks   Key schedule, of type aes_key_t
1510  * pt   Input block (plain text)
1511  * ct   Output block (crypto text).  Can overlap with pt
1512  */
1513 int
1514 aes_encrypt_block(const void *ks, const uint8_t *pt, uint8_t *ct)
1515 {
1516 /* EXPORT DELETE START */
1517         aes_key_t       *ksch = (aes_key_t *)ks;
1518 
1519 #ifndef AES_BYTE_SWAP
1520         if (IS_P2ALIGNED2(pt, ct, sizeof (uint32_t))) {
1521                 AES_ENCRYPT_IMPL(&ksch->encr_ks.ks32[0], ksch->nr,
1522                     /* LINTED:  pointer alignment */
1523                     (uint32_t *)pt, (uint32_t *)ct);
1524         } else {
1525 #endif
1526                 uint32_t buffer[AES_BLOCK_LEN / sizeof (uint32_t)];
1527 
1528                 /* Copy input block into buffer */
1529 #ifndef AES_BYTE_SWAP
1530                 bcopy(pt, &buffer, AES_BLOCK_LEN);
1531 
1532 #else   /* byte swap */
1533                 buffer[0] = (((uint32_t)pt[0] << 24) | ((uint32_t)pt[1] << 16) |
1534                     ((uint32_t)pt[2] << 8) | (uint32_t)pt[3]);
1535                 buffer[1] = (((uint32_t)pt[4] << 24) | ((uint32_t)pt[5] << 16) |
1536                     ((uint32_t)pt[6] << 8) | (uint32_t)pt[7]);
1537                 buffer[2] = (((uint32_t)pt[8] << 24) | ((uint32_t)pt[9] << 16) |
1538                     ((uint32_t)pt[10] << 8) | (uint32_t)pt[11]);
1539                 buffer[3] = (((uint32_t)pt[12] << 24) |
1540                     ((uint32_t)pt[13] << 16) | ((uint32_t)pt[14] << 8) |
1541                     (uint32_t)pt[15]);
1542 #endif
1543 
1544                 AES_ENCRYPT_IMPL(&ksch->encr_ks.ks32[0], ksch->nr,
1545                     buffer, buffer);
1546 
1547                 /* Copy result from buffer to output block */
1548 #ifndef AES_BYTE_SWAP
1549                 bcopy(&buffer, ct, AES_BLOCK_LEN);
1550         }
1551 
1552 #else   /* byte swap */
1553                 ct[0] = buffer[0] >> 24;
1554                 ct[1] = buffer[0] >> 16;
1555                 ct[2] = buffer[0] >> 8;
1556                 ct[3] = (uint8_t)buffer[0];
1557                 ct[4] = buffer[1] >> 24;
1558                 ct[5] = buffer[1] >> 16;
1559                 ct[6] = buffer[1] >> 8;
1560                 ct[7] = (uint8_t)buffer[1];
1561                 ct[8] = buffer[2] >> 24;
1562                 ct[9] = buffer[2] >> 16;
1563                 ct[10] = buffer[2] >> 8;
1564                 ct[11] = (uint8_t)buffer[2];
1565                 ct[12] = buffer[3] >> 24;
1566                 ct[13] = buffer[3] >> 16;
1567                 ct[14] = buffer[3] >> 8;
1568                 ct[15] = (uint8_t)buffer[3];
1569 #endif
1570 /* EXPORT DELETE END */
1571         return (CRYPTO_SUCCESS);
1572 }
1573 
1574 /*
1575  * Decrypt one block using AES.
1576  * Align and byte-swap if needed.
1577  *
1578  * Parameters:
1579  * ks   Key schedule, of type aes_key_t
1580  * ct   Input block (crypto text)
1581  * pt   Output block (plain text). Can overlap with pt
1582  */
1583 int
1584 aes_decrypt_block(const void *ks, const uint8_t *ct, uint8_t *pt)
1585 {
1586 /* EXPORT DELETE START */
1587         aes_key_t       *ksch = (aes_key_t *)ks;
1588 
1589 #ifndef AES_BYTE_SWAP
1590         if (IS_P2ALIGNED2(ct, pt, sizeof (uint32_t))) {
1591                 AES_DECRYPT_IMPL(&ksch->decr_ks.ks32[0], ksch->nr,
1592                     /* LINTED:  pointer alignment */
1593                     (uint32_t *)ct, (uint32_t *)pt);
1594         } else {
1595 #endif
1596                 uint32_t buffer[AES_BLOCK_LEN / sizeof (uint32_t)];
1597 
1598                 /* Copy input block into buffer */
1599 #ifndef AES_BYTE_SWAP
1600                 bcopy(ct, &buffer, AES_BLOCK_LEN);
1601 
1602 #else   /* byte swap */
1603                 buffer[0] = (((uint32_t)ct[0] << 24) | ((uint32_t)ct[1] << 16) |
1604                     ((uint32_t)ct[2] << 8) | (uint32_t)ct[3]);
1605 
1606                 buffer[1] = (((uint32_t)ct[4] << 24) | ((uint32_t)ct[5] << 16) |
1607                     ((uint32_t)ct[6] << 8) | (uint32_t)ct[7]);
1608 
1609                 buffer[2] = (((uint32_t)ct[8] << 24) | ((uint32_t)ct[9] << 16) |
1610                     ((uint32_t)ct[10] << 8) | (uint32_t)ct[11]);
1611 
1612                 buffer[3] = (((uint32_t)ct[12] << 24) |
1613                     ((uint32_t)ct[13] << 16) | ((uint32_t)ct[14] << 8) |
1614                     (uint32_t)ct[15]);
1615 #endif
1616 
1617                 AES_DECRYPT_IMPL(&ksch->decr_ks.ks32[0], ksch->nr,
1618                     buffer, buffer);
1619 
1620                 /* Copy result from buffer to output block */
1621 #ifndef AES_BYTE_SWAP
1622                 bcopy(&buffer, pt, AES_BLOCK_LEN);
1623         }
1624 
1625 #else   /* byte swap */
1626                 pt[0] = buffer[0] >> 24;
1627                 pt[1] = buffer[0] >> 16;
1628                 pt[2] = buffer[0] >> 8;
1629                 pt[3] = (uint8_t)buffer[0];
1630                 pt[4] = buffer[1] >> 24;
1631                 pt[5] = buffer[1] >> 16;
1632                 pt[6] = buffer[1] >> 8;
1633                 pt[7] = (uint8_t)buffer[1];
1634                 pt[8] = buffer[2] >> 24;
1635                 pt[9] = buffer[2] >> 16;
1636                 pt[10] = buffer[2] >> 8;
1637                 pt[11] = (uint8_t)buffer[2];
1638                 pt[12] = buffer[3] >> 24;
1639                 pt[13] = buffer[3] >> 16;
1640                 pt[14] = buffer[3] >> 8;
1641                 pt[15] = (uint8_t)buffer[3];
1642 #endif
1643 
1644 /* EXPORT DELETE END */
1645         return (CRYPTO_SUCCESS);
1646 }
1647 
1648 
1649 /*
1650  * Allocate key schedule for AES.
1651  *
1652  * Return the pointer and set size to the number of bytes allocated.
1653  * Memory allocated must be freed by the caller when done.
1654  *
1655  * Parameters:
1656  * size         Size of key schedule allocated, in bytes
1657  * kmflag       Flag passed to kmem_alloc(9F); ignored in userland.
1658  */
1659 /* ARGSUSED */
1660 void *
1661 aes_alloc_keysched(size_t *size, int kmflag)




   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 


  26 #include <sys/types.h>
  27 #include <sys/systm.h>
  28 #include <sys/ddi.h>
  29 #include <sys/sysmacros.h>
  30 #include <sys/strsun.h>
  31 #include <netinet/in.h>
  32 #include <sys/crypto/spi.h>
  33 #include <modes/modes.h>
  34 #include "aes_impl.h"
  35 #ifndef _KERNEL
  36 #include <strings.h>
  37 #include <stdlib.h>
  38 #endif  /* !_KERNEL */
  39 
  40 
  41 /*
  42  * This file is derived from the file  rijndael-alg-fst.c  taken from the
  43  * "optimized C code v3.0" on the "rijndael home page"
  44  * http://www.iaik.tu-graz.ac.at/research/krypto/AES/old/~rijmen/rijndael/
  45  * pointed by the NIST web-site http://csrc.nist.gov/archive/aes/


1471          * For _LITTLE_ENDIAN machines (except AMD64), reverse every
1472          * 4 bytes in the key.  On _BIG_ENDIAN and AMD64, copy the key
1473          * without reversing bytes.
1474          * For AMD64, do not byte swap for aes_setupkeys().
1475          *
1476          * SPARCv8/v9 uses a key schedule array with 64-bit elements.
1477          * X86/AMD64  uses a key schedule array with 32-bit elements.
1478          */
1479 #ifndef AES_BYTE_SWAP
1480         if (IS_P2ALIGNED(cipherKey, sizeof (uint64_t))) {
1481                 for (i = 0, j = 0; j < keysize; i++, j += 8) {
1482                         /* LINTED: pointer alignment */
1483                         keyarr.ka64[i] = *((uint64_t *)&cipherKey[j]);
1484                 }
1485         } else {
1486                 bcopy(cipherKey, keyarr.ka32, keysize);
1487         }
1488 
1489 #else   /* byte swap */
1490         for (i = 0, j = 0; j < keysize; i++, j += 4) {
1491                 keyarr.ka32[i] = htonl(*(uint32_t *)&cipherKey[j]);



1492         }
1493 #endif
1494 
1495         aes_setupkeys(newbie, keyarr.ka32, keyBits);
1496 /* EXPORT DELETE END */
1497 }
1498 
1499 /*
1500  * Encrypt one block using AES.
1501  * Align if needed and (for x86 32-bit only) byte-swap.
1502  *
1503  * Parameters:
1504  * ks   Key schedule, of type aes_key_t
1505  * pt   Input block (plain text)
1506  * ct   Output block (crypto text).  Can overlap with pt
1507  */
1508 int
1509 aes_encrypt_block(const void *ks, const uint8_t *pt, uint8_t *ct)
1510 {
1511 /* EXPORT DELETE START */
1512         aes_key_t       *ksch = (aes_key_t *)ks;
1513 
1514 #ifndef AES_BYTE_SWAP
1515         if (IS_P2ALIGNED2(pt, ct, sizeof (uint32_t))) {
1516                 AES_ENCRYPT_IMPL(&ksch->encr_ks.ks32[0], ksch->nr,
1517                     /* LINTED:  pointer alignment */
1518                     (uint32_t *)pt, (uint32_t *)ct);
1519         } else {
1520 #endif
1521                 uint32_t buffer[AES_BLOCK_LEN / sizeof (uint32_t)];
1522 
1523                 /* Copy input block into buffer */
1524 #ifndef AES_BYTE_SWAP
1525                 bcopy(pt, &buffer, AES_BLOCK_LEN);
1526 
1527 #else   /* byte swap */
1528                 buffer[0] = htonl(*(uint32_t *)&pt[0]);
1529                 buffer[1] = htonl(*(uint32_t *)&pt[4]);
1530                 buffer[2] = htonl(*(uint32_t *)&pt[8]);
1531                 buffer[3] = htonl(*(uint32_t *)&pt[12]);





1532 #endif
1533 
1534                 AES_ENCRYPT_IMPL(&ksch->encr_ks.ks32[0], ksch->nr,
1535                     buffer, buffer);
1536 
1537                 /* Copy result from buffer to output block */
1538 #ifndef AES_BYTE_SWAP
1539                 bcopy(&buffer, ct, AES_BLOCK_LEN);
1540         }
1541 
1542 #else   /* byte swap */
1543                 *(uint32_t *)&ct[0] = htonl(buffer[0]);
1544                 *(uint32_t *)&ct[4] = htonl(buffer[1]);
1545                 *(uint32_t *)&ct[8] = htonl(buffer[2]);
1546                 *(uint32_t *)&ct[12] = htonl(buffer[3]);












1547 #endif
1548 /* EXPORT DELETE END */
1549         return (CRYPTO_SUCCESS);
1550 }
1551 
1552 /*
1553  * Decrypt one block using AES.
1554  * Align and byte-swap if needed.
1555  *
1556  * Parameters:
1557  * ks   Key schedule, of type aes_key_t
1558  * ct   Input block (crypto text)
1559  * pt   Output block (plain text). Can overlap with pt
1560  */
1561 int
1562 aes_decrypt_block(const void *ks, const uint8_t *ct, uint8_t *pt)
1563 {
1564 /* EXPORT DELETE START */
1565         aes_key_t       *ksch = (aes_key_t *)ks;
1566 
1567 #ifndef AES_BYTE_SWAP
1568         if (IS_P2ALIGNED2(ct, pt, sizeof (uint32_t))) {
1569                 AES_DECRYPT_IMPL(&ksch->decr_ks.ks32[0], ksch->nr,
1570                     /* LINTED:  pointer alignment */
1571                     (uint32_t *)ct, (uint32_t *)pt);
1572         } else {
1573 #endif
1574                 uint32_t buffer[AES_BLOCK_LEN / sizeof (uint32_t)];
1575 
1576                 /* Copy input block into buffer */
1577 #ifndef AES_BYTE_SWAP
1578                 bcopy(ct, &buffer, AES_BLOCK_LEN);
1579 
1580 #else   /* byte swap */
1581                 buffer[0] = htonl(*(uint32_t *)&ct[0]);
1582                 buffer[1] = htonl(*(uint32_t *)&ct[4]);
1583                 buffer[2] = htonl(*(uint32_t *)&ct[8]);
1584                 buffer[3] = htonl(*(uint32_t *)&ct[12]);








1585 #endif
1586 
1587                 AES_DECRYPT_IMPL(&ksch->decr_ks.ks32[0], ksch->nr,
1588                     buffer, buffer);
1589 
1590                 /* Copy result from buffer to output block */
1591 #ifndef AES_BYTE_SWAP
1592                 bcopy(&buffer, pt, AES_BLOCK_LEN);
1593         }
1594 
1595 #else   /* byte swap */
1596         *(uint32_t *)&pt[0] = htonl(buffer[0]);
1597         *(uint32_t *)&pt[4] = htonl(buffer[1]);
1598         *(uint32_t *)&pt[8] = htonl(buffer[2]);
1599         *(uint32_t *)&pt[12] = htonl(buffer[3]);












1600 #endif
1601 
1602 /* EXPORT DELETE END */
1603         return (CRYPTO_SUCCESS);
1604 }
1605 
1606 
1607 /*
1608  * Allocate key schedule for AES.
1609  *
1610  * Return the pointer and set size to the number of bytes allocated.
1611  * Memory allocated must be freed by the caller when done.
1612  *
1613  * Parameters:
1614  * size         Size of key schedule allocated, in bytes
1615  * kmflag       Flag passed to kmem_alloc(9F); ignored in userland.
1616  */
1617 /* ARGSUSED */
1618 void *
1619 aes_alloc_keysched(size_t *size, int kmflag)