1/* 2 * Copyright (c) 2012 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 29 30#include <libkern/crypto/crypto_internal.h> 31#include <libkern/libkern.h> 32#include <kern/debug.h> 33#include <libkern/crypto/des.h> 34#include <corecrypto/ccmode.h> 35 36/* Single DES ECB - used by ipv6 (esp_core.c) */ 37int des_ecb_key_sched(des_cblock *key, des_ecb_key_schedule *ks) 38{ 39 const struct ccmode_ecb *enc = g_crypto_funcs->ccdes_ecb_encrypt; 40 const struct ccmode_ecb *dec = g_crypto_funcs->ccdes_ecb_decrypt; 41 42 /* Make sure the context size for the mode fits in the one we have */ 43 if((enc->size>sizeof(ks->enc)) || (dec->size>sizeof(ks->dec))) 44 panic("%s: inconsistent size for DES-ECB context", __FUNCTION__); 45 46 enc->init(enc, ks->enc, CCDES_KEY_SIZE, key); 47 dec->init(dec, ks->dec, CCDES_KEY_SIZE, key); 48 49 /* The old DES interface could return -1 or -2 for weak keys and wrong parity, 50 but this was disabled all the time, so we never fail here */ 51 return 0; 52} 53 54/* Simple des - 1 block */ 55void des_ecb_encrypt(des_cblock *in, des_cblock *out, des_ecb_key_schedule *ks, int enc) 56{ 57 const struct ccmode_ecb *ecb = enc ? g_crypto_funcs->ccdes_ecb_encrypt : g_crypto_funcs->ccdes_ecb_decrypt; 58 ccecb_ctx *ctx = enc ? ks->enc : ks->dec; 59 60 ecb->ecb(ctx, 1, in, out); 61} 62 63 64/* Triple DES ECB - used by ipv6 (esp_core.c) */ 65int des3_ecb_key_sched(des_cblock *key, des3_ecb_key_schedule *ks) 66{ 67 const struct ccmode_ecb *enc = g_crypto_funcs->cctdes_ecb_encrypt; 68 const struct ccmode_ecb *dec = g_crypto_funcs->cctdes_ecb_decrypt; 69 70 /* Make sure the context size for the mode fits in the one we have */ 71 if((enc->size>sizeof(ks->enc)) || (dec->size>sizeof(ks->dec))) 72 panic("%s: inconsistent size for 3DES-ECB context", __FUNCTION__); 73 74 enc->init(enc, ks->enc, CCDES_KEY_SIZE*3, key); 75 dec->init(dec, ks->dec, CCDES_KEY_SIZE*3, key); 76 77 /* The old DES interface could return -1 or -2 for weak keys and wrong parity, 78 but this was disabled all the time, so we never fail here */ 79 return 0; 80} 81 82/* Simple des - 1 block */ 83void des3_ecb_encrypt(des_cblock *in, des_cblock *out, des3_ecb_key_schedule *ks, int enc) 84{ 85 const struct ccmode_ecb *ecb = enc ? g_crypto_funcs->cctdes_ecb_encrypt : g_crypto_funcs->cctdes_ecb_decrypt; 86 ccecb_ctx *ctx = enc ? ks->enc : ks->dec; 87 88 ecb->ecb(ctx, 1, in, out); 89} 90 91/* Single DES CBC - used by nfs_gss */ 92int des_cbc_key_sched(des_cblock *key, des_cbc_key_schedule *ks) 93{ 94 const struct ccmode_cbc *enc = g_crypto_funcs->ccdes_cbc_encrypt; 95 const struct ccmode_cbc *dec = g_crypto_funcs->ccdes_cbc_decrypt; 96 97 /* Make sure the context size for the mode fits in the one we have */ 98 if((enc->size>sizeof(ks->enc)) || (dec->size>sizeof(ks->dec))) 99 panic("%s: inconsistent size for DES-CBC context", __FUNCTION__); 100 101 102 cccbc_init(enc, ks->enc, CCDES_KEY_SIZE, key); 103 cccbc_init(dec, ks->dec, CCDES_KEY_SIZE, key); 104 105 /* The old DES interface could return -1 or -2 for weak keys and wrong parity, 106 but this was disabled all the time, so we never fail here */ 107 return 0; 108} 109 110/* this is normally only called with length an 8 bytes multiple */ 111void 112des_cbc_encrypt(des_cblock *in, des_cblock *out, int32_t length, 113 des_cbc_key_schedule *ks, des_cblock *iv, des_cblock *retiv, int encrypt) 114{ 115 const struct ccmode_cbc *cbc = encrypt?g_crypto_funcs->ccdes_cbc_encrypt:g_crypto_funcs->ccdes_cbc_decrypt; 116 cccbc_ctx *ctx = encrypt ? ks->enc : ks->dec; 117 int nblocks; 118 cccbc_iv_decl(cbc->block_size, ctx_iv); 119 120 assert(length%8==0); 121 nblocks=length/8; 122 123 /* set the iv */ 124 cccbc_set_iv(cbc, ctx_iv, iv); 125 126 cccbc_update(cbc, ctx, ctx_iv, nblocks, in, out); 127 128 /* copy back iv */ 129 if(retiv) 130 memcpy(retiv, ctx_iv, 8); 131} 132 133/* Triple DES CBC - used by nfs_gss */ 134int des3_cbc_key_sched(des_cblock *key, des3_cbc_key_schedule *ks) 135{ 136 const struct ccmode_cbc *enc = g_crypto_funcs->cctdes_cbc_encrypt; 137 const struct ccmode_cbc *dec = g_crypto_funcs->cctdes_cbc_decrypt; 138 139 /* Make sure the context size for the mode fits in the one we have */ 140 if((enc->size>sizeof(ks->enc)) || (dec->size>sizeof(ks->dec))) 141 panic("%s: inconsistent size for 3DES-CBC context", __FUNCTION__); 142 143 cccbc_init(enc, ks->enc, CCDES_KEY_SIZE*3, key); 144 cccbc_init(dec, ks->dec, CCDES_KEY_SIZE*3, key); 145 146 /* The old DES interface could return -1 or -2 for weak keys and wrong parity, 147 but this was disabled all the time, so we never fail here */ 148 return 0; 149} 150 151/* this is normally only called with length an 8 bytes multiple */ 152void 153des3_cbc_encrypt(des_cblock *in, des_cblock *out, int32_t length, 154 des3_cbc_key_schedule *ks, des_cblock *iv, des_cblock *retiv, int encrypt) 155{ 156 const struct ccmode_cbc *cbc = encrypt?g_crypto_funcs->cctdes_cbc_encrypt:g_crypto_funcs->cctdes_cbc_decrypt; 157 cccbc_ctx *ctx = encrypt ? ks->enc : ks->dec; 158 int nblocks; 159 cccbc_iv_decl(cbc->block_size, ctx_iv); 160 161 assert(length%8==0); 162 nblocks=length/8; 163 164 /* set the iv */ 165 cccbc_set_iv(cbc, ctx_iv, iv); 166 167 cccbc_update(cbc, ctx, ctx_iv, nblocks, in, out); 168 169 /* copy back iv */ 170 if(retiv) 171 memcpy(retiv, ctx_iv, 8); 172} 173 174 175/* 176 * DES MAC implemented according to FIPS 113 177 * http://www.itl.nist.gov/fipspubs/fip113.htm 178 * Only full blocks. 179 * Used by nfs-gss 180 */ 181void 182des_cbc_cksum(des_cblock *in, des_cblock *out, 183 int len, des_cbc_key_schedule *ks) 184{ 185 const struct ccmode_cbc *cbc = g_crypto_funcs->ccdes_cbc_encrypt; 186 int nblocks; 187 des_cblock cksum; 188 cccbc_iv_decl(cbc->block_size, ctx_iv); 189 190 assert(len%8==0); 191 nblocks=len/8; 192 193 cccbc_set_iv(cbc, ctx_iv, NULL); 194 while(nblocks--) { 195 cccbc_update(cbc, ks->enc, ctx_iv, 1, in++, cksum); 196 } 197 memcpy(out, cksum, sizeof(des_cblock)); 198} 199 200 201/* Raw key helper functions */ 202void des_fixup_key_parity(des_cblock *key) 203{ 204 g_crypto_funcs->ccdes_key_set_odd_parity_fn(key, CCDES_KEY_SIZE); 205} 206 207int des_is_weak_key(des_cblock *key) 208{ 209 return g_crypto_funcs->ccdes_key_is_weak_fn(key, CCDES_KEY_SIZE); 210} 211