1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 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 2000 by Cisco Systems, Inc. All rights reserved. 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 * 26 * This file contains CRC-32C code use to verify 27 * iSCSI HeaderDigests and DataDigests. 28 */ 29 30 #include <sys/types.h> /* standard types */ 31 #include "iscsi.h" /* contains prototypes */ 32 33 /* 34 * This is the CRC-32C table 35 * Generated with: 36 * width = 32 bits 37 * poly = 0x1EDC6F41 38 * reflect input bytes = true 39 * reflect output bytes = true 40 */ 41 42 uint32_t iscsi_crc32c_table[256] = 43 { 44 0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4, 45 0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB, 46 0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B, 47 0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24, 48 0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B, 49 0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384, 50 0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54, 51 0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B, 52 0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A, 53 0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35, 54 0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5, 55 0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA, 56 0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45, 57 0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A, 58 0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A, 59 0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595, 60 0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48, 61 0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957, 62 0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687, 63 0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198, 64 0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927, 65 0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38, 66 0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8, 67 0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7, 68 0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096, 69 0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789, 70 0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859, 71 0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46, 72 0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9, 73 0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6, 74 0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36, 75 0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829, 76 0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C, 77 0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93, 78 0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043, 79 0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C, 80 0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3, 81 0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC, 82 0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C, 83 0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033, 84 0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652, 85 0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D, 86 0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D, 87 0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982, 88 0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D, 89 0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622, 90 0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2, 91 0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED, 92 0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530, 93 0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F, 94 0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF, 95 0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0, 96 0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F, 97 0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540, 98 0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90, 99 0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F, 100 0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE, 101 0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1, 102 0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321, 103 0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E, 104 0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81, 105 0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E, 106 0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E, 107 0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351 108 }; 109 110 /* 111 * iscsi_crc32c - Steps through buffer one byte at at time, calculates 112 * reflected crc using table. 113 */ 114 uint32_t 115 iscsi_crc32c(void *address, unsigned long length) 116 { 117 uint8_t *buffer = address; 118 uint32_t crc = 0xffffffff, result; 119 #ifdef _BIG_ENDIAN 120 uint8_t byte0, byte1, byte2, byte3; 121 #endif 122 123 ASSERT(address != NULL); 124 125 while (length--) { 126 crc = iscsi_crc32c_table[(crc ^ *buffer++) & 0xFFL] ^ 127 (crc >> 8); 128 } 129 result = crc ^ 0xffffffff; 130 131 #ifdef _BIG_ENDIAN 132 byte0 = (uint8_t)(result & 0xFF); 133 byte1 = (uint8_t)((result >> 8) & 0xFF); 134 byte2 = (uint8_t)((result >> 16) & 0xFF); 135 byte3 = (uint8_t)((result >> 24) & 0xFF); 136 result = ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3); 137 #endif /* _BIG_ENDIAN */ 138 139 return (result); 140 } 141 142 143 /* 144 * iscsi_crc32c_continued - Continues stepping through buffer one 145 * byte at at time, calculates reflected crc using table. 146 */ 147 uint32_t 148 iscsi_crc32c_continued(void *address, unsigned long length, uint32_t crc) 149 { 150 uint8_t *buffer = address; 151 uint32_t result; 152 #ifdef _BIG_ENDIAN 153 uint8_t byte0, byte1, byte2, byte3; 154 #endif 155 156 ASSERT(address != NULL); 157 158 #ifdef _BIG_ENDIAN 159 byte0 = (uint8_t)((crc >> 24) & 0xFF); 160 byte1 = (uint8_t)((crc >> 16) & 0xFF); 161 byte2 = (uint8_t)((crc >> 8) & 0xFF); 162 byte3 = (uint8_t)(crc & 0xFF); 163 crc = ((byte3 << 24) | (byte2 << 16) | (byte1 << 8) | byte0); 164 #endif 165 166 crc = crc ^ 0xffffffff; 167 while (length--) { 168 crc = iscsi_crc32c_table[(crc ^ *buffer++) & 0xFFL] ^ 169 (crc >> 8); 170 } 171 result = crc ^ 0xffffffff; 172 173 #ifdef _BIG_ENDIAN 174 byte0 = (uint8_t)(result & 0xFF); 175 byte1 = (uint8_t)((result >> 8) & 0xFF); 176 byte2 = (uint8_t)((result >> 16) & 0xFF); 177 byte3 = (uint8_t)((result >> 24) & 0xFF); 178 result = ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3); 179 #endif 180 return (result); 181 } 182