1 #include <libkern/crypto/crypto_internal.h>
2 #include <libkern/crypto/sha1.h>
3 #include <kern/debug.h>
4 #include <corecrypto/ccdigest.h>
8 getCount(SHA1_CTX
*ctx
)
14 setCount(SHA1_CTX
*ctx
, uint64_t count
)
16 ctx
->c
.b64
[0] = count
;
19 /* Copy a ccdigest ctx into a legacy SHA1 context */
21 DiToSHA1(const struct ccdigest_info
*di
, struct ccdigest_ctx
*di_ctx
, SHA1_CTX
*sha1_ctx
)
23 setCount(sha1_ctx
, ccdigest_nbits(di
, di_ctx
) / 8 + ccdigest_num(di
, di_ctx
));
24 memcpy(sha1_ctx
->m
.b8
, ccdigest_data(di
, di_ctx
), di
->block_size
);
25 memcpy(sha1_ctx
->h
.b8
, ccdigest_state_ccn(di
, di_ctx
), di
->state_size
);
28 /* Copy a legacy SHA1 context into a ccdigest ctx */
30 SHA1ToDi(const struct ccdigest_info
*di
, SHA1_CTX
*sha1_ctx
, struct ccdigest_ctx
*di_ctx
)
32 uint64_t count
= getCount(sha1_ctx
);
34 ccdigest_num(di
, di_ctx
) = (unsigned)(count
% di
->block_size
);
35 ccdigest_nbits(di
, di_ctx
) = (count
- ccdigest_num(di
, di_ctx
)) * 8;
36 memcpy(ccdigest_data(di
, di_ctx
), sha1_ctx
->m
.b8
, di
->block_size
);
37 memcpy(ccdigest_state_ccn(di
, di_ctx
), sha1_ctx
->h
.b8
, di
->state_size
);
41 SHA1Init(SHA1_CTX
*ctx
)
43 const struct ccdigest_info
*di
= g_crypto_funcs
->ccsha1_di
;
44 ccdigest_di_decl(di
, di_ctx
);
46 g_crypto_funcs
->ccdigest_init_fn(di
, di_ctx
);
48 DiToSHA1(di
, di_ctx
, ctx
);
52 SHA1Update(SHA1_CTX
*ctx
, const void *data
, size_t len
)
54 const struct ccdigest_info
*di
= g_crypto_funcs
->ccsha1_di
;
55 ccdigest_di_decl(di
, di_ctx
);
57 SHA1ToDi(di
, ctx
, di_ctx
);
58 g_crypto_funcs
->ccdigest_update_fn(di
, di_ctx
, len
, data
);
59 DiToSHA1(di
, di_ctx
, ctx
);
63 SHA1Final(void *digest
, SHA1_CTX
*ctx
)
65 const struct ccdigest_info
*di
= g_crypto_funcs
->ccsha1_di
;
66 ccdigest_di_decl(di
, di_ctx
);
68 SHA1ToDi(di
, ctx
, di_ctx
);
69 ccdigest_final(di
, di_ctx
, digest
);
72 #ifdef XNU_KERNEL_PRIVATE
74 SHA1UpdateUsePhysicalAddress(SHA1_CTX
*ctx
, const void *data
, size_t len
)
76 //TODO: What the hell ?
77 SHA1Update(ctx
, data
, len
);
81 /* This is not publicised in header, but exported in libkern.exports */
82 void SHA1Final_r(SHA1_CTX
*context
, void *digest
);
84 SHA1Final_r(SHA1_CTX
*context
, void *digest
)
86 SHA1Final(digest
, context
);
91 * This function is called by the SHA1 hardware kext during its init.
92 * This will register the function to call to perform SHA1 using hardware.
94 #include <sys/types.h>
95 #include <libkern/OSAtomic.h>
96 #include <sys/systm.h>
98 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
);
99 void sha1_hardware_hook(Boolean option
, InKernelPerformSHA1Func func
, void *ref
);
100 static void *SHA1Ref
;
101 static InKernelPerformSHA1Func performSHA1WithinKernelOnly
;
104 sha1_hardware_hook(Boolean option
, InKernelPerformSHA1Func func
, void *ref
)
107 // Establish the hook. The hardware is ready.
108 OSCompareAndSwapPtr((void*)NULL
, (void*)ref
, (void * volatile*)&SHA1Ref
);
110 if (!OSCompareAndSwapPtr((void *)NULL
, (void *)func
, (void * volatile *)&performSHA1WithinKernelOnly
)) {
111 panic("sha1_hardware_hook: Called twice.. Should never happen\n");
114 // The hardware is going away. Tear down the hook.
115 performSHA1WithinKernelOnly
= NULL
;