Skip to content

Commit

Permalink
Introduce soter_wipe() function (#488)
Browse files Browse the repository at this point in the history
Add a utility function to securely wipe memory region. We have quite
a few places in our code where this can be useful, and it's a good
function to export for the users (of Soter).

It's implemented via OPENSSL_cleanse() function on both OpenSSL and
BoringSSL. That's an old function available since OpenSSL 1.0.2 so we
should not run into any compatibility issues (and we *do* recommend
using latest OpenSSL anyway).

Note that it intentionally accepts `void*`, not `uint8_t*` (just like
free() does). Implicit cast is expected here and allow wiping any object
without warnings from compiler.

Replace ad-hoc memset() calls with soter_wipe(). This ensures that
these calls will not be optimized out by the compiler in release
build mode.
  • Loading branch information
ilammy authored Jul 4, 2019
1 parent ecec622 commit df8632a
Show file tree
Hide file tree
Showing 10 changed files with 136 additions and 6 deletions.
12 changes: 12 additions & 0 deletions Themis.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,10 @@
9F4A2622223ABEF2005CB63A /* sym_enc_message.c in Sources */ = {isa = PBXBuildFile; fileRef = 9F4A2431223A74AF005CB63A /* sym_enc_message.c */; };
9F5391F12293F2D90051DA66 /* portable_endian.h in Headers */ = {isa = PBXBuildFile; fileRef = 9F5391F02293F2D90051DA66 /* portable_endian.h */; };
9F5391F22293F2D90051DA66 /* portable_endian.h in Headers */ = {isa = PBXBuildFile; fileRef = 9F5391F02293F2D90051DA66 /* portable_endian.h */; };
9F98F32522CCEA5D008E14E6 /* soter_wipe.h in Headers */ = {isa = PBXBuildFile; fileRef = 9F98F32422CCEA5D008E14E6 /* soter_wipe.h */; };
9F98F32622CCEA5D008E14E6 /* soter_wipe.h in Headers */ = {isa = PBXBuildFile; fileRef = 9F98F32422CCEA5D008E14E6 /* soter_wipe.h */; };
9F98F32822CCEB0E008E14E6 /* soter_wipe.c in Sources */ = {isa = PBXBuildFile; fileRef = 9F98F32722CCEB0E008E14E6 /* soter_wipe.c */; };
9F98F32922CCEB0E008E14E6 /* soter_wipe.c in Sources */ = {isa = PBXBuildFile; fileRef = 9F98F32722CCEB0E008E14E6 /* soter_wipe.c */; };
9FBD853D223BFB5E009EAEB3 /* openssl.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9FBD853C223BFB5E009EAEB3 /* openssl.framework */; };
/* End PBXBuildFile section */

Expand Down Expand Up @@ -400,6 +404,8 @@
9F4A24C2223A8FA8005CB63A /* smessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = smessage.h; path = "src/wrappers/themis/Obj-C/objcthemis/smessage.h"; sourceTree = "<group>"; };
9F4A24C3223A8FA8005CB63A /* scell_token.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = scell_token.h; path = "src/wrappers/themis/Obj-C/objcthemis/scell_token.h"; sourceTree = "<group>"; };
9F5391F02293F2D90051DA66 /* portable_endian.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = portable_endian.h; path = src/soter/portable_endian.h; sourceTree = "<group>"; };
9F98F32422CCEA5D008E14E6 /* soter_wipe.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = soter_wipe.h; path = src/soter/soter_wipe.h; sourceTree = "<group>"; };
9F98F32722CCEB0E008E14E6 /* soter_wipe.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = soter_wipe.c; path = src/soter/openssl/soter_wipe.c; sourceTree = "<group>"; };
9FBD853C223BFB5E009EAEB3 /* openssl.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = openssl.framework; path = Carthage/Build/iOS/openssl.framework; sourceTree = "<group>"; };
9FD4C3522260D41700132A88 /* soter_api.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = soter_api.h; path = src/soter/soter_api.h; sourceTree = "<group>"; };
9FD4C3532260D43B00132A88 /* themis_api.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = themis_api.h; path = src/themis/themis_api.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -471,6 +477,7 @@
9F4A2344223A73B0005CB63A /* soter_sign_rsa.h */,
9F4A2351223A73B1005CB63A /* soter_sign.c */,
9F4A2356223A73B1005CB63A /* soter_sym.h */,
9F98F32422CCEA5D008E14E6 /* soter_wipe.h */,
9F4A2346223A73B0005CB63A /* soter_t.h */,
9F4A2345223A73B0005CB63A /* soter.h */,
);
Expand All @@ -497,6 +504,7 @@
9F4A2394223A7426005CB63A /* soter_sym.c */,
9F4A2393223A7426005CB63A /* soter_verify_ecdsa.c */,
9F4A238D223A7426005CB63A /* soter_verify_rsa.c */,
9F98F32722CCEB0E008E14E6 /* soter_wipe.c */,
);
name = openssl;
sourceTree = "<group>";
Expand Down Expand Up @@ -659,6 +667,7 @@
buildActionMask = 2147483647;
files = (
9F5391F22293F2D90051DA66 /* portable_endian.h in Headers */,
9F98F32622CCEA5D008E14E6 /* soter_wipe.h in Headers */,
9F00E8E0223C19E000EC1EF3 /* themis.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand All @@ -668,6 +677,7 @@
buildActionMask = 2147483647;
files = (
9F5391F12293F2D90051DA66 /* portable_endian.h in Headers */,
9F98F32522CCEA5D008E14E6 /* soter_wipe.h in Headers */,
9F00E8DF223C19D900EC1EF3 /* themis.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -796,6 +806,7 @@
9F00E927223C1AC000EC1EF3 /* soter_rsa_common.c in Sources */,
9F00E928223C1AC000EC1EF3 /* soter_rsa_key_pair_gen.c in Sources */,
9F00E929223C1AC000EC1EF3 /* soter_rsa_key.c in Sources */,
9F98F32922CCEB0E008E14E6 /* soter_wipe.c in Sources */,
9F00E92A223C1AC000EC1EF3 /* soter_sign_ecdsa.c in Sources */,
9F00E92B223C1AC000EC1EF3 /* soter_sign_rsa.c in Sources */,
9F00E92C223C1AC000EC1EF3 /* soter_sym.c in Sources */,
Expand Down Expand Up @@ -885,6 +896,7 @@
9F4A260A223ABECC005CB63A /* soter_rsa_common.c in Sources */,
9F4A260B223ABECC005CB63A /* soter_rsa_key_pair_gen.c in Sources */,
9F4A260C223ABECC005CB63A /* soter_rsa_key.c in Sources */,
9F98F32822CCEB0E008E14E6 /* soter_wipe.c in Sources */,
9F4A260D223ABECC005CB63A /* soter_sign_ecdsa.c in Sources */,
9F4A260E223ABECC005CB63A /* soter_sign_rsa.c in Sources */,
9F4A260F223ABECC005CB63A /* soter_sym.c in Sources */,
Expand Down
30 changes: 30 additions & 0 deletions src/soter/boringssl/soter_wipe.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2019 Cossack Labs Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "soter/soter_wipe.h"

#include <openssl/crypto.h>

soter_status_t soter_wipe(void* data, size_t length)
{
if (!data) {
return SOTER_INVALID_PARAMETER;
}

OPENSSL_cleanse(data, length);

return SOTER_SUCCESS;
}
30 changes: 30 additions & 0 deletions src/soter/openssl/soter_wipe.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2019 Cossack Labs Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "soter/soter_wipe.h"

#include <openssl/crypto.h>

soter_status_t soter_wipe(void* data, size_t length)
{
if (!data) {
return SOTER_INVALID_PARAMETER;
}

OPENSSL_cleanse(data, length);

return SOTER_SUCCESS;
}
1 change: 1 addition & 0 deletions src/soter/soter.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#include <soter/soter_rand.h>
#include <soter/soter_rsa_key_pair_gen.h>
#include <soter/soter_sym.h>
#include <soter/soter_wipe.h>

/**@}*/
#endif /* SOTER_H */
3 changes: 2 additions & 1 deletion src/soter/soter_hmac.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <string.h>

#include "soter/soter_t.h"
#include "soter/soter_wipe.h"

static size_t hash_block_size(soter_hash_algo_t algo)
{
Expand Down Expand Up @@ -97,7 +98,7 @@ soter_status_t soter_hmac_init(soter_hmac_ctx_t* hmac_ctx,
return res;
}

memset(i_key_pad, 0, sizeof(i_key_pad));
soter_wipe(i_key_pad, sizeof(i_key_pad));

for (i = 0; i < block_size; i++) {
hmac_ctx->o_key_pad[i] ^= 0x5c;
Expand Down
3 changes: 2 additions & 1 deletion src/soter/soter_kdf.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <string.h>

#include "soter/soter_t.h"
#include "soter/soter_wipe.h"

#define MAX_HMAC_SIZE 64 /* For HMAC-SHA512 */
#define MIN_VAL(_X_, _Y_) ((_X_ < _Y_) ? (_X_) : (_Y_))
Expand Down Expand Up @@ -105,7 +106,7 @@ soter_status_t soter_kdf(const void* key,

err:

memset(out, 0, sizeof(out));
soter_wipe(out, sizeof(out));

soter_hmac_destroy(hmac_ctx);

Expand Down
46 changes: 46 additions & 0 deletions src/soter/soter_wipe.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright (c) 2019 Cossack Labs Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifndef SOTER_WIPE_H
#define SOTER_WIPE_H

#include <soter/soter_api.h>
#include <soter/soter_error.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
* Securely erases sensitive data from memory.
*
* Use this function to wipe sensitive data (e.g., passwords, private keys)
* after you don't need it anymore. This function call will not be optimized
* out by the compiler.
*
* @param [in] data pointer to data to wiped
* @param [in] length length of the data in bytes
* @return SOTER_SUCCESS on success,
* SOTER_INVALID_PARAMETER on NULL data
*/
SOTER_API
soter_status_t soter_wipe(void* data, size_t length);

#ifdef __cplusplus
}
#endif

#endif /* SOTER_WIPE_H */
10 changes: 7 additions & 3 deletions src/themis/secure_comparator.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@

#include <string.h>

#include "soter/soter_wipe.h"

#include "themis/secure_comparator_t.h"

static themis_status_t secure_comparator_alice_step1(secure_comparator_t* comp_ctx,
Expand Down Expand Up @@ -479,7 +481,8 @@ themis_status_t secure_comparator_cleanup(secure_comparator_t* comp_ctx)
}

soter_hash_cleanup(&(comp_ctx->hash_ctx));
memset(comp_ctx, 0, sizeof(secure_comparator_t));

soter_wipe(comp_ctx, sizeof(secure_comparator_t));

return THEMIS_SUCCESS;
}
Expand Down Expand Up @@ -938,7 +941,7 @@ static themis_status_t secure_comparator_bob_step4(secure_comparator_t* comp_ctx
return themis_status;
}

memset(comp_ctx->secret, 0, sizeof(comp_ctx->secret));
soter_wipe(comp_ctx->secret, sizeof(comp_ctx->secret));

/* Finally Bob sends to Alice on 4 step:
* Rb || Rb signature
Expand Down Expand Up @@ -1005,7 +1008,8 @@ static themis_status_t secure_comparator_alice_step5(secure_comparator_t* comp_c
comp_ctx->result = ge_cmp(&Rab, &Pa_Pb) ? THEMIS_SCOMPARE_NO_MATCH : THEMIS_SCOMPARE_MATCH;
}

memset(comp_ctx->secret, 0, sizeof(comp_ctx->secret));
soter_wipe(comp_ctx->secret, sizeof(comp_ctx->secret));

comp_ctx->state_handler = NULL;

return THEMIS_SUCCESS;
Expand Down
3 changes: 2 additions & 1 deletion src/themis/secure_session.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "soter/soter_ec_key.h"
#include "soter/soter_rsa_key.h"
#include "soter/soter_t.h"
#include "soter/soter_wipe.h"

#include "themis/portable_endian.h"
#include "themis/secure_session_t.h"
Expand Down Expand Up @@ -61,7 +62,7 @@ themis_status_t secure_session_cleanup(secure_session_t* session_ctx)

soter_asym_ka_cleanup(&(session_ctx->ecdh_ctx));

memset(session_ctx, 0, sizeof(secure_session_t));
soter_wipe(session_ctx, sizeof(secure_session_t));

return THEMIS_SUCCESS;
}
Expand Down
4 changes: 4 additions & 0 deletions src/themis/secure_session_peer.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,13 @@

#include <string.h>

#include "soter/soter_wipe.h"

void secure_session_peer_cleanup(secure_session_peer_t* peer)
{
if (peer->id) {
size_t length = peer->id_length + peer->ecdh_key_length + peer->sign_key_length;
soter_wipe(peer->id, length);
free(peer->id);
}

Expand Down

0 comments on commit df8632a

Please sign in to comment.