2 #include <libkern/crypto/crypto_internal.h>
3 #include <libkern/crypto/sha1.h>
4 #include <kern/debug.h>
5 #include <corecrypto/ccdigest.h>
8 static uint64_t getCount(SHA1_CTX
*ctx
)
13 static void setCount(SHA1_CTX
*ctx
, uint64_t count
)
18 /* Copy a ccdigest ctx into a legacy SHA1 context */
19 static void DiToSHA1(const struct ccdigest_info
*di
, struct ccdigest_ctx
*di_ctx
, SHA1_CTX
*sha1_ctx
)
21 setCount(sha1_ctx
, ccdigest_nbits(di
, di_ctx
)/8+ccdigest_num(di
, di_ctx
));
22 memcpy(sha1_ctx
->m
.b8
, ccdigest_data(di
, di_ctx
), di
->block_size
);
23 memcpy(sha1_ctx
->h
.b8
, ccdigest_state_ccn(di
, di_ctx
), di
->state_size
);
26 /* Copy a legacy SHA1 context into a ccdigest ctx */
27 static void SHA1ToDi(const struct ccdigest_info
*di
, SHA1_CTX
*sha1_ctx
, struct ccdigest_ctx
*di_ctx
)
29 uint64_t count
= getCount(sha1_ctx
);
31 ccdigest_num(di
, di_ctx
)=count%di
->block_size
;
32 ccdigest_nbits(di
, di_ctx
)=(count
-ccdigest_num(di
, di_ctx
))*8;
33 memcpy(ccdigest_data(di
, di_ctx
), sha1_ctx
->m
.b8
, di
->block_size
);
34 memcpy(ccdigest_state_ccn(di
, di_ctx
), sha1_ctx
->h
.b8
, di
->state_size
);
37 void SHA1Init(SHA1_CTX
*ctx
)
39 const struct ccdigest_info
*di
=g_crypto_funcs
->ccsha1_di
;
40 ccdigest_di_decl(di
, di_ctx
);
42 g_crypto_funcs
->ccdigest_init_fn(di
, di_ctx
);
44 DiToSHA1(di
, di_ctx
, ctx
);
47 void SHA1Update(SHA1_CTX
*ctx
, const void *data
, size_t len
)
49 const struct ccdigest_info
*di
=g_crypto_funcs
->ccsha1_di
;
50 ccdigest_di_decl(di
, di_ctx
);
52 SHA1ToDi(di
, ctx
, di_ctx
);
53 g_crypto_funcs
->ccdigest_update_fn(di
, di_ctx
, len
, data
);
54 DiToSHA1(di
, di_ctx
, ctx
);
57 void SHA1Final(void *digest
, SHA1_CTX
*ctx
)
59 const struct ccdigest_info
*di
=g_crypto_funcs
->ccsha1_di
;
60 ccdigest_di_decl(di
, di_ctx
);
62 SHA1ToDi(di
, ctx
, di_ctx
);
63 ccdigest_final(di
, di_ctx
, digest
);
66 #ifdef XNU_KERNEL_PRIVATE
67 void SHA1UpdateUsePhysicalAddress(SHA1_CTX
*ctx
, const void *data
, size_t len
)
69 //TODO: What the hell ?
70 SHA1Update(ctx
, data
, len
);
74 /* This is not publicised in header, but exported in libkern.exports */
75 void SHA1Final_r(SHA1_CTX
*context
, void *digest
);
76 void SHA1Final_r(SHA1_CTX
*context
, void *digest
)
78 SHA1Final(digest
, context
);
83 * This function is called by the SHA1 hardware kext during its init.
84 * This will register the function to call to perform SHA1 using hardware.
86 #include <sys/types.h>
87 #include <libkern/OSAtomic.h>
88 #include <sys/systm.h>
90 typedef kern_return_t (*InKernelPerformSHA1Func
)(void *ref
, const void *data
, size_t dataLen
, u_int32_t
*inHash
, u_int32_t options
, u_int32_t
*outHash
, Boolean usePhysicalAddress
);
91 void sha1_hardware_hook(Boolean option
, InKernelPerformSHA1Func func
, void *ref
);
93 static InKernelPerformSHA1Func performSHA1WithinKernelOnly
;
95 void sha1_hardware_hook(Boolean option
, InKernelPerformSHA1Func func
, void *ref
)
98 // Establish the hook. The hardware is ready.
99 OSCompareAndSwapPtr((void*)NULL
, (void*)ref
, (void * volatile*)&SHA1Ref
);
101 if(!OSCompareAndSwapPtr((void *)NULL
, (void *)func
, (void * volatile *)&performSHA1WithinKernelOnly
)) {
102 panic("sha1_hardware_hook: Called twice.. Should never happen\n");
106 // The hardware is going away. Tear down the hook.
107 performSHA1WithinKernelOnly
= NULL
;