/******************************************************************************* * Copyright (C) 2020 Intel Corporation * * Licensed under the Apache License, Version 2.0 (the 'License'); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an 'AS IS' BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions * and limitations under the License. * *******************************************************************************/ /*! * * \file * * \brief SMS4 Cipher Block Chaining mode of operation (CBC) example * * This example demonstrates usage of SMS4 block cipher * run with CBC mode of operation. Decryption scheme. * * The CBC mode of operation is implemented according to the * "NIST Special Publication 800-38A: Recommendation for Block Cipher Modes of * Operation" document: * * https://csrc.nist.gov/publications/detail/sp/800-38a/final * */ #include #include "ippcp.h" #include "examples_common.h" /*! SMS4 block size in bytes */ static const int SMS4_BLOCK_SIZE = 16; /*! Key size in bytes */ static const int KEY_SIZE = 16; /*! Message size in bytes */ static const int SRC_LEN = 16; /*! Plain text */ static Ipp8u plainText[SRC_LEN] = { 0xAA,0xAA,0xAA,0xAA,0xBB,0xBB,0xBB,0xBB, 0xCC,0xCC,0xCC,0xCC,0xDD,0xDD,0xDD,0xDD }; /*! Cipher text */ static Ipp8u cipherText[SRC_LEN] = { 0x78,0xEB,0xB1,0x1C,0xC4,0x0B,0x0A,0x48, 0x31,0x2A,0xAE,0xB2,0x04,0x02,0x44,0xCB }; /*! 128-bit secret key */ static Ipp8u key[KEY_SIZE] = { 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF, 0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10 }; /*! Initialization vector for CBC mode. * Size of initialization vector for SMS4-CBC shall be equal to the size of SMS4 block (16 bytes). */ static Ipp8u iv[SMS4_BLOCK_SIZE] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F }; /*! Main function */ int main(void) { /* Size of SMS4 context structure. It will be set up in ippsSMS4GetSize(). */ int ctxSize = 0; Ipp8u pOut[SRC_LEN] = {}; /* Internal function status */ IppStatus status = ippStsNoErr; /* Pointer to SMS4 context structure */ IppsSMS4Spec* pSMS4 = 0; do { /* 1. Get size needed for SMS4 context structure */ status = ippsSMS4GetSize(&ctxSize); if (!checkStatus("ippsSMS4GetSize", ippStsNoErr, status)) return status; /* 2. Allocate memory for SMS4 context structure */ pSMS4 = (IppsSMS4Spec*)(new Ipp8u[ctxSize]); if (NULL == pSMS4) { printf("ERROR: Cannot allocate memory (%d bytes) for SMS4 context\n", ctxSize); return -1; } /* 3. Initialize SMS4 context */ status = ippsSMS4Init(key, sizeof(key), pSMS4, ctxSize); if (!checkStatus("ippsSMS4Init", ippStsNoErr, status)) break; /* 4. Decryption */ status = ippsSMS4DecryptCBC(cipherText, pOut, sizeof(cipherText), pSMS4, iv); if (!checkStatus("ippsSMS4DecryptCBC", ippStsNoErr, status)) break; /* Compare decrypted message and reference text */ if (0 != memcmp(pOut, plainText, sizeof(plainText))) { printf("ERROR: Decrypted and reference messages do not match\n"); break; } } while (0); /* 5. Remove secret and release resources */ ippsSMS4Init(0, KEY_SIZE, pSMS4, ctxSize); if (pSMS4) delete [] (Ipp8u*)pSMS4; PRINT_EXAMPLE_STATUS("ippsSMS4DecryptCBC", "SMS4-CBC Decryption", !status) return status; }