├── .gitignore ├── AUTHORS ├── Doxyfile ├── INSTALL ├── LICENSE ├── LICENSE.GPL2 ├── Makefile ├── README.md ├── src ├── .gitignore ├── Makefile ├── SecureBlockDeviceInterface.h ├── config.h ├── crypto │ ├── .gitignore │ ├── .license_exclude │ ├── Makefile │ ├── ae.h │ ├── aes.c │ ├── aes.h │ ├── nwd-perf.c │ ├── nwd-stopwatch.c │ ├── nwd-stopwatch.h │ ├── ocb.c │ ├── rijndael-alg-fst.c │ ├── rijndael-alg-fst.h │ ├── sbdi_hmac.c │ ├── sbdi_hmac.h │ ├── sbdi_nocrypto.c │ ├── sbdi_nocrypto.h │ ├── sbdi_ocb.c │ ├── sbdi_ocb.h │ ├── sbdi_siv.c │ ├── sbdi_siv.h │ ├── siv.c │ └── siv.h ├── sbdi.c ├── sbdi_blic.h ├── sbdi_block.c ├── sbdi_block.h ├── sbdi_buffer.c ├── sbdi_buffer.h ├── sbdi_cache.c ├── sbdi_cache.h ├── sbdi_config.h ├── sbdi_crypto.h ├── sbdi_crypto_type.h ├── sbdi_ctr_128b.c ├── sbdi_ctr_128b.h ├── sbdi_debug.c ├── sbdi_debug.h ├── sbdi_err.h ├── sbdi_hdr.c ├── sbdi_hdr.h ├── sbdi_pio.c ├── sbdi_pio.h └── sbdi_test.c └── tests ├── .gitignore ├── AesSivTest.cpp ├── Makefile ├── SbdiBlockLayerTest.cpp ├── SbdiCacheTest.cpp ├── SbdiCtrTest.cpp ├── SbdiTest.cpp ├── SbdiTest.h ├── SbdiTestRunner.cpp ├── siv_test_vectors_1.txt └── siv_test_vectors_2.txt /.gitignore: -------------------------------------------------------------------------------- 1 | *.gcda 2 | *.gcno 3 | sbdi_tst_enc 4 | .cproject 5 | .project 6 | .settings 7 | .*.swp 8 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Authors of the Secure Block Device 2 | 3 | The first version of the Secure Block Device was written by Daniel Hein 4 | (daniel.hein@iaik.tugraz.at), with contributions from Johannes Winter 5 | (johannes.winter@iaik.tugraz.at), and Andreas Fitzek 6 | (andreas.fitzek@iaik.tugraz.at). 7 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | Installing the Secure Block Device 2 | 3 | The Secure Block Device Library is a software library intended for linking to 4 | your software, it is therefore not installed. See README for details on how to 5 | build and use the Secure Block Device. 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | === 1. License === 2 | 3 | Copyright (c) IAIK, Graz University of Technology, 2014, 2015. 4 | All rights reserved. 5 | 6 | The Secure Block Device Library is released under a dual licensing model: 7 | 8 | * For Open Source development, the Secure Block Device Library is licensed under the terms of the GNU 9 | GPL version 2. The full text of the GNU GPL v2 is shipped with the product (see LICENSE.GPL2) 10 | or can be found online at https://www.gnu.org/licenses/gpl-2.0.html. 11 | 12 | * In all other cases, the "Stiftung SIC Java (tm) Crypto-Software Development Kit Licence Agreement" 13 | applies. The full license text can be found online at Stiftung SIC. For pricing and further information 14 | please contact jce-sales@iaik.at. 15 | 16 | === 2. 3rd Party Software Sources === 17 | 18 | The Secure Block Device Library uses the following 3rd party software source 19 | files for implementing the following components: SHA-256, AES, SIV, and OCB. 20 | In the following we detail which files belong to which component and the 21 | respective licenses for using these source files. 22 | 23 | === 2.1 SHA-256 === 24 | 25 | === 2.1.1 Files === 26 | 27 | src/sha.h - from RFC 4634, Section 8.1 28 | src/sha224-256.c - from RFC 4634, Section 8.2.2 29 | 30 | === 2.1.2 License === 31 | (From RFC 4634 - 1.1 License) 32 | 33 | Permission is granted for all uses, commercial and non-commercial, of the 34 | sample code found in Section 8. Royalty free license to use, copy, modify and 35 | distribute the software found in Section 8 is granted, provided that this 36 | document is identified in all material mentioning or referencing this software, 37 | and provided that redistributed derivative works do not contain misleading 38 | author or version information. 39 | 40 | The authors make no representations concerning either the merchantability of 41 | this software or the suitability of this software for any particular purpose. 42 | It is provided "as is" without express or implied warranty of any kind. 43 | 44 | === 2.2 AES === 45 | 46 | === 2.2.1 Files === 47 | 48 | src/crypto/aes.c 49 | src/crypto/aes.h 50 | src/crypto/rijndael-alg-fst.c 51 | src/crypto/rijndael-alg-fst.h 52 | 53 | === 2.2.2 Licence === 54 | 55 | === 2.2.2.1 aes.c aes.h === 56 | (Excerpt from source documentation) 57 | 58 | Copyright (c) 2003-2004 Kungliga Tekniska Högskolan 59 | (Royal Institute of Technology, Stockholm, Sweden). 60 | All rights reserved. 61 | 62 | Redistribution and use in source and binary forms, with or without 63 | modification, are permitted provided that the following conditions 64 | are met: 65 | 66 | 1. Redistributions of source code must retain the above copyright 67 | notice, this list of conditions and the following disclaimer. 68 | 69 | 2. Redistributions in binary form must reproduce the above copyright 70 | notice, this list of conditions and the following disclaimer in the 71 | documentation and/or other materials provided with the distribution. 72 | 73 | 3. Neither the name of the Institute nor the names of its contributors 74 | may be used to endorse or promote products derived from this software 75 | without specific prior written permission. 76 | 77 | THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 78 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 79 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 80 | ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 81 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 82 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 83 | OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 84 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 85 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 86 | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 87 | SUCH DAMAGE. 88 | 89 | === 2.2.2.1 rijndael-alg-fst.c rijndael-alg-fst.h === 90 | (Excerpt from source documentation) 91 | 92 | Optimised ANSI C code for the Rijndael cipher (now AES) 93 | 94 | @author Vincent Rijmen 95 | @author Antoon Bosselaers 96 | @author Paulo Barreto 97 | 98 | This code is hereby placed in the public domain. 99 | 100 | THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS 101 | OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 102 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 103 | ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE 104 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 105 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 106 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 107 | BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 108 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 109 | OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 110 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 111 | 112 | === 2.3 SIV === 113 | 114 | === 2.3.1 Files === 115 | 116 | src/crypto/siv.c 117 | src/crypto/siv.h 118 | 119 | === 2.2.2 Licence === 120 | (Excerpt from source documentation) 121 | 122 | Copyright (c) The Industrial Lounge, 2007 123 | 124 | Copyright holder grants permission for redistribution and use in source 125 | and binary forms, with or without modification, provided that the 126 | following conditions are met: 127 | 1. Redistribution of source code must retain the above copyright 128 | notice, this list of conditions, and the following disclaimer 129 | in all source files. 130 | 2. Redistribution in binary form must retain the above copyright 131 | notice, this list of conditions, and the following disclaimer 132 | in the documentation and/or other materials provided with the 133 | distribution. 134 | 3. All advertising materials and documentation mentioning features 135 | or use of this software must display the following acknowledgement: 136 | 137 | "This product includes software written by 138 | Dan Harkins (dharkins at lounge dot org)" 139 | 140 | "DISCLAIMER OF LIABILITY 141 | 142 | THIS SOFTWARE IS PROVIDED BY THE INDUSTRIAL LOUNGE ``AS IS'' 143 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 144 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 145 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INDUSTRIAL LOUNGE BE LIABLE 146 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 147 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 148 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 149 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 150 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 151 | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 152 | SUCH DAMAGE." 153 | 154 | This license and distribution terms cannot be changed. In other words, 155 | this code cannot simply be copied and put under another distribution 156 | license (including the GNU public license). 157 | 158 | === 2.3 OCB === 159 | 160 | Note that Phillip Rogaway holds patents relevant to OCB. See the following for 161 | his patent grant: http://www.cs.ucdavis.edu/~rogaway/ocb/grant.htm 162 | 163 | === 2.3.1 Files === 164 | 165 | src/crypto/ae.h 166 | src/crypto/ocb.c 167 | 168 | === 2.3.2 Licence === 169 | (Excerpt from source documentation) 170 | 171 | === 2.3.2.1 ocb.c === 172 | 173 | OCB Version 3 Reference Code (Optimized C) Last modified 12-JUN-2013 174 | ------------------------------------------------------------------------ 175 | Copyright (c) 2013 Ted Krovetz. 176 | 177 | Permission to use, copy, modify, and/or distribute this software for any 178 | purpose with or without fee is hereby granted, provided that the above 179 | copyright notice and this permission notice appear in all copies. 180 | 181 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 182 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 183 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 184 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 185 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 186 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 187 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 188 | 189 | Phillip Rogaway holds patents relevant to OCB. See the following for 190 | his patent grant: http://www.cs.ucdavis.edu/~rogaway/ocb/grant.htm 191 | 192 | Special thanks to Keegan McAllister for suggesting several good improvements 193 | 194 | Comments are welcome: Ted Krovetz - Dedicated to Laurel K 195 | 196 | === 2.3.2.2 ae.h === 197 | 198 | AEAD API 0.12 - 23-MAY-2012 199 | 200 | This file gives an interface appropriate for many authenticated 201 | encryption with associated data (AEAD) implementations. It does not try 202 | to accommodate all possible options or limitations that an implementation 203 | might have -- you should consult the documentation of your chosen 204 | implementation to find things like RFC 5116 constants, alignment 205 | requirements, whether the incremental interface is supported, etc. 206 | 207 | This file is in the public domain. It is provided "as is", without 208 | warranty of any kind. Use at your own risk. 209 | 210 | Comments are welcome: Ted Krovetz . 211 | 212 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # allows to call make Q= all and quiet will be disabled 2 | Q=@ 3 | 4 | .PHONY: clean doc 5 | 6 | all: debug 7 | 8 | release: 9 | $(Q)$(MAKE) -C src/crypto release 10 | $(Q)$(MAKE) -C src/ release 11 | -$(Q)$(MAKE) -C tests/ all 12 | 13 | debug: 14 | $(Q)$(MAKE) -C src/crypto debug 15 | $(Q)$(MAKE) -C src/ debug 16 | $(Q)$(MAKE) -C tests/ all 17 | 18 | coverage: 19 | $(Q)$(MAKE) -C src/crypto coverage 20 | $(Q)$(MAKE) -C src/ coverage 21 | $(Q)$(MAKE) -C tests/ coverage 22 | 23 | clean: 24 | $(Q)$(MAKE) -C src/crypto clean 25 | $(Q)$(MAKE) -C tests/ clean 26 | $(Q)$(MAKE) -C src/ clean 27 | $(Q)rm -Rf doc 28 | 29 | test: 30 | $(Q)$(MAKE) -C tests/ test 31 | 32 | doc: 33 | $(Q)doxygen 34 | -------------------------------------------------------------------------------- /src/.gitignore: -------------------------------------------------------------------------------- 1 | .depend 2 | libSecureBlock.a 3 | *.o 4 | sbdi-test 5 | -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | Q = @ 2 | CFLAGS +=-Wall -Werror -pedantic -std=gnu99 3 | 4 | DEPENDFILE = .depend 5 | LIB_SRC = sbdi.c sbdi_hdr.c sbdi_block.c sbdi_ctr_128b.c sbdi_cache.c sbdi_buffer.c sbdi_pio.c sbdi_debug.c 6 | PRG_SRC = sbdi_test.c 7 | SRC = $(LIB_SRC) $(PRG_SRC) 8 | LIB_OBJS = $(LIB_SRC:%.c=%.o) 9 | PRG_OBJS = $(PRG_SRC:%.c=%.o) 10 | OBJS = $(LIB_OBJS) $(PRG_OBJS) 11 | LIB = libSecureBlock.a 12 | EXT_INC = -I. -I../../merkle-tree/src -I./crypto 13 | EXT_LIB = -L../../merkle-tree/src -L./crypto -lMerkleTree -lSbdiCrypto 14 | BIN = sbdi-test 15 | 16 | CFLAGS += $(EXT_INC) $(EXTRA_CFLAGS) 17 | LDFLAGS += $(EXT_LIB) $(EXTRA_LDFLAGS) 18 | 19 | all: debug 20 | 21 | debug: LDFLAGS +=-ggdb 22 | debug: CFLAGS +=-ggdb -DSBDI_DEBUG 23 | debug: dep $(BIN) 24 | 25 | coverage: LDFLAGS +=-ggdb -coverage 26 | coverage: CFLAGS +=-ggdb -fprofile-arcs -ftest-coverage 27 | coverage: dep $(BIN) 28 | 29 | #silent: CFLAGS +=-ggdb -pg 30 | silent: CFLAGS +=-ggdb 31 | silent: clean dep $(BIN) 32 | 33 | release: CFLAGS +=-O3 -fgnu89-inline -DNDEBUG -Wno-error=unused-function 34 | release: clean dep $(BIN) 35 | 36 | .PHONY: clean 37 | clean: 38 | $(Q)rm -Rf $(BIN) $(OBJS) $(LIB) html latex .depend *.gcov *.gcno *.gcda 39 | 40 | $(BIN) : $(PRG_OBJS) $(LIB) 41 | $(Q)$(CC) $(CFLAGS) -o $(BIN) $(PRG_OBJS) $(LIB) $(LDFLAGS) 42 | 43 | $(LIB): $(LIB_OBJS) 44 | $(Q)$(AR) crvs $(LIB) $(LIB_OBJS) 45 | 46 | dep: $(SRC) 47 | $(Q)$(CC) $(EXT_INC) -MM $(SRC) > $(DEPENDFILE) 48 | 49 | -include $(DEPENDFILE) 50 | -------------------------------------------------------------------------------- /src/SecureBlockDeviceInterface.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) IAIK, Graz University of Technology, 2015. 2 | * All rights reserved. 3 | * Contact: http://opensource.iaik.tugraz.at 4 | * 5 | * This file is part of the Secure Block Device Library. 6 | * 7 | * Commercial License Usage 8 | * Licensees holding valid commercial licenses may use this file in 9 | * accordance with the commercial license agreement provided with the 10 | * Software or, alternatively, in accordance with the terms contained in 11 | * a written agreement between you and SIC. For further information 12 | * contact us at http://opensource.iaik.tugraz.at. 13 | * 14 | * Alternatively, this file may be used under the terms of the GNU General 15 | * Public License as published by the Free Software Foundation version 2. 16 | * 17 | * The Secure Block Device Library is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 20 | * Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with the Secure Block Device Library. If not, see . 24 | */ 25 | /// 26 | /// \file 27 | /// \brief Specifies the Secure Block Device Library's application programmer 28 | /// interface. 29 | /// 30 | /// The SBD API is modeled after the POSIX file abstraction. 31 | /// 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | #ifndef SECURE_BLOCK_DEVICE_INTERFACE_H_ 38 | #define SECURE_BLOCK_DEVICE_INTERFACE_H_ 39 | 40 | #include "sbdi_config.h" 41 | #include "sbdi_pio.h" 42 | #include "sbdi_crypto.h" 43 | #include "sbdi_cache.h" 44 | #include "sbdi_ctr_128b.h" 45 | #include "sbdi_block.h" 46 | #include "sbdi_hdr.h" 47 | #include "sbdi_crypto_type.h" 48 | 49 | #include 50 | #include 51 | 52 | /*! 53 | * \brief converts a Merkle tree error into a secure block device interface 54 | * error 55 | * 56 | * @param mr the Merkle tree error code 57 | * @return the corresponding secure block device interface error code 58 | */ 59 | static inline sbdi_error_t sbdi_mt_sbdi_err_conv(mt_error_t mr) 60 | { 61 | switch (mr) { 62 | case MT_SUCCESS: 63 | return SBDI_SUCCESS; 64 | case MT_ERR_OUT_Of_MEMORY: 65 | return SBDI_ERR_OUT_Of_MEMORY; 66 | case MT_ERR_ILLEGAL_PARAM: 67 | return SBDI_ERR_ILLEGAL_PARAM; 68 | case MT_ERR_ILLEGAL_STATE: 69 | return SBDI_ERR_ILLEGAL_STATE; 70 | case MT_ERR_ROOT_MISMATCH: 71 | return SBDI_ERR_TAG_MISMATCH; 72 | case MT_ERR_UNSPECIFIED: 73 | return SBDI_ERR_UNSPECIFIED; 74 | default: 75 | return SBDI_ERR_UNSUPPORTED; 76 | } 77 | } 78 | 79 | typedef uint8_t sbdi_sym_mst_key_t[32]; 80 | 81 | /*! 82 | * \brief enumeration type for defining secure block device lseek constants 83 | */ 84 | typedef enum sbdi_whence { 85 | SBDI_SEEK_SET = 1, //!< SBDI_SEEK_SET 86 | SBDI_SEEK_CUR = 2, //!< SBDI_SEEK_CUR 87 | SBDI_SEEK_END = 3 //!< SBDI_SEEK_END 88 | } sbdi_whence_t; 89 | 90 | struct secure_block_device_interface { 91 | sbdi_pio_t *pio; 92 | sbdi_crypto_t *crypto; 93 | void *mt; 94 | sbdi_hdr_v1_t *hdr; 95 | sbdi_bc_t *cache; 96 | sbdi_bl_data_t write_store_dat[2]; 97 | sbdi_block_t write_store[2]; 98 | size_t offset; 99 | }; 100 | 101 | sbdi_t *sbdi_create(sbdi_pio_t *pioypto); 102 | void sbdi_delete(sbdi_t *sbdi); 103 | 104 | sbdi_error_t sbdi_open(sbdi_t **s, sbdi_pio_t *pio, sbdi_crypto_type_t ct, sbdi_sym_mst_key_t mkey, 105 | mt_hash_t root); 106 | sbdi_error_t sbdi_close(sbdi_t *sbdi, sbdi_sym_mst_key_t mkey, mt_hash_t root); 107 | 108 | sbdi_error_t sbdi_pread(ssize_t *rd, sbdi_t *sbdi, void *buf, size_t nbyte, 109 | off_t offset); 110 | sbdi_error_t sbdi_pwrite(ssize_t *wr, sbdi_t *sbdi, const void *buf, 111 | size_t nbyte, off_t offset); 112 | 113 | sbdi_error_t sbdi_read(ssize_t *rd, sbdi_t *sbdi, void *buf, size_t nbyte); 114 | sbdi_error_t sbdi_write(ssize_t *wr, sbdi_t *sbdi, const void *buf, 115 | size_t nbyte); 116 | 117 | sbdi_error_t sbdi_lseek(off_t *new_off, sbdi_t *sbdi, off_t offset, 118 | sbdi_whence_t whence); 119 | 120 | sbdi_error_t sbdi_fsync(sbdi_t *sbdi, sbdi_sym_mst_key_t mkey); 121 | sbdi_error_t sbdi_sync(sbdi_t *sbdi, sbdi_sym_mst_key_t mkey, mt_hash_t root); 122 | 123 | #endif /* SECURE_BLOCK_DEVICE_INTERFACE_H_ */ 124 | 125 | #ifdef __cplusplus 126 | } 127 | #endif 128 | -------------------------------------------------------------------------------- /src/config.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) IAIK, Graz University of Technology, 2015. 2 | * All rights reserved. 3 | * Contact: http://opensource.iaik.tugraz.at 4 | * 5 | * This file is part of the Secure Block Device Library. 6 | * 7 | * Commercial License Usage 8 | * Licensees holding valid commercial licenses may use this file in 9 | * accordance with the commercial license agreement provided with the 10 | * Software or, alternatively, in accordance with the terms contained in 11 | * a written agreement between you and SIC. For further information 12 | * contact us at http://opensource.iaik.tugraz.at. 13 | * 14 | * Alternatively, this file may be used under the terms of the GNU General 15 | * Public License as published by the Free Software Foundation version 2. 16 | * 17 | * The Secure Block Device Library is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 20 | * Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with the Secure Block Device Library. If not, see . 24 | */ 25 | /// 26 | /// \file 27 | /// \brief Global compile time configuration options for the Secure Block 28 | /// Device Library. 29 | /// 30 | #ifndef CONFIG_H_ 31 | #define CONFIG_H_ 32 | 33 | // NOTE Requirement MAX BLOCK INDEX < UINT32_MAX! 34 | #define SBDI_BLOCK_SIZE 2048u //!< The block size of the secure block device interface 35 | #define SBDI_SIZE_MAX UINT32_C(2147483647) //!< The maximum size in bytes of the secure block device interface 36 | #define SBDI_BLK_MAX_LOG (SBDI_SIZE_MAX / SBDI_BLOCK_SIZE) + (((SBDI_SIZE_MAX % SBDI_BLOCK_SIZE) > 0)?1:0) //!< The maximum number of logical blocks supported by the secure block device interface 37 | #define SBDI_BLOCK_CTR_SIZE 16u //!< The size in bytes of the counter (nonce) used to make every block write unique 38 | #define SBDI_BLOCK_TAG_SIZE 16u //!< The size in bytes of a cryptographic block tag (a mac over a single block) 39 | #define SBDI_MNGT_BLOCK_ENTRIES (SBDI_BLOCK_SIZE/(SBDI_BLOCK_CTR_SIZE + SBDI_BLOCK_TAG_SIZE)) //!< The number of tag/counter entries in a management block 40 | #define SBDI_BLK_MAX_PHY ((SBDI_BLK_MAX_LOG) + ((SBDI_BLK_MAX_LOG)/(SBDI_MNGT_BLOCK_ENTRIES)) + 2) //!< The maximum number of physical blocks supported by the secure block device interface 41 | #define SBDI_CRYPTO_TYPE_NONE 65535u //!< Cryptographic abstraction layer that implements all crypto implementations as NOPs 42 | #define SBDI_CRYPTO_TYPE_SIV 1u //!< Cryptographic abstraction layer that uses SIV and CMAC for its cryptographic operations 43 | #define SBDI_CRYPTO_TYPE_OCB 2u //!< Cryptographic abstraction layer that uses OCB and CMAC for its cryptographic operations 44 | #define SBDI_CRYPTO_TYPE_HMAC 3u //!< Cryptographic abstraction layer that uses CBC and HMAC for its cryptographic operations 45 | /* Enable runtime cryptographic abstraction layer selection */ 46 | #undef SBDI_CRYPTO_TYPE 47 | // #define SBDI_CRYPTO_TYPE SBDI_CRYPTO_TYPE_OCB /*!< Specify which kind of cryptography to use as default */ 48 | 49 | #define SBDI_CACHE_MAX_SIZE 16u 50 | #define SBDI_CACHE_PROFILE 51 | 52 | #endif /* CONFIG_H_ */ 53 | -------------------------------------------------------------------------------- /src/crypto/.gitignore: -------------------------------------------------------------------------------- 1 | libSbdiCrypto.a 2 | sbdi-crypto-test 3 | /nwd-crypto-perf 4 | *~ 5 | -------------------------------------------------------------------------------- /src/crypto/.license_exclude: -------------------------------------------------------------------------------- 1 | ae.h 2 | aes.c 3 | aes.h 4 | ocb.c 5 | rijndael-alg-fst.c 6 | rijndael-alg-fst.h 7 | siv.c 8 | siv.h 9 | -------------------------------------------------------------------------------- /src/crypto/Makefile: -------------------------------------------------------------------------------- 1 | Q = @ 2 | CFLAGS +=-Wall -Werror -pedantic -std=gnu99 3 | CPPFLAGS = -I../ 4 | 5 | DEPENDFILE = .depend 6 | LIB_SRC = rijndael-alg-fst.c aes.c ocb.c siv.c sbdi_nocrypto.c sbdi_ocb.c sbdi_siv.c sbdi_hmac.c 7 | SRC = $(LIB_SRC) 8 | LIB_OBJS = $(LIB_SRC:%.c=%.o) 9 | OBJS = $(LIB_OBJS) 10 | LIB = libSbdiCrypto.a 11 | EXT_LIB = 12 | 13 | NWD_PERF_SRC = nwd-perf.c nwd-stopwatch.c 14 | NWD_PERF_OBJS = $(NWD_PERF_SRC:%.c=%.o) 15 | NWD_PERF_APP = nwd-crypto-perf 16 | 17 | OBJS += $(NWD_PERF_OBJS) 18 | 19 | CFLAGS += $(CPPFLAGS) $(EXTRA_CFLAGS) 20 | LDFLAGS += $(EXT_LIB) $(EXTRA_LDFLAGS) 21 | 22 | all: debug 23 | 24 | debug: LDFLAGS +=-ggdb 25 | debug: CFLAGS +=-ggdb 26 | debug: dep $(LIB) $(NWD_PERF_APP) 27 | 28 | coverage: LDFLAGS +=-ggdb -coverage 29 | coverage: CFLAGS +=-ggdb -fprofile-arcs -ftest-coverage 30 | coverage: dep $(LIB) $(NWD_PERF_APP) 31 | 32 | #silent: CFLAGS +=-ggdb -pg 33 | silent: CFLAGS +=-ggdb 34 | silent: clean dep $(LIB) $(NWD_PERF_APP) 35 | 36 | release: CFLAGS +=-O3 -fgnu89-inline -DNDEBUG -Wno-error=unused-function 37 | release: clean dep $(LIB) $(NWD_PERF_APP) 38 | 39 | .PHONY: clean doc 40 | clean: 41 | $(Q)rm -Rf $(NWD_PERF_APP) $(OBJS) $(LIB) html latex .depend *.gcov *.gcno *.gcda 42 | 43 | doc: 44 | $(Q)doxygen 45 | 46 | $(LIB): $(LIB_OBJS) 47 | $(Q)$(AR) crvs $(LIB) $(LIB_OBJS) 48 | 49 | dep: $(SRC) 50 | $(Q)$(CC) $(CPPFLAGS) -MM $(SRC) > $(DEPENDFILE) 51 | 52 | # Normal world performance test app 53 | $(NWD_PERF_OBJS): CFLAGS += -I. -I.. -I../../../merkle-tree/src 54 | $(NWD_PERF_APP): LDFLAGS += 55 | $(NWD_PERF_APP): LIBS += -L ../../../merkle-tree/src -L. -lSbdiCrypto -lMerkleTree -lrt -lm 56 | 57 | $(NWD_PERF_APP): $(NWD_PERF_OBJS) $(LIB) 58 | $(Q)$(CC) -o$@ $(LDFLAGS) $(NWD_PERF_OBJS) $(LIBS) 59 | 60 | 61 | -include $(DEPENDFILE) 62 | -------------------------------------------------------------------------------- /src/crypto/ae.h: -------------------------------------------------------------------------------- 1 | /* --------------------------------------------------------------------------- 2 | * 3 | * AEAD API 0.12 - 23-MAY-2012 4 | * 5 | * This file gives an interface appropriate for many authenticated 6 | * encryption with associated data (AEAD) implementations. It does not try 7 | * to accommodate all possible options or limitations that an implementation 8 | * might have -- you should consult the documentation of your chosen 9 | * implementation to find things like RFC 5116 constants, alignment 10 | * requirements, whether the incremental interface is supported, etc. 11 | * 12 | * This file is in the public domain. It is provided "as is", without 13 | * warranty of any kind. Use at your own risk. 14 | * 15 | * Comments are welcome: Ted Krovetz . 16 | * 17 | * ------------------------------------------------------------------------ */ 18 | 19 | #ifndef _AE_H_ 20 | #define _AE_H_ 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | /* -------------------------------------------------------------------------- 27 | * 28 | * Constants 29 | * 30 | * ----------------------------------------------------------------------- */ 31 | 32 | /* Return status codes: Negative return values indicate an error occurred. 33 | * For full explanations of error values, consult the implementation's 34 | * documentation. */ 35 | #define AE_SUCCESS ( 0) /* Indicates successful completion of call */ 36 | #define AE_INVALID (-1) /* Indicates bad tag during decryption */ 37 | #define AE_NOT_SUPPORTED (-2) /* Indicates unsupported option requested */ 38 | 39 | /* Flags: When data can be processed "incrementally", these flags are used 40 | * to indicate whether the submitted data is the last or not. */ 41 | #define AE_FINALIZE (1) /* This is the last of data */ 42 | #define AE_PENDING (0) /* More data of is coming */ 43 | 44 | /* -------------------------------------------------------------------------- 45 | * 46 | * AEAD opaque structure definition 47 | * 48 | * ----------------------------------------------------------------------- */ 49 | 50 | typedef struct _ae_ctx ae_ctx; 51 | 52 | /* -------------------------------------------------------------------------- 53 | * 54 | * Data Structure Routines 55 | * 56 | * ----------------------------------------------------------------------- */ 57 | 58 | ae_ctx* ae_allocate (void *misc); /* Allocate ae_ctx, set optional ptr */ 59 | void ae_free (ae_ctx *ctx); /* Deallocate ae_ctx struct */ 60 | int ae_clear (ae_ctx *ctx); /* Undo initialization */ 61 | int ae_ctx_sizeof(void); /* Return sizeof(ae_ctx) */ 62 | /* ae_allocate() allocates an ae_ctx structure, but does not initialize it. 63 | * ae_free() deallocates an ae_ctx structure, but does not zero it. 64 | * ae_clear() zeroes sensitive values associated with an ae_ctx structure 65 | * and deallocates any auxiliary structures allocated during ae_init(). 66 | * ae_ctx_sizeof() returns sizeof(ae_ctx), to aid in any static allocations. 67 | */ 68 | 69 | /* -------------------------------------------------------------------------- 70 | * 71 | * AEAD Routines 72 | * 73 | * ----------------------------------------------------------------------- */ 74 | 75 | int ae_init(ae_ctx *ctx, 76 | const void *key, 77 | int key_len, 78 | int nonce_len, 79 | int tag_len); 80 | /* -------------------------------------------------------------------------- 81 | * 82 | * Initialize an ae_ctx context structure. 83 | * 84 | * Parameters: 85 | * ctx - Pointer to an ae_ctx structure to be initialized 86 | * key - Pointer to user-supplied key 87 | * key_len - Length of key supplied, in bytes 88 | * nonce_len - Length of nonces to be used for this key, in bytes 89 | * tag_len - Length of tags to be produced for this key, in bytes 90 | * 91 | * Returns: 92 | * AE_SUCCESS - Success. Ctx ready for use. 93 | * AE_NOT_SUPPORTED - An unsupported length was supplied. Ctx is untouched. 94 | * Otherwise - Error. Check implementation documentation for codes. 95 | * 96 | * ----------------------------------------------------------------------- */ 97 | 98 | int ae_encrypt(ae_ctx *ctx, 99 | const void *nonce, 100 | const void *pt, 101 | int pt_len, 102 | const void *ad, 103 | int ad_len, 104 | void *ct, 105 | void *tag, 106 | int final); 107 | /* -------------------------------------------------------------------------- 108 | * 109 | * Encrypt plaintext; provide for authentication of ciphertext/associated data. 110 | * 111 | * Parameters: 112 | * ctx - Pointer to an ae_ctx structure initialized by ae_init. 113 | * nonce - Pointer to a nonce_len (defined in ae_init) byte nonce. 114 | * pt - Pointer to plaintext bytes to be encrypted. 115 | * pt_len - number of bytes pointed to by pt. 116 | * ad - Pointer to associated data. 117 | * ad_len - number of bytes pointed to by ad. 118 | * ct - Pointer to buffer to receive ciphertext encryption. 119 | * tag - Pointer to receive authentication tag; or NULL 120 | * if tag is to be bundled into the ciphertext. 121 | * final - Non-zero if this call completes the plaintext being encrypted. 122 | * 123 | * If nonce!=NULL then a message is being initiated. If final!=0 124 | * then a message is being finalized. If final==0 or nonce==NULL 125 | * then the incremental interface is being used. If nonce!=NULL and 126 | * ad_len<0, then use same ad as last message. 127 | * 128 | * Returns: 129 | * non-negative - Number of bytes written to ct. 130 | * AE_NOT_SUPPORTED - Usage mode unsupported (eg, incremental and/or sticky). 131 | * Otherwise - Error. Check implementation documentation for codes. 132 | * 133 | * ----------------------------------------------------------------------- */ 134 | 135 | int ae_decrypt(ae_ctx *ctx, 136 | const void *nonce, 137 | const void *ct, 138 | int ct_len, 139 | const void *ad, 140 | int ad_len, 141 | void *pt, 142 | const void *tag, 143 | int final); 144 | /* -------------------------------------------------------------------------- 145 | * 146 | * Decrypt ciphertext; provide authenticity of plaintext and associated data. 147 | * 148 | * Parameters: 149 | * ctx - Pointer to an ae_ctx structure initialized by ae_init. 150 | * nonce - Pointer to a nonce_len (defined in ae_init) byte nonce. 151 | * ct - Pointer to ciphertext bytes to be decrypted. 152 | * ct_len - number of bytes pointed to by ct. 153 | * ad - Pointer to associated data. 154 | * ad_len - number of bytes pointed to by ad. 155 | * pt - Pointer to buffer to receive plaintext decryption. 156 | * tag - Pointer to tag_len (defined in ae_init) bytes; or NULL 157 | * if tag is bundled into the ciphertext. Non-NULL tag is only 158 | * read when final is non-zero. 159 | * final - Non-zero if this call completes the ciphertext being decrypted. 160 | * 161 | * If nonce!=NULL then "ct" points to the start of a ciphertext. If final!=0 162 | * then "in" points to the final piece of ciphertext. If final==0 or nonce== 163 | * NULL then the incremental interface is being used. If nonce!=NULL and 164 | * ad_len<0, then use same ad as last message. 165 | * 166 | * Returns: 167 | * non-negative - Number of bytes written to pt. 168 | * AE_INVALID - Authentication failure. 169 | * AE_NOT_SUPPORTED - Usage mode unsupported (eg, incremental and/or sticky). 170 | * Otherwise - Error. Check implementation documentation for codes. 171 | * 172 | * NOTE !!! NOTE !!! -- The ciphertext should be assumed possibly inauthentic 173 | * until it has been completely written and it is 174 | * verified that this routine did not return AE_INVALID. 175 | * 176 | * ----------------------------------------------------------------------- */ 177 | 178 | #ifdef __cplusplus 179 | } /* closing brace for extern "C" */ 180 | #endif 181 | 182 | #endif /* _AE_H_ */ 183 | -------------------------------------------------------------------------------- /src/crypto/aes.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2003 Kungliga Tekniska Högskolan 3 | * (Royal Institute of Technology, Stockholm, Sweden). 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * 3. Neither the name of the Institute nor the names of its contributors 18 | * may be used to endorse or promote products derived from this software 19 | * without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 | * SUCH DAMAGE. 32 | */ 33 | 34 | #include "rijndael-alg-fst.h" 35 | #include "aes.h" 36 | 37 | #include 38 | 39 | int 40 | AES_set_encrypt_key(const unsigned char *userkey, const int bits, AES_KEY *key) 41 | { 42 | key->rounds = rijndaelKeySetupEnc(key->key, userkey, bits); 43 | if (key->rounds == 0) 44 | return -1; 45 | return 0; 46 | } 47 | 48 | int 49 | AES_set_decrypt_key(const unsigned char *userkey, const int bits, AES_KEY *key) 50 | { 51 | key->rounds = rijndaelKeySetupDec(key->key, userkey, bits); 52 | if (key->rounds == 0) 53 | return -1; 54 | return 0; 55 | } 56 | 57 | void 58 | AES_encrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key) 59 | { 60 | rijndaelEncrypt(key->key, key->rounds, in, out); 61 | } 62 | 63 | void 64 | AES_decrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key) 65 | { 66 | rijndaelDecrypt(key->key, key->rounds, in, out); 67 | } 68 | 69 | void 70 | AES_cbc_encrypt(const unsigned char *in, unsigned char *out, 71 | unsigned long size, const AES_KEY *key, 72 | unsigned char *iv, int forward_encrypt) 73 | { 74 | unsigned char tmp[AES_BLOCK_SIZE]; 75 | int i; 76 | 77 | if (forward_encrypt) { 78 | while (size >= AES_BLOCK_SIZE) { 79 | for (i = 0; i < AES_BLOCK_SIZE; i++) 80 | tmp[i] = in[i] ^ iv[i]; 81 | AES_encrypt(tmp, out, key); 82 | memcpy(iv, out, AES_BLOCK_SIZE); 83 | size -= AES_BLOCK_SIZE; 84 | in += AES_BLOCK_SIZE; 85 | out += AES_BLOCK_SIZE; 86 | } 87 | if (size) { 88 | for (i = 0; i < size; i++) 89 | tmp[i] = in[i] ^ iv[i]; 90 | for (i = size; i < AES_BLOCK_SIZE; i++) 91 | tmp[i] = iv[i]; 92 | AES_encrypt(tmp, out, key); 93 | memcpy(iv, out, AES_BLOCK_SIZE); 94 | } 95 | } else { 96 | while (size >= AES_BLOCK_SIZE) { 97 | memcpy(tmp, in, AES_BLOCK_SIZE); 98 | AES_decrypt(tmp, out, key); 99 | for (i = 0; i < AES_BLOCK_SIZE; i++) 100 | out[i] ^= iv[i]; 101 | memcpy(iv, tmp, AES_BLOCK_SIZE); 102 | size -= AES_BLOCK_SIZE; 103 | in += AES_BLOCK_SIZE; 104 | out += AES_BLOCK_SIZE; 105 | } 106 | if (size) { 107 | memcpy(tmp, in, AES_BLOCK_SIZE); 108 | AES_decrypt(tmp, out, key); 109 | for (i = 0; i < size; i++) 110 | out[i] ^= iv[i]; 111 | memcpy(iv, tmp, AES_BLOCK_SIZE); 112 | } 113 | } 114 | } 115 | 116 | void aes_cfb8_encrypt(const uint8_t *in, uint8_t *out, 117 | size_t length, const AES_KEY *key, 118 | uint8_t *iv, int forward) 119 | { 120 | size_t i; 121 | 122 | for (i=0; i < length; i++) { 123 | uint8_t tiv[AES_BLOCK_SIZE*2]; 124 | 125 | memcpy(tiv, iv, AES_BLOCK_SIZE); 126 | AES_encrypt(iv, iv, key); 127 | if (!forward) { 128 | tiv[AES_BLOCK_SIZE] = in[i]; 129 | } 130 | out[i] = in[i] ^ iv[0]; 131 | if (forward) { 132 | tiv[AES_BLOCK_SIZE] = out[i]; 133 | } 134 | memcpy(iv, tiv+1, AES_BLOCK_SIZE); 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /src/crypto/aes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2003-2004 Kungliga Tekniska Högskolan 3 | * (Royal Institute of Technology, Stockholm, Sweden). 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * 3. Neither the name of the Institute nor the names of its contributors 18 | * may be used to endorse or promote products derived from this software 19 | * without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 | * SUCH DAMAGE. 32 | */ 33 | 34 | #ifndef LIB_CRYPTO_AES_H 35 | #define LIB_CRYPTO_AES_H 1 36 | 37 | #include 38 | #include 39 | 40 | #define AES_BLOCK_SIZE 16 41 | #define AES_MAXNR 14 42 | 43 | #define AES_ENCRYPT 1 44 | #define AES_DECRYPT 0 45 | 46 | typedef struct aes_key { 47 | uint32_t key[(AES_MAXNR+1)*4]; 48 | int rounds; 49 | } AES_KEY; 50 | 51 | #ifdef __cplusplus 52 | extern "C" { 53 | #endif 54 | 55 | int AES_set_encrypt_key(const unsigned char *, const int, AES_KEY *); 56 | int AES_set_decrypt_key(const unsigned char *, const int, AES_KEY *); 57 | 58 | void AES_encrypt(const unsigned char *, unsigned char *, const AES_KEY *); 59 | void AES_decrypt(const unsigned char *, unsigned char *, const AES_KEY *); 60 | 61 | void AES_cbc_encrypt(const unsigned char *, unsigned char *, 62 | const unsigned long, const AES_KEY *, 63 | unsigned char *, int); 64 | 65 | void aes_cfb8_encrypt(const uint8_t *in, uint8_t *out, 66 | size_t length, const AES_KEY *key, 67 | uint8_t *iv, int forward); 68 | 69 | #ifdef __cplusplus 70 | } 71 | #endif 72 | 73 | #endif /* LIB_CRYPTO_AES_H */ 74 | -------------------------------------------------------------------------------- /src/crypto/nwd-perf.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) IAIK, Graz University of Technology, 2015. 2 | * All rights reserved. 3 | * Contact: http://opensource.iaik.tugraz.at 4 | * 5 | * This file is part of the Secure Block Device Library. 6 | * 7 | * Commercial License Usage 8 | * Licensees holding valid commercial licenses may use this file in 9 | * accordance with the commercial license agreement provided with the 10 | * Software or, alternatively, in accordance with the terms contained in 11 | * a written agreement between you and SIC. For further information 12 | * contact us at http://opensource.iaik.tugraz.at. 13 | * 14 | * Alternatively, this file may be used under the terms of the GNU General 15 | * Public License as published by the Free Software Foundation version 2. 16 | * 17 | * The Secure Block Device Library is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 20 | * Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with the Secure Block Device Library. If not, see . 24 | */ 25 | /// 26 | /// \file 27 | /// \brief Normal World Crypto Performance Test 28 | /// 29 | #define _GNU_SOURCE 1 30 | #include 31 | #include 32 | #include 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | #include "nwd-stopwatch.h" 44 | 45 | 46 | // Pull-in the normal world APIs 47 | #include "sbdi_nocrypto.h" 48 | #include "sbdi_ocb.h" 49 | #include "sbdi_siv.h" 50 | #include "sbdi_hmac.h" 51 | #include "sbdi_buffer.h" 52 | 53 | static const sbdi_key_t key = { 54 | 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 55 | 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 56 | 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 57 | 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x10, 58 | }; 59 | 60 | typedef void (*sbdi_crypto_destroy)(sbdi_crypto_t *crypto); 61 | 62 | //---------------------------------------------------------------------- 63 | #define SBDI_BLOCK_CTR_SIZE 16u //!< The size in bytes of the counter (nonce) used to make every block write unique 64 | #define SBDI_BLOCK_TAG_SIZE 16u //!< The size in bytes of a cryptographic block tag (a mac over a single block) 65 | 66 | #define NWD_PERF_MAX_BLOCK_COUNT 256u //!< Maximum block count 67 | #define NWD_PERF_RUNS_PER_OP 3u //!< Runs per operation 68 | #define NWD_PERF_MAJOR_LOOPS 10u //!< Major loops for encrypt and decrypt 69 | 70 | // Enable (define) to compare decryption results with plaintexts 71 | #define NWD_PERF_CRYPTO_CHECKS 1 72 | 73 | #if NWD_PERF_CRYPTO_CHECKS 74 | static uint8_t g_block_ref[NWD_PERF_MAX_BLOCK_COUNT * SBDI_BLOCK_SIZE]; 75 | #endif 76 | 77 | static uint8_t g_block_data[NWD_PERF_MAX_BLOCK_COUNT * SBDI_BLOCK_SIZE]; 78 | static uint8_t g_block_ciph[NWD_PERF_MAX_BLOCK_COUNT * SBDI_BLOCK_SIZE]; 79 | static uint8_t g_block_tags[NWD_PERF_MAX_BLOCK_COUNT * SBDI_BLOCK_TAG_SIZE]; 80 | 81 | #define SBDI_ERR_CHECK(ret) \ 82 | do { \ 83 | sbdi_error_t _ret = (ret); \ 84 | if (_ret != SBDI_SUCCESS) { \ 85 | fprintf(stderr, "fatal sbdi error %s(%d): [%d] %s\n", \ 86 | __FILE__, __LINE__, (int) (_ret), #ret); \ 87 | abort(); \ 88 | } \ 89 | } while(0) 90 | 91 | //---------------------------------------------------------------------- 92 | typedef struct sbdi_perf_setup { 93 | sbdi_crypto_t *crypto; 94 | uint8_t *plaintext; 95 | uint8_t *ciphertext; 96 | uint8_t *tag; 97 | size_t idx; 98 | sbdi_ctr_128b_t *ctr; 99 | } sbdi_perf_setup_t; 100 | 101 | static void nwd_perf_encrypt(void *arg); 102 | static void nwd_perf_decrypt(void *arg); 103 | static void nwd_perf_random(uint8_t *data, size_t size); 104 | static void nwd_perf_test(const char *name, size_t num_blocks, 105 | sbdi_error_t (*create)(sbdi_crypto_t **crypto, const sbdi_key_t key), 106 | void (*destroy)(sbdi_crypto_t *crypto)); 107 | 108 | //---------------------------------------------------------------------- 109 | int main(void) 110 | { 111 | nwd_stopwatch_init(); 112 | 113 | // Setup random data (and create a reference copy) 114 | nwd_perf_random(g_block_data, sizeof(g_block_data)); 115 | 116 | // No crypto 117 | // 118 | nwd_perf_test("nocrypto", NWD_PERF_MAX_BLOCK_COUNT, 119 | &sbdi_nocrypto_create, &sbdi_nocrypto_destroy); 120 | 121 | // OCB mode 122 | nwd_perf_test("ocb", NWD_PERF_MAX_BLOCK_COUNT, 123 | &sbdi_ocb_create, &sbdi_ocb_destroy); 124 | 125 | // SIV mode 126 | nwd_perf_test("siv", NWD_PERF_MAX_BLOCK_COUNT, 127 | &sbdi_siv_create, &sbdi_siv_destroy); 128 | 129 | // HMAC mode 130 | nwd_perf_test("hmac", NWD_PERF_MAX_BLOCK_COUNT, 131 | &sbdi_hmac_create, &sbdi_hmac_destroy); 132 | return 0; 133 | } 134 | 135 | //---------------------------------------------------------------------- 136 | static void nwd_perf_random(uint8_t *data, size_t size) 137 | { 138 | int fd = open("/dev/urandom", O_RDONLY); 139 | if (fd == -1) { 140 | perror("failed to open /dev/urandom"); 141 | abort(); 142 | } 143 | 144 | if (read(fd, data, size) != size) { 145 | perror("failed to read random bytes from /dev/urandom"); 146 | abort(); 147 | } 148 | 149 | close(fd); 150 | } 151 | 152 | //---------------------------------------------------------------------- 153 | static void nwd_perf_test(const char *name, size_t num_blocks, 154 | sbdi_error_t (*create)(sbdi_crypto_t **crypto, const sbdi_key_t key), 155 | void (*destroy)(sbdi_crypto_t *crypto)) 156 | { 157 | sbdi_crypto_t *ctx = NULL; 158 | sbdi_ctr_128b_t ctr; 159 | 160 | printf("perf %s start\n", name); 161 | 162 | SBDI_ERR_CHECK(create(&ctx, key)); 163 | 164 | // Prepare test blocks 165 | memset(g_block_data, 0, sizeof(g_block_data)); 166 | nwd_perf_random(g_block_data, num_blocks * NWD_PERF_MAX_BLOCK_COUNT); 167 | 168 | #if NWD_PERF_CRYPTO_CHECKS 169 | // Sample reference blocks 170 | memcpy(g_block_ref, g_block_data, sizeof(g_block_data)); 171 | #endif 172 | 173 | // We assume all block counters as zero (for simplicity) 174 | SBDI_ERR_CHECK(sbdi_ctr_128b_init(&ctr, 0, 0)); 175 | 176 | // Run the encryption tests (this will create valid ciphertexts and tags) 177 | for (size_t k = 0; k < NWD_PERF_MAJOR_LOOPS; ++k) { 178 | printf("perf %s encrypt(%u) ", name, (unsigned) k); 179 | for (size_t i = 0; i < num_blocks; ++i) { 180 | uint8_t *plaintext = g_block_data + i * SBDI_BLOCK_SIZE; 181 | uint8_t *ciphertext = g_block_ciph + i * SBDI_BLOCK_SIZE; 182 | uint8_t *tag = g_block_tags + i * SBDI_BLOCK_TAG_SIZE; 183 | 184 | // Clear ciphertext and tag 185 | memset(ciphertext, 0, SBDI_BLOCK_SIZE); 186 | memset(tag, 0, SBDI_BLOCK_TAG_SIZE); 187 | 188 | // Run the actual encryption 189 | sbdi_perf_setup_t op_ctx = { 190 | .crypto = ctx, 191 | .plaintext = plaintext, 192 | .ciphertext = ciphertext, 193 | .tag = tag, 194 | .ctr = &ctr, 195 | .idx = i, 196 | }; 197 | 198 | int64_t duration = nwd_stopwatch_measure(&nwd_perf_encrypt, &op_ctx, NWD_PERF_RUNS_PER_OP); 199 | printf(" %" PRId64, duration); 200 | fflush(stdout); 201 | } 202 | printf("\n"); 203 | } 204 | 205 | // Run the decryption tests (we have valid tags and ciphertexts from above) 206 | for (size_t k = 0; k < NWD_PERF_MAJOR_LOOPS; ++k) { 207 | printf("perf %s decrypt(%u)", name, (unsigned) k); 208 | for (size_t i = 0; i < num_blocks; ++i) { 209 | uint8_t *plaintext = g_block_data + i * SBDI_BLOCK_SIZE; 210 | uint8_t *ciphertext = g_block_ciph + i * SBDI_BLOCK_SIZE; 211 | uint8_t *tag = g_block_tags + i * SBDI_BLOCK_TAG_SIZE; 212 | 213 | // Clear ciphertext and tag 214 | memset(plaintext, 0, SBDI_BLOCK_SIZE); 215 | 216 | // Run the actual encryption 217 | sbdi_perf_setup_t op_ctx = { 218 | .crypto = ctx, 219 | .plaintext = plaintext, 220 | .ciphertext = ciphertext, 221 | .tag = tag, 222 | .ctr = &ctr, 223 | .idx = i, 224 | }; 225 | 226 | int64_t duration = nwd_stopwatch_measure(&nwd_perf_decrypt, &op_ctx, NWD_PERF_RUNS_PER_OP); 227 | printf(" %" PRId64, duration); 228 | fflush(stdout); 229 | 230 | #if NWD_PERF_CRYPTO_CHECKS 231 | // Sanity check: Must be at reference value again 232 | const uint8_t *ref_plaintext = g_block_ref + i * SBDI_BLOCK_SIZE; 233 | if (memcmp(plaintext, ref_plaintext, SBDI_BLOCK_SIZE) != 0) { 234 | fprintf(stderr, "corrupted data after decryption\n"); 235 | abort(); 236 | } 237 | #endif 238 | } 239 | printf("\n"); 240 | } 241 | 242 | destroy(ctx); 243 | 244 | printf("perf %s --stop--\n", name); 245 | fflush(stdout); 246 | } 247 | 248 | //---------------------------------------------------------------------- 249 | static void nwd_perf_encrypt(void *arg) 250 | { 251 | sbdi_perf_setup_t *ctx = arg; 252 | 253 | // First encrypt 254 | SBDI_ERR_CHECK((ctx->crypto->enc)(ctx->crypto->ctx, ctx->plaintext, SBDI_BLOCK_SIZE, 255 | ctx->ctr, ctx->idx, ctx->ciphertext, ctx->tag)); 256 | } 257 | 258 | //---------------------------------------------------------------------- 259 | static void nwd_perf_decrypt(void *arg) 260 | { 261 | sbdi_perf_setup_t *ctx = arg; 262 | SBDI_ERR_CHECK((ctx->crypto->dec)(ctx->crypto->ctx, ctx->ciphertext, SBDI_BLOCK_SIZE, 263 | (uint8_t *) ctx->ctr, ctx->idx, 264 | ctx->plaintext, ctx->tag)); 265 | } 266 | //---------------------------------------------------------------------- 267 | // Pull in relevant parts of the SBDI implementation 268 | // 269 | #include "sbdi_ctr_128b.c" 270 | #include "sbdi_buffer.c" 271 | -------------------------------------------------------------------------------- /src/crypto/nwd-stopwatch.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) IAIK, Graz University of Technology, 2015. 2 | * All rights reserved. 3 | * Contact: http://opensource.iaik.tugraz.at 4 | * 5 | * This file is part of the Secure Block Device Library. 6 | * 7 | * Commercial License Usage 8 | * Licensees holding valid commercial licenses may use this file in 9 | * accordance with the commercial license agreement provided with the 10 | * Software or, alternatively, in accordance with the terms contained in 11 | * a written agreement between you and SIC. For further information 12 | * contact us at http://opensource.iaik.tugraz.at. 13 | * 14 | * Alternatively, this file may be used under the terms of the GNU General 15 | * Public License as published by the Free Software Foundation version 2. 16 | * 17 | * The Secure Block Device Library is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 20 | * Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with the Secure Block Device Library. If not, see . 24 | */ 25 | /// 26 | /// \file 27 | /// \brief Normal World Crypto Performance Test 28 | /// 29 | #define _GNU_SOURCE 1 30 | #include "nwd-stopwatch.h" 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | // The clock (time-base) to be used for performance measurements 43 | // 44 | // Typical sensible values are [cf. time(8)]: 45 | // CLOCK_REALTIME - System-wide clock that measures real (i.e., wall-clock) 46 | // time. 47 | // CLOCK_MONOTONIC - Clock that cannot be set and represents monotonic time 48 | // CLOCK_MONOTONIC_RAW since some unspecified starting point. 49 | // 50 | // CLOCK_PROCESS_CPUTIME_ID - High-resolution per-process timer from the CPU. 51 | // 52 | static clockid_t g_clock_id = CLOCK_MONOTONIC_RAW; 53 | 54 | // Clock resolution (in ns) 55 | static int64_t g_clock_res = UINT64_C(1); 56 | 57 | // Estimated syscall overhead (average) 58 | static double g_clock_overhead_avg = 0.0; 59 | 60 | // Estimated deviation of syscall overhead (sigma) 61 | static double g_clock_overhead_dev = 0.0; 62 | 63 | //---------------------------------------------------------------------- 64 | static __attribute__((noinline)) void nwd_stopwatch_dummy(void *unused) 65 | { 66 | __asm__ volatile ("nop" : : : "memory"); 67 | } 68 | 69 | //---------------------------------------------------------------------- 70 | void nwd_stopwatch_init(void) 71 | { 72 | // Determine the clock resolution 73 | struct timespec ts; 74 | if (clock_getres(g_clock_id, &ts) != 0) { 75 | perror("stopwatch: failed to determine clock resolution."); 76 | abort(); 77 | } 78 | 79 | g_clock_res = nwd_stopwatch_nanos(&ts); 80 | if (g_clock_res <= 0) { 81 | fprintf(stderr, "stopwatch: broken clock_getres() result. assuming 1ns\n"); 82 | g_clock_res = 1; 83 | } 84 | 85 | // Estimate the overhead of an nwd_stopwatch_measure() call with an empty target function. 86 | const size_t count = 100000; 87 | int64_t total = 0; 88 | double square_sum = 0.0; 89 | 90 | for (size_t n = 0; n < count; ++n) { 91 | int64_t sample = nwd_stopwatch_measure(&nwd_stopwatch_dummy, NULL, 1); 92 | total += sample; 93 | square_sum += (double) sample * (double) sample; 94 | } 95 | 96 | g_clock_overhead_avg = (double) total / (double) count; 97 | g_clock_overhead_dev = sqrt((square_sum - (double) total * (double) total / count) / (count - 1.0)); 98 | 99 | // Print setup 100 | printf("stopwatch resolution: %" PRId64 "\n", g_clock_res); 101 | printf("stopwatch overhead(avg) %g\n", g_clock_overhead_avg); 102 | printf("stopwatch overhead(dev) %g\n", g_clock_overhead_dev); 103 | } 104 | 105 | //---------------------------------------------------------------------- 106 | void nwd_stopwatch_start(nwd_stopwatch_t *sw) 107 | { 108 | memset(sw, 0, sizeof(nwd_stopwatch_t)); 109 | 110 | if (clock_gettime(g_clock_id, &sw->start) != 0) { 111 | perror("stopwatch: failed to measure start time"); 112 | abort(); 113 | } 114 | } 115 | 116 | //---------------------------------------------------------------------- 117 | void nwd_stopwatch_stop(nwd_stopwatch_t *sw) 118 | { 119 | if (clock_gettime(g_clock_id, &sw->stop) != 0) { 120 | perror("stopwatch: failed to measure stop time"); 121 | abort(); 122 | } 123 | } 124 | 125 | //---------------------------------------------------------------------- 126 | int64_t nwd_stopwatch_nanos(const struct timespec *ts) 127 | { 128 | return ts->tv_sec * INT64_C(1000000000) + ts->tv_nsec; 129 | } 130 | 131 | //---------------------------------------------------------------------- 132 | int64_t nwd_stopwatch_delta(const nwd_stopwatch_t *sw) 133 | { 134 | int64_t t_start = nwd_stopwatch_nanos(&sw->start); 135 | int64_t t_stop = nwd_stopwatch_nanos(&sw->stop); 136 | 137 | // Clamp to INT64_MAX on wrap-around 138 | if (t_start > t_stop) { 139 | return INT64_MAX; 140 | } 141 | 142 | return t_stop - t_start; 143 | } 144 | 145 | //---------------------------------------------------------------------- 146 | int64_t nwd_stopwatch_measure(void (*func)(void*), void *arg, size_t iterations) 147 | { 148 | nwd_stopwatch_t sw; 149 | assert (func != NULL); 150 | 151 | // Measure n rounds 152 | nwd_stopwatch_start(&sw); 153 | for (size_t n = 0; n < iterations; ++n) { 154 | func(arg); 155 | } 156 | nwd_stopwatch_stop(&sw); 157 | 158 | return nwd_stopwatch_delta(&sw) / iterations; 159 | } 160 | -------------------------------------------------------------------------------- /src/crypto/nwd-stopwatch.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) IAIK, Graz University of Technology, 2015. 2 | * All rights reserved. 3 | * Contact: http://opensource.iaik.tugraz.at 4 | * 5 | * This file is part of the Secure Block Device Library. 6 | * 7 | * Commercial License Usage 8 | * Licensees holding valid commercial licenses may use this file in 9 | * accordance with the commercial license agreement provided with the 10 | * Software or, alternatively, in accordance with the terms contained in 11 | * a written agreement between you and SIC. For further information 12 | * contact us at http://opensource.iaik.tugraz.at. 13 | * 14 | * Alternatively, this file may be used under the terms of the GNU General 15 | * Public License as published by the Free Software Foundation version 2. 16 | * 17 | * The Secure Block Device Library is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 20 | * Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with the Secure Block Device Library. If not, see . 24 | */ 25 | /// 26 | /// \file 27 | /// \brief Normal World Crypto Performance Test 28 | /// 29 | #ifndef NWD_STOPWATCH_H 30 | #define NWD_STOPWATCH_H 31 | 32 | #include 33 | #include 34 | 35 | // Performance measurement time-span 36 | typedef struct nwd_stopwatch { 37 | struct timespec start; // Start of measurement 38 | struct timespec stop; // End of measurement 39 | } nwd_stopwatch_t; 40 | 41 | void nwd_stopwatch_init(void); 42 | void nwd_stopwatch_start(nwd_stopwatch_t *sw) __attribute__((noinline)); 43 | void nwd_stopwatch_stop(nwd_stopwatch_t *sw) __attribute__((noinline)); 44 | int64_t nwd_stopwatch_nanos(const struct timespec *ts); 45 | int64_t nwd_stopwatch_delta(const nwd_stopwatch_t *sw); 46 | int64_t nwd_stopwatch_measure(void (*func)(void*), void *arg, size_t iterations) __attribute__((noinline)); 47 | 48 | #endif // NWD_STOPWATCH_H 49 | -------------------------------------------------------------------------------- /src/crypto/rijndael-alg-fst.h: -------------------------------------------------------------------------------- 1 | /** 2 | * rijndael-alg-fst.h 3 | * 4 | * @version 3.0 (December 2000) 5 | * 6 | * Optimised ANSI C code for the Rijndael cipher (now AES) 7 | * 8 | * @author Vincent Rijmen 9 | * @author Antoon Bosselaers 10 | * @author Paulo Barreto 11 | * 12 | * This code is hereby placed in the public domain. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS 15 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE 18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 21 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 23 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 24 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #ifndef LIB_CRYPTO_RIJNDAEL_ALG_FST_H 27 | #define LIB_CRYPTO_RIJNDAEL_ALG_FST_H 28 | 29 | #include 30 | 31 | #define RIJNDAEL_MAXKC (256/32) 32 | #define RIJNDAEL_MAXKB (256/8) 33 | #define RIJNDAEL_MAXNR 14 34 | 35 | int rijndaelKeySetupEnc(uint32_t rk[/*4*(Nr + 1)*/], const uint8_t cipherKey[], int keyBits); 36 | int rijndaelKeySetupDec(uint32_t rk[/*4*(Nr + 1)*/], const uint8_t cipherKey[], int keyBits); 37 | void rijndaelEncrypt(const uint32_t rk[/*4*(Nr + 1)*/], int Nr, const uint8_t pt[16], uint8_t ct[16]); 38 | void rijndaelDecrypt(const uint32_t rk[/*4*(Nr + 1)*/], int Nr, const uint8_t ct[16], uint8_t pt[16]); 39 | 40 | #endif /* LIB_CRYPTO_RIJNDAEL_ALG_FST_H */ 41 | -------------------------------------------------------------------------------- /src/crypto/sbdi_hmac.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) IAIK, Graz University of Technology, 2015. 2 | * All rights reserved. 3 | * Contact: http://opensource.iaik.tugraz.at 4 | * 5 | * This file is part of the Secure Block Device Library. 6 | * 7 | * Commercial License Usage 8 | * Licensees holding valid commercial licenses may use this file in 9 | * accordance with the commercial license agreement provided with the 10 | * Software or, alternatively, in accordance with the terms contained in 11 | * a written agreement between you and SIC. For further information 12 | * contact us at http://opensource.iaik.tugraz.at. 13 | * 14 | * Alternatively, this file may be used under the terms of the GNU General 15 | * Public License as published by the Free Software Foundation version 2. 16 | * 17 | * The Secure Block Device Library is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 20 | * Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with the Secure Block Device Library. If not, see . 24 | */ 25 | /// 26 | /// \file 27 | /// \brief Specifies a Secure Block Device Library cryptographic abstraction 28 | /// layer that uses AES-CBC and HMAC-SHA256. 29 | /// 30 | /// This cryptographic abstraction layer is implemented for comparison only. 31 | /// 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | #ifndef SBDI_HMAC_H_ 37 | #define SBDI_HMAC_H_ 38 | 39 | #include "sbdi_crypto.h" 40 | 41 | sbdi_error_t sbdi_hmac_create(sbdi_crypto_t **crypto, const sbdi_key_t key); 42 | void sbdi_hmac_destroy(sbdi_crypto_t *crypto); 43 | 44 | #endif /* SBDI_HMAC_H_ */ 45 | 46 | #ifdef __cplusplus 47 | } 48 | #endif 49 | -------------------------------------------------------------------------------- /src/crypto/sbdi_nocrypto.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) IAIK, Graz University of Technology, 2015. 2 | * All rights reserved. 3 | * Contact: http://opensource.iaik.tugraz.at 4 | * 5 | * This file is part of the Secure Block Device Library. 6 | * 7 | * Commercial License Usage 8 | * Licensees holding valid commercial licenses may use this file in 9 | * accordance with the commercial license agreement provided with the 10 | * Software or, alternatively, in accordance with the terms contained in 11 | * a written agreement between you and SIC. For further information 12 | * contact us at http://opensource.iaik.tugraz.at. 13 | * 14 | * Alternatively, this file may be used under the terms of the GNU General 15 | * Public License as published by the Free Software Foundation version 2. 16 | * 17 | * The Secure Block Device Library is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 20 | * Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with the Secure Block Device Library. If not, see . 24 | */ 25 | /// 26 | /// \file 27 | /// \brief Implements a Secure Block Device Library cryptographic abstraction 28 | /// layer using no cryptography whatsoever. 29 | /// 30 | /// This cryptographic abstraction layer implementation is intended for 31 | /// testing and debugging the Secure Block Device Library. It does not provide 32 | /// any form of protection for the actual data. 33 | /// 34 | #include "sbdi_nocrypto.h" 35 | 36 | #include 37 | #include 38 | 39 | sbdi_error_t sbdi_nocrypto_encrypt(void *ctx, const uint8_t *pt, 40 | const int pt_len, const sbdi_ctr_128b_t *ctr, uint32_t blk_nbr, uint8_t *ct, 41 | sbdi_tag_t tag) 42 | { 43 | // if the context is non-null then this is used incorrectly 44 | assert(!ctx); 45 | SBDI_CHK_PARAM(pt && ctr && pt_len > 0 && tag); 46 | memset(tag, 0xFF, SBDI_BLOCK_TAG_SIZE); 47 | if (pt == ct) { 48 | return SBDI_SUCCESS; 49 | } 50 | memcpy(ct, pt, pt_len); 51 | return SBDI_SUCCESS; 52 | } 53 | 54 | sbdi_error_t sbdi_nocrypto_decrypt(void *ctx, const uint8_t *ct, 55 | const int ct_len, const sbdi_ctr_pkd_t ctr, const uint32_t blk_nbr, 56 | uint8_t *pt, const sbdi_tag_t tag) 57 | { 58 | // if the context is non-null then this is used incorrectly 59 | assert(!ctx); 60 | SBDI_CHK_PARAM( 61 | ct && ct_len > 0 && ctr && sbdi_block_is_valid_phy(blk_nbr) && pt && tag); 62 | int i; 63 | // sanity check 64 | for (i = 0; i < SBDI_BLOCK_TAG_SIZE; ++i) { 65 | if (tag[i] != 0xFF) { 66 | return SBDI_ERR_TAG_MISMATCH; 67 | } 68 | } 69 | if (pt == ct) { 70 | return SBDI_SUCCESS; 71 | } 72 | memcpy(pt, ct, ct_len); 73 | return SBDI_SUCCESS; 74 | } 75 | 76 | sbdi_error_t sbdi_nocrypto_mac(void *ctx, const unsigned char *msg, 77 | const int mlen, unsigned char *C, const unsigned char *ad, const int ad_len) 78 | { 79 | // if their is a context, then something is wrong 80 | assert(!ctx); 81 | SBDI_CHK_PARAM(msg && mlen > 0 && C); 82 | memset(C, 0x00, SBDI_BLOCK_TAG_SIZE); 83 | return SBDI_SUCCESS; 84 | } 85 | 86 | sbdi_error_t sbdi_nocrypto_create(sbdi_crypto_t **crypto, const sbdi_key_t key) 87 | { 88 | sbdi_crypto_t *c = calloc(1, sizeof(sbdi_crypto_t)); 89 | if (!c) { 90 | return SBDI_ERR_OUT_Of_MEMORY; 91 | } 92 | c->enc = &sbdi_nocrypto_encrypt; 93 | c->dec = &sbdi_nocrypto_decrypt; 94 | c->mac = &sbdi_nocrypto_mac; 95 | *crypto = c; 96 | return SBDI_SUCCESS; 97 | } 98 | 99 | void sbdi_nocrypto_destroy(sbdi_crypto_t *crypto) 100 | { 101 | free(crypto); 102 | } 103 | -------------------------------------------------------------------------------- /src/crypto/sbdi_nocrypto.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) IAIK, Graz University of Technology, 2015. 2 | * All rights reserved. 3 | * Contact: http://opensource.iaik.tugraz.at 4 | * 5 | * This file is part of the Secure Block Device Library. 6 | * 7 | * Commercial License Usage 8 | * Licensees holding valid commercial licenses may use this file in 9 | * accordance with the commercial license agreement provided with the 10 | * Software or, alternatively, in accordance with the terms contained in 11 | * a written agreement between you and SIC. For further information 12 | * contact us at http://opensource.iaik.tugraz.at. 13 | * 14 | * Alternatively, this file may be used under the terms of the GNU General 15 | * Public License as published by the Free Software Foundation version 2. 16 | * 17 | * The Secure Block Device Library is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 20 | * Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with the Secure Block Device Library. If not, see . 24 | */ 25 | /// 26 | /// \file 27 | /// \brief Specifies a Secure Block Device Library cryptographic abstraction 28 | /// layer using no cryptography whatsoever. 29 | /// 30 | /// This cryptographic abstraction layer is intended for testing and debugging 31 | /// the Secure Block Device Library. It does not provide any form of protection 32 | /// for the actual data. 33 | /// 34 | #ifdef __cplusplus 35 | extern "C" { 36 | #endif 37 | 38 | #ifndef SBDI_NOCRYPTO_H_ 39 | #define SBDI_NOCRYPTO_H_ 40 | 41 | #include "sbdi_crypto.h" 42 | 43 | /*! 44 | * \brief Creates a new SBDI cryptographic abstraction layer that does not 45 | * actually perform any cryptography 46 | * 47 | * This Cryptography Abstraction Layer generated by this function implements 48 | * the encryption and decryption as NOP. This means the encryption will 49 | * return a simple copy of the plaintext, and an empty tag consisting of 50 | * solely zeros. 51 | * 52 | * @param crypto[out] a pointer pointer to the newly created cryptography 53 | * abstraction layer 54 | * @param key[in] the key to use for the cryptography abstraction layer; can be 55 | * NULL as it will be ignored. 56 | * @return SBDI_SUCCESS if the operation succeeds; 57 | */ 58 | sbdi_error_t sbdi_nocrypto_create(sbdi_crypto_t **crypto, const sbdi_key_t key); 59 | 60 | /*! 61 | * \brief Destroys the given SBDI cryptographic abstraction layer 62 | * 63 | * Warning: Only use this function for cryptographic abstraction layers 64 | * created with the sbdi_nocrypto_create function! 65 | * 66 | * @param crypto[in] the cryptographic abstraction layer to destroy 67 | */ 68 | void sbdi_nocrypto_destroy(sbdi_crypto_t *crypto); 69 | 70 | #endif /* SBDI_NOCRYPTO_H_ */ 71 | 72 | #ifdef __cplusplus 73 | } 74 | #endif 75 | -------------------------------------------------------------------------------- /src/crypto/sbdi_ocb.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) IAIK, Graz University of Technology, 2015. 2 | * All rights reserved. 3 | * Contact: http://opensource.iaik.tugraz.at 4 | * 5 | * This file is part of the Secure Block Device Library. 6 | * 7 | * Commercial License Usage 8 | * Licensees holding valid commercial licenses may use this file in 9 | * accordance with the commercial license agreement provided with the 10 | * Software or, alternatively, in accordance with the terms contained in 11 | * a written agreement between you and SIC. For further information 12 | * contact us at http://opensource.iaik.tugraz.at. 13 | * 14 | * Alternatively, this file may be used under the terms of the GNU General 15 | * Public License as published by the Free Software Foundation version 2. 16 | * 17 | * The Secure Block Device Library is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 20 | * Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with the Secure Block Device Library. If not, see . 24 | */ 25 | /// 26 | /// \file 27 | /// \brief Implements Secure Block Device Library cryptographic abstraction 28 | /// layer that uses AES in OCB mode for data block protection and AES CMAC for 29 | /// management block protection. 30 | /// 31 | /// This cryptographic abstraction layer is very efficient, as it uses the 32 | /// one-pass OCB authenticating encryption mode. OCB is patent-encumbered. If 33 | /// you plan on using this cryptographic abstraction layer check 34 | /// http://web.cs.ucdavis.edu/~rogaway/ocb/license.htm . 35 | /// 36 | #include "sbdi_ocb.h" 37 | #include "sbdi_buffer.h" 38 | 39 | #include "ae.h" 40 | #include "siv.h" 41 | 42 | #include 43 | #include 44 | 45 | // NOTE OCB truncates counter to 12 bytes 46 | 47 | #define SBDI_OCB_KEY_SIZE 16u 48 | #define SBDI_OCB_NONCE_SIZE (SBDI_BLOCK_CTR_SIZE) - 4 49 | #define SBDI_OCB_AE_KEY_IDX 16u 50 | #define SBDI_OCB_AD_SIZE (4u + (SBDI_BLOCK_CTR_SIZE)) 51 | 52 | /*! 53 | * \brief Wraps the two sub-contexts required by the OCB cryptographic 54 | * abstraction layer 55 | * 56 | * The OCB cryptographic abstraction layer actually uses two different 57 | * cryptographic operations, an OCB authenticating encryption based on AES, 58 | * and an AES cmac. 59 | */ 60 | typedef struct sbdi_ocb_ctx { 61 | ae_ctx *ae_ctx; //!< the OCB authenticating encryption context 62 | siv_ctx *siv_ctx; //!< the SIV context which is used for computing the CMAC 63 | } sbdi_ocb_ctx_t; 64 | 65 | //---------------------------------------------------------------------- 66 | sbdi_error_t sbdi_ocb_encrypt(void *ctx, const uint8_t *pt, const int pt_len, 67 | const sbdi_ctr_128b_t *ctr, const uint32_t blk_nbr, uint8_t *ct, 68 | sbdi_tag_t tag) 69 | { 70 | SBDI_CHK_PARAM( 71 | ctx && pt && pt_len > 0 && ctr && sbdi_block_is_valid_phy(blk_nbr) && ct 72 | && tag); 73 | ae_ctx *ae_ctx = ((sbdi_ocb_ctx_t *) ctx)->ae_ctx; 74 | 75 | uint8_t ad[SBDI_OCB_AD_SIZE]; 76 | memset(ad, 0, SBDI_OCB_AD_SIZE); 77 | sbdi_buffer_t b; 78 | memset(&b, 0, sizeof(sbdi_buffer_t)); 79 | 80 | sbdi_buffer_init(&b, ad, SBDI_OCB_AD_SIZE); 81 | const unsigned char *ap = sbdi_buffer_get_cptr(&b); 82 | sbdi_buffer_write_uint32_t(&b, blk_nbr); 83 | // Truncate the 4 highermost bytes of the counter! 84 | const unsigned char *np = sbdi_buffer_get_cptr(&b) + 4; 85 | sbdi_buffer_write_ctr_128b(&b, ctr); 86 | 87 | int cr = ae_encrypt(ae_ctx, np, pt, pt_len, ap, 4, ct, tag, 1); 88 | if (cr != SBDI_BLOCK_SIZE) { 89 | return SBDI_ERR_CRYPTO_FAIL; 90 | } 91 | return SBDI_SUCCESS; 92 | } 93 | 94 | //---------------------------------------------------------------------- 95 | sbdi_error_t sbdi_ocb_decrypt(void *ctx, const uint8_t *ct, const int ct_len, 96 | const sbdi_ctr_pkd_t ctr, const uint32_t blk_nbr, uint8_t *pt, 97 | const sbdi_tag_t tag) 98 | { 99 | SBDI_CHK_PARAM( 100 | ctx && ct && ct_len > 0 && ctr && sbdi_block_is_valid_phy(blk_nbr) && pt 101 | && tag); 102 | ae_ctx *ae_ctx = ((sbdi_ocb_ctx_t *) ctx)->ae_ctx; 103 | 104 | uint8_t ad[SBDI_OCB_AD_SIZE]; 105 | memset(ad, 0, SBDI_OCB_AD_SIZE); 106 | sbdi_buffer_t b; 107 | memset(&b, 0, sizeof(sbdi_buffer_t)); 108 | 109 | sbdi_buffer_init(&b, ad, SBDI_OCB_AD_SIZE); 110 | const unsigned char *ap = sbdi_buffer_get_cptr(&b); 111 | sbdi_buffer_write_uint32_t(&b, blk_nbr); 112 | // Truncate the 4 highermost bytes of the counter! 113 | const unsigned char *np = sbdi_buffer_get_cptr(&b) + 4; 114 | sbdi_buffer_write_bytes(&b, ctr, SBDI_BLOCK_CTR_SIZE); 115 | 116 | int cr = ae_decrypt(ae_ctx, np, ct, ct_len, ap, 4, pt, tag, 1); 117 | if (cr != SBDI_BLOCK_SIZE) { 118 | return SBDI_ERR_CRYPTO_FAIL; 119 | } 120 | return SBDI_SUCCESS; 121 | } 122 | 123 | //---------------------------------------------------------------------- 124 | sbdi_error_t sbdi_ocb_mac(void *ctx, const unsigned char *msg, const int mlen, 125 | unsigned char *C, const unsigned char *ad, const int ad_len) 126 | { 127 | SBDI_CHK_PARAM(ctx && msg && mlen > 0 && C && ad && ad_len > 0); 128 | siv_ctx *siv_ctx = ((sbdi_ocb_ctx_t *) ctx)->siv_ctx; 129 | sbdi_bl_aes_cmac(siv_ctx, ad, ad_len, msg, mlen, C); 130 | return SBDI_SUCCESS; 131 | } 132 | 133 | //---------------------------------------------------------------------- 134 | sbdi_error_t sbdi_ocb_create(sbdi_crypto_t **crypto, const sbdi_key_t key) 135 | { 136 | SBDI_CHK_PARAM(crypto && key); 137 | ae_ctx *ae_ctx = NULL; 138 | siv_ctx *si_ctx = NULL; 139 | sbdi_ocb_ctx_t *ocb_ctx = NULL; 140 | sbdi_crypto_t *c = NULL; 141 | 142 | sbdi_error_t r = SBDI_ERR_UNSPECIFIED; 143 | ae_ctx = ae_allocate(NULL); 144 | if (!ae_ctx) { 145 | r = SBDI_ERR_OUT_Of_MEMORY; 146 | goto FAIL; 147 | } 148 | si_ctx = calloc(1, sizeof(siv_ctx)); 149 | if (!si_ctx) { 150 | r = SBDI_ERR_OUT_Of_MEMORY; 151 | goto FAIL; 152 | } 153 | ocb_ctx = calloc(1, sizeof(sbdi_ocb_ctx_t)); 154 | if (!ocb_ctx) { 155 | r = SBDI_ERR_OUT_Of_MEMORY; 156 | goto FAIL; 157 | } 158 | c = calloc(1, sizeof(sbdi_crypto_t)); 159 | if (!c) { 160 | r = SBDI_ERR_OUT_Of_MEMORY; 161 | goto FAIL; 162 | } 163 | // Use the upper 16 bytes of the 32 byte key for OCB 164 | int cr = ae_init(ae_ctx, key + SBDI_OCB_AE_KEY_IDX, SBDI_OCB_KEY_SIZE, 165 | SBDI_OCB_NONCE_SIZE, SBDI_BLOCK_TAG_SIZE); 166 | if (cr != AE_SUCCESS) { 167 | r = SBDI_ERR_CRYPTO_FAIL; 168 | goto FAIL; 169 | } 170 | cr = siv_init(si_ctx, key, SIV_256); 171 | if (cr == -1) { 172 | r = SBDI_ERR_CRYPTO_FAIL; 173 | goto FAIL; 174 | } 175 | ocb_ctx->ae_ctx = ae_ctx; 176 | ocb_ctx->siv_ctx = si_ctx; 177 | c->ctx = ocb_ctx; 178 | c->enc = &sbdi_ocb_encrypt; 179 | c->dec = &sbdi_ocb_decrypt; 180 | c->mac = &sbdi_ocb_mac; 181 | *crypto = c; 182 | return SBDI_SUCCESS; 183 | FAIL: if (ae_ctx) { 184 | ae_clear(ae_ctx); 185 | ae_free(ae_ctx); 186 | } 187 | if (si_ctx) { 188 | memset(si_ctx, 0, sizeof(siv_ctx)); 189 | free(si_ctx); 190 | } 191 | if (ocb_ctx) { 192 | free(ocb_ctx); 193 | } 194 | if (c) { 195 | free(c); 196 | } 197 | return r; 198 | } 199 | 200 | //---------------------------------------------------------------------- 201 | void sbdi_ocb_destroy(sbdi_crypto_t *crypto) 202 | { 203 | if (crypto) { 204 | sbdi_ocb_ctx_t *ctx = (sbdi_ocb_ctx_t *) crypto->ctx; 205 | if (ctx) { 206 | if (ctx->ae_ctx) { 207 | ae_clear(ctx->ae_ctx); 208 | ae_free(ctx->ae_ctx); 209 | } 210 | if (ctx->siv_ctx) { 211 | memset(ctx->siv_ctx, 0, sizeof(siv_ctx)); 212 | free(ctx->siv_ctx); 213 | } 214 | } 215 | free(crypto); 216 | } 217 | } 218 | -------------------------------------------------------------------------------- /src/crypto/sbdi_ocb.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) IAIK, Graz University of Technology, 2015. 2 | * All rights reserved. 3 | * Contact: http://opensource.iaik.tugraz.at 4 | * 5 | * This file is part of the Secure Block Device Library. 6 | * 7 | * Commercial License Usage 8 | * Licensees holding valid commercial licenses may use this file in 9 | * accordance with the commercial license agreement provided with the 10 | * Software or, alternatively, in accordance with the terms contained in 11 | * a written agreement between you and SIC. For further information 12 | * contact us at http://opensource.iaik.tugraz.at. 13 | * 14 | * Alternatively, this file may be used under the terms of the GNU General 15 | * Public License as published by the Free Software Foundation version 2. 16 | * 17 | * The Secure Block Device Library is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 20 | * Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with the Secure Block Device Library. If not, see . 24 | */ 25 | /// 26 | /// \file 27 | /// \brief Specifies a Secure Block Device Library cryptographic abstraction 28 | /// layer that uses AES in OCB mode for data block protection and AES CMAC for 29 | /// management block protection. 30 | /// 31 | /// This cryptographic abstraction layer is very efficient, as it uses the 32 | /// one-pass OCB authenticating encryption mode. OCB is patent-encumbered. If 33 | /// you plan on using this cryptographic abstraction layer check 34 | /// http://web.cs.ucdavis.edu/~rogaway/ocb/license.htm . 35 | /// 36 | #ifdef __cplusplus 37 | extern "C" { 38 | #endif 39 | 40 | #ifndef SBDI_OCB_H_ 41 | #define SBDI_OCB_H_ 42 | 43 | #include "sbdi_crypto.h" 44 | 45 | /*! 46 | * \brief Creates a new cryptographic abstraction layer for use with the 47 | * secure block device interface that uses AES in OCB mode and AES CMAC to 48 | * implement its cryptographic operations 49 | * 50 | * The created cryptographic abstraction layer uses the lower 16 bytes of the 51 | * key for the CMAC and the upper 16 bytes of the key for OCB. 52 | * 53 | * @param crypto[out] a pointer pointer that will be set to the newly created 54 | * cryptographic abstraction layer 55 | * @param key[in] the key to use for the cryptographic operations 56 | * @return SBDI_SUCCESS if the creation of the cryptographic abstraction 57 | * layer is successful; 58 | * SBDI_OUT_OF_MEMORY if there was insufficient memory to create the 59 | * OCB context, the SIV (CMAC) context, the 60 | * wrapper context, or the cryptographic 61 | * abstraction layer itself 62 | * SBDI_ERR_CRYPTO_FAIL if creation of the OCB AE, or the SIV context 63 | * fails 64 | */ 65 | sbdi_error_t sbdi_ocb_create(sbdi_crypto_t **crypto, const sbdi_key_t key); 66 | 67 | /*! 68 | * \brief Cleans up the given cryptographic abstraction layer by freeing all 69 | * associated resources 70 | * 71 | * Warning: Only apply this function to cryptographic abstraction layers 72 | * created with the sbdi_ocb_create function! 73 | * 74 | * @param crypto[in] the cryptographic abstraction layer to destroy 75 | */ 76 | void sbdi_ocb_destroy(sbdi_crypto_t *crypto); 77 | 78 | #endif /* SBDI_OCB_H_ */ 79 | 80 | #ifdef __cplusplus 81 | } 82 | #endif 83 | -------------------------------------------------------------------------------- /src/crypto/sbdi_siv.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) IAIK, Graz University of Technology, 2015. 2 | * All rights reserved. 3 | * Contact: http://opensource.iaik.tugraz.at 4 | * 5 | * This file is part of the Secure Block Device Library. 6 | * 7 | * Commercial License Usage 8 | * Licensees holding valid commercial licenses may use this file in 9 | * accordance with the commercial license agreement provided with the 10 | * Software or, alternatively, in accordance with the terms contained in 11 | * a written agreement between you and SIC. For further information 12 | * contact us at http://opensource.iaik.tugraz.at. 13 | * 14 | * Alternatively, this file may be used under the terms of the GNU General 15 | * Public License as published by the Free Software Foundation version 2. 16 | * 17 | * The Secure Block Device Library is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 20 | * Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with the Secure Block Device Library. If not, see . 24 | */ 25 | /// 26 | /// \file 27 | /// \brief Implements a Secure Block Device Library cryptographic abstraction 28 | /// layer using the AES SIV mode of operation for data block protection and 29 | /// AES CMAC for management block protection. 30 | /// 31 | #include "sbdi_siv.h" 32 | #include "sbdi_crypto.h" 33 | #include "sbdi_buffer.h" 34 | 35 | #include 36 | #include 37 | #include 38 | 39 | #define SBDI_SIV_AD_SIZE (4u + (SBDI_BLOCK_CTR_SIZE)) 40 | 41 | void sbdi_siv_decrypt_dep(siv_ctx *ctx, const unsigned char *c, 42 | unsigned char *p, const int len, unsigned char *counter, const int nad, ...) 43 | { 44 | va_list ap; 45 | unsigned char *ad; 46 | int adlen, numad = nad; 47 | unsigned char ctr[AES_BLOCK_SIZE]; 48 | 49 | memcpy(ctr, counter, AES_BLOCK_SIZE); 50 | siv_aes_ctr(ctx, c, len, p, ctr); 51 | if (numad) { 52 | va_start(ap, nad); 53 | while (numad) { 54 | ad = (unsigned char *) va_arg(ap, char *); 55 | adlen = va_arg(ap, int); 56 | s2v_update(ctx, ad, adlen); 57 | numad--; 58 | } 59 | } 60 | s2v_final(ctx, p, len, ctr); 61 | 62 | /* 63 | * the only part of the context that is carried along with 64 | * subsequent calls to siv_decrypt() are the keys, so reset 65 | * everything else. 66 | */ 67 | siv_restart(ctx); 68 | memcpy(counter, ctr, AES_BLOCK_SIZE); 69 | } 70 | 71 | sbdi_error_t sbdi_siv_encrypt(void *ctx, const uint8_t *pt, const int pt_len, 72 | const sbdi_ctr_128b_t *ctr, uint32_t blk_nbr, uint8_t *ct, sbdi_tag_t tag) 73 | { 74 | // SIV does not use a nonce, make sure it is null! 75 | SBDI_CHK_PARAM( 76 | ctx && pt && pt_len > 0 && ctr && sbdi_block_is_valid_phy(blk_nbr) && ct 77 | && tag); 78 | siv_ctx *s_ctx = (siv_ctx *) ctx; 79 | unsigned char *counter = (unsigned char *) tag; 80 | 81 | uint8_t ad[SBDI_SIV_AD_SIZE]; 82 | memset(ad, 0, SBDI_SIV_AD_SIZE); 83 | sbdi_buffer_t b; 84 | memset(&b, 0, sizeof(sbdi_buffer_t)); 85 | 86 | sbdi_buffer_init(&b, ad, SBDI_SIV_AD_SIZE); 87 | sbdi_buffer_write_uint32_t(&b, blk_nbr); 88 | sbdi_buffer_write_ctr_128b(&b, ctr); 89 | 90 | int r = siv_encrypt(s_ctx, pt, ct, pt_len, counter, 1, ad, SBDI_SIV_AD_SIZE); 91 | if (r != 1) { 92 | return SBDI_ERR_CRYPTO_FAIL; 93 | } else { 94 | return SBDI_SUCCESS; 95 | } 96 | } 97 | 98 | sbdi_error_t sbdi_siv_decrypt(void *ctx, const uint8_t *ct, const int ct_len, 99 | const sbdi_ctr_pkd_t ctr, const uint32_t blk_nbr, uint8_t *pt, 100 | const sbdi_tag_t tag) 101 | { 102 | SBDI_CHK_PARAM( 103 | ctx && ct && ct_len > 0 && ctr && sbdi_block_is_valid_phy(blk_nbr) && pt 104 | && tag); 105 | siv_ctx *s_ctx = (siv_ctx *) ctx; 106 | unsigned char *counter = (unsigned char *) tag; 107 | 108 | uint8_t ad[SBDI_SIV_AD_SIZE]; 109 | memset(ad, 0, SBDI_SIV_AD_SIZE); 110 | sbdi_buffer_t b; 111 | memset(&b, 0, sizeof(sbdi_buffer_t)); 112 | 113 | sbdi_buffer_init(&b, ad, SBDI_SIV_AD_SIZE); 114 | sbdi_buffer_write_uint32_t(&b, blk_nbr); 115 | sbdi_buffer_write_bytes(&b, ctr, SBDI_BLOCK_CTR_SIZE); 116 | 117 | int r = siv_decrypt(s_ctx, ct, pt, ct_len, counter, 1, ad, SBDI_SIV_AD_SIZE); 118 | if (r != 1) { 119 | return SBDI_ERR_TAG_MISMATCH; 120 | } else { 121 | return SBDI_SUCCESS; 122 | } 123 | } 124 | 125 | sbdi_error_t sbdi_siv_cmac(void *ctx, const unsigned char *msg, const int mlen, 126 | unsigned char *C, const unsigned char *ad, const int ad_len) 127 | { 128 | SBDI_CHK_PARAM(ctx && msg && mlen > 0 && C && ad && ad_len > 0); 129 | siv_ctx *s_ctx = (siv_ctx *) ctx; 130 | sbdi_bl_aes_cmac(s_ctx, ad, ad_len, msg, mlen, C); 131 | return SBDI_SUCCESS; 132 | } 133 | 134 | sbdi_error_t sbdi_siv_init(siv_ctx *ctx, const sbdi_key_t key) 135 | { 136 | SBDI_CHK_PARAM(ctx && key); 137 | memset(ctx, 0, sizeof(siv_ctx)); 138 | int cr = siv_init(ctx, key, SIV_256); 139 | if (cr == -1) { 140 | return SBDI_ERR_CRYPTO_FAIL; 141 | } else { 142 | return SBDI_SUCCESS; 143 | } 144 | } 145 | 146 | void sbdi_siv_clear(siv_ctx *ctx) 147 | { 148 | memset(ctx, 0, sizeof(siv_ctx)); 149 | } 150 | 151 | sbdi_error_t sbdi_siv_create(sbdi_crypto_t **crypto, const sbdi_key_t key) 152 | { 153 | // The following is a sanity check required by the encrypt and decrypt fun. 154 | assert(sizeof(sbdi_tag_t) == AES_BLOCK_SIZE); 155 | SBDI_CHK_PARAM(crypto && key); 156 | sbdi_error_t r = SBDI_ERR_UNSPECIFIED; 157 | siv_ctx *ctx = calloc(1, sizeof(siv_ctx)); 158 | if (!ctx) { 159 | return SBDI_ERR_OUT_Of_MEMORY; 160 | } 161 | r = sbdi_siv_init(ctx, key); 162 | if (r != SBDI_SUCCESS) { 163 | goto FAIL; 164 | } 165 | sbdi_crypto_t *c = calloc(1, sizeof(sbdi_crypto_t)); 166 | if (!c) { 167 | r = SBDI_ERR_OUT_Of_MEMORY; 168 | goto FAIL; 169 | } 170 | c->ctx = ctx; 171 | c->enc = &sbdi_siv_encrypt; 172 | c->dec = &sbdi_siv_decrypt; 173 | c->mac = &sbdi_siv_cmac; 174 | *crypto = c; 175 | return SBDI_SUCCESS; 176 | 177 | FAIL: if (ctx) { 178 | sbdi_siv_clear(ctx); 179 | free(ctx); 180 | } 181 | return r; 182 | } 183 | 184 | void sbdi_siv_destroy(sbdi_crypto_t *crypto) 185 | { 186 | if (crypto) { 187 | assert(crypto->ctx); 188 | sbdi_siv_clear(crypto->ctx); 189 | free(crypto->ctx); 190 | memset(crypto, 0, sizeof(sbdi_crypto_t)); 191 | free(crypto); 192 | } 193 | } 194 | -------------------------------------------------------------------------------- /src/crypto/sbdi_siv.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) IAIK, Graz University of Technology, 2015. 2 | * All rights reserved. 3 | * Contact: http://opensource.iaik.tugraz.at 4 | * 5 | * This file is part of the Secure Block Device Library. 6 | * 7 | * Commercial License Usage 8 | * Licensees holding valid commercial licenses may use this file in 9 | * accordance with the commercial license agreement provided with the 10 | * Software or, alternatively, in accordance with the terms contained in 11 | * a written agreement between you and SIC. For further information 12 | * contact us at http://opensource.iaik.tugraz.at. 13 | * 14 | * Alternatively, this file may be used under the terms of the GNU General 15 | * Public License as published by the Free Software Foundation version 2. 16 | * 17 | * The Secure Block Device Library is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 20 | * Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with the Secure Block Device Library. If not, see . 24 | */ 25 | /// 26 | /// \file 27 | /// \brief Specifies a Secure Block Device Library cryptographic abstraction 28 | /// layer using the AES SIV mode of operation for data block protection and 29 | /// AES CMAC for management block protection. 30 | /// 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #endif 34 | 35 | 36 | #ifndef SBDI_SIV_H_ 37 | #define SBDI_SIV_H_ 38 | 39 | #include "siv.h" 40 | 41 | #include "sbdi_crypto.h" 42 | 43 | /*! 44 | * \brief A version of siv_decrypt that omits the tag check. DEPRECATED! 45 | * 46 | * This function is required for the merkle hash tree based integrity 47 | * protection mechanism used by the secure block device interface. 48 | * 49 | * @param ctx[in] the siv context 50 | * @param c[in] the ciphertext 51 | * @param p[out] the plaintext 52 | * @param len[in] the length of the plaintext (also the length of the 53 | * ciphertext) 54 | * @param counter[out] the block tag 55 | * @param nad[in] the number of (unsigned char *, int) length tuples describing 56 | * additional header information for the mac. 57 | */ 58 | void sbdi_siv_decrypt_dep(siv_ctx *ctx, const unsigned char *c, unsigned char *p, 59 | const int len, unsigned char *counter, const int nad, ...); 60 | 61 | sbdi_error_t sbdi_siv_create(sbdi_crypto_t **crypto, const sbdi_key_t key); 62 | void sbdi_siv_destroy(sbdi_crypto_t *crypto); 63 | 64 | #endif /* SBDI_SIV_H_ */ 65 | 66 | #ifdef __cplusplus 67 | } 68 | #endif 69 | -------------------------------------------------------------------------------- /src/crypto/siv.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) The Industrial Lounge, 2007 3 | * 4 | * Copyright holder grants permission for redistribution and use in source 5 | * and binary forms, with or without modification, provided that the 6 | * following conditions are met: 7 | * 1. Redistribution of source code must retain the above copyright 8 | * notice, this list of conditions, and the following disclaimer 9 | * in all source files. 10 | * 2. Redistribution in binary form must retain the above copyright 11 | * notice, this list of conditions, and the following disclaimer 12 | * in the documentation and/or other materials provided with the 13 | * distribution. 14 | * 3. All advertising materials and documentation mentioning features 15 | * or use of this software must display the following acknowledgement: 16 | * 17 | * "This product includes software written by 18 | * Dan Harkins (dharkins at lounge dot org)" 19 | * 20 | * "DISCLAIMER OF LIABILITY 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE INDUSTRIAL LOUNGE ``AS IS'' 23 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 24 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 25 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INDUSTRIAL LOUNGE BE LIABLE 26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 | * SUCH DAMAGE." 33 | * 34 | * This license and distribution terms cannot be changed. In other words, 35 | * this code cannot simply be copied and put under another distribution 36 | * license (including the GNU public license). 37 | */ 38 | #ifndef _SIV_H_ 39 | #define _SIV_H_ 40 | 41 | #include "aes.h" 42 | 43 | #define AES_128_BYTES 16 44 | #define AES_192_BYTES 24 45 | #define AES_256_BYTES 32 46 | #define SIV_256 256 47 | #define SIV_384 384 48 | #define SIV_512 512 49 | 50 | typedef struct _siv_ctx { 51 | unsigned char K1[AES_BLOCK_SIZE]; 52 | unsigned char K2[AES_BLOCK_SIZE]; 53 | unsigned char T[AES_BLOCK_SIZE]; 54 | unsigned char benchmark[AES_BLOCK_SIZE]; 55 | AES_KEY ctr_sched; 56 | AES_KEY s2v_sched; 57 | } siv_ctx; 58 | 59 | #ifdef AES_LONG 60 | typedef unsigned long u32; 61 | #else 62 | typedef unsigned int u32; 63 | #endif 64 | typedef unsigned short u16; 65 | typedef unsigned char u8; 66 | 67 | #if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64)) 68 | # define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00) 69 | # define GETU32(p) SWAP(*((u32 *)(p))) 70 | # define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); } 71 | #else 72 | # define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3])) 73 | # define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); } 74 | #endif 75 | 76 | #ifdef __cplusplus 77 | extern "C" { 78 | #endif 79 | 80 | /* 81 | * exported APIs 82 | */ 83 | void aes_cmac(siv_ctx *, const unsigned char *, int, unsigned char *); 84 | int siv_init(siv_ctx *, const unsigned char *, int); 85 | void s2v_reset(siv_ctx *); 86 | void s2v_benchmark(siv_ctx *); 87 | void s2v_add(siv_ctx *, const unsigned char *); 88 | void s2v_update(siv_ctx *, const unsigned char *, int); 89 | int s2v_final(siv_ctx *, const unsigned char *, int, unsigned char *); 90 | void vprf(siv_ctx *, unsigned char *, const int, ...); 91 | void siv_restart(siv_ctx *); 92 | void siv_aes_ctr(siv_ctx *, const unsigned char *, const int, unsigned char *, 93 | const unsigned char *); 94 | int siv_encrypt(siv_ctx *, const unsigned char *, unsigned char *, const int, 95 | unsigned char *, const int, ...); 96 | int siv_decrypt(siv_ctx *, const unsigned char *, unsigned char *, const int, 97 | unsigned char *, const int, ...); 98 | 99 | /*! 100 | * 101 | * \brief This is a slightly modified aes cmac implementation to simplify block 102 | * index handling 103 | * 104 | * @param ctx[in] the siv context providing the key for the MAC operation 105 | * @param ad[in] the additional data 106 | * @param ad_len[in] the length of the additional data (must be 107 | * AES_BLOCK_SIZE) 108 | * @param msg[in] the message to compute the CMAC of 109 | * @param mlen[in] the length of the message 110 | * @param C[out] the resulting CMAC 111 | */ 112 | void sbdi_bl_aes_cmac(siv_ctx *ctx, const unsigned char *ad, 113 | const int ad_len, const unsigned char *msg, const int mlen, 114 | unsigned char *C); 115 | 116 | 117 | #ifdef __cplusplus 118 | } 119 | #endif 120 | 121 | #endif /* _SIV_H_ */ 122 | -------------------------------------------------------------------------------- /src/sbdi_blic.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) IAIK, Graz University of Technology, 2015. 2 | * All rights reserved. 3 | * Contact: http://opensource.iaik.tugraz.at 4 | * 5 | * This file is part of the Secure Block Device Library. 6 | * 7 | * Commercial License Usage 8 | * Licensees holding valid commercial licenses may use this file in 9 | * accordance with the commercial license agreement provided with the 10 | * Software or, alternatively, in accordance with the terms contained in 11 | * a written agreement between you and SIC. For further information 12 | * contact us at http://opensource.iaik.tugraz.at. 13 | * 14 | * Alternatively, this file may be used under the terms of the GNU General 15 | * Public License as published by the Free Software Foundation version 2. 16 | * 17 | * The Secure Block Device Library is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 20 | * Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with the Secure Block Device Library. If not, see . 24 | */ 25 | /// 26 | /// \file 27 | /// \brief Secure Block Device Block Layer Index Conversion library 28 | /// 29 | /// This header contains all functions used for converting between logic and 30 | /// physical block indices and computing management block index from diverse 31 | /// input indices. 32 | /// 33 | 34 | #ifndef SBDI_BLIC_H_ 35 | #define SBDI_BLIC_H_ 36 | 37 | #include "sbdi_config.h" 38 | 39 | #include 40 | #include 41 | 42 | /*! 43 | * \brief Determines if the given physical block index points to a management 44 | * block 45 | * 46 | * @param phy[in] the physical block index 47 | * @return true if the given physical index points to a management block; 48 | * false otherwise 49 | */ 50 | static inline int sbdi_blic_is_phy_mng_blk(const uint32_t phy) 51 | { 52 | assert(phy > 0); 53 | return ((phy - 1) % (SBDI_MNGT_BLOCK_ENTRIES + 1)) == 0; 54 | } 55 | 56 | /*! 57 | * \brief Determines if the given physical block index points to a data block 58 | * 59 | * @param phy[in] the physical block index 60 | * @return true if the given physical index points to a data block; false 61 | * otherwise 62 | */ 63 | static inline int sbdi_blic_is_phy_dat_blk(const uint32_t phy) 64 | { 65 | assert(phy > 1); 66 | return !sbdi_blic_is_phy_mng_blk(phy); 67 | } 68 | 69 | /*! 70 | * \brief Converts a logical block index into the number of management blocks 71 | * required up to the logical block index 72 | * @param log[in] the logical block index 73 | * @return the number of management blocks required for the given logical 74 | * index 75 | */ 76 | static inline uint32_t sbdi_blic_log_to_mng_blk_nbr(const uint32_t log) 77 | { 78 | return log / SBDI_MNGT_BLOCK_ENTRIES; 79 | } 80 | 81 | /*! 82 | * \brief Converts the given physical block index into the number of 83 | * management blocks required up to the physical index 84 | * @param phy[in] the physical block index 85 | * @return the number of management blocks required for the given physical 86 | * index 87 | */ 88 | static inline uint32_t sbdi_blic_phy_to_mng_blk_nbr(const uint32_t phy) 89 | { 90 | assert(phy > 0); 91 | return (phy - 1) / (SBDI_MNGT_BLOCK_ENTRIES + 1); 92 | } 93 | 94 | /*! 95 | * \brief Converts the given physical block index into the number of 96 | * management blocks required up to the physical index and checks that the 97 | * given index points to a management block 98 | * @param phy_mng[in] the physical management block index 99 | * @return the number of management blocks required for the given physical 100 | * index 101 | */ 102 | static inline uint32_t sbdi_blic_phy_mng_to_mng_blk_nbr(const uint32_t phy_mng) 103 | { 104 | assert(phy_mng > 0); 105 | assert(sbdi_blic_is_phy_mng_blk(phy_mng)); 106 | return (phy_mng - 1) / (SBDI_MNGT_BLOCK_ENTRIES + 1); 107 | } 108 | 109 | /*! 110 | * \brief Converts the given logical index into the physical management block 111 | * index of the management block that stores the management information for 112 | * the logical block specified by the given index 113 | * @param log[in] the logical block index 114 | * @return the physical management block index that stores the management 115 | * information for the data block specified by the given logical index 116 | */ 117 | static inline uint32_t sbdi_blic_log_to_phy_mng_blk(const uint32_t log) 118 | { 119 | return (sbdi_blic_log_to_mng_blk_nbr(log) * (SBDI_MNGT_BLOCK_ENTRIES + 1)) + 1; 120 | } 121 | 122 | /*! 123 | * \brief Converts the given logical data block index into the corresponding 124 | * physical data block index 125 | * @param log[in] the logical data block index to convert 126 | * @return the physical data block index for the given logical block index 127 | */ 128 | static inline uint32_t sbdi_blic_log_to_phy_dat_blk(const uint32_t log) 129 | { 130 | return log + sbdi_blic_log_to_mng_blk_nbr(log) + 2; 131 | } 132 | 133 | /*! 134 | * \brief Computes the position of a data block's tag in its management block 135 | * 136 | * Each data block is associated with a management block. The management 137 | * block stores the block counter used to make the last encryption of the 138 | * data block unique and also the tag(MAC) that was computed of the data 139 | * block. The tag and the counter for a specific data block are stored in the 140 | * management block at a position depending on the data blocks logical index. 141 | * This function computes this position. 142 | * 143 | * @param log[in] the logical data block index 144 | * @return the position of a data block's tag from the management block base 145 | * address 146 | */ 147 | static inline uint32_t sbdi_blic_log_to_mng_tag_pos(const uint32_t log) 148 | { 149 | return log % SBDI_MNGT_BLOCK_ENTRIES; 150 | } 151 | 152 | /*! 153 | * \brief Converts a physical data block index into its corresponding logical 154 | * index 155 | * 156 | * This function asserts that the given index is greater than one (otherwise 157 | * is either points to the header, or is the first management block) and 158 | * makes sure the given physical index does not point to a management block! 159 | * 160 | * @param phy_dat[in] the physical data block index to convert into a logical 161 | * data block index 162 | * @return the logical data block index for the given physical data block 163 | * index 164 | */ 165 | static inline uint32_t sbdi_blic_phy_dat_to_log(const uint32_t phy_dat) 166 | { 167 | assert(phy_dat > 1 && !sbdi_blic_is_phy_mng_blk(phy_dat)); 168 | return (phy_dat - 2) - (phy_dat - 2) / (SBDI_MNGT_BLOCK_ENTRIES + 1); 169 | } 170 | 171 | /*! 172 | * \brief Computes a physical management block index from a physical data 173 | * block index 174 | * 175 | * This function asserts that the given index is greater than one (otherwise 176 | * is either points to the header, or is the first management block) and 177 | * makes sure the given physical index does not point to a management block! 178 | * 179 | * @param phy[in] the physical data block index to compute the physical 180 | * management block index for 181 | * @return the physical management block index for the given physical data 182 | * block index 183 | */ 184 | static inline uint32_t sbdi_blic_phy_dat_to_phy_mng_blk(const uint32_t phy_dat) 185 | { 186 | assert(phy_dat > 1 && !sbdi_blic_is_phy_mng_blk(phy_dat)); 187 | uint32_t tmp = (phy_dat - 2) / (SBDI_MNGT_BLOCK_ENTRIES + 1); 188 | return tmp * (SBDI_MNGT_BLOCK_ENTRIES + 1) + 1; 189 | } 190 | 191 | /*! 192 | * \brief Computes the physical management block index from the given 193 | * management block number 194 | * 195 | * @param mng_blk_nbr[in] the management block number to compute the physical 196 | * management block index for 197 | * @return the physical management block index for the given management 198 | * number 199 | */ 200 | static inline uint32_t sbdi_blic_mng_blk_nbr_to_mng_phy( 201 | const uint32_t mng_blk_nbr) 202 | { 203 | return (mng_blk_nbr * (SBDI_MNGT_BLOCK_ENTRIES + 1)) + 1; 204 | } 205 | 206 | /*! 207 | * \brief computes if the block with the given physical data block index is 208 | * in scope of the management block with the given physical block index 209 | * 210 | * A data block is in scope of a management block if its counter value and 211 | * tag are stored in the management block. This can be computed from the 212 | * physical management block index, by simply adding the amount of entries 213 | * that fit into a management block and see if the physical index of the 214 | * data block is less than or equal to this number: 215 | * 216 | * in_scope(mng_idx, blk_idx) = 217 | * blk_idx > mng_idx && blk_idx <= (mng_idx + MNGT_BLOCK_ENTRIES) 218 | * 219 | * @param phy_mng the physical block index of a management block 220 | * @param phy_dat the physical block index of a data block 221 | * @return true if the data block with the given physical index is in scope 222 | * of the management block with the given index 223 | */ 224 | static inline int sbdi_blic_is_phy_dat_in_phy_mngt_scope(uint32_t phy_mng, 225 | uint32_t phy_dat) 226 | { 227 | return phy_dat > phy_mng && phy_dat <= (phy_mng + SBDI_MNGT_BLOCK_ENTRIES); 228 | } 229 | 230 | #endif /* SBDI_BLIC_H_ */ 231 | -------------------------------------------------------------------------------- /src/sbdi_block.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) IAIK, Graz University of Technology, 2015. 2 | * All rights reserved. 3 | * Contact: http://opensource.iaik.tugraz.at 4 | * 5 | * This file is part of the Secure Block Device Library. 6 | * 7 | * Commercial License Usage 8 | * Licensees holding valid commercial licenses may use this file in 9 | * accordance with the commercial license agreement provided with the 10 | * Software or, alternatively, in accordance with the terms contained in 11 | * a written agreement between you and SIC. For further information 12 | * contact us at http://opensource.iaik.tugraz.at. 13 | * 14 | * Alternatively, this file may be used under the terms of the GNU General 15 | * Public License as published by the Free Software Foundation version 2. 16 | * 17 | * The Secure Block Device Library is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 20 | * Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with the Secure Block Device Library. If not, see . 24 | */ 25 | /// 26 | /// \file 27 | /// \brief Secure Block Device Library block layer interface. 28 | /// 29 | /// The block layer handles all data operations on block granularity. Together 30 | /// with the cache it implements the "plumbing" of the SBD: reading/writing and 31 | /// protecting/checking data blocks. 32 | /// 33 | 34 | #ifdef __cplusplus 35 | extern "C" { 36 | #endif 37 | 38 | #ifndef SBDI_BLOCK_H_ 39 | #define SBDI_BLOCK_H_ 40 | 41 | #include "merkletree.h" 42 | 43 | #include "sbdi_config.h" 44 | #include "sbdi_blic.h" 45 | #include "sbdi_cache.h" 46 | #include "sbdi_ctr_128b.h" 47 | 48 | sbdi_error_t sbdi_bl_sync(void *sbdi, sbdi_block_t *blk); 49 | 50 | sbdi_error_t sbdi_bl_read_block(const sbdi_t *sbdi, sbdi_block_t *blk, 51 | size_t len, uint32_t *read); 52 | 53 | sbdi_error_t sbdi_bl_read_data_block(sbdi_t *sbdi, unsigned char *ptr, 54 | uint32_t idx, size_t off, size_t len); 55 | 56 | sbdi_error_t sbdi_bl_write_data_block(sbdi_t *sbdi, unsigned char *ptr, 57 | uint32_t idx, size_t off, size_t len); 58 | 59 | sbdi_error_t sbdi_bl_verify_block_layer(sbdi_t *sbdi, mt_hash_t root); 60 | 61 | sbdi_error_t sbdi_bl_verify_header(sbdi_t *sbdi, sbdi_block_t *hdr); 62 | 63 | sbdi_error_t sbdi_bl_write_hdr_block(sbdi_t *sbdi, sbdi_block_t *hdr); 64 | 65 | #endif /* SBDI_BLOCK_H_ */ 66 | 67 | #ifdef __cplusplus 68 | } 69 | #endif 70 | -------------------------------------------------------------------------------- /src/sbdi_buffer.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) IAIK, Graz University of Technology, 2015. 2 | * All rights reserved. 3 | * Contact: http://opensource.iaik.tugraz.at 4 | * 5 | * This file is part of the Secure Block Device Library. 6 | * 7 | * Commercial License Usage 8 | * Licensees holding valid commercial licenses may use this file in 9 | * accordance with the commercial license agreement provided with the 10 | * Software or, alternatively, in accordance with the terms contained in 11 | * a written agreement between you and SIC. For further information 12 | * contact us at http://opensource.iaik.tugraz.at. 13 | * 14 | * Alternatively, this file may be used under the terms of the GNU General 15 | * Public License as published by the Free Software Foundation version 2. 16 | * 17 | * The Secure Block Device Library is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 20 | * Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with the Secure Block Device Library. If not, see . 24 | */ 25 | /// 26 | /// \file 27 | /// \brief Memory buffer for reading and writing primitive data types to an 28 | /// untyped memory region (implementation). 29 | /// 30 | #include "sbdi_buffer.h" 31 | #include "sbdi_err.h" 32 | 33 | #include 34 | 35 | /*! 36 | * \brief tests if the given buffer pointer points to a valid SBDI buffer 37 | * @param buf[in] a pointer to the SBDI buffer to validate 38 | * @return true if the buffer is valid; false otherwise 39 | */ 40 | static int sbdi_buffer_is_valid(const sbdi_buffer_t *buf) 41 | { 42 | return (buf && buf->buffer && buf->pos < buf->length); 43 | } 44 | 45 | //---------------------------------------------------------------------- 46 | void sbdi_buffer_init(sbdi_buffer_t *buf, uint8_t *buffer, const size_t length) 47 | { 48 | assert(buf && buffer && length > 0); 49 | buf->buffer = buffer; 50 | buf->length = length; 51 | buf->pos = 0; 52 | } 53 | 54 | //---------------------------------------------------------------------- 55 | void sbdi_buffer_reset(sbdi_buffer_t *buf) 56 | { 57 | assert(buf && buf->buffer && buf->pos <= buf->length); 58 | buf->pos = 0; 59 | } 60 | 61 | //---------------------------------------------------------------------- 62 | uint8_t *sbdi_buffer_get_cptr(const sbdi_buffer_t *buf) 63 | { 64 | assert(sbdi_buffer_is_valid(buf)); 65 | return &buf->buffer[buf->pos]; 66 | } 67 | 68 | //---------------------------------------------------------------------- 69 | uint8_t *sbdi_buffer_get_cptr_off(const sbdi_buffer_t *buf, const uint32_t off) 70 | { 71 | assert(buf && buf->buffer && off < buf->length); 72 | return &buf->buffer[off]; 73 | } 74 | 75 | //---------------------------------------------------------------------- 76 | void sbdi_buffer_add_pos(sbdi_buffer_t *buf, const uint32_t add) 77 | { 78 | assert(sbdi_buffer_is_valid(buf)); 79 | // Overflow protection 80 | assert(buf->pos <= (UINT32_MAX - add)); 81 | assert((buf->pos + add) < buf->length); 82 | buf->pos += add; 83 | } 84 | 85 | //---------------------------------------------------------------------- 86 | void sbdi_buffer_write_uint8_t(sbdi_buffer_t *buf, uint8_t value) 87 | { 88 | assert(sbdi_buffer_is_valid(buf)); 89 | // Overflow protection 90 | assert(buf->pos != UINT32_MAX); 91 | buf->buffer[buf->pos] = value; 92 | buf->pos += 1; 93 | } 94 | 95 | //---------------------------------------------------------------------- 96 | void sbdi_buffer_write_uint16_t(sbdi_buffer_t *buf, uint16_t value) 97 | { 98 | assert(sbdi_buffer_is_valid(buf)); 99 | assert(buf->pos <= buf->length - 2); 100 | sbdi_buffer_write_uint8_t(buf, (value >> 8) & 0xFF); 101 | sbdi_buffer_write_uint8_t(buf, value & 0xFF); 102 | } 103 | 104 | //---------------------------------------------------------------------- 105 | void sbdi_buffer_write_uint32_t(sbdi_buffer_t *buf, uint32_t value) 106 | { 107 | assert(sbdi_buffer_is_valid(buf)); 108 | assert(buf->pos <= buf->length - 4); 109 | sbdi_buffer_write_uint8_t(buf, (value >> 24) & 0xFF); 110 | sbdi_buffer_write_uint8_t(buf, (value >> 16) & 0xFF); 111 | sbdi_buffer_write_uint8_t(buf, (value >> 8) & 0xFF); 112 | sbdi_buffer_write_uint8_t(buf, (value) & 0xFF); 113 | } 114 | 115 | //---------------------------------------------------------------------- 116 | void sbdi_buffer_write_uint64_t(sbdi_buffer_t *buf, const uint64_t value) 117 | { 118 | assert(sbdi_buffer_is_valid(buf)); 119 | assert(buf->pos <= buf->length - 8); 120 | sbdi_buffer_write_uint8_t(buf, (value >> 56) & 0xFF); 121 | sbdi_buffer_write_uint8_t(buf, (value >> 48) & 0xFF); 122 | sbdi_buffer_write_uint8_t(buf, (value >> 40) & 0xFF); 123 | sbdi_buffer_write_uint8_t(buf, (value >> 32) & 0xFF); 124 | sbdi_buffer_write_uint8_t(buf, (value >> 24) & 0xFF); 125 | sbdi_buffer_write_uint8_t(buf, (value >> 16) & 0xFF); 126 | sbdi_buffer_write_uint8_t(buf, (value >> 8) & 0xFF); 127 | sbdi_buffer_write_uint8_t(buf, (value) & 0xFF); 128 | } 129 | 130 | //---------------------------------------------------------------------- 131 | void sbdi_buffer_write_bytes(sbdi_buffer_t *buf, const uint8_t *src, 132 | const size_t length) 133 | { 134 | assert(sbdi_buffer_is_valid(buf)); 135 | // Overflow protection 136 | assert(buf->pos <= (UINT32_MAX - length)); 137 | assert(buf->pos <= buf->length - length); 138 | for (int i = 0; i < length; ++i) { 139 | sbdi_buffer_write_uint8_t(buf, src[i]); 140 | } 141 | } 142 | 143 | //---------------------------------------------------------------------- 144 | void sbdi_buffer_write_ctr_128b(sbdi_buffer_t *buf, const sbdi_ctr_128b_t *ctr) 145 | { 146 | assert(sbdi_buffer_is_valid(buf)); 147 | sbdi_buffer_write_uint64_t(buf, ctr->hi); 148 | sbdi_buffer_write_uint64_t(buf, ctr->lo); 149 | } 150 | 151 | //---------------------------------------------------------------------- 152 | uint8_t sbdi_buffer_read_uint8_t(sbdi_buffer_t *buf) 153 | { 154 | assert(sbdi_buffer_is_valid(buf)); 155 | // Overflow protection 156 | assert(buf->pos != UINT32_MAX); 157 | uint8_t value = buf->buffer[buf->pos]; 158 | buf->pos += 1; 159 | return value; 160 | } 161 | 162 | //---------------------------------------------------------------------- 163 | uint16_t sbdi_buffer_read_uint16_t(sbdi_buffer_t *buf) 164 | { 165 | assert(sbdi_buffer_is_valid(buf)); 166 | assert(buf->pos <= buf->length - 2); 167 | uint16_t value = 0; 168 | value |= ((uint16_t) sbdi_buffer_read_uint8_t(buf)) << 8; 169 | value |= ((uint16_t) sbdi_buffer_read_uint8_t(buf)) << 0; 170 | return value; 171 | } 172 | 173 | //---------------------------------------------------------------------- 174 | uint32_t sbdi_buffer_read_uint32_t(sbdi_buffer_t *buf) 175 | { 176 | assert(sbdi_buffer_is_valid(buf)); 177 | assert(buf->pos <= buf->length - 4); 178 | uint32_t value = 0; 179 | value |= ((uint32_t) sbdi_buffer_read_uint8_t(buf)) << 24; 180 | value |= ((uint32_t) sbdi_buffer_read_uint8_t(buf)) << 16; 181 | value |= ((uint32_t) sbdi_buffer_read_uint8_t(buf)) << 8; 182 | value |= ((uint32_t) sbdi_buffer_read_uint8_t(buf)) << 0; 183 | return value; 184 | } 185 | 186 | //---------------------------------------------------------------------- 187 | uint64_t sbdi_buffer_read_uint64_t(sbdi_buffer_t *buf) 188 | { 189 | assert(sbdi_buffer_is_valid(buf)); 190 | assert(buf->pos <= buf->length - 8); 191 | uint64_t value = 0; 192 | value |= ((uint64_t) sbdi_buffer_read_uint8_t(buf)) << 56; 193 | value |= ((uint64_t) sbdi_buffer_read_uint8_t(buf)) << 48; 194 | value |= ((uint64_t) sbdi_buffer_read_uint8_t(buf)) << 40; 195 | value |= ((uint64_t) sbdi_buffer_read_uint8_t(buf)) << 32; 196 | value |= ((uint64_t) sbdi_buffer_read_uint8_t(buf)) << 24; 197 | value |= ((uint64_t) sbdi_buffer_read_uint8_t(buf)) << 16; 198 | value |= ((uint64_t) sbdi_buffer_read_uint8_t(buf)) << 8; 199 | value |= ((uint64_t) sbdi_buffer_read_uint8_t(buf)) << 0; 200 | return value; 201 | } 202 | 203 | //---------------------------------------------------------------------- 204 | void sbdi_buffer_read_bytes(sbdi_buffer_t *buf, uint8_t *dest, 205 | const size_t length) 206 | { 207 | assert(sbdi_buffer_is_valid(buf)); 208 | // Overflow protection 209 | assert(buf->pos <= (UINT32_MAX - length)); 210 | assert(buf->pos <= buf->length - length); 211 | for (int i = 0; i < length; ++i) { 212 | dest[i] = sbdi_buffer_read_uint8_t(buf); 213 | } 214 | } 215 | 216 | //---------------------------------------------------------------------- 217 | sbdi_error_t sbdi_buffer_read_ctr_128b(sbdi_buffer_t *buf, sbdi_ctr_128b_t *ctr) 218 | { 219 | assert(sbdi_buffer_is_valid(buf)); 220 | uint64_t hi = sbdi_buffer_read_uint64_t(buf); 221 | uint64_t lo = sbdi_buffer_read_uint64_t(buf); 222 | return sbdi_ctr_128b_init(ctr, hi, lo); 223 | } 224 | -------------------------------------------------------------------------------- /src/sbdi_buffer.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) IAIK, Graz University of Technology, 2015. 2 | * All rights reserved. 3 | * Contact: http://opensource.iaik.tugraz.at 4 | * 5 | * This file is part of the Secure Block Device Library. 6 | * 7 | * Commercial License Usage 8 | * Licensees holding valid commercial licenses may use this file in 9 | * accordance with the commercial license agreement provided with the 10 | * Software or, alternatively, in accordance with the terms contained in 11 | * a written agreement between you and SIC. For further information 12 | * contact us at http://opensource.iaik.tugraz.at. 13 | * 14 | * Alternatively, this file may be used under the terms of the GNU General 15 | * Public License as published by the Free Software Foundation version 2. 16 | * 17 | * The Secure Block Device Library is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 20 | * Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with the Secure Block Device Library. If not, see . 24 | */ 25 | /// 26 | /// \file 27 | /// \brief Memory buffer for reading and writing primitive data types to an 28 | /// untyped memory region (interface). 29 | /// 30 | 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #endif 34 | 35 | #ifndef SBDI_BUFFER_H_ 36 | #define SBDI_BUFFER_H_ 37 | 38 | #include 39 | #include 40 | 41 | #include "sbdi_ctr_128b.h" 42 | 43 | /*! 44 | * \brief defines data type for reading and writing data to and from a byte 45 | * buffer 46 | */ 47 | typedef struct sbdi_buffer { 48 | uint8_t *buffer; //!< the actual byte data buffer 49 | size_t length; //!< the total length of the buffer in bytes 50 | size_t pos; //!< the current position where the next read or write operation will be performed 51 | } sbdi_buffer_t; 52 | 53 | /*! 54 | * \brief initializes the given buffer with the given data buffer pointer and 55 | * buffer size 56 | * 57 | * @param buf[inout] a pointer to the buffer to initialize 58 | * @param buffer[in] the data buffer pointer to wrap with the SBDI buffer 59 | * @param length[in] the length in bytes of the data buffer 60 | */ 61 | void sbdi_buffer_init(sbdi_buffer_t *buf, uint8_t *buffer, const size_t length); 62 | 63 | /*! 64 | * \brief Resets the buffer position to zero 65 | * 66 | * @param buf[inout] a pointer to the buffer to reset 67 | */ 68 | void sbdi_buffer_reset(sbdi_buffer_t *buf); 69 | 70 | /*! 71 | * \brief Returns a pointer to the data buffer underlying the SBDI buffer 72 | * that points to the current offset of the SBDI buffer 73 | * 74 | * Basically, this function provides unsafe access to the underlying data 75 | * buffer. The caller must ensure that the position is updated, if necessary. 76 | * 77 | * @param buf[in] a pointer to the buffer from which to extract the pointer 78 | * @return a pointer to the underlying data buffer at the current SBDI buffer 79 | * offset 80 | */ 81 | uint8_t *sbdi_buffer_get_cptr(const sbdi_buffer_t *buf); 82 | 83 | /*! 84 | * \brief Returns a pointer to the data buffer underlying the SBDI buffer 85 | * that points to the specified byte offset 86 | * 87 | * Basically, this function provides unsafe access to the underlying data 88 | * buffer. The caller must ensure that the position is updated, if necessary. 89 | * The function ensures that the given offset is less then the length of the 90 | * buffer. 91 | * 92 | * @param buf[in] a pointer to the buffer from which to extract the pointer 93 | * @param off[in] the byte offset into the buffer (must be less than the 94 | * length of the buffer) 95 | * @return a pointer to the underlying data buffer at the specified offset 96 | */ 97 | uint8_t *sbdi_buffer_get_cptr_off(const sbdi_buffer_t *buf, const uint32_t off); 98 | 99 | /*! 100 | * \brief Add a value to the position pointer (offset) of the SBDI buffer 101 | * 102 | * @param buf[inout] a pointer to the buffer to update 103 | * @param add[in] the value to add to the position 104 | */ 105 | void sbdi_buffer_add_pos(sbdi_buffer_t *buf, const uint32_t add); 106 | 107 | /*! 108 | * \brief Writes the given unsigned 8 bit integer into the buffer 109 | * 110 | * @param buf[inout] a pointer to the buffer to which to write 111 | * @param value[in] the value to write 112 | */ 113 | void sbdi_buffer_write_uint8_t(sbdi_buffer_t *buf, uint8_t value); 114 | 115 | /*! 116 | * \brief Writes the given unsigned 16 bit integer into the buffer 117 | * 118 | * @param buf[inout] a pointer to the buffer to which to write 119 | * @param value[in] the value to write 120 | */ 121 | void sbdi_buffer_write_uint16_t(sbdi_buffer_t *buf, uint16_t value); 122 | 123 | /*! 124 | * \brief Writes the given unsigned 32 bit integer into the buffer 125 | * 126 | * @param buf[inout] a pointer to the buffer to which to write 127 | * @param value[in] the value to write 128 | */ 129 | void sbdi_buffer_write_uint32_t(sbdi_buffer_t *buf, const uint32_t value); 130 | 131 | /*! 132 | * \brief Writes the given unsigned 64 bit integer into the buffer 133 | * 134 | * @param buf[inout] a pointer to the buffer to which to write 135 | * @param value[in] the value to write 136 | */ 137 | void sbdi_buffer_write_uint64_t(sbdi_buffer_t *buf, const uint64_t value); 138 | 139 | /*! 140 | * \brief Writes length bytes from src into the buffer 141 | * 142 | * @param buf[inout] a pointer to the buffer to write to 143 | * @param src[in] a pointer to the data buffer to read from 144 | * @param length[in] the number of bytes to copy from src into the buffer 145 | */ 146 | void sbdi_buffer_write_bytes(sbdi_buffer_t *buf, const uint8_t *src, 147 | const size_t length); 148 | 149 | /*! 150 | * \brief Writes the given 128 bit counter into the buffer 151 | * 152 | * @param buf[inout] a pointer to the buffer to write to 153 | * @param ctr[in] a pointer to the 128 bit counter to write into the buffer 154 | */ 155 | void sbdi_buffer_write_ctr_128b(sbdi_buffer_t *buf, const sbdi_ctr_128b_t *ctr); 156 | 157 | /*! 158 | * \brief Reads a unsigned 8 bit integer from the buffer 159 | * 160 | * @param buf[inout] a pointer to the buffer from which to read 161 | * @return the unsigned 8 bit integer read from the buffer 162 | */ 163 | uint8_t sbdi_buffer_read_uint8_t(sbdi_buffer_t *buf); 164 | 165 | /*! 166 | * \brief Reads a unsigned 16 bit integer from the buffer 167 | * 168 | * @param buf[inout] a pointer to the buffer from which to read 169 | * @return the unsigned 16 bit integer read from the buffer 170 | */ 171 | uint16_t sbdi_buffer_read_uint16_t(sbdi_buffer_t *buf); 172 | 173 | /*! 174 | * \brief Reads a unsigned 32 bit integer from the buffer 175 | * 176 | * @param buf[inout] a pointer to the buffer from which to read 177 | * @return the unsigned 32 bit integer read from the buffer 178 | */ 179 | uint32_t sbdi_buffer_read_uint32_t(sbdi_buffer_t *buf); 180 | 181 | /*! 182 | * \brief Reads a unsigned 64 bit integer from the buffer 183 | * 184 | * @param buf[inout] a pointer to the buffer from which to read 185 | * @return the unsigned 64 bit integer read from the buffer 186 | */ 187 | uint64_t sbdi_buffer_read_uint64_t(sbdi_buffer_t *buf); 188 | 189 | /*! 190 | * \brief Reads length bytes from the buffer and writes them into dest 191 | * 192 | * @param buf[inout] a pointer to the buffer to read from 193 | * @param dest[inout] a pointer to the byte buffer to write to 194 | * @param length[in] the number of bytes to copy from the buffer to dest 195 | */ 196 | void sbdi_buffer_read_bytes(sbdi_buffer_t *buf, uint8_t *dest, 197 | const size_t length); 198 | 199 | /*! 200 | * \brief Reads a 128b counter from the buffer 201 | * 202 | * @param buf[inout] a pointer to the buffer to read from 203 | * @param ctr[out] a pointer to the 128 bit counter to read from the buffer 204 | * @returns SBDI_SUCCESS if the counter could be initialized; 205 | * SBDI_ILLEGAL_PARAM otherwise 206 | */ 207 | sbdi_error_t sbdi_buffer_read_ctr_128b(sbdi_buffer_t *buf, sbdi_ctr_128b_t *ctr); 208 | 209 | #endif /* SBDI_BUFFER_H_ */ 210 | 211 | #ifdef __cplusplus 212 | } 213 | #endif 214 | -------------------------------------------------------------------------------- /src/sbdi_config.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) IAIK, Graz University of Technology, 2015. 2 | * All rights reserved. 3 | * Contact: http://opensource.iaik.tugraz.at 4 | * 5 | * This file is part of the Secure Block Device Library. 6 | * 7 | * Commercial License Usage 8 | * Licensees holding valid commercial licenses may use this file in 9 | * accordance with the commercial license agreement provided with the 10 | * Software or, alternatively, in accordance with the terms contained in 11 | * a written agreement between you and SIC. For further information 12 | * contact us at http://opensource.iaik.tugraz.at. 13 | * 14 | * Alternatively, this file may be used under the terms of the GNU General 15 | * Public License as published by the Free Software Foundation version 2. 16 | * 17 | * The Secure Block Device Library is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 20 | * Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with the Secure Block Device Library. If not, see . 24 | */ 25 | /// 26 | /// \file 27 | /// \brief Specifies global data types. 28 | /// 29 | #ifndef SBDI_CONFIG_H_ 30 | #define SBDI_CONFIG_H_ 31 | 32 | #include "config.h" 33 | #include "sbdi_err.h" 34 | 35 | #include 36 | #include 37 | #include 38 | 39 | #define SBDI_BLOCK_INDEX_INVALID UINT32_MAX 40 | 41 | /*! 42 | * \brief the tag data type for the integrity tags used by the secure block 43 | * device interface 44 | */ 45 | typedef uint8_t sbdi_tag_t[SBDI_BLOCK_TAG_SIZE]; 46 | 47 | /*! 48 | * \brief the packed representation of the counter used to make every 49 | * encryption unique 50 | * 51 | * The runtime representation of the the counter might differ from its data 52 | * at rest state. This data type defines how much space a packed counter 53 | * needs. 54 | */ 55 | typedef uint8_t sbdi_ctr_pkd_t[SBDI_BLOCK_CTR_SIZE]; 56 | 57 | /*! 58 | * \brief the block data data type for storing actual block data 59 | */ 60 | typedef uint8_t sbdi_bl_data_t[SBDI_BLOCK_SIZE]; 61 | 62 | typedef struct secure_block_device_interface sbdi_t; 63 | 64 | /*! 65 | * \brief the basic block data type combining a block index with the block 66 | * data 67 | * 68 | * The block itself does not distinguish between physical block indexes and 69 | * logical block indices. The user of this data type has to take care of the 70 | * semantic of the index. 71 | */ 72 | typedef struct sbdi_block { 73 | uint32_t idx; //!< the block index 74 | sbdi_bl_data_t *data; //!< a pointer to the actual block data 75 | } sbdi_block_t; 76 | 77 | /*! 78 | * \brief Initializes a secure block device interface block with the given 79 | * block index and block data pointer 80 | * 81 | * This function is purely for initialization, the block needs to be 82 | * allocated first by the caller. 83 | * 84 | * @param blk[inout] a pointer to the block to initialize 85 | * @param blk_idx[in] the index of the block 86 | * @param blk_data[in] a pointer to the block data 87 | */ 88 | static inline void sbdi_block_init(sbdi_block_t *blk, const uint32_t blk_idx, 89 | sbdi_bl_data_t *blk_data) 90 | { 91 | assert(blk && blk_idx < SBDI_BLOCK_INDEX_INVALID); 92 | blk->idx = blk_idx; 93 | blk->data = blk_data; 94 | } 95 | 96 | /*! 97 | * \brief Invalidates a given secure block device block by setting its block 98 | * index to SBDI_BLOCK_INDEX_INVALID 99 | * @param blk[in] a pointer to the block to invalidate 100 | */ 101 | static inline void sbdi_block_invalidate(sbdi_block_t *blk) 102 | { 103 | assert(blk); 104 | blk->idx = SBDI_BLOCK_INDEX_INVALID; 105 | blk->data = NULL; 106 | } 107 | 108 | /*! 109 | * \brief Determines if the given physical block index is valid 110 | * 111 | * This function checks if the given physical block index value is less than 112 | * or equal to the maximum physical block index. 113 | * 114 | * @param phy[in] the physical block index value to check 115 | * @return true if the given physical block index value is less than or equal 116 | * to the maximum physical block index value; false otherwise 117 | */ 118 | static inline int sbdi_block_is_valid_phy(const uint32_t phy) 119 | { 120 | return phy <= SBDI_BLK_MAX_PHY; 121 | } 122 | 123 | /*! 124 | * \brief Determines if the given logical block index is valid 125 | * 126 | * This function checks if the given logical block index value is less than 127 | * or equal to the maximum logical block index. 128 | * 129 | * @param log[in] the logical block index value to check 130 | * @return true if the given logical block index value is less than or equal 131 | * to the maximum logical block index value; false otherwise 132 | */ 133 | static inline int sbdi_block_is_valid_log(const uint32_t log) 134 | { 135 | return log <= SBDI_BLK_MAX_PHY; 136 | } 137 | 138 | #endif /* SBDI_CONFIG_H_ */ 139 | -------------------------------------------------------------------------------- /src/sbdi_crypto.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) IAIK, Graz University of Technology, 2015. 2 | * All rights reserved. 3 | * Contact: http://opensource.iaik.tugraz.at 4 | * 5 | * This file is part of the Secure Block Device Library. 6 | * 7 | * Commercial License Usage 8 | * Licensees holding valid commercial licenses may use this file in 9 | * accordance with the commercial license agreement provided with the 10 | * Software or, alternatively, in accordance with the terms contained in 11 | * a written agreement between you and SIC. For further information 12 | * contact us at http://opensource.iaik.tugraz.at. 13 | * 14 | * Alternatively, this file may be used under the terms of the GNU General 15 | * Public License as published by the Free Software Foundation version 2. 16 | * 17 | * The Secure Block Device Library is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 20 | * Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with the Secure Block Device Library. If not, see . 24 | */ 25 | /// 26 | /// \file 27 | /// \brief Specifies the Secure Block Device Library's cryptographic 28 | /// abstraction layer. 29 | /// 30 | /// The cryptographic abstraction layer hides the implementation of the actual 31 | /// authenticating encryption used to achieve the data security goals. It also 32 | /// hides the implementation of the message authentication code used to 33 | /// protect the integrity of the management blocks. 34 | /// 35 | 36 | #ifdef __cplusplus 37 | extern "C" { 38 | #endif 39 | 40 | #ifndef SBDI_CRYPTO_H_ 41 | #define SBDI_CRYPTO_H_ 42 | 43 | #include "sbdi_config.h" 44 | #include "sbdi_ctr_128b.h" 45 | 46 | #include 47 | 48 | typedef uint8_t sbdi_key_t[32]; 49 | 50 | typedef sbdi_error_t (*sbdi_encrypt)(void *ctx, const uint8_t *pt, 51 | const int pt_len, const sbdi_ctr_128b_t *ctr, const uint32_t blk_nbr, 52 | uint8_t *ct, sbdi_tag_t tag); 53 | 54 | typedef sbdi_error_t (*sbdi_decrypt)(void *ctx, const uint8_t *ct, 55 | const int ct_len, const sbdi_ctr_pkd_t ctr, const uint32_t blk_nbr, 56 | uint8_t *pt, const sbdi_tag_t tag); 57 | 58 | typedef sbdi_error_t (*sbdi_mac)(void *ctx, const unsigned char *msg, 59 | const int mlen, unsigned char *C, const unsigned char *ad, const int ad_len); 60 | 61 | typedef struct sbdi_crypto { 62 | void *ctx; 63 | sbdi_encrypt enc; 64 | sbdi_decrypt dec; 65 | sbdi_mac mac; 66 | } sbdi_crypto_t; 67 | 68 | #endif /* SBDI_CRYPTO_H_ */ 69 | 70 | #ifdef __cplusplus 71 | } 72 | #endif 73 | -------------------------------------------------------------------------------- /src/sbdi_crypto_type.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) IAIK, Graz University of Technology, 2015. 2 | * All rights reserved. 3 | * Contact: http://opensource.iaik.tugraz.at 4 | * 5 | * This file is part of the Secure Block Device Library. 6 | * 7 | * Commercial License Usage 8 | * Licensees holding valid commercial licenses may use this file in 9 | * accordance with the commercial license agreement provided with the 10 | * Software or, alternatively, in accordance with the terms contained in 11 | * a written agreement between you and SIC. For further information 12 | * contact us at http://opensource.iaik.tugraz.at. 13 | * 14 | * Alternatively, this file may be used under the terms of the GNU General 15 | * Public License as published by the Free Software Foundation version 2. 16 | * 17 | * The Secure Block Device Library is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 20 | * Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with the Secure Block Device Library. If not, see . 24 | */ 25 | /// 26 | /// \file 27 | /// \brief Specifies the data type used to select the cryptographic abstraction 28 | /// layer to use for the cryptographic operations. 29 | /// 30 | /// The Secure Block Device Library supports a number of different 31 | /// cryptographic operations for providing the data security. 32 | /// 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | #ifndef SBDI_CRYPTO_TYPE_H_ 38 | #define SBDI_CRYPTO_TYPE_H_ 39 | 40 | #include "sbdi_config.h" 41 | 42 | /*! 43 | * \brief Used to select which cryptographic abstraction layer to use 44 | */ 45 | typedef enum sbdi_crypto_type { 46 | SBDI_CRYPTO_NONE = SBDI_CRYPTO_TYPE_NONE, /*!< Crypto operations implemented as no operations */ //!< SBDI_CRYPTO_NONE 47 | SBDI_CRYPTO_SIV = SBDI_CRYPTO_TYPE_SIV, /*!< Crypto operations implemented using the SIV authenticated encryption mode of operation with AES *///!< SBDI_CRYPTO_SIV 48 | SBDI_CRYPTO_OCB = SBDI_CRYPTO_TYPE_OCB, /*!< Crypto operations implemented using the OCB authenticated encryption mode of operation with AES */ //!< SBDI_CRYPTO_OCB 49 | SBDI_CRYPTO_HMAC = SBDI_CRYPTO_TYPE_HMAC, /*!< Cryptographic abstraction layer that uses CBC and HMAC for its cryptographic operations */ 50 | } sbdi_crypto_type_t; 51 | 52 | #endif /* SBDI_CRYPTO_TYPE_H_ */ 53 | 54 | #ifdef __cplusplus 55 | } 56 | #endif 57 | -------------------------------------------------------------------------------- /src/sbdi_ctr_128b.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) IAIK, Graz University of Technology, 2015. 2 | * All rights reserved. 3 | * Contact: http://opensource.iaik.tugraz.at 4 | * 5 | * This file is part of the Secure Block Device Library. 6 | * 7 | * Commercial License Usage 8 | * Licensees holding valid commercial licenses may use this file in 9 | * accordance with the commercial license agreement provided with the 10 | * Software or, alternatively, in accordance with the terms contained in 11 | * a written agreement between you and SIC. For further information 12 | * contact us at http://opensource.iaik.tugraz.at. 13 | * 14 | * Alternatively, this file may be used under the terms of the GNU General 15 | * Public License as published by the Free Software Foundation version 2. 16 | * 17 | * The Secure Block Device Library is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 20 | * Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with the Secure Block Device Library. If not, see . 24 | */ 25 | /// 26 | /// \file 27 | /// \brief Implements a 128-bit counter 28 | /// 29 | #include "sbdi_ctr_128b.h" 30 | 31 | #include 32 | #include 33 | 34 | //---------------------------------------------------------------------- 35 | sbdi_error_t sbdi_ctr_128b_init(sbdi_ctr_128b_t *ctr, uint64_t hi, uint64_t lo) 36 | { 37 | if (!ctr) { 38 | return SBDI_ERR_ILLEGAL_PARAM; 39 | } 40 | ctr->hi = hi; 41 | ctr->lo = lo; 42 | return SBDI_SUCCESS; 43 | } 44 | //---------------------------------------------------------------------- 45 | sbdi_error_t sbdi_ctr_128b_reset(sbdi_ctr_128b_t *ctr) 46 | { 47 | if (!ctr) { 48 | return SBDI_ERR_ILLEGAL_PARAM; 49 | } 50 | ctr->hi = 0; 51 | ctr->lo = 0; 52 | return SBDI_SUCCESS; 53 | } 54 | //---------------------------------------------------------------------- 55 | sbdi_error_t sbdi_ctr_128b_inc(sbdi_ctr_128b_t *ctr) 56 | { 57 | if (!ctr) { 58 | return SBDI_ERR_ILLEGAL_PARAM; 59 | } 60 | if (ctr->lo == UINT64_MAX) { 61 | if (ctr->hi == UINT64_MAX) { 62 | return SBDI_ERR_ILLEGAL_STATE; 63 | } else { 64 | ctr->lo = 0; 65 | ctr->hi += 1; 66 | } 67 | } else { 68 | ctr->lo += 1; 69 | } 70 | return SBDI_SUCCESS; 71 | } 72 | //---------------------------------------------------------------------- 73 | sbdi_error_t sbdi_ctr_128b_dec(sbdi_ctr_128b_t *ctr) 74 | { 75 | if (!ctr) { 76 | return SBDI_ERR_ILLEGAL_PARAM; 77 | } 78 | if (ctr->lo == 0) { 79 | if (ctr->hi == 0) { 80 | return SBDI_ERR_ILLEGAL_STATE; 81 | } else { 82 | ctr->lo = UINT64_MAX; 83 | ctr->hi -= 1; 84 | } 85 | } else { 86 | ctr->lo -= 1; 87 | } 88 | return SBDI_SUCCESS; 89 | } 90 | //---------------------------------------------------------------------- 91 | sbdi_error_t sbdi_ctr_128b_cmp(const sbdi_ctr_128b_t *ctr1, 92 | const sbdi_ctr_128b_t *ctr2, int *res) 93 | { 94 | if (!ctr1 || !ctr2 || !res) { 95 | return SBDI_ERR_ILLEGAL_PARAM; 96 | } 97 | if (ctr1->hi == ctr2->hi) { 98 | if (ctr1->lo == ctr2->lo) { 99 | // Identical 100 | *res = 0; 101 | } else { 102 | // Counter differing in low part 103 | if (ctr1->lo < ctr2->lo) { 104 | *res = -1; 105 | } else { 106 | *res = 1; 107 | } 108 | } 109 | } else { 110 | // Counter differing in high part 111 | if (ctr1->hi < ctr2->hi) { 112 | *res = -1; 113 | } else { 114 | *res = 1; 115 | } 116 | } 117 | return SBDI_SUCCESS; 118 | } 119 | 120 | //---------------------------------------------------------------------- 121 | void sbdi_ctr_128b_print(sbdi_ctr_128b_t *ctr) 122 | { 123 | if (!ctr) { 124 | fprintf(stderr, "[ERROR][sbdi_ctr_128b_print]: Counter is NULL"); 125 | return; 126 | } 127 | printf("0x%" PRIx64 "%" PRIx64 "\n", ctr->hi, ctr->lo); 128 | } 129 | //---------------------------------------------------------------------- 130 | -------------------------------------------------------------------------------- /src/sbdi_ctr_128b.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) IAIK, Graz University of Technology, 2015. 2 | * All rights reserved. 3 | * Contact: http://opensource.iaik.tugraz.at 4 | * 5 | * This file is part of the Secure Block Device Library. 6 | * 7 | * Commercial License Usage 8 | * Licensees holding valid commercial licenses may use this file in 9 | * accordance with the commercial license agreement provided with the 10 | * Software or, alternatively, in accordance with the terms contained in 11 | * a written agreement between you and SIC. For further information 12 | * contact us at http://opensource.iaik.tugraz.at. 13 | * 14 | * Alternatively, this file may be used under the terms of the GNU General 15 | * Public License as published by the Free Software Foundation version 2. 16 | * 17 | * The Secure Block Device Library is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 20 | * Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with the Secure Block Device Library. If not, see . 24 | */ 25 | /// 26 | /// \file 27 | /// \brief Specifies the interface of a 128-bit counter. 28 | /// 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | #ifndef SBDI_CTR_128B_H_ 34 | #define SBDI_CTR_128B_H_ 35 | 36 | #include "sbdi_err.h" 37 | #include 38 | 39 | #define SBDI_CTR_128B_SIZE 16 40 | 41 | typedef struct sbdi_counter_128bit { 42 | uint64_t hi; 43 | uint64_t lo; 44 | } sbdi_ctr_128b_t; 45 | 46 | sbdi_error_t sbdi_ctr_128b_init(sbdi_ctr_128b_t *ctr, uint64_t hi, uint64_t lo); 47 | sbdi_error_t sbdi_ctr_128b_reset(sbdi_ctr_128b_t *ctr); 48 | sbdi_error_t sbdi_ctr_128b_inc(sbdi_ctr_128b_t *ctr); 49 | sbdi_error_t sbdi_ctr_128b_dec(sbdi_ctr_128b_t *ctr); 50 | sbdi_error_t sbdi_ctr_128b_cmp(const sbdi_ctr_128b_t *ctr1, const sbdi_ctr_128b_t *ctr2, 51 | int *res); 52 | void sbdi_ctr_128b_print(sbdi_ctr_128b_t *ctr); 53 | 54 | #endif /* SBDI_CTR_128B_H_ */ 55 | 56 | #ifdef __cplusplus 57 | } 58 | #endif 59 | -------------------------------------------------------------------------------- /src/sbdi_debug.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) IAIK, Graz University of Technology, 2015. 2 | * All rights reserved. 3 | * Contact: http://opensource.iaik.tugraz.at 4 | * 5 | * This file is part of the Secure Block Device Library. 6 | * 7 | * Commercial License Usage 8 | * Licensees holding valid commercial licenses may use this file in 9 | * accordance with the commercial license agreement provided with the 10 | * Software or, alternatively, in accordance with the terms contained in 11 | * a written agreement between you and SIC. For further information 12 | * contact us at http://opensource.iaik.tugraz.at. 13 | * 14 | * Alternatively, this file may be used under the terms of the GNU General 15 | * Public License as published by the Free Software Foundation version 2. 16 | * 17 | * The Secure Block Device Library is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 20 | * Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with the Secure Block Device Library. If not, see . 24 | */ 25 | /// 26 | /// \file 27 | /// \brief Implements functions used to debug the Secure Block Device Library. 28 | /// 29 | #include "sbdi_cache.h" 30 | 31 | #include 32 | #include 33 | 34 | #ifdef SBDI_DEBUG 35 | int debug = 1; 36 | #else 37 | int debug = 0; 38 | #endif 39 | 40 | void sbdi_dbg_print_delim() 41 | { 42 | #ifndef SBDI_NO_DEBUG 43 | printf( 44 | "================================================================================\n"); 45 | #endif 46 | } 47 | 48 | void sbdi_dbg_print_block(sbdi_block_t *blk) 49 | { 50 | assert(blk); 51 | #ifndef SBDI_NO_DEBUG 52 | printf("[BLK]: {0x%08" PRIx32 ", %p}\n", blk->idx, (void *) blk->data); 53 | #endif 54 | } 55 | 56 | void sbdi_dbg_print_sbdi_bl_write_data_block_params(unsigned char *ptr, 57 | uint32_t idx, size_t off, size_t len) 58 | { 59 | #ifndef SBDI_NO_DEBUG 60 | printf("[SBDI_BL_WRITE_DB]: (ptr: %p, idx: %" PRIu32 ", off: %zx, len: %zx)\n", ptr, 61 | idx, off, len); 62 | #endif 63 | } 64 | 65 | void sbdi_dbg_print_cache_idx(sbdi_bc_t *cache) 66 | { 67 | assert(cache); 68 | #ifndef SBDI_NO_DEBUG 69 | sbdi_bc_idx_t *idx = &cache->index; 70 | printf("[IDX]: Least Recently Used: %02" PRIu32 "\n", idx->lru); 71 | for (uint32_t i = 0; i < SBDI_CACHE_MAX_SIZE; ++i) { 72 | printf("[IDX][%02" PRIu32 "]:{0x%08" PRIx32 ", %02" PRIu32, i, 73 | idx->list[i].block_idx, idx->list[i].cache_idx); 74 | char dirty = (sbdi_bc_is_elem_dirty(cache, i)) ? 'd' : ' '; 75 | sbdi_bc_bt_t t = sbdi_bc_get_blk_type(cache, i); 76 | char type = ' '; 77 | switch (t) { 78 | case SBDI_BC_BT_DATA: 79 | type = 'd'; 80 | break; 81 | case SBDI_BC_BT_MNGT: 82 | type = 'm'; 83 | break; 84 | default: 85 | type = 'e'; 86 | break; 87 | } 88 | printf(", [%c%c]}\n", dirty, type); 89 | } 90 | #endif 91 | } 92 | -------------------------------------------------------------------------------- /src/sbdi_debug.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) IAIK, Graz University of Technology, 2015. 2 | * All rights reserved. 3 | * Contact: http://opensource.iaik.tugraz.at 4 | * 5 | * This file is part of the Secure Block Device Library. 6 | * 7 | * Commercial License Usage 8 | * Licensees holding valid commercial licenses may use this file in 9 | * accordance with the commercial license agreement provided with the 10 | * Software or, alternatively, in accordance with the terms contained in 11 | * a written agreement between you and SIC. For further information 12 | * contact us at http://opensource.iaik.tugraz.at. 13 | * 14 | * Alternatively, this file may be used under the terms of the GNU General 15 | * Public License as published by the Free Software Foundation version 2. 16 | * 17 | * The Secure Block Device Library is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 20 | * Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with the Secure Block Device Library. If not, see . 24 | */ 25 | /// 26 | /// \file 27 | /// \brief Specifies functions used to debug the Secure Block Device Library. 28 | /// 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | #ifndef SBDI_DEBUG_H_ 34 | #define SBDI_DEBUG_H_ 35 | 36 | #include "sbdi_cache.h" 37 | 38 | extern int debug; 39 | 40 | #define SBDI_DBG(f) do {if (debug) {(f);}} while (0) 41 | 42 | void sbdi_dbg_print_delim(); 43 | void sbdi_dbg_print_block(sbdi_block_t *blk); 44 | void sbdi_dbg_print_cache_idx(sbdi_bc_t *cache); 45 | void sbdi_dbg_print_sbdi_bl_write_data_block_params(unsigned char *ptr, 46 | uint32_t idx, size_t off, size_t len); 47 | 48 | #endif /* SBDI_DEBUG_H_ */ 49 | 50 | #ifdef __cplusplus 51 | } 52 | #endif 53 | -------------------------------------------------------------------------------- /src/sbdi_err.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) IAIK, Graz University of Technology, 2015. 2 | * All rights reserved. 3 | * Contact: http://opensource.iaik.tugraz.at 4 | * 5 | * This file is part of the Secure Block Device Library. 6 | * 7 | * Commercial License Usage 8 | * Licensees holding valid commercial licenses may use this file in 9 | * accordance with the commercial license agreement provided with the 10 | * Software or, alternatively, in accordance with the terms contained in 11 | * a written agreement between you and SIC. For further information 12 | * contact us at http://opensource.iaik.tugraz.at. 13 | * 14 | * Alternatively, this file may be used under the terms of the GNU General 15 | * Public License as published by the Free Software Foundation version 2. 16 | * 17 | * The Secure Block Device Library is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 20 | * Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with the Secure Block Device Library. If not, see . 24 | */ 25 | /// 26 | /// \file 27 | /// \brief Global error codes an error handling macros. 28 | /// 29 | #ifndef SBDI_ERR_H_ 30 | #define SBDI_ERR_H_ 31 | 32 | /*! 33 | * \brief Used to convey error information, if a secure block device 34 | * interface operation fails. 35 | */ 36 | typedef enum sbdi_error { 37 | SBDI_SUCCESS = 0, /*!< Operation terminated successfully */ 38 | SBDI_ERR_OUT_Of_MEMORY = -1, /*!< There was not enough memory to complete the operation */ 39 | SBDI_ERR_ILLEGAL_PARAM = -2, /*!< At least one of the specified parameters was illegal */ 40 | SBDI_ERR_ILLEGAL_STATE = -3, /*!< The operation reached an illegal state */ 41 | SBDI_ERR_IO = -4, /*!< An I/O error occurred */ 42 | SBDI_ERR_IO_MISSING_BLOCK = -5, //!< Missing block 43 | SBDI_ERR_IO_MISSING_DATA = -6, /*!< Incomplete block */ 44 | SBDI_ERR_UNSUPPORTED = -7, /*!< This operation or data format is not supported */ 45 | SBDI_ERR_TAG_MISMATCH = -8, /*!< Cryptographic tag validation failed */ 46 | SBDI_ERR_CRYPTO_FAIL = -9, /*!< The cryptographic layer fails to perform an operation such as an encryption */ 47 | SBDI_ERR_UNSPECIFIED = -255 /*!< A general error occurred */ 48 | } sbdi_error_t; 49 | 50 | /*! 51 | * \brief wraps a given expression (e.g. a function call) with a test if the 52 | * result of the expression is MT_SUCCESS. If this is not the case, then the 53 | * macro returns the error code 54 | */ 55 | #define SBDI_ERR_CHK(f) do {sbdi_error_t r = (f);if (r != SBDI_SUCCESS) {return r;}} while (0) 56 | 57 | /*! 58 | * \brief wraps a given expression and if the expression evaluates to false 59 | * returns SBDI_ERR_ILLEGAL_PARAM 60 | */ 61 | #define SBDI_CHK_PARAM(p) do {if (!(p)) {return SBDI_ERR_ILLEGAL_PARAM;}} while (0) 62 | 63 | #endif /* SBDI_ERR_H_ */ 64 | -------------------------------------------------------------------------------- /src/sbdi_hdr.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) IAIK, Graz University of Technology, 2015. 2 | * All rights reserved. 3 | * Contact: http://opensource.iaik.tugraz.at 4 | * 5 | * This file is part of the Secure Block Device Library. 6 | * 7 | * Commercial License Usage 8 | * Licensees holding valid commercial licenses may use this file in 9 | * accordance with the commercial license agreement provided with the 10 | * Software or, alternatively, in accordance with the terms contained in 11 | * a written agreement between you and SIC. For further information 12 | * contact us at http://opensource.iaik.tugraz.at. 13 | * 14 | * Alternatively, this file may be used under the terms of the GNU General 15 | * Public License as published by the Free Software Foundation version 2. 16 | * 17 | * The Secure Block Device Library is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 20 | * Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with the Secure Block Device Library. If not, see . 24 | */ 25 | /// 26 | /// \file 27 | /// \brief Manages Secure Block Device headers. 28 | /// 29 | #include "sbdi_siv.h" 30 | #include "sbdi_nocrypto.h" 31 | #include "sbdi_ocb.h" 32 | #include "sbdi_hmac.h" 33 | #include "sbdi_hdr.h" 34 | #include "sbdi_buffer.h" 35 | 36 | #include "SecureBlockDeviceInterface.h" 37 | 38 | #include 39 | 40 | //---------------------------------------------------------------------- 41 | void sbdi_hdr_v1_derive_key(siv_ctx *master, sbdi_hdr_v1_sym_key_t key, 42 | uint8_t *n1, size_t n1_len, uint8_t *n2, size_t n2_len) 43 | { 44 | memset(key, 0, sizeof(sbdi_hdr_v1_sym_key_t)); 45 | vprf(master, key, 1, n1, n1_len); 46 | vprf(master, key + SBDI_BLOCK_TAG_SIZE, 1, n2, n2_len); 47 | } 48 | 49 | /*! 50 | * \brief Determines if the given key type is supported by this header 51 | * library implementation 52 | * 53 | * @param type the key type to validate 54 | * @return true if the key type is supported (valid); false otherwise 55 | */ 56 | static inline int hdr_is_key_type_valid(const sbdi_hdr_v1_key_type_t type) 57 | { 58 | return (type == SBDI_HDR_KEY_TYPE_NONE) || (type == SBDI_HDR_KEY_TYPE_OCB) 59 | || (type == SBDI_HDR_KEY_TYPE_SIV) || (type == SBDI_HDR_KEY_TYPE_HMAC); 60 | } 61 | 62 | //---------------------------------------------------------------------- 63 | sbdi_error_t sbdi_hdr_v1_create(sbdi_hdr_v1_t **hdr, 64 | const sbdi_hdr_v1_key_type_t type, const sbdi_hdr_v1_sym_key_t key) 65 | { 66 | SBDI_CHK_PARAM( 67 | hdr && key && hdr_is_key_type_valid(type)); 68 | sbdi_hdr_v1_t *h = calloc(1, sizeof(sbdi_hdr_v1_t)); 69 | if (!h) { 70 | return SBDI_ERR_OUT_Of_MEMORY; 71 | } 72 | memcpy(h->id.magic, SBDI_HDR_MAGIC, SBDI_HDR_MAGIC_LEN); 73 | h->id.version = SBDI_HDR_VERSION_1; 74 | sbdi_error_t r = sbdi_ctr_128b_init(&h->ctr, 0, 0); 75 | if (r != SBDI_SUCCESS) { 76 | free(h); 77 | return r; 78 | } 79 | h->type = type; 80 | // Tag will be created once the header is written 81 | // Copy previously created key into header 82 | memcpy(h->key, key, sizeof(sbdi_hdr_v1_sym_key_t)); 83 | *hdr = h; 84 | return SBDI_SUCCESS; 85 | } 86 | 87 | void sbdi_hdr_v1_delete(sbdi_hdr_v1_t *hdr) 88 | { 89 | if (!hdr) { 90 | return; 91 | } 92 | memset(hdr, 0, sizeof(sbdi_hdr_v1_t)); 93 | free(hdr); 94 | } 95 | 96 | //---------------------------------------------------------------------- 97 | sbdi_error_t sbdi_hdr_v1_read(sbdi_t *sbdi, siv_ctx *master) 98 | { 99 | SBDI_CHK_PARAM(sbdi && master); 100 | sbdi_hdr_v1_t *h = calloc(1, sizeof(sbdi_hdr_v1_t)); 101 | if (!h) { 102 | return SBDI_ERR_OUT_Of_MEMORY; 103 | } 104 | sbdi->write_store[0].idx = 0; 105 | uint32_t rd; 106 | sbdi_block_t *rd_buf = sbdi->write_store; 107 | sbdi_error_t r = sbdi_bl_read_block(sbdi, rd_buf, SBDI_BLOCK_SIZE, &rd); 108 | if (r != SBDI_SUCCESS) { 109 | free(h); 110 | return r; 111 | } 112 | sbdi_buffer_t b; 113 | sbdi_buffer_init(&b, *sbdi->write_store[0].data, SBDI_HDR_V1_PACKED_SIZE); 114 | sbdi_buffer_read_bytes(&b, h->id.magic, SBDI_HDR_MAGIC_LEN); 115 | if (memcmp(h->id.magic, SBDI_HDR_MAGIC, SBDI_HDR_MAGIC_LEN)) { 116 | free(h); 117 | return SBDI_ERR_ILLEGAL_STATE; 118 | } 119 | h->id.version = sbdi_buffer_read_uint32_t(&b); 120 | if (h->id.version > SBDI_HDR_SUPPORTED_VERSION) { 121 | free(h); 122 | return SBDI_ERR_UNSUPPORTED; 123 | } 124 | h->size = sbdi_buffer_read_uint64_t(&b); 125 | r = sbdi_buffer_read_ctr_128b(&b, &h->ctr); 126 | if (r != SBDI_SUCCESS) { 127 | free(h); 128 | return r; 129 | } 130 | h->type = sbdi_buffer_read_uint32_t(&b); 131 | if (!hdr_is_key_type_valid(h->type)) { 132 | free(h); 133 | return SBDI_ERR_UNSUPPORTED; 134 | } 135 | uint8_t *kptr = sbdi_buffer_get_cptr(&b); 136 | sbdi_buffer_add_pos(&b, SBDI_HDR_V1_KEY_MAX_SIZE); 137 | sbdi_buffer_read_bytes(&b, h->tag, SBDI_HDR_V1_TAG_SIZE); 138 | int cr = siv_decrypt(master, kptr, h->key, SBDI_HDR_V1_KEY_MAX_SIZE, h->tag, 139 | 0); 140 | if (cr == -1) { 141 | free(h); 142 | return SBDI_ERR_TAG_MISMATCH; 143 | } 144 | switch (h->type) { 145 | case SBDI_HDR_KEY_TYPE_NONE: 146 | r = sbdi_nocrypto_create(&sbdi->crypto, h->key); 147 | if (r != SBDI_SUCCESS) { 148 | free(h); 149 | return r; 150 | } 151 | break; 152 | case SBDI_HDR_KEY_TYPE_SIV: 153 | r = sbdi_siv_create(&sbdi->crypto, h->key); 154 | if (r != SBDI_SUCCESS) { 155 | // Cleanup of secret information must be handled by next layer up 156 | free(h); 157 | return r; 158 | } 159 | break; 160 | case SBDI_HDR_KEY_TYPE_OCB: 161 | r = sbdi_ocb_create(&sbdi->crypto, h->key); 162 | if (r != SBDI_SUCCESS) { 163 | // Cleanup of header SIV must be handled next layer up 164 | free(h); 165 | return r; 166 | } 167 | break; 168 | case SBDI_HDR_KEY_TYPE_HMAC: 169 | r = sbdi_hmac_create(&sbdi->crypto, h->key); 170 | if (r != SBDI_SUCCESS) { 171 | // Cleanup of header SIV must be handled next layer up 172 | free(h); 173 | return r; 174 | } 175 | break; 176 | default: 177 | free(h); 178 | return SBDI_ERR_UNSUPPORTED; 179 | } 180 | r = sbdi_bl_verify_header(sbdi, rd_buf); 181 | if (r != SBDI_SUCCESS) { 182 | free(h); 183 | return r; 184 | } 185 | sbdi->hdr = h; 186 | return SBDI_SUCCESS; 187 | } 188 | 189 | //---------------------------------------------------------------------- 190 | sbdi_error_t sbdi_hdr_v1_write(sbdi_t *sbdi, siv_ctx *master) 191 | { 192 | SBDI_CHK_PARAM(sbdi); 193 | sbdi_hdr_v1_t *hdr = sbdi->hdr; 194 | uint8_t *wrt_buf = *sbdi->write_store[0].data; 195 | memset(wrt_buf, 0, SBDI_BLOCK_SIZE); 196 | sbdi_buffer_t b; 197 | sbdi->write_store[0].idx = 0; 198 | sbdi_buffer_init(&b, wrt_buf, SBDI_HDR_V1_PACKED_SIZE); 199 | sbdi_buffer_write_bytes(&b, hdr->id.magic, SBDI_HDR_MAGIC_LEN); 200 | sbdi_buffer_write_uint32_t(&b, hdr->id.version); 201 | sbdi_buffer_write_uint64_t(&b, hdr->size); 202 | sbdi_buffer_write_ctr_128b(&b, &hdr->ctr); 203 | sbdi_buffer_write_uint32_t(&b, hdr->type); 204 | uint8_t *kptr = sbdi_buffer_get_cptr(&b); 205 | sbdi_buffer_add_pos(&b, SBDI_HDR_V1_KEY_MAX_SIZE); 206 | uint8_t *tptr = sbdi_buffer_get_cptr(&b); 207 | siv_encrypt(master, hdr->key, kptr, SBDI_HDR_V1_KEY_MAX_SIZE, tptr, 0); 208 | return sbdi_bl_write_hdr_block(sbdi, sbdi->write_store); 209 | } 210 | 211 | //---------------------------------------------------------------------- 212 | void sbdi_hdr_v1_update_size(sbdi_t *sbdi, const size_t size) 213 | { 214 | sbdi->hdr->size = size; 215 | } 216 | 217 | //---------------------------------------------------------------------- 218 | uint64_t sbdi_hdr_v1_get_size(sbdi_t *sbdi) 219 | { 220 | return (size_t) sbdi->hdr->size; 221 | } 222 | -------------------------------------------------------------------------------- /src/sbdi_hdr.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) IAIK, Graz University of Technology, 2015. 2 | * All rights reserved. 3 | * Contact: http://opensource.iaik.tugraz.at 4 | * 5 | * This file is part of the Secure Block Device Library. 6 | * 7 | * Commercial License Usage 8 | * Licensees holding valid commercial licenses may use this file in 9 | * accordance with the commercial license agreement provided with the 10 | * Software or, alternatively, in accordance with the terms contained in 11 | * a written agreement between you and SIC. For further information 12 | * contact us at http://opensource.iaik.tugraz.at. 13 | * 14 | * Alternatively, this file may be used under the terms of the GNU General 15 | * Public License as published by the Free Software Foundation version 2. 16 | * 17 | * The Secure Block Device Library is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 20 | * Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with the Secure Block Device Library. If not, see . 24 | */ 25 | /// 26 | /// \file 27 | /// \brief Specifies interface for handling Secure Block Device headers. 28 | /// 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | #ifndef SBDI_HDR_H_ 34 | #define SBDI_HDR_H_ 35 | 36 | #include "sbdi_config.h" 37 | #include "sbdi_buffer.h" 38 | #include "sbdi_ctr_128b.h" 39 | #include "sbdi_block.h" 40 | 41 | #include 42 | 43 | #include 44 | 45 | #define SBDI_HDR_VERSION_1 1u 46 | #define SBDI_HDR_MAGIC_LEN 8u 47 | 48 | #define SBDI_HDR_SUPPORTED_VERSION SBDI_HDR_VERSION_1 49 | 50 | #define SBDI_HDR_V1_PACKED_SIZE 88u 51 | #define SBDI_HDR_V1_KEY_MAX_SIZE 32u 52 | #define SBDI_HDR_V1_TAG_SIZE SBDI_BLOCK_TAG_SIZE 53 | #define SBDI_HDR_V1_KEY_INVALID 0 54 | #define SBDI_HDR_V1_KEY_SIV 1 55 | #define SBDI_HDR_V1_KEY_OCB 2 56 | #define SBDI_HDR_V1_KEY_HMAC 3 57 | #define SBDI_HDR_V1_KEY_NONE 65535 58 | 59 | typedef uint8_t sbdi_hdr_magic_t[SBDI_HDR_MAGIC_LEN]; 60 | typedef uint8_t sbdi_hdr_v1_sym_key_t[SBDI_HDR_V1_KEY_MAX_SIZE]; 61 | 62 | typedef enum sbdi_hdr_v1_key_type { 63 | SBDI_HDR_KEY_TYPE_INVALID = SBDI_HDR_V1_KEY_INVALID, 64 | SBDI_HDR_KEY_TYPE_NONE = SBDI_HDR_V1_KEY_NONE, 65 | SBDI_HDR_KEY_TYPE_SIV = SBDI_HDR_V1_KEY_SIV, 66 | SBDI_HDR_KEY_TYPE_OCB = SBDI_HDR_V1_KEY_OCB, 67 | SBDI_HDR_KEY_TYPE_HMAC = SBDI_HDR_V1_KEY_HMAC, 68 | } sbdi_hdr_v1_key_type_t; 69 | 70 | static const sbdi_hdr_magic_t SBDI_HDR_MAGIC = { 0xA1, 0x1D, 0x1F, 0xDE, 0xAD, 71 | 0xDA, 0x7A, 0xFF }; 72 | 73 | /*! 74 | * \brief holds the information necessary to identify a secure block device 75 | * interface header and its version 76 | */ 77 | typedef struct secure_block_device_interface_header_id { 78 | sbdi_hdr_magic_t magic; //!< the magic number identifying a secure block device interface 79 | uint32_t version; //!< the version of the secure block device interface header 80 | } sbdi_hdr_id_t; 81 | 82 | /*! 83 | * \brief the secure block device interface header 84 | */ 85 | typedef struct secure_block_device_interface_header_v1 { 86 | sbdi_hdr_id_t id; //!< the secure block device interface identification information 87 | uint64_t size; //!< the current size of the secure block device in bytes 88 | sbdi_ctr_128b_t ctr; //!< access counter protecting the header against replay attacks 89 | sbdi_hdr_v1_key_type_t type; //!< type of the key used to protect the secure block device 90 | sbdi_hdr_v1_sym_key_t key; //!< the plaintext secure block device key 91 | sbdi_tag_t tag; //!< the tag protecting the integrity of the key 92 | } sbdi_hdr_v1_t; 93 | 94 | void sbdi_hdr_v1_derive_key(siv_ctx *master, sbdi_hdr_v1_sym_key_t key, 95 | uint8_t *n1, size_t n1_len, uint8_t *n2, size_t n2_len); 96 | 97 | /*! 98 | * \brief creates a new secure block device v1 header 99 | * 100 | * This function follows a callee allocates, callee frees pattern. To release 101 | * the memory associated with the header and also clean up any key data left 102 | * in memory call the corresponding sbdi_delete_hdr_v1 function. 103 | * 104 | * @param hdr[out] an out pointer to the header set by this function on 105 | * successful header creation 106 | * @param type[in] the key type that is encrypted in the header (OCB || SIV) 107 | * @param key[in] the plaintext symmetric SBDI v1 key to store in this header 108 | * @return SBDI_SUCCESS if the header could be created successfully; 109 | * SBDI_ERR_OUT_Of_MEMORY if the space for the header could not be 110 | * allocated; 111 | * SBDI_ERR_ILLEGAL_PARAM if any of the given parameters is null. 112 | */ 113 | sbdi_error_t sbdi_hdr_v1_create(sbdi_hdr_v1_t **hdr, 114 | const sbdi_hdr_v1_key_type_t type, const sbdi_hdr_v1_sym_key_t key); 115 | 116 | /*! 117 | * \brief Overwrites the key data and frees the memory allocated for the 118 | * secure block device v1 header 119 | * 120 | * @param hdr[in] the pointer to the header to delete 121 | */ 122 | void sbdi_hdr_v1_delete(sbdi_hdr_v1_t *hdr); 123 | 124 | /*! 125 | * \brief tries to read a SBDI v1 header from from the secure block device 126 | * 127 | * This function follows a callee allocates, callee frees pattern. To release 128 | * the memory associated with the header and also clean up any key data left 129 | * in memory call the corresponding sbdi_delete_hdr_v1 function. 130 | * 131 | * This function tries to decrypt the SBDI specific key stored in the header. 132 | * 133 | * @param sbdi[inout] a pointer to the secure block device interface to read the 134 | * header from, and also store the header 135 | * @param master[in] a pointer to the SIV context of the master key 136 | * @return SBDI_SUCCESS if the header could be read successfully; 137 | * SBDI_ERR_ILLEGAL_PARAM if any of the given parameters is null, or 138 | * the Merkle tree is inconsistent; 139 | * SBDI_ERR_OUT_Of_MEMORY if the space for the header could not be 140 | * allocated; 141 | * SBDI_ERR_IO if there is an I/O error when reading from the SBDI; 142 | * SBDI_ERR_IO_MISSING_BLOCK if there is no header block; 143 | * SBDI_ERR_IO_MISSING_DATA if the header was incompletely written; 144 | * SBDI_ERR_ILLEGAL_STATE if the written header magic does not match, 145 | * or if updating the Merkle tree fails; 146 | * SBDI_ERR_UNSUPPORTED if the written version is higher than the 147 | * supported version; 148 | * SBDI_ERR_TAG_MISMATCH if the key in the header has been modified. 149 | */ 150 | sbdi_error_t sbdi_hdr_v1_read(sbdi_t *sbdi, siv_ctx *master); 151 | 152 | /*! 153 | * \brief Writes a secure block device interface header v1 to the SBDI 154 | * 155 | * This function encrypts the SBDI specific key before writing the header. 156 | * 157 | * @param sbdi[in] a pointer to the secure block device interface to write 158 | * the header to, and it also contains the header to write 159 | * @param hdr[in] a pointer to the header to write to the SBDI 160 | * @param master[in] a pointer to the SIV context of the master key 161 | * @return SBDI_SUCCESS if the header could be written successfully; 162 | * SBDI_ERR_ILLEGAL_PARAM if any of the given parameters is null, or 163 | * the Merkle tree is inconsistent; 164 | * SBDI_ERR_ILLEGAL_STATE if updating the Merkle tree fails; 165 | * SBDI_ERR_IO if there is an I/O error when writing to the SBDI; 166 | * SBDI_ERR_IO_MISSING_BLOCK if nothing could be written 167 | * SBDI_ERR_IO_MISSING_DATA if the header was only partially written; 168 | * SBDI_ERR_TAG_MISMATCH if the key in the header has been modified. 169 | */ 170 | sbdi_error_t sbdi_hdr_v1_write(sbdi_t *sbdi, siv_ctx *master); 171 | 172 | /*! 173 | * \brief Updates the current size of the secure block device in the header 174 | * 175 | * FIXME For now I track the size of the file in the header. This, as well as 176 | * tracking the global counter in the header is susceptible to attacks, as an 177 | * attacker can prevent updating the header. Both the global counter, as well 178 | * as the actual size of secure block device can be recovered from the secure 179 | * block device, if only a suitable mechanism of detecting an out of date 180 | * header is in place. 181 | * One such mechanism might be setting the header to corrupt as soon as 182 | * the secure block device is opened and updating this state in the Merkle 183 | * tree. On close, when the header is written, the flag is cleared and the 184 | * Merkle tree updated appropriately. This way a corrupt header should be 185 | * detected. The global counter value can then be determined by reading all 186 | * management blocks and taking the max global counter found + 1. Determining 187 | * the logical file size requires the use of an appropriate padding 188 | * mechanism. This has yet to be added. 189 | * 190 | * The logical size of the file is stored as an unsigned 64 bit data type. 191 | * This might not match the platform specific size_t type. The caller has to 192 | * make sure to take care of this fact. 193 | * 194 | * @param sbdi[in] a pointer to the secure block device interface to update 195 | * the size of 196 | * @param size the new size of the secure block device 197 | */ 198 | void sbdi_hdr_v1_update_size(sbdi_t *sbdi, const size_t size); 199 | 200 | /*! 201 | * \brief Retrieves the current logical file size from the header 202 | * 203 | * FIXME: This is currently unsafe (see update_size). 204 | * 205 | * The logical size of the file is stored as an unsigned 64 bit data type. 206 | * This might not match the platform specific size_t type. The caller has to 207 | * make sure to take care of this fact. 208 | * 209 | * @param sbdi[in] a pointer to the secure block device interface to get the 210 | * logical secure block device size from 211 | * @return the secure block device size 212 | */ 213 | uint64_t sbdi_hdr_v1_get_size(sbdi_t *sbdi); 214 | 215 | #endif /* SBDI_HDR_H_ */ 216 | 217 | #ifdef __cplusplus 218 | } 219 | #endif 220 | -------------------------------------------------------------------------------- /src/sbdi_pio.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) IAIK, Graz University of Technology, 2015. 2 | * All rights reserved. 3 | * Contact: http://opensource.iaik.tugraz.at 4 | * 5 | * This file is part of the Secure Block Device Library. 6 | * 7 | * Commercial License Usage 8 | * Licensees holding valid commercial licenses may use this file in 9 | * accordance with the commercial license agreement provided with the 10 | * Software or, alternatively, in accordance with the terms contained in 11 | * a written agreement between you and SIC. For further information 12 | * contact us at http://opensource.iaik.tugraz.at. 13 | * 14 | * Alternatively, this file may be used under the terms of the GNU General 15 | * Public License as published by the Free Software Foundation version 2. 16 | * 17 | * The Secure Block Device Library is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 20 | * Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with the Secure Block Device Library. If not, see . 24 | */ 25 | /// 26 | /// \file 27 | /// \brief An implementation of the Secure Block Device Libarary's block 28 | /// device abstraction layer that uses files as storage back end. 29 | /// 30 | 31 | #include "sbdi_pio.h" 32 | 33 | #include 34 | #include 35 | #include 36 | 37 | //---------------------------------------------------------------------- 38 | static ssize_t bl_pread_i(void *iod, void *buf, size_t nbyte, off_t offset) 39 | { 40 | int fd = *((int *)iod); 41 | return pread(fd, buf, nbyte, offset); 42 | } 43 | 44 | //---------------------------------------------------------------------- 45 | static ssize_t bl_pwrite_i(void *iod, const void * buf, size_t nbyte, off_t offset) 46 | { 47 | int fd = *((int *)iod); 48 | return pwrite(fd, buf, nbyte, offset); 49 | } 50 | 51 | //---------------------------------------------------------------------- 52 | static ssize_t bl_generate_seed_i(uint8_t *buf, size_t nbyte) 53 | { 54 | int rfh = open("/dev/random", O_RDONLY); 55 | if (rfh < 0) { 56 | return -1; 57 | } 58 | size_t l = 0; 59 | while (l < nbyte) { 60 | ssize_t r = read(rfh, buf + l, nbyte - l); 61 | if (r < 0) { 62 | close(rfh); 63 | return -1; 64 | } 65 | l += r; 66 | } 67 | close(rfh); 68 | return l; 69 | } 70 | 71 | //---------------------------------------------------------------------- 72 | sbdi_pio_t *sbdi_pio_create(void *iod, off_t size_at_open) 73 | { 74 | sbdi_pio_t *io = calloc(1, sizeof(sbdi_pio_t)); 75 | if (!io) { 76 | return NULL; 77 | } 78 | io->iod = iod; 79 | io->pread = &bl_pread_i; 80 | io->pwrite = &bl_pwrite_i; 81 | io->genseed = &bl_generate_seed_i; 82 | return io; 83 | } 84 | 85 | //---------------------------------------------------------------------- 86 | void sbdi_pio_delete(sbdi_pio_t *io) { 87 | free(io); 88 | } 89 | 90 | -------------------------------------------------------------------------------- /src/sbdi_pio.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) IAIK, Graz University of Technology, 2015. 2 | * All rights reserved. 3 | * Contact: http://opensource.iaik.tugraz.at 4 | * 5 | * This file is part of the Secure Block Device Library. 6 | * 7 | * Commercial License Usage 8 | * Licensees holding valid commercial licenses may use this file in 9 | * accordance with the commercial license agreement provided with the 10 | * Software or, alternatively, in accordance with the terms contained in 11 | * a written agreement between you and SIC. For further information 12 | * contact us at http://opensource.iaik.tugraz.at. 13 | * 14 | * Alternatively, this file may be used under the terms of the GNU General 15 | * Public License as published by the Free Software Foundation version 2. 16 | * 17 | * The Secure Block Device Library is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 20 | * Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with the Secure Block Device Library. If not, see . 24 | */ 25 | /// 26 | /// \file 27 | /// \brief Specifies the interface of the Secure Block Device Library's block 28 | /// device abstraction layer. 29 | /// 30 | /// The block device abstraction layer abstracts the details of the underlying 31 | /// back end storage used by the SBD. 32 | /// 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | #ifndef SBDI_PIO_H_ 38 | #define SBDI_PIO_H_ 39 | 40 | #include 41 | #include 42 | 43 | /*! 44 | * \brief Defines a function pointer similar to pread 45 | * 46 | * @param iod[in] a pointer to the I/O descriptor, e.g. a pointer to a file 47 | * descriptor 48 | * @param buf[out] a pointer to the output buffer 49 | * @param nbyte[in] the number of bytes to read 50 | * @param offset[in] the offset of the data to read 51 | * @return the number of bytes read if successful; -1 otherwise 52 | */ 53 | typedef ssize_t (*bl_pread)(void *iod, void *buf, size_t nbyte, off_t offset); 54 | 55 | /*! 56 | * \brief Defines a pwrite like function pointer 57 | * 58 | * @param iod[in] a pointer to the I/O descriptor, e.g. a pointer to a file 59 | * descriptor 60 | * @param buf[in] a pointer to a buffer containing the data to write 61 | * @param nbyte[in] the number of bytes to write 62 | * @param offset[in] the offset where to write the data 63 | * @return the number of bytes written if successful; -1 otherwise 64 | */ 65 | typedef ssize_t (*bl_pwrite)(void *iod, const void * buf, size_t nbyte, 66 | off_t offset); 67 | 68 | /*! 69 | * \brief Defines a function pointer for a function that generates random 70 | * numbers into a caller created buffer 71 | * 72 | * This function is used to generate the seed information required when 73 | * generating a new secure block device root key. For security reasons this 74 | * should be as close to a true random number generator as possible. 75 | * 76 | * @param buf[out] a pointer to the buffer to fill with random bytes 77 | * @param nbyte[in] the number of random bytes to generate 78 | * @param offset[in] the offset into the given buffer where to start generating 79 | * random bytes 80 | * @return the number of random bytes generated if successful; -1 otherwise 81 | */ 82 | typedef ssize_t (*bl_generate_seed)(uint8_t *buf, size_t nbyte); 83 | 84 | /*! 85 | * \brief wrapper data type to hide pread and pwrite implementation 86 | */ 87 | typedef struct sbdi_pio { 88 | void *iod; //!< I/O descriptor pointer, e.g. file decriptor pointer 89 | bl_pread pread; //!< pread like function pointer 90 | bl_pwrite pwrite; //!< pwrite like function pointer 91 | bl_generate_seed genseed; //!< function pointer to seed generator function 92 | } sbdi_pio_t; 93 | 94 | /*! 95 | * \brief creates a new pio type using pread and pwrite as underlying 96 | * implementation 97 | * 98 | * This function follows the callee allocates callee frees pattern. Use 99 | * sbdi_pio_delete to free the memory allocated for the pio type. 100 | * 101 | * @param iod[in] a void pointer to the file descriptor used for the 102 | * underlying pread and pwrite 103 | * @return a pointer to a pio type if successful; NULL otherwise 104 | */ 105 | sbdi_pio_t *sbdi_pio_create(void *iod, off_t size_at_open); 106 | 107 | /*! 108 | * \brief frees the memory allocated for the given pio type 109 | * 110 | * @param pio[in] a pointer to the pio type to delete 111 | */ 112 | void sbdi_pio_delete(sbdi_pio_t *pio); 113 | 114 | #endif /* SBDI_PIO_H_ */ 115 | 116 | #ifdef __cplusplus 117 | } 118 | #endif 119 | -------------------------------------------------------------------------------- /src/sbdi_test.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) IAIK, Graz University of Technology, 2015. 2 | * All rights reserved. 3 | * Contact: http://opensource.iaik.tugraz.at 4 | * 5 | * This file is part of the Secure Block Device Library. 6 | * 7 | * Commercial License Usage 8 | * Licensees holding valid commercial licenses may use this file in 9 | * accordance with the commercial license agreement provided with the 10 | * Software or, alternatively, in accordance with the terms contained in 11 | * a written agreement between you and SIC. For further information 12 | * contact us at http://opensource.iaik.tugraz.at. 13 | * 14 | * Alternatively, this file may be used under the terms of the GNU General 15 | * Public License as published by the Free Software Foundation version 2. 16 | * 17 | * The Secure Block Device Library is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 20 | * Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with the Secure Block Device Library. If not, see . 24 | */ 25 | /// 26 | /// \file 27 | /// \brief Dummy application. If you are looking for an example of how to use 28 | /// the Secure Block Device Library have a look at the tests directory, 29 | /// especially the SbdiTest.cpp file contained therein. 30 | /// 31 | #include "SecureBlockDeviceInterface.h" 32 | 33 | int main() { 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /tests/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | .depend 3 | secure-block-test 4 | -------------------------------------------------------------------------------- /tests/AesSivTest.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) IAIK, Graz University of Technology, 2015. 2 | * All rights reserved. 3 | * Contact: http://opensource.iaik.tugraz.at 4 | * 5 | * This file is part of the Secure Block Device Library. 6 | * 7 | * Commercial License Usage 8 | * Licensees holding valid commercial licenses may use this file in 9 | * accordance with the commercial license agreement provided with the 10 | * Software or, alternatively, in accordance with the terms contained in 11 | * a written agreement between you and SIC. For further information 12 | * contact us at http://opensource.iaik.tugraz.at. 13 | * 14 | * Alternatively, this file may be used under the terms of the GNU General 15 | * Public License as published by the Free Software Foundation version 2. 16 | * 17 | * The Secure Block Device Library is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 20 | * Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with the Secure Block Device Library. If not, see . 24 | */ 25 | /// 26 | /// \file 27 | /// \brief Tests the SIV implementaion used by the Secure Block Device Library. 28 | /// 29 | #include "crypto/siv.h" 30 | 31 | #include 32 | #include 33 | 34 | #include 35 | 36 | #define PT_LEN 14 37 | #define PT2_LEN 16 38 | #define IV_LEN 16 39 | #define AD_LEN 24 40 | 41 | class AesSivTest: public CppUnit::TestFixture { 42 | CPPUNIT_TEST_SUITE( AesSivTest ); 43 | CPPUNIT_TEST(testSivEncryption); 44 | CPPUNIT_TEST(testSivDecryption); 45 | CPPUNIT_TEST(testSivInplaceEnDecryption); 46 | CPPUNIT_TEST(testSivAesCmac); 47 | CPPUNIT_TEST_SUITE_END(); 48 | 49 | private: 50 | static unsigned char SIV_KEYS[32]; 51 | static unsigned char PLAIN_TEXT[PT_LEN]; 52 | static unsigned char PLAIN_TEXT_2[IV_LEN]; 53 | static unsigned char PLAIN_TEXT_3[IV_LEN*2]; 54 | static unsigned char AD_H1[AD_LEN]; 55 | 56 | static unsigned char TV_CIPHER_TEXT[PT_LEN]; 57 | static unsigned char TV_IV[IV_LEN]; 58 | 59 | siv_ctx ctx; 60 | siv_ctx tst; 61 | unsigned char CIPHER_TEXT[PT_LEN]; 62 | unsigned char IV[IV_LEN]; 63 | 64 | unsigned char tst_mem[PT2_LEN * 10]; 65 | unsigned char iv_mem[IV_LEN * 10]; 66 | 67 | public: 68 | void setUp() 69 | { 70 | siv_init(&ctx, SIV_KEYS, SIV_256); 71 | siv_init(&tst, SIV_KEYS, SIV_256); 72 | memset(tst_mem, 0, PT2_LEN * 10); 73 | memset(iv_mem, 0, IV_LEN * 10); 74 | } 75 | 76 | void tearDown() 77 | { 78 | siv_restart(&ctx); 79 | siv_restart(&tst); 80 | } 81 | 82 | void testSivEncryption() 83 | { 84 | siv_encrypt(&ctx, PLAIN_TEXT, CIPHER_TEXT, PT_LEN, IV, 1, AD_H1, AD_LEN); 85 | CPPUNIT_ASSERT(!memcmp(CIPHER_TEXT, TV_CIPHER_TEXT, PT_LEN)); 86 | CPPUNIT_ASSERT(!memcmp(IV, TV_IV, IV_LEN)); 87 | } 88 | 89 | void testSivDecryption() 90 | { 91 | unsigned char DECRYPTED_PT[PT_LEN]; 92 | siv_encrypt(&ctx, PLAIN_TEXT, CIPHER_TEXT, PT_LEN, IV, 1, AD_H1, AD_LEN); 93 | siv_decrypt(&ctx, CIPHER_TEXT, DECRYPTED_PT, PT_LEN, IV, 1, AD_H1, AD_LEN); 94 | CPPUNIT_ASSERT(!memcmp(PLAIN_TEXT, DECRYPTED_PT, PT_LEN)); 95 | } 96 | 97 | inline unsigned char *tstMemIdx(unsigned idx) 98 | { 99 | return tst_mem + idx * PT2_LEN; 100 | } 101 | 102 | inline unsigned char *ivMemIdx(unsigned idx) 103 | { 104 | return iv_mem + idx * IV_LEN; 105 | } 106 | 107 | inline void enc(const unsigned char *pt, unsigned char *ct, unsigned char *iv, 108 | int len) 109 | { 110 | CPPUNIT_ASSERT(siv_encrypt(&ctx, pt, ct, len, iv, 1, AD_H1, AD_LEN) != -1); 111 | } 112 | 113 | inline void enc2(const unsigned char *pt, unsigned char *ct, 114 | unsigned char *iv, int len) 115 | { 116 | CPPUNIT_ASSERT(siv_encrypt(&tst, pt, ct, len, iv, 1, AD_H1, AD_LEN) != -1); 117 | } 118 | 119 | inline void dec(const unsigned char *ct, unsigned char *pt, unsigned char *iv, 120 | int len) 121 | { 122 | CPPUNIT_ASSERT(siv_decrypt(&ctx, ct, pt, len, iv, 1, AD_H1, AD_LEN) != -1); 123 | } 124 | 125 | inline void dec2(const unsigned char *ct, unsigned char *pt, 126 | unsigned char *iv, int len) 127 | { 128 | CPPUNIT_ASSERT(siv_decrypt(&tst, ct, pt, len, iv, 1, AD_H1, AD_LEN) != -1); 129 | } 130 | 131 | void testSivInplaceEnDecryption() 132 | { 133 | enc(PLAIN_TEXT_2, tstMemIdx(0), ivMemIdx(0), PT2_LEN); 134 | enc(tstMemIdx(0), tstMemIdx(1), ivMemIdx(1), PT2_LEN); 135 | enc(PLAIN_TEXT_2, tstMemIdx(2), ivMemIdx(2), PT2_LEN); 136 | enc(tstMemIdx(2), tstMemIdx(2), ivMemIdx(9), PT2_LEN); 137 | CPPUNIT_ASSERT(!memcmp(tstMemIdx(1), tstMemIdx(2), PT2_LEN)); 138 | dec(tstMemIdx(1), tstMemIdx(3), ivMemIdx(1), PT2_LEN); 139 | CPPUNIT_ASSERT(!memcmp(tstMemIdx(0), tstMemIdx(3), PT2_LEN)); 140 | dec(tstMemIdx(3), tstMemIdx(4), ivMemIdx(0), PT2_LEN); 141 | CPPUNIT_ASSERT(!memcmp(PLAIN_TEXT_2, tstMemIdx(4), PT2_LEN)); 142 | dec(tstMemIdx(2), tstMemIdx(2), ivMemIdx(9), PT2_LEN); 143 | dec(tstMemIdx(2), tstMemIdx(2), ivMemIdx(2), PT2_LEN); 144 | CPPUNIT_ASSERT(!memcmp(PLAIN_TEXT_2, tstMemIdx(2), PT2_LEN)); 145 | } 146 | 147 | void testSivCtxSwitches() 148 | { 149 | enc(PLAIN_TEXT_2, tstMemIdx(0), ivMemIdx(0), PT2_LEN); 150 | enc2(tstMemIdx(0), tstMemIdx(1), ivMemIdx(1), PT2_LEN); 151 | dec(tstMemIdx(1), tstMemIdx(3), ivMemIdx(1), PT2_LEN); 152 | dec2(tstMemIdx(3), tstMemIdx(4), ivMemIdx(0), PT2_LEN); 153 | } 154 | 155 | void testSivAesCmac() { 156 | memcpy(iv_mem, PLAIN_TEXT_2, PT2_LEN); 157 | memcpy(iv_mem + PT2_LEN, PLAIN_TEXT_3, IV_LEN*2); 158 | sbdi_bl_aes_cmac(&ctx, PLAIN_TEXT_2, PT2_LEN, PLAIN_TEXT_3, IV_LEN*2, tstMemIdx(0)); 159 | aes_cmac(&tst, iv_mem, (IV_LEN * 3), tstMemIdx(1)); 160 | CPPUNIT_ASSERT(!memcmp(tstMemIdx(0), tstMemIdx(1), PT2_LEN)); 161 | CPPUNIT_ASSERT(memcmp(tstMemIdx(0), tstMemIdx(2), PT2_LEN)); 162 | } 163 | 164 | }; 165 | 166 | unsigned char AesSivTest::SIV_KEYS[32] = { 167 | // Part 1: fffefdfc fbfaf9f8 f7f6f5f4 f3f2f1f0 168 | 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 169 | 0xf3, 0xf2, 0xf1, 0xf0, 170 | // Part 2: f0f1f2f3 f4f5f6f7 f8f9fafb fcfdfeff 171 | 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 172 | 0xfc, 0xfd, 0xfe, 0xff }; 173 | 174 | unsigned char AesSivTest::PLAIN_TEXT[PT_LEN] = { 175 | // 11223344 55667788 99aabbcc ddee 176 | 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 177 | 0xdd, 0xee }; 178 | 179 | unsigned char AesSivTest::PLAIN_TEXT_2[IV_LEN] = { 0x00, 0x11, 0x22, 0x33, 0x44, 180 | 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; 181 | 182 | unsigned char AesSivTest::PLAIN_TEXT_3[IV_LEN*2] = { 183 | 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x00, 0x11, 184 | 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 185 | 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 186 | 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F 187 | }; 188 | 189 | unsigned char AesSivTest::AD_H1[24] = { 190 | //AD (H1) 10111213 14151617 18191a1b 1c1d1e1f 191 | // 20212223 24252627 192 | 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 193 | 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27 }; 194 | 195 | unsigned char AesSivTest::TV_CIPHER_TEXT[14] = { 196 | // 40c02b96 90c4dc04 daef7f6a fe5c 197 | 0x40, 0xc0, 0x2b, 0x96, 0x90, 0xc4, 0xdc, 0x04, 0xda, 0xef, 0x7f, 0x6a, 198 | 0xfe, 0x5c }; 199 | unsigned char AesSivTest::TV_IV[16] = { 200 | // 85632d07 c6e8f37f 950acd32 0a2ecc93 201 | 0x85, 0x63, 0x2d, 0x07, 0xc6, 0xe8, 0xf3, 0x7f, 0x95, 0x0a, 0xcd, 0x32, 202 | 0x0a, 0x2e, 0xcc, 0x93 }; 203 | 204 | CPPUNIT_TEST_SUITE_REGISTRATION(AesSivTest); 205 | -------------------------------------------------------------------------------- /tests/Makefile: -------------------------------------------------------------------------------- 1 | Q=@ 2 | VGRUN = valgrind --tool=memcheck 3 | VGPROF = valgrind --tool=callgrind --dump-instr=yes --cacheuse=yes 4 | 5 | LDFLAGS += -lcppunit -ggdb $(EXTRA_LDFLAGS) 6 | CFLAGS += -Wall -ggdb -std=gnu++11 $(EXTRA_CFLAGS) 7 | CXXFLAGS += -Wall -ggdb -std=gnu++11 $(EXTRA_CXXFLAGS) 8 | CPPFLAGS += -std=gnu++11 -I../src/crypto/ -I../src/ -I../../merkle-tree/src 9 | 10 | TST_DEP_FILE = .depend 11 | TST_CXX_SRC = AesSivTest.cpp SbdiCtrTest.cpp SbdiCacheTest.cpp SbdiTestRunner.cpp SbdiBlockLayerTest.cpp SbdiTest.cpp 12 | TST_CXX_OBJS = $(TST_CXX_SRC:%.cpp=%.o) 13 | TST_SRC = $(TST_CXX_SRC) 14 | TST_OBJS = $(TST_CXX_OBJS) 15 | TST_LIB = -Wl,--start-group ../../merkle-tree/src/libMerkleTree.a ../src/crypto/libSbdiCrypto.a ../src/libSecureBlock.a -Wl,--end-group 16 | TST_BIN = secure-block-test 17 | 18 | all: dep $(TST_BIN) 19 | 20 | coverage: LDFLAGS +=-ggdb -coverage 21 | coverage: CFLAGS +=-ggdb -fprofile-arcs -ftest-coverage 22 | coverage: dep $(TST_BIN) 23 | 24 | test: $(TST_BIN) 25 | $(Q)$(VGRUN) ./$(TST_BIN) 26 | 27 | prof: $(TST_BIN) 28 | $(Q)$(VGPROF) ./$(TST_BIN) 29 | 30 | .PHONY: clean 31 | clean: 32 | $(Q)rm -Rf $(TST_BIN) $(TST_OBJS) html latex .depend 33 | 34 | $(TST_BIN): $(TST_OBJS) $(TST_LIB) 35 | $(Q)$(CXX) $(CFLAGS) $(CPPFLAGS) -o $(TST_BIN) $(TST_OBJS) $(TST_LIB) $(LDFLAGS) 36 | 37 | $(TST_LIB): 38 | $(Q)$(MAKE) -C ../src/ debug 39 | 40 | dep: $(TST_SRC) 41 | $(Q)$(CXX) $(CPPFLAGS) -MM $(TST_SRC) > $(TST_DEP_FILE) 42 | 43 | -include $(TST_DEP_FILE) 44 | -------------------------------------------------------------------------------- /tests/SbdiBlockLayerTest.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) IAIK, Graz University of Technology, 2015. 2 | * All rights reserved. 3 | * Contact: http://opensource.iaik.tugraz.at 4 | * 5 | * This file is part of the Secure Block Device Library. 6 | * 7 | * Commercial License Usage 8 | * Licensees holding valid commercial licenses may use this file in 9 | * accordance with the commercial license agreement provided with the 10 | * Software or, alternatively, in accordance with the terms contained in 11 | * a written agreement between you and SIC. For further information 12 | * contact us at http://opensource.iaik.tugraz.at. 13 | * 14 | * Alternatively, this file may be used under the terms of the GNU General 15 | * Public License as published by the Free Software Foundation version 2. 16 | * 17 | * The Secure Block Device Library is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 20 | * Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with the Secure Block Device Library. If not, see . 24 | */ 25 | /// 26 | /// \file 27 | /// \brief Tests the Secure Block Device Library's block layer. 28 | /// 29 | /// The block layer handles all data operations on block granularity. Together 30 | /// with the cache it implements the "plumbing" of the SBD: reading/writing and 31 | /// protecting/checking data blocks. 32 | /// 33 | 34 | #ifndef UINT32_MAX 35 | #include 36 | #define UINT32_MAX std::numeric_limits::max() 37 | #endif 38 | #ifndef UINT32_C 39 | #define UINT32_C(c) c ## u 40 | #endif 41 | #ifndef UINT16_MAX 42 | #define UINT16_MAX 65535u 43 | #endif 44 | #ifndef UINT8_MAX 45 | #define UINT8_MAX 255u 46 | #endif 47 | 48 | #include "SbdiTest.h" 49 | #include "SecureBlockDeviceInterface.h" 50 | 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | 57 | #include 58 | 59 | class SbdiBLockLayerTest: public CppUnit::TestFixture { 60 | CPPUNIT_TEST_SUITE( SbdiBLockLayerTest ); 61 | CPPUNIT_TEST(testIndexComp); 62 | CPPUNIT_TEST(testSimpleReadWrite); 63 | CPPUNIT_TEST(testSimpleIntegrityCheck); 64 | CPPUNIT_TEST(testExtendedReadWrite); 65 | CPPUNIT_TEST(testLinearReadWrite);CPPUNIT_TEST_SUITE_END() 66 | ; 67 | 68 | private: 69 | static unsigned char SIV_KEYS[32]; 70 | sbdi_t *sbdi; 71 | unsigned char b[SBDI_BLOCK_SIZE]; 72 | mt_hash_t root; 73 | int fd; 74 | sbdi_pio_t *pio; 75 | 76 | void loadStore() 77 | { 78 | fd = open(FILE_NAME, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); 79 | CPPUNIT_ASSERT(fd != -1); 80 | struct stat s; 81 | CPPUNIT_ASSERT(fstat(fd, &s) == 0); 82 | pio = sbdi_pio_create(&fd, s.st_size); 83 | CPPUNIT_ASSERT(sbdi_open(&sbdi, pio, SBDI_CRYPTO_NONE, SIV_KEYS, root) == SBDI_SUCCESS); 84 | } 85 | 86 | void closeStore() 87 | { 88 | CPPUNIT_ASSERT(sbdi_close(sbdi, SIV_KEYS, root) == SBDI_SUCCESS); 89 | int fd = *(int *) pio->iod; 90 | CPPUNIT_ASSERT(close(fd) != -1); 91 | sbdi_pio_delete (pio); 92 | } 93 | 94 | void deleteStore() 95 | { 96 | memset(root, 0, sizeof(mt_hash_t)); 97 | CPPUNIT_ASSERT(unlink(FILE_NAME) != -1); 98 | } 99 | 100 | void read(uint32_t i) 101 | { 102 | sbdi_error_t r = sbdi_bl_read_data_block(sbdi, b, i, 0, SBDI_BLOCK_SIZE); 103 | if (r != SBDI_SUCCESS) { 104 | std::cout << "Reading file @ block " << i << ". Error: " 105 | << err_to_string(r) << std::endl; 106 | } 107 | CPPUNIT_ASSERT(r == SBDI_SUCCESS); 108 | } 109 | 110 | void write(uint32_t i) 111 | { 112 | sbdi_error_t r = sbdi_bl_write_data_block(sbdi, b, i, 0, SBDI_BLOCK_SIZE); 113 | if (r != SBDI_SUCCESS) { 114 | std::cout << "Writing file @ block " << i << ". Error: " 115 | << err_to_string(r) << std::endl; 116 | 117 | } 118 | CPPUNIT_ASSERT(r == SBDI_SUCCESS); 119 | } 120 | 121 | void fill(uint32_t c) 122 | { 123 | CPPUNIT_ASSERT(c <= UINT8_MAX); 124 | memset(b, c, SBDI_BLOCK_SIZE); 125 | } 126 | 127 | void f_write(uint32_t i, uint32_t v) 128 | { 129 | fill(v); 130 | write(i); 131 | } 132 | 133 | void cmp(uint32_t c) 134 | { 135 | CPPUNIT_ASSERT(c <= UINT8_MAX); 136 | CPPUNIT_ASSERT(memchrcmp(b, c, SBDI_BLOCK_SIZE)); 137 | } 138 | 139 | void c_read(uint32_t i, uint32_t v) 140 | { 141 | fill(0xFF); 142 | read(i); 143 | cmp(v); 144 | } 145 | 146 | public: 147 | void setUp() 148 | { 149 | unlink(FILE_NAME); 150 | memset(b, 0, SBDI_BLOCK_SIZE); 151 | memset(root, 0, sizeof(mt_hash_t)); 152 | } 153 | 154 | void tearDown() 155 | { 156 | 157 | } 158 | 159 | void testIndexComp() 160 | { 161 | for (uint32_t log_idx = 0; log_idx < SBDI_BLK_MAX_LOG; ++log_idx) { 162 | uint32_t phy_idx = sbdi_blic_log_to_phy_dat_blk(log_idx); 163 | if (log_idx != sbdi_blic_phy_dat_to_log(phy_idx)) { 164 | std::cout << "log: " << log_idx << " phy: " << phy_idx << " phy(log): " 165 | << sbdi_blic_phy_dat_to_log(phy_idx) << std::endl; 166 | CPPUNIT_ASSERT(0); 167 | } 168 | uint32_t mng_log_idx = sbdi_blic_log_to_phy_mng_blk(log_idx); 169 | uint32_t mng_phy_idx = sbdi_blic_phy_dat_to_phy_mng_blk(phy_idx); 170 | if (mng_log_idx != mng_phy_idx) { 171 | std::cout << "log: " << log_idx << " phy: " << phy_idx << " mng(log): " 172 | << mng_log_idx << " mng(phy) " << mng_phy_idx << std::endl; 173 | CPPUNIT_ASSERT(0); 174 | } 175 | uint32_t mng_log_blk_nbr = sbdi_blic_log_to_mng_blk_nbr(log_idx); 176 | uint32_t mng_phy_blk_nbr = sbdi_blic_phy_to_mng_blk_nbr(mng_phy_idx); 177 | if (mng_log_blk_nbr != mng_phy_blk_nbr) { 178 | std::cout << "log: " << log_idx << " phy: " << phy_idx 179 | << " mng_nbr(log): " << mng_log_blk_nbr << " mng_nbr(phy) " 180 | << mng_phy_blk_nbr << std::endl; 181 | CPPUNIT_ASSERT(0); 182 | } 183 | if (mng_log_idx != sbdi_blic_mng_blk_nbr_to_mng_phy(mng_log_blk_nbr)) { 184 | std::cout << "log: " << log_idx << " phy: " << phy_idx << " mng_idx_1: " 185 | << mng_log_idx << " mng_idx_2 " 186 | << sbdi_blic_mng_blk_nbr_to_mng_phy(mng_log_blk_nbr) << std::endl; 187 | CPPUNIT_ASSERT(0); 188 | } 189 | mng_phy_blk_nbr = sbdi_blic_phy_to_mng_blk_nbr(phy_idx); 190 | if (mng_phy_blk_nbr != mng_log_blk_nbr) { 191 | std::cout << "log: " << log_idx << " phy: " << phy_idx 192 | << " mng_nbr_phy: " << mng_phy_blk_nbr << " mng_nbr_log " 193 | << mng_log_blk_nbr << std::endl; 194 | CPPUNIT_ASSERT(0); 195 | } 196 | } 197 | } 198 | 199 | void testSimpleReadWrite() 200 | { 201 | loadStore(); 202 | f_write(0, 0x10); 203 | c_read(0, 0x10); 204 | f_write(1, 0x11); 205 | c_read(1, 0x11); 206 | CPPUNIT_ASSERT(sbdi_bc_sync(sbdi->cache) == SBDI_SUCCESS); 207 | closeStore(); 208 | loadStore(); 209 | c_read(1, 0x11); 210 | c_read(0, 0x10); 211 | closeStore(); 212 | deleteStore(); 213 | } 214 | 215 | void testSimpleIntegrityCheck() 216 | { 217 | loadStore(); 218 | f_write(0, 0); 219 | f_write(128, 128); 220 | closeStore(); 221 | loadStore(); 222 | c_read(0, 0); 223 | c_read(128, 128); 224 | closeStore(); 225 | deleteStore(); 226 | } 227 | 228 | void testExtendedReadWrite() 229 | { 230 | loadStore(); 231 | f_write(0x80, 0x80); 232 | c_read(0x80, 0x80); 233 | f_write(2049, 0xF0); 234 | c_read(2049, 0xF0); 235 | closeStore(); 236 | loadStore(); 237 | c_read(0x80, 0x80); 238 | c_read(2049, 0xF0); 239 | closeStore(); 240 | deleteStore(); 241 | } 242 | 243 | void testLinearReadWrite() 244 | { 245 | loadStore(); 246 | const int linear_rw_test_size = 4122; 247 | for (int i = 0; i < linear_rw_test_size; ++i) { 248 | f_write(i, i % UINT8_MAX); 249 | } 250 | for (int i = 0; i < linear_rw_test_size; ++i) { 251 | c_read(i, i % UINT8_MAX); 252 | } 253 | std::cout << std::endl; 254 | sbdi_bc_print_stats(sbdi->cache); 255 | closeStore(); 256 | loadStore(); 257 | for (int i = 0; i < linear_rw_test_size; ++i) { 258 | c_read(i, i % UINT8_MAX); 259 | } 260 | std::cout << std::endl; 261 | sbdi_bc_print_stats(sbdi->cache); 262 | closeStore(); 263 | deleteStore(); 264 | } 265 | 266 | }; 267 | 268 | unsigned char SbdiBLockLayerTest::SIV_KEYS[32] = { 269 | // Part 1: fffefdfc fbfaf9f8 f7f6f5f4 f3f2f1f0 270 | 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 271 | 0xf3, 0xf2, 0xf1, 0xf0, 272 | // Part 2: f0f1f2f3 f4f5f6f7 f8f9fafb fcfdfeff 273 | 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 274 | 0xfc, 0xfd, 0xfe, 0xff }; 275 | 276 | CPPUNIT_TEST_SUITE_REGISTRATION(SbdiBLockLayerTest); 277 | -------------------------------------------------------------------------------- /tests/SbdiCtrTest.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) IAIK, Graz University of Technology, 2015. 2 | * All rights reserved. 3 | * Contact: http://opensource.iaik.tugraz.at 4 | * 5 | * This file is part of the Secure Block Device Library. 6 | * 7 | * Commercial License Usage 8 | * Licensees holding valid commercial licenses may use this file in 9 | * accordance with the commercial license agreement provided with the 10 | * Software or, alternatively, in accordance with the terms contained in 11 | * a written agreement between you and SIC. For further information 12 | * contact us at http://opensource.iaik.tugraz.at. 13 | * 14 | * Alternatively, this file may be used under the terms of the GNU General 15 | * Public License as published by the Free Software Foundation version 2. 16 | * 17 | * The Secure Block Device Library is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 20 | * Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with the Secure Block Device Library. If not, see . 24 | */ 25 | /// 26 | /// \file 27 | /// \brief Tests the 128-bit counter used by the Secure Block Device Library. 28 | /// 29 | 30 | #include "sbdi_ctr_128b.h" 31 | 32 | #include 33 | 34 | #ifndef UINT64_C 35 | #define UINT64_C(c) c ## ULL 36 | #endif 37 | #ifndef UINT64_MAX 38 | #include 39 | #define UINT64_MAX std::numeric_limits::max() 40 | #endif 41 | 42 | #define TP_1 UINT64_C(0xFFEEDDCCBBAA9988) 43 | #define TP_2 UINT64_C(0x7766554433221100) 44 | 45 | 46 | class SbdiCtrTest: public CppUnit::TestFixture { 47 | CPPUNIT_TEST_SUITE( SbdiCtrTest ); 48 | CPPUNIT_TEST(testInit); 49 | CPPUNIT_TEST(testReset); 50 | CPPUNIT_TEST(testBasicIncrement); 51 | CPPUNIT_TEST(testBorderIncrement); 52 | CPPUNIT_TEST_SUITE_END(); 53 | 54 | private: 55 | static const sbdi_ctr_128b_t ZERO; 56 | static const sbdi_ctr_128b_t ONE; 57 | static const sbdi_ctr_128b_t TWO; 58 | static const sbdi_ctr_128b_t LO_MAX; 59 | static const sbdi_ctr_128b_t ONE_ZERO; 60 | static const sbdi_ctr_128b_t MAX_LO_MAX; 61 | static const sbdi_ctr_128b_t MAX_M1; 62 | static const sbdi_ctr_128b_t MAX; 63 | 64 | public: 65 | void setUp() 66 | { 67 | } 68 | 69 | void tearDown() 70 | { 71 | 72 | } 73 | 74 | void testInit() 75 | { 76 | sbdi_ctr_128b_t tst; 77 | sbdi_ctr_128b_init(&tst, TP_1, TP_2); 78 | CPPUNIT_ASSERT(tst.hi == TP_1); 79 | CPPUNIT_ASSERT(tst.lo == TP_2); 80 | } 81 | 82 | void testReset() 83 | { 84 | sbdi_ctr_128b_t tst; 85 | tst.hi = TP_1; 86 | tst.lo = TP_2; 87 | sbdi_ctr_128b_reset(&tst); 88 | CPPUNIT_ASSERT(tst.hi == 0); 89 | CPPUNIT_ASSERT(tst.lo == 0); 90 | } 91 | 92 | void testBasicIncrement() 93 | { 94 | int res = 0; 95 | sbdi_ctr_128b_t tst; 96 | sbdi_ctr_128b_reset(&tst); 97 | CPPUNIT_ASSERT(sbdi_ctr_128b_cmp(&tst, &ZERO, &res) == SBDI_SUCCESS); 98 | CPPUNIT_ASSERT(!res); 99 | sbdi_ctr_128b_inc(&tst); 100 | CPPUNIT_ASSERT(sbdi_ctr_128b_cmp(&tst, &ONE, &res) == SBDI_SUCCESS); 101 | CPPUNIT_ASSERT(!res); 102 | sbdi_ctr_128b_inc(&tst); 103 | CPPUNIT_ASSERT(sbdi_ctr_128b_cmp(&tst, &TWO, &res) == SBDI_SUCCESS); 104 | CPPUNIT_ASSERT(!res); 105 | } 106 | 107 | void testBorderIncrement() { 108 | int res = 0; 109 | sbdi_ctr_128b_t tst, cmp; 110 | CPPUNIT_ASSERT(sbdi_ctr_128b_init(&tst, UINT64_MAX - 1, UINT64_MAX) == SBDI_SUCCESS); 111 | CPPUNIT_ASSERT(sbdi_ctr_128b_init(&cmp, UINT64_MAX, 0) == SBDI_SUCCESS); 112 | CPPUNIT_ASSERT(sbdi_ctr_128b_cmp(&tst, &MAX_LO_MAX, &res) == SBDI_SUCCESS); 113 | CPPUNIT_ASSERT(!res); 114 | CPPUNIT_ASSERT(sbdi_ctr_128b_inc(&tst) == SBDI_SUCCESS); 115 | CPPUNIT_ASSERT(sbdi_ctr_128b_cmp(&tst, &cmp, &res) == SBDI_SUCCESS); 116 | CPPUNIT_ASSERT(!res); 117 | CPPUNIT_ASSERT(sbdi_ctr_128b_init(&tst, 0, UINT64_MAX) == SBDI_SUCCESS); 118 | CPPUNIT_ASSERT(sbdi_ctr_128b_cmp(&tst, &ONE_ZERO, &res) == SBDI_SUCCESS); 119 | CPPUNIT_ASSERT(!res); 120 | CPPUNIT_ASSERT(sbdi_ctr_128b_init(&tst, UINT64_MAX, UINT64_MAX-1) == SBDI_SUCCESS); 121 | CPPUNIT_ASSERT(sbdi_ctr_128b_cmp(&tst, &MAX_M1, &res) == SBDI_SUCCESS); 122 | CPPUNIT_ASSERT(!res); 123 | CPPUNIT_ASSERT(sbdi_ctr_128b_inc(&tst) == SBDI_SUCCESS); 124 | CPPUNIT_ASSERT(sbdi_ctr_128b_cmp(&tst, &MAX, &res) == SBDI_SUCCESS); 125 | CPPUNIT_ASSERT(!res); 126 | CPPUNIT_ASSERT(sbdi_ctr_128b_inc(&tst) == SBDI_ERR_ILLEGAL_STATE); 127 | CPPUNIT_ASSERT(sbdi_ctr_128b_cmp(&tst, &MAX, &res) == SBDI_SUCCESS); 128 | CPPUNIT_ASSERT(!res); 129 | } 130 | 131 | }; 132 | 133 | const sbdi_ctr_128b_t SbdiCtrTest::ZERO = { 0, 0 }; 134 | const sbdi_ctr_128b_t SbdiCtrTest::ONE = { 0, 1 }; 135 | const sbdi_ctr_128b_t SbdiCtrTest::TWO = { 0, 2 }; 136 | const sbdi_ctr_128b_t SbdiCtrTest::LO_MAX = { 0, UINT64_MAX }; 137 | const sbdi_ctr_128b_t SbdiCtrTest::ONE_ZERO = { 0, UINT64_MAX }; 138 | const sbdi_ctr_128b_t SbdiCtrTest::MAX_LO_MAX = { UINT64_MAX - 1, UINT64_MAX }; 139 | const sbdi_ctr_128b_t SbdiCtrTest::MAX_M1 = { UINT64_MAX, UINT64_MAX - 1 }; 140 | const sbdi_ctr_128b_t SbdiCtrTest::MAX = { UINT64_MAX, UINT64_MAX }; 141 | 142 | CPPUNIT_TEST_SUITE_REGISTRATION(SbdiCtrTest); 143 | -------------------------------------------------------------------------------- /tests/SbdiTest.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) IAIK, Graz University of Technology, 2015. 2 | * All rights reserved. 3 | * Contact: http://opensource.iaik.tugraz.at 4 | * 5 | * This file is part of the Secure Block Device Library. 6 | * 7 | * Commercial License Usage 8 | * Licensees holding valid commercial licenses may use this file in 9 | * accordance with the commercial license agreement provided with the 10 | * Software or, alternatively, in accordance with the terms contained in 11 | * a written agreement between you and SIC. For further information 12 | * contact us at http://opensource.iaik.tugraz.at. 13 | * 14 | * Alternatively, this file may be used under the terms of the GNU General 15 | * Public License as published by the Free Software Foundation version 2. 16 | * 17 | * The Secure Block Device Library is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 20 | * Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with the Secure Block Device Library. If not, see . 24 | */ 25 | /// 26 | /// \file 27 | /// \brief Tests the Secure Block Device Library API. 28 | /// 29 | /// If you are interested in an example on how to use the Secure Block Device 30 | /// Library in your application this is a good place to start. 31 | /// 32 | #ifndef UINT32_MAX 33 | #include 34 | #define UINT32_MAX std::numeric_limits::max() 35 | #endif 36 | #ifndef UINT32_C 37 | #define UINT32_C(c) c ## u 38 | #endif 39 | #ifndef UINT16_MAX 40 | #define UINT16_MAX 65535u 41 | #endif 42 | #ifndef UINT8_MAX 43 | #define UINT8_MAX 255u 44 | #endif 45 | 46 | #include "SbdiTest.h" 47 | #include "SecureBlockDeviceInterface.h" 48 | 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | 55 | #include 56 | 57 | #include 58 | #include 59 | #include 60 | 61 | class SbdiTest: public CppUnit::TestFixture { 62 | CPPUNIT_TEST_SUITE( SbdiTest ); 63 | CPPUNIT_TEST(testParameterChecks); 64 | CPPUNIT_TEST(testSimpleReadWrite); 65 | CPPUNIT_TEST(testRandomAccess); 66 | CPPUNIT_TEST_SUITE_END(); 67 | 68 | private: 69 | static unsigned char SIV_KEYS[32]; 70 | sbdi_t *sbdi; 71 | mt_hash_t root; 72 | int fd; 73 | sbdi_pio_t *pio; 74 | 75 | void loadStore() 76 | { 77 | fd = open(FILE_NAME, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); 78 | CPPUNIT_ASSERT(fd != -1); 79 | struct stat s; 80 | CPPUNIT_ASSERT(fstat(fd, &s) == 0); 81 | pio = sbdi_pio_create(&fd, s.st_size); 82 | CPPUNIT_ASSERT(sbdi_open(&sbdi, pio, SBDI_CRYPTO_NONE, SIV_KEYS, root) == SBDI_SUCCESS); 83 | } 84 | 85 | void closeStore() 86 | { 87 | CPPUNIT_ASSERT(sbdi_close(sbdi, SIV_KEYS, root) == SBDI_SUCCESS); 88 | int fd = *(int *) pio->iod; 89 | CPPUNIT_ASSERT(close(fd) != -1); 90 | sbdi_pio_delete(pio); 91 | } 92 | 93 | void deleteStore() 94 | { 95 | memset(root, 0, sizeof(mt_hash_t)); 96 | CPPUNIT_ASSERT(unlink(FILE_NAME) != -1); 97 | } 98 | 99 | void read(unsigned char *buf, size_t len, off_t off) 100 | { 101 | ssize_t rd = 0; 102 | sbdi_error_t r = sbdi_pread(&rd, sbdi, buf, len, off); 103 | if (r != SBDI_SUCCESS) { 104 | std::cout << "Reading file @ offset " << off << ". Error: " 105 | << err_to_string(r) << std::endl; 106 | } 107 | CPPUNIT_ASSERT(r == SBDI_SUCCESS); 108 | } 109 | 110 | void write(unsigned char *buf, size_t len, off_t off) 111 | { 112 | ssize_t wr = 0; 113 | sbdi_error_t r = sbdi_pwrite(&wr, sbdi, buf, len, off); 114 | if (r != SBDI_SUCCESS) { 115 | std::cout << "Writing file @ offset " << off << ". Error: " 116 | << err_to_string(r) << std::endl; 117 | } 118 | CPPUNIT_ASSERT(r == SBDI_SUCCESS); 119 | } 120 | 121 | void fill(uint32_t c, unsigned char *buf, size_t len) 122 | { 123 | CPPUNIT_ASSERT(c <= UINT8_MAX); 124 | for (size_t i = 0; i < len; ++i, ++c) { 125 | buf[i] = c % UINT8_MAX; 126 | } 127 | } 128 | 129 | void cmp(uint32_t c, unsigned char *buf, size_t len) 130 | { 131 | CPPUNIT_ASSERT(c <= UINT8_MAX); 132 | for (size_t i = 0; i < len; ++i, ++c) { 133 | if (buf[i] != c % UINT8_MAX) { 134 | std::cout << "Comparison @ offset " << i << " fails." << std::endl; 135 | } 136 | CPPUNIT_ASSERT(buf[i] == c % UINT8_MAX); 137 | } 138 | } 139 | 140 | void f_write(uint32_t v, unsigned char *buf, size_t len, off_t off) 141 | { 142 | fill(v, buf, len); 143 | write(buf, len, off); 144 | } 145 | 146 | void c_read(uint32_t v, unsigned char *buf, size_t len, off_t off) 147 | { 148 | memset(buf, 0xFF, len); 149 | read(buf, len, off); 150 | cmp(v, buf, len); 151 | } 152 | 153 | public: 154 | void setUp() 155 | { 156 | unlink(FILE_NAME); 157 | memset(root, 0, sizeof(mt_hash_t)); 158 | } 159 | 160 | void tearDown() 161 | { 162 | 163 | } 164 | 165 | void testParameterChecks() 166 | { 167 | loadStore(); 168 | ssize_t rd = 0; 169 | off_t of = 0; 170 | uint8_t d[2] = { 42, 23 }; 171 | ASS_ERR_ILL_PAR(sbdi_read(NULL, NULL, NULL, SBDI_SIZE_MAX + 1)); 172 | ASS_ERR_ILL_PAR(sbdi_read(&rd, NULL, NULL, SBDI_SIZE_MAX + 1)); 173 | ASS_ERR_ILL_PAR(sbdi_read(&rd, sbdi, NULL, SBDI_SIZE_MAX + 1)); 174 | ASS_ERR_ILL_PAR(sbdi_read(&rd, sbdi, d, SBDI_SIZE_MAX + 1)); 175 | ASS_SUC(sbdi_read(&rd, sbdi, d, 1)); 176 | CPPUNIT_ASSERT(rd == 0 && d[0] == 42); 177 | ASS_ERR_ILL_PAR(sbdi_write(NULL, NULL, NULL, SBDI_SIZE_MAX + 1)); 178 | ASS_ERR_ILL_PAR(sbdi_write(&rd, NULL, NULL, SBDI_SIZE_MAX + 1)); 179 | ASS_ERR_ILL_PAR(sbdi_write(&rd, sbdi, NULL, SBDI_SIZE_MAX + 1)); 180 | ASS_ERR_ILL_PAR(sbdi_write(&rd, sbdi, d, SBDI_SIZE_MAX + 1)); 181 | ASS_SUC(sbdi_write(&rd, sbdi, d, 1)); 182 | ASS_SUC(sbdi_lseek(&of, sbdi, 0, SBDI_SEEK_SET)); 183 | ASS_SUC(sbdi_read(&rd, sbdi, d, 1)); 184 | CPPUNIT_ASSERT(rd == 1 && d[0] == 42); 185 | ASS_ERR_ILL_PAR(sbdi_lseek(NULL, NULL, SBDI_SIZE_MAX + 1, SBDI_SEEK_SET)); 186 | ASS_ERR_ILL_PAR(sbdi_lseek(&of, NULL, SBDI_SIZE_MAX + 1, SBDI_SEEK_SET)); 187 | ASS_ERR_ILL_PAR(sbdi_lseek(NULL, sbdi, SBDI_SIZE_MAX + 1, SBDI_SEEK_SET)); 188 | ASS_ERR_ILL_PAR(sbdi_lseek(&of, sbdi, SBDI_SIZE_MAX + 1, SBDI_SEEK_SET)); 189 | ASS_SUC(sbdi_lseek(&of, sbdi, SBDI_SIZE_MAX-1, SBDI_SEEK_SET)); 190 | // NOTE: This check fails on 32 bit systems, because the overflow detection is triggered 191 | ASS_SUC(sbdi_write(&rd, sbdi, d, 1)); 192 | ASS_SUC(sbdi_lseek(&of, sbdi, SBDI_SIZE_MAX-1, SBDI_SEEK_SET)); 193 | ASS_SUC(sbdi_read(&rd, sbdi, d, 1)); 194 | CPPUNIT_ASSERT(rd == 1 && d[0] == 42); 195 | ASS_SUC(sbdi_lseek(&of, sbdi, SBDI_SIZE_MAX-1, SBDI_SEEK_SET)); 196 | ASS_ERR_ILL_PAR(sbdi_lseek(&of, sbdi, 1, SBDI_SEEK_CUR)); 197 | ASS_SUC(sbdi_lseek(&of, sbdi, 0, SBDI_SEEK_CUR)); 198 | ASS_SUC(sbdi_write(&rd, sbdi, d, 2)); 199 | CPPUNIT_ASSERT(rd == 1); 200 | ASS_ERR_ILL_PAR(sbdi_lseek(&of, sbdi, 1, SBDI_SEEK_END)); 201 | ASS_ERR_ILL_PAR(sbdi_lseek(&of, sbdi, 0, SBDI_SEEK_END)); 202 | closeStore(); 203 | deleteStore(); 204 | } 205 | void testSimpleReadWrite() 206 | { 207 | loadStore(); 208 | unsigned char *b = (unsigned char *) malloc( 209 | sizeof(unsigned char) * 1024 * 1024); 210 | f_write(17, b, 5 * 1024, 34); 211 | c_read(17, b, 5 * 1024, 34); 212 | CPPUNIT_ASSERT(sbdi_fsync(sbdi, SIV_KEYS) == SBDI_SUCCESS); 213 | closeStore(); 214 | loadStore(); 215 | c_read(17, b, 5 * 1024, 34); 216 | closeStore(); 217 | deleteStore(); 218 | free(b); 219 | } 220 | 221 | void testReadWriteUpdate() 222 | { 223 | loadStore(); 224 | closeStore(); 225 | deleteStore(); 226 | } 227 | 228 | void testRandomAccess() 229 | { 230 | loadStore(); 231 | const int BLK_SIZE = 1 * 1024; 232 | const int BLKS = 2048; 233 | unsigned char *b = (unsigned char *) malloc( 234 | sizeof(unsigned char) * BLK_SIZE); 235 | CPPUNIT_ASSERT(b); 236 | //==== Sequential Setup Phase ==== 237 | for (int i = 0; i < BLKS; ++i) { 238 | f_write(i % 256, b, BLK_SIZE, i * BLK_SIZE); 239 | } 240 | for (int i = 0; i < BLKS; ++i) { 241 | c_read(i % 256, b, BLK_SIZE, i * BLK_SIZE); 242 | } 243 | 244 | //==== Random Write Test ==== 245 | std::vector idxs; 246 | for (int i = 0; i < BLKS; ++i) { 247 | idxs.push_back(i); 248 | } 249 | std::random_shuffle(idxs.begin(), idxs.end()); 250 | for (int i = 0; i < BLKS; ++i) { 251 | f_write(i % 256, b, BLK_SIZE, idxs.at(i) * BLK_SIZE); 252 | } 253 | for (int i = 0; i < BLKS; ++i) { 254 | c_read(i % 256, b, BLK_SIZE, idxs.at(i) * BLK_SIZE); 255 | } 256 | closeStore(); 257 | deleteStore(); 258 | free(b); 259 | } 260 | }; 261 | 262 | unsigned char SbdiTest::SIV_KEYS[32] = { 263 | // Part 1: fffefdfc fbfaf9f8 f7f6f5f4 f3f2f1f0 264 | 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 265 | 0xf3, 0xf2, 0xf1, 0xf0, 266 | // Part 2: f0f1f2f3 f4f5f6f7 f8f9fafb fcfdfeff 267 | 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 268 | 0xfc, 0xfd, 0xfe, 0xff }; 269 | 270 | CPPUNIT_TEST_SUITE_REGISTRATION(SbdiTest); 271 | -------------------------------------------------------------------------------- /tests/SbdiTest.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) IAIK, Graz University of Technology, 2015. 2 | * All rights reserved. 3 | * Contact: http://opensource.iaik.tugraz.at 4 | * 5 | * This file is part of the Secure Block Device Library. 6 | * 7 | * Commercial License Usage 8 | * Licensees holding valid commercial licenses may use this file in 9 | * accordance with the commercial license agreement provided with the 10 | * Software or, alternatively, in accordance with the terms contained in 11 | * a written agreement between you and SIC. For further information 12 | * contact us at http://opensource.iaik.tugraz.at. 13 | * 14 | * Alternatively, this file may be used under the terms of the GNU General 15 | * Public License as published by the Free Software Foundation version 2. 16 | * 17 | * The Secure Block Device Library is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 20 | * Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with the Secure Block Device Library. If not, see . 24 | */ 25 | /// 26 | /// \file 27 | /// \brief Global functions and macros used for testing. 28 | /// 29 | #ifndef SBDITEST_H_ 30 | #define SBDITEST_H_ 31 | 32 | #include "sbdi_err.h" 33 | 34 | #include 35 | #include 36 | #include 37 | 38 | #define FILE_NAME "sbdi_tst_enc" 39 | 40 | #define ASS_SUC(f) CPPUNIT_ASSERT((f) == SBDI_SUCCESS) 41 | #define ASS_ERR_ILL_PAR(f) CPPUNIT_ASSERT((f) == SBDI_ERR_ILLEGAL_PARAM) 42 | 43 | /*! 44 | * \brief Checks if every byte in the given buffer is set to the specified 45 | * value 46 | * @param buffer[in] the unsigned byte buffer to check the contents of 47 | * @param chr[in] the byte to compare each byte in the buffer to 48 | * @param len[in] the length of the buffer in bytes 49 | * @return 1 if each byte in the buffer equals the specified value; 0 50 | * otherwise 51 | */ 52 | static inline int memchrcmp(const unsigned char *buffer, const int chr, 53 | const size_t len) 54 | { 55 | assert(chr <= UINT8_MAX); 56 | for (size_t i = 0; i < len; ++i) { 57 | if (buffer[i] != (unsigned char) chr) { 58 | return 0; 59 | } 60 | } 61 | return 1; 62 | } 63 | 64 | /*! 65 | * \brief convert an SBDI error code to a human readable description 66 | * 67 | * @param r[in] the error code to convert 68 | * @return a human readable representation of the error code 69 | */ 70 | static const char *err_to_string(sbdi_error_t r) 71 | { 72 | { 73 | switch (r) { 74 | case SBDI_SUCCESS: 75 | return "success"; 76 | case SBDI_ERR_OUT_Of_MEMORY: 77 | return "out of memory"; 78 | case SBDI_ERR_ILLEGAL_PARAM: 79 | return "illegal parameter"; 80 | case SBDI_ERR_ILLEGAL_STATE: 81 | return "illegal state"; 82 | case SBDI_ERR_IO: 83 | return "IO error"; 84 | case SBDI_ERR_IO_MISSING_BLOCK: 85 | return "missing block"; 86 | case SBDI_ERR_IO_MISSING_DATA: 87 | return "missing data"; 88 | case SBDI_ERR_UNSUPPORTED: 89 | return "operation unsupported"; 90 | case SBDI_ERR_TAG_MISMATCH: 91 | return "tag mismatch"; 92 | case SBDI_ERR_CRYPTO_FAIL: 93 | return "crypto fail"; 94 | case SBDI_ERR_UNSPECIFIED: 95 | return "unspecified"; 96 | default: 97 | return "unknown error"; 98 | } 99 | } 100 | } 101 | 102 | #endif /* SBDITEST_H_ */ 103 | -------------------------------------------------------------------------------- /tests/SbdiTestRunner.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) IAIK, Graz University of Technology, 2015. 2 | * All rights reserved. 3 | * Contact: http://opensource.iaik.tugraz.at 4 | * 5 | * This file is part of the Secure Block Device Library. 6 | * 7 | * Commercial License Usage 8 | * Licensees holding valid commercial licenses may use this file in 9 | * accordance with the commercial license agreement provided with the 10 | * Software or, alternatively, in accordance with the terms contained in 11 | * a written agreement between you and SIC. For further information 12 | * contact us at http://opensource.iaik.tugraz.at. 13 | * 14 | * Alternatively, this file may be used under the terms of the GNU General 15 | * Public License as published by the Free Software Foundation version 2. 16 | * 17 | * The Secure Block Device Library is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 20 | * Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License along 23 | * with the Secure Block Device Library. If not, see . 24 | */ 25 | /// 26 | /// \file 27 | /// \brief Runs the Secure Block Device Library tests. 28 | /// 29 | #include 30 | #include 31 | 32 | int main(int argc, char **argv) 33 | { 34 | CppUnit::TextUi::TestRunner runner; 35 | CppUnit::TestFactoryRegistry ®istry = 36 | CppUnit::TestFactoryRegistry::getRegistry(); 37 | runner.addTest(registry.makeTest()); 38 | runner.run(); 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /tests/siv_test_vectors_1.txt: -------------------------------------------------------------------------------- 1 | ================================================== 2 | SIV Test Vectors 3 | Dan Harkins 4 | August 20, 2007 5 | ================================================== 6 | 7 | TEST CASE #1 8 | 9 | Input 10 | Key (K1) fffefdfc fbfaf9f8 f7f6f5f4 f3f2f1f0 11 | (K2) f0f1f2f3 f4f5f6f7 f8f9fafb fcfdfeff 12 | AD (H1) 10111213 14151617 18191a1b 1c1d1e1f 13 | 20212223 24252627 14 | Plaintext 11223344 55667788 99aabbcc ddee 15 | 16 | Yields (* output) 17 | 18 | CMAC(0) 0e04dfaf c1efbf04 01405828 59bf073a 19 | dbl 1c09bf5f 83df7e08 0280b050 b37e0e74 20 | CMAC(H1) f1f922b7 f5193ce6 4ff80cb4 7d93f23b 21 | xor edf09de8 76c642ee 4d78bce4 ceedfc4f 22 | dbl dbe13bd0 ed8c85dc 9af179c9 9ddbf819 23 | pad 11223344 55667788 99aabbcc ddee8000 24 | xor cac30894 b8eaf254 035bc205 40357819 25 | * IV 85632d07 c6e8f37f 950acd32 0a2ecc93 26 | 27 | Ctr 85632d07 c6e8f37f 150acd32 0a2ecc93 28 | E(K,Ctr) 51e218d2 c5a2ab8c 4345c4a6 23b2f08f 29 | * C 40c02b96 90c4dc04 daef7f6a fe5c 30 | 31 | -------------------------------------------------- 32 | 33 | TEST CASE #2 34 | 35 | Input 36 | Key (K1) 7f7e7d7c 7b7a7978 77767574 73727170 37 | (K2) 40414243 44454647 48494a4b 4c4d4e4f 38 | AD (H1) 00112233 44556677 8899aabb ccddeeff 39 | deaddada deaddada ffeeddcc bbaa9988 40 | 77665544 33221100 41 | (H2) 10203040 50607080 90a0 42 | (H3) 09f91102 9d74e35b d84156c5 635688c0 43 | Plaintext 74686973 20697320 736f6d65 20706c61 44 | 696e7465 78742074 6f20656e 63727970 45 | 74207573 696e6720 5349562d 414553 46 | 47 | Yields (* output) 48 | 49 | CMAC(0) c8b43b59 74960e7c e6a5dd85 231e591a 50 | dbl 916876b2 e92c1cf9 cd4bbb0a 463cb2b3 51 | CMAC(H1) 3c9b689a b41102e4 80954714 1dd0d15a 52 | xor adf31e28 5d3d1e1d 4ddefc1e 5bec63e9 53 | dbl 5be63c50 ba7a3c3a 9bbdf83c b7d8c755 54 | CMAC(H2) d98c9b0b e42cb2d7 aa98478e d11eda1b 55 | xor 826aa75b 5e568eed 3125bfb2 66c61d4e 56 | dbl 04d54eb6 bcad1dda 624b7f64 cd8c3a1b 57 | CMAC(H3) 128c62a1 ce3747a8 372c1c05 a538b96d 58 | xor 16592c17 729a5a72 55676361 68b48376 59 | xor-end 74686973 20697320 736f6d65 20706c61 60 | 696e7465 78742074 6f20656e 63727966 61 | 2d0c6201 f3341575 342a3745 f5c625 62 | * IV 7bdb6e3b 432667eb 06f4d14b ff2fbd0f 63 | 64 | Ctr 7bdb6e3b 432667eb 06f4d14b 7f2fbd0f 65 | E(K,Ctr) bff8665c fdd73363 550f7400 e8f9d376 66 | Ctr+1 7bdb6e3b 432667eb 06f4d14b 7f2fbd10 67 | E(K,Ctr+1) b2c9088e 713b8617 d8839226 d9f88159 68 | Ctr+2 7bdb6e3b 432667eb 06f4d14b 7f2fbd11 69 | E(K,Ctr+2) 9e44d827 234949bc 1b12348e bc195ec7 70 | * C cb900f2f ddbe4043 26601965 c889bf17 71 | dba77ceb 094fa663 b7a3f748 ba8af829 72 | ea64ad54 4a272e9c 485b62a3 fd5c0d 73 | -------------------------------------------------------------------------------- /tests/siv_test_vectors_2.txt: -------------------------------------------------------------------------------- 1 | 2 | TEST CASE #1 3 | 4 | Input, 128 bit keys 5 | Key (K1) fffefdfc fbfaf9f8 f7f6f5f4 f3f2f1f0 6 | (K2) f0f1f2f3 f4f5f6f7 f8f9fafb fcfdfeff 7 | AD (H1) 10111213 14151617 18191a1b 1c1d1e1f 8 | 20212223 24252627 9 | Plaintext 11223344 55667788 99aabbcc ddee 10 | 11 | Yields (* output) 12 | 13 | CMAC(0) 0e04dfaf c1efbf04 01405828 59bf073a 14 | dbl 1c09bf5f 83df7e08 0280b050 b37e0e74 15 | CMAC(H1) f1f922b7 f5193ce6 4ff80cb4 7d93f23b 16 | xor edf09de8 76c642ee 4d78bce4 ceedfc4f 17 | dbl dbe13bd0 ed8c85dc 9af179c9 9ddbf819 18 | pad 11223344 55667788 99aabbcc ddee8000 19 | xor cac30894 b8eaf254 035bc205 40357819 20 | * IV 85632d07 c6e8f37f 950acd32 0a2ecc93 21 | 22 | Ctr 85632d07 c6e8f37f 150acd32 0a2ecc93 23 | E(K,Ctr) 51e218d2 c5a2ab8c 4345c4a6 23b2f08f 24 | * C 40c02b96 90c4dc04 daef7f6a fe5c 25 | 26 | ------- 27 | 28 | Input, 192 bit keys 29 | Key (K1) fffefdfc fbfaf9f8 f7f6f5f4 f3f2f1f0 30 | 6f6e6d6c 6b6a6968 31 | (K2) f0f1f2f3 f4f5f6f7 f8f9fafb fcfdfeff 32 | 00010203 04050607 33 | AD (H1) 10111213 14151617 18191a1b 1c1d1e1f 34 | 20212223 24252627 35 | Plaintext 11223344 55667788 99aabbcc ddee 36 | 37 | Yields (* output) 38 | 39 | CMAC(0) e7201d9c 20aa76b9 d9a5b741 fa836c06 40 | dbl ce403b38 4154ed73 b34b6e83 f506d88b 41 | CMAC(H1) d5434a82 b7c82590 300d2fd4 8d22775e 42 | xor 1b0371ba f69cc8e3 83464157 7824afd5 43 | dbl 3606e375 ed3991c7 068c82ae f0495faa 44 | pad 11223344 55667788 99aabbcc ddee8000 45 | xor 2724d031 b85fe64f 9f263962 2da7dfaa 46 | * IV 02347811 daa8b274 91f24448 932775a6 47 | 48 | Ctr 02347811 daa8b274 11f24448 132775a6 49 | E(K,Ctr) 3bd17942 f9666160 3582f199 c9188160 50 | * C 2af34a06 ac0016e8 ac284a55 14f6 51 | 52 | ------- 53 | 54 | Input, 256 bit keys 55 | Key (K1) fffefdfc fbfaf9f8 f7f6f5f4 f3f2f1f0 56 | 6f6e6d6c 6b6a6968 67666564 63626160 57 | (K2) f0f1f2f3 f4f5f6f7 f8f9fafb fcfdfeff 58 | 00010203 04050607 08090a0b 0c0d0e0f 59 | AD (H1) 10111213 14151617 18191a1b 1c1d1e1f 60 | 20212223 24252627 61 | Plaintext 11223344 55667788 99aabbcc ddee 62 | 63 | Yields (* output) 64 | 65 | CMAC(0) 29f9541e fbf839bb 62082e05 0616865d 66 | dbl 53f2a83d f7f07376 c4105c0a 0c2d0cba 67 | CMAC(H1) a53e456f ee28ecdf a212ba71 d425b602 68 | xor f6cced52 19d89fa9 6602e67b d808bab8 69 | dbl ed99daa4 33b13f52 cc05ccf7 b01175f7 70 | pad 11223344 55667788 99aabbcc ddee8000 71 | xor fcbbe9e0 66d748da 55af773b 6dfff5f7 72 | * IV f125274c 598065cf c26b0e71 57502908 73 | 74 | Ctr f125274c 598065cf 426b0e71 57502908 75 | E(K,Ctr) 9a216153 b6e6bd40 083453cc 1cc812c3 76 | * C 8b035217 e380cac8 919ee800 c126 77 | 78 | -------------------------------------------------- 79 | 80 | TEST CASE #2 81 | 82 | Input, 128 bit keys 83 | Key (K1) 7f7e7d7c 7b7a7978 77767574 73727170 84 | (K2) 40414243 44454647 48494a4b 4c4d4e4f 85 | AD (H1) 00112233 44556677 8899aabb ccddeeff 86 | deaddada deaddada ffeeddcc bbaa9988 87 | 77665544 33221100 88 | (H2) 10203040 50607080 90a0 89 | (H3) 09f91102 9d74e35b d84156c5 635688c0 90 | Plaintext 74686973 20697320 736f6d65 20706c61 91 | 696e7465 78742074 6f20656e 63727970 92 | 74207573 696e6720 5349562d 414553 93 | 94 | Yields (* output) 95 | 96 | CMAC(0) c8b43b59 74960e7c e6a5dd85 231e591a 97 | dbl 916876b2 e92c1cf9 cd4bbb0a 463cb2b3 98 | CMAC(H1) 3c9b689a b41102e4 80954714 1dd0d15a 99 | xor adf31e28 5d3d1e1d 4ddefc1e 5bec63e9 100 | dbl 5be63c50 ba7a3c3a 9bbdf83c b7d8c755 101 | CMAC(H2) d98c9b0b e42cb2d7 aa98478e d11eda1b 102 | xor 826aa75b 5e568eed 3125bfb2 66c61d4e 103 | dbl 04d54eb6 bcad1dda 624b7f64 cd8c3a1b 104 | CMAC(H3) 128c62a1 ce3747a8 372c1c05 a538b96d 105 | xor 16592c17 729a5a72 55676361 68b48376 106 | xor-end 74686973 20697320 736f6d65 20706c61 107 | 696e7465 78742074 6f20656e 63727966 108 | 2d0c6201 f3341575 342a3745 f5c625 109 | * IV 7bdb6e3b 432667eb 06f4d14b ff2fbd0f 110 | 111 | Ctr 7bdb6e3b 432667eb 06f4d14b 7f2fbd0f 112 | E(K,Ctr) bff8665c fdd73363 550f7400 e8f9d376 113 | Ctr+1 7bdb6e3b 432667eb 06f4d14b 7f2fbd10 114 | E(K,Ctr+1) b2c9088e 713b8617 d8839226 d9f88159 115 | Ctr+2 7bdb6e3b 432667eb 06f4d14b 7f2fbd11 116 | E(K,Ctr+2) 9e44d827 234949bc 1b12348e bc195ec7 117 | * C cb900f2f ddbe4043 26601965 c889bf17 118 | dba77ceb 094fa663 b7a3f748 ba8af829 119 | ea64ad54 4a272e9c 485b62a3 fd5c0d 120 | 121 | ------- 122 | 123 | Input, 192 bit keys 124 | Key (K1) 7f7e7d7c 7b7a7978 77767574 73727170 125 | 6f6e6d6c 6b6a6968 126 | Key (K2) 40414243 44454647 48494a4b 4c4d4e4f 127 | 50515253 54555657 128 | AD (H1) 00112233 44556677 8899aabb ccddeeff 129 | deaddada deaddada ffeeddcc bbaa9988 130 | 77665544 33221100 131 | (H2) 10203040 50607080 90a0 132 | (H3) 09f91102 9d74e35b d84156c5 635688c0 133 | Plaintext 74686973 20697320 736f6d65 20706c61 134 | 696e7465 78742074 6f20656e 63727970 135 | 74207573 696e6720 5349562d 414553 136 | 137 | Yields (* output) 138 | 139 | CMAC(0) e4c31ce1 106aa406 1e7fc22f 350d7021 140 | dbl c98639c2 20d5480c 3cff845e 6a1ae0c5 141 | CMAC(H1) b9f50277 17c9b57b 37ae7f9e 5ea20eaa 142 | xor 70733bb5 371cfd77 0b51fbc0 34b8ee6f 143 | dbl e0e6776a 6e39faee 16a3f780 6971dcde 144 | CMAC(H2) f09d0a8d a275de97 c52a590a 44abd960 145 | xor 107b7de7 cc4c2479 d389ae8a 2dda05be 146 | dbl 20f6fbcf 989848f3 a7135d14 5bb40b7c 147 | CMAC(H3) fcad4261 054ad7ed 66a6d983 364b0986 148 | xor dc5bb9ae 9dd29f1e c1b58497 6dff02fa 149 | xor-end 74686973 20697320 736f6d65 20706c61 150 | 696e7465 78742074 6f20656e 637279ac 151 | 2f99dbee bbf179e1 e6cdc140 be47a9 152 | * IV de40aa1e 7180d519 cb14308e a7f77586 153 | 154 | Ctr de40aa1e 7180d519 4b14308e 27f77586 155 | E(K,Ctr) ae61ee0f 71665a45 6c2d5c7f 97588537 156 | Ctr+1 de40aa1e 7180d519 4b14308e 27f77587 157 | E(K,Ctr+1) 6089aa4c ecc9d87f d6bb9fc2 806e37b0 158 | Ctr+2 de40aa1e 7180d519 4b14308e 27f77588 159 | E(K,Ctr+2) a57bd323 f63d944a 846c8a86 88a7f4d5 160 | * C da09877c 510f2965 1f42311a b728e956 161 | 09e7de29 94bdf80b b99bfaac e31c4ec0 162 | d15ba650 9f53f36a d725dcab c9e2a7 163 | 164 | ------- 165 | 166 | Input, 256 bit keys 167 | Key (K1) 7f7e7d7c 7b7a7978 77767574 73727170 168 | 6f6e6d6c 6b6a6968 67666564 63626160 169 | Key (K2) 40414243 44454647 48494a4b 4c4d4e4f 170 | 50515253 54555657 58595a5b 5b5d5e5f 171 | AD (H1) 00112233 44556677 8899aabb ccddeeff 172 | deaddada deaddada ffeeddcc bbaa9988 173 | 77665544 33221100 174 | (H2) 10203040 50607080 90a0 175 | (H3) 09f91102 9d74e35b d84156c5 635688c0 176 | Plaintext 74686973 20697320 736f6d65 20706c61 177 | 696e7465 78742074 6f20656e 63727970 178 | 74207573 696e6720 5349562d 414553 179 | 180 | CMAC(0) 689a3570 3908ab2e 9cc1ef2c c4218fa2 181 | dbl d1346ae0 7211565d 3983de59 88431f44 182 | CMAC(H1) ce7cc86a 9432253b e0e62840 4216da0c 183 | xor 1f48a28a e6237366 d965f619 ca55c548 184 | dbl 3e914515 cc46e6cd b2cbec33 94ab8a90 185 | CMAC(H2) 6814d4b4 b1da05df 16ead8c8 d6b287a2 186 | xor 568591a1 7d9ce312 a42134fb 42190d32 187 | dbl ad0b2342 fb39c625 484269f6 84321a64 188 | CMAC(H3) 0a1f8725 ee033783 432b36f4 0345c3e2 189 | xor a714a467 153af1a6 0b695f02 8777d986 190 | xor-end 74686973 20697320 736f6d65 20706c61 191 | 696e7465 78742074 6f20656e 637279d7 192 | 60841266 539fc12b 3a1654aa 369cd5 193 | * IV 85b81673 10038db7 dc4692c0 281ca358 194 | 195 | Ctr 85b81673 10038db7 5c4692c0 281ca358 196 | E(K,Ctr) 1c707254 429ab16f 5d9532dd 2cc12f30 197 | Ctr+1 85b81673 10038db7 5c4692c0 281ca359 198 | E(K,Ctr+1) 0588b051 c0ec8689 e199ef2f eb308c6f 199 | Ctr+2 85b81673 10038db7 5c4692c0 281ca35a 200 | E(K,Ctr+2) 12dc12ad 2ac27f7a 3594246a 1afe5b8e 201 | * C 68181b27 62f3c24f 2efa5fb8 0cb14351 202 | 6ce6c434 b898a6fd 8eb98a41 8842f51f 203 | 66fc67de 43ac185a 66dd7247 5bbb08 204 | 205 | --------------------------------------------------------------------------------