1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>VeraCrypt - Free Open source disk encryption with strong security for the Paranoid</title>
<meta name="description" content="VeraCrypt is free open-source disk encryption software for Windows, Mac OS X and Linux. In case an attacker forces you to reveal the password, VeraCrypt provides plausible deniability. In contrast to file encryption, data encryption performed by VeraCrypt is real-time (on-the-fly), automatic, transparent, needs very little memory, and does not involve temporary unencrypted files."/>
<meta name="keywords" content="encryption, security"/>
<link href="styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div>
<a href="https://www.veracrypt.fr/en/Home.html"><img src="VeraCrypt128x128.png" alt="VeraCrypt"/></a>
</div>
<div id="menu">
<ul>
<li><a href="Home.html">Home</a></li>
<li><a href="/code/">Source Code</a></li>
<li><a href="Downloads.html">Downloads</a></li>
<li><a class="active" href="Documentation.html">Documentation</a></li>
<li><a href="Donation.html">Donate</a></li>
<li><a href="https://sourceforge.net/p/veracrypt/discussion/" target="_blank">Forums</a></li>
</ul>
</div>
<div>
<p>
<a href="Documentation.html">Documentation</a>
<img src="arrow_right.gif" alt=">>" style="margin-top: 5px">
<a href="Plausible%20Deniability.html">Plausible Deniability</a>
<img src="arrow_right.gif" alt=">>" style="margin-top: 5px">
<a href="Hidden%20Volume.html">Hidden Volume</a>
<img src="arrow_right.gif" alt=">>" style="margin-top: 5px">
<a href="Security%20Requirements%20for%20Hidden%20Volumes.html">Security Requirements for Hidden Volumes</a>
</p></div>
<div class="wikidoc">
<h1>Security Requirements and Precautions Pertaining to Hidden Volumes.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long *//*
Derived from source code of TrueCrypt 7.1a, which is
Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
by the TrueCrypt License 3.0.
Modifications and additions to the original source code (contained in this file)
and all other portions of this file are Copyright (c) 2013-2017 IDRIX
and are governed by the Apache License 2.0 the full text of which is
contained in the file License.txt included in VeraCrypt binary and source
code distribution packages.
*/
#define FUSE_USE_VERSION 25
#include <errno.h>
#include <fcntl.h>
#include <fuse.h>
#include <iostream>
#include <signal.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <time.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <sys/wait.h>
#include "FuseService.h"
#include "Platform/FileStream.h"
#include "Platform/MemoryStream.h"
#include "Platform/Serializable.h"
#include "Platform/SystemLog.h"
#include "Platform/Unix/Pipe.h"
#include "Platform/Unix/Poller.h"
#include "Volume/EncryptionThreadPool.h"
#include "Core/Core.h"
namespace VeraCrypt
{
static int fuse_service_access (const char *path, int mask)
{
try
{
if (!FuseService::CheckAccessRights())
return -EACCES;
}
catch (...)
{
return FuseService::ExceptionToErrorCode();
}
return 0;
}
static void *fuse_service_init ()
{
try
{
// Termination signals are handled by a separate process to allow clean dismount on shutdown
struct sigaction action;
Memory::Zero (&action, sizeof (action));
action.sa_handler = SIG_IGN;
sigaction (SIGINT, &action, nullptr);
sigaction (SIGQUIT, &action, nullptr);
sigaction (SIGTERM, &action, nullptr);
if (!EncryptionThreadPool::IsRunning())
EncryptionThreadPool::Start();
}
catch (exception &e)
{
SystemLog::WriteException (e);
}
catch (...)
{
SystemLog::WriteException (UnknownException (SRC_POS));
}
return nullptr;
}
static void fuse_service_destroy (void *userdata)
{
try
{
FuseService::Dismount();
}
catch (exception &e)
{
SystemLog::WriteException (e);
}
catch (...)
{
SystemLog::WriteException (UnknownException (SRC_POS));
}
}
static int fuse_service_getattr (const char *path, struct stat *statData)
{
try
{
Memory::Zero (statData, sizeof(*statData));
statData->st_uid = FuseService::GetUserId();
statData->st_gid = FuseService::GetGroupId();
statData->st_atime = time (NULL);
statData->st_ctime = time (NULL);
statData->st_mtime = time (NULL);
if (strcmp (path, "/") == 0)
{
statData->st_mode = S_IFDIR | 0500;
statData->st_nlink = 2;
}
else
{
if (!FuseService::CheckAccessRights())
return -EACCES;
if (strcmp (path, FuseService::GetVolumeImagePath()) == 0)
{
statData->st_mode = S_IFREG | 0600;
statData->st_nlink = 1;
statData->st_size = FuseService::GetVolumeSize();
}
else if (strcmp (path, FuseService::GetControlPath()) == 0)
{
statData->st_mode = S_IFREG | 0600;
statData->st_nlink = 1;
statData->st_size = FuseService::GetVolumeInfo()->Size();
}
else
{
return -ENOENT;
}
}
}
catch (...)
{
return FuseService::ExceptionToErrorCode();
}
return 0;
}
static int fuse_service_opendir (const char *path, struct fuse_file_info *fi)
{
try
{
if (!FuseService::CheckAccessRights())
return -EACCES;
if (strcmp (path, "/") != 0)
return -ENOENT;
}
catch (...)
{
return FuseService::ExceptionToErrorCode();
}
return 0;
}
static int fuse_service_open (const char *path, struct fuse_file_info *fi)
{
try
{
if (!FuseService::CheckAccessRights())
return -EACCES;
if (strcmp (path, FuseService::GetVolumeImagePath()) == 0)
return 0;
if (strcmp (path, FuseService::GetControlPath()) == 0)
{
fi->direct_io = 1;
return 0;
}
}
catch (...)
{
return FuseService::ExceptionToErrorCode();
}
return -ENOENT;
}
static int fuse_service_read (const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi)
{
try
{
if (!FuseService::CheckAccessRights())
return -EACCES;
if (strcmp (path, FuseService::GetVolumeImagePath()) == 0)
{
try
{
// Test for read beyond the end of the volume
if ((uint64) offset + size > FuseService::GetVolumeSize())
size = FuseService::GetVolumeSize() - offset;
size_t sectorSize = FuseService::GetVolumeSectorSize();
if (size % sectorSize != 0 || offset % sectorSize != 0)
{
// Support for non-sector-aligned read operations is required by some loop device tools
// which may analyze the volume image before attaching it as a device
uint64 alignedOffset = offset - (offset % sectorSize);
uint64 alignedSize = size + (offset % sectorSize);
if (alignedSize % sectorSize != 0)
alignedSize += sectorSize - (alignedSize % sectorSize);
SecureBuffer alignedBuffer (alignedSize);
FuseService::ReadVolumeSectors (alignedBuffer, alignedOffset);
BufferPtr ((byte *) buf, size).CopyFrom (alignedBuffer.GetRange (offset % sectorSize, size));
}
else
{
FuseService::ReadVolumeSectors (BufferPtr ((byte *) buf, size), offset);
}
}
catch (MissingVolumeData)
{
return 0;
}
return size;
}
if (strcmp (path, FuseService::GetControlPath()) == 0)
{
shared_ptr <Buffer> infoBuf = FuseService::GetVolumeInfo();
BufferPtr outBuf ((byte *)buf, size);
if (offset >= (off_t) infoBuf->Size())
return 0;
if (offset + size > infoBuf->Size())
size = infoBuf->Size () - offset;
outBuf.CopyFrom (infoBuf->GetRange (offset, size));
return size;
}
}
catch (...)
{
return FuseService::ExceptionToErrorCode();
}
return -ENOENT;
}
static int fuse_service_readdir (const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi)
{
try
{
if (!FuseService::CheckAccessRights())
return -EACCES;
if (strcmp (path, "/") != 0)
return -ENOENT;
filler (buf, ".", NULL, 0);
filler (buf, "..", NULL, 0);
filler (buf, FuseService::GetVolumeImagePath() + 1, NULL, 0);
filler (buf, FuseService::GetControlPath() + 1, NULL, 0);
}
catch (...)
{
return FuseService::ExceptionToErrorCode();
}
return 0;
}
static int fuse_service_write (const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi)
{
try
{
if (!FuseService::CheckAccessRights())
return -EACCES;
if (strcmp (path, FuseService::GetVolumeImagePath()) == 0)
{
FuseService::WriteVolumeSectors (BufferPtr ((byte *) buf, size), offset);
return size;
}
if (strcmp (path, FuseService::GetControlPath()) == 0)
{
if (FuseService::AuxDeviceInfoReceived())
return -EACCES;
FuseService::ReceiveAuxDeviceInfo (ConstBufferPtr ((const byte *)buf, size));
return size;
}
}
#ifdef TC_FREEBSD
// FreeBSD apparently retries failed write operations forever, which may lead to a system crash.
catch (VolumeReadOnly&)
{
return size;
}
catch (VolumeProtected&)
{
return size;
}
#endif
catch (...)
{
return FuseService::ExceptionToErrorCode();
}
return -ENOENT;
}
bool FuseService::CheckAccessRights ()
{
return fuse_get_context()->uid == 0 || fuse_get_context()->uid == UserId;
}
void FuseService::CloseMountedVolume ()
{
if (MountedVolume)
{
// Thi
|