VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/checksum/RTSha256Digest.cpp@ 51851

Last change on this file since 51851 was 51851, checked in by vboxsync, 10 years ago

Renamed hash implementations to fit better into the build system, supplying the missing OpenSSL-based MD5. VBoxRT uses the OpenSSL variants, all other libraries uses the alternatives. Also removed stupid OpenSSL dependencies in RTSha1Digest.cpp and RTSha256Digest.cpp.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.6 KB
Line 
1/** @file
2 * IPRT - SHA256 digest creation
3 *
4 * @todo Replace this with generic RTCrDigest based implementation. Too much
5 * stupid code duplication.
6 */
7
8/*
9 * Copyright (C) 2009-2014 Oracle Corporation
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.virtualbox.org. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18 *
19 * The contents of this file may alternatively be used under the terms
20 * of the Common Development and Distribution License Version 1.0
21 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
22 * VirtualBox OSE distribution, in which case the provisions of the
23 * CDDL are applicable instead of those of the GPL.
24 *
25 * You may elect to license modified versions of this file under the
26 * terms and conditions of either the GPL or the CDDL or both.
27 */
28
29
30/*******************************************************************************
31* Header Files *
32*******************************************************************************/
33#include "internal/iprt.h"
34#include <iprt/sha.h>
35
36#include <iprt/alloca.h>
37#include <iprt/assert.h>
38#include <iprt/mem.h>
39#include <iprt/string.h>
40#include <iprt/file.h>
41
42
43RTR3DECL(int) RTSha256Digest(void* pvBuf, size_t cbBuf, char **ppszDigest, PFNRTPROGRESS pfnProgressCallback, void *pvUser)
44{
45 /* Validate input */
46 AssertPtrReturn(pvBuf, VERR_INVALID_POINTER);
47 AssertPtrReturn(ppszDigest, VERR_INVALID_POINTER);
48 AssertPtrNullReturn(pfnProgressCallback, VERR_INVALID_PARAMETER);
49
50 int rc = VINF_SUCCESS;
51 *ppszDigest = NULL;
52
53 /* Initialize the hash context. */
54 RTSHA256CONTEXT Ctx;
55 RTSha256Init(&Ctx);
56
57 /* Buffer size for progress callback */
58 double rdMulti = 100.0 / (cbBuf ? cbBuf : 1);
59
60 /* Working buffer */
61 char *pvTmp = (char*)pvBuf;
62
63 /* Process the memory in blocks */
64 size_t cbReadTotal = 0;
65 for (;;)
66 {
67 size_t cbRead = RT_MIN(cbBuf - cbReadTotal, _1M);
68 RTSha256Update(&Ctx, pvTmp, cbRead);
69 cbReadTotal += cbRead;
70 pvTmp += cbRead;
71
72 /* Call the progress callback if one is defined */
73 if (pfnProgressCallback)
74 {
75 rc = pfnProgressCallback((unsigned)(cbReadTotal * rdMulti), pvUser);
76 if (RT_FAILURE(rc))
77 break; /* canceled */
78 }
79 /* Finished? */
80 if (cbReadTotal == cbBuf)
81 break;
82 }
83 if (RT_SUCCESS(rc))
84 {
85 /* Finally calculate & format the SHA256 sum */
86 uint8_t abHash[RTSHA256_HASH_SIZE];
87 RTSha256Final(&Ctx, abHash);
88
89 char *pszDigest;
90 rc = RTStrAllocEx(&pszDigest, RTSHA256_DIGEST_LEN + 1);
91 if (RT_SUCCESS(rc))
92 {
93 rc = RTSha256ToString(abHash, pszDigest, RTSHA256_DIGEST_LEN + 1);
94 if (RT_SUCCESS(rc))
95 *ppszDigest = pszDigest;
96 else
97 RTStrFree(pszDigest);
98 }
99 }
100
101 return rc;
102}
103
104RTR3DECL(int) RTSha256DigestFromFile(const char *pszFile, char **ppszDigest, PFNRTPROGRESS pfnProgressCallback, void *pvUser)
105{
106 /* Validate input */
107 AssertPtrReturn(pszFile, VERR_INVALID_POINTER);
108 AssertPtrReturn(ppszDigest, VERR_INVALID_POINTER);
109 AssertPtrNullReturn(pfnProgressCallback, VERR_INVALID_PARAMETER);
110
111 *ppszDigest = NULL;
112
113 /* Initialize the hash context. */
114 RTSHA256CONTEXT Ctx;
115 RTSha256Init(&Ctx);
116
117 /* Open the file to calculate a SHA256 sum of */
118 RTFILE hFile;
119 int rc = RTFileOpen(&hFile, pszFile, RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_WRITE);
120 if (RT_FAILURE(rc))
121 return rc;
122
123 /* Fetch the file size. Only needed if there is a progress callback. */
124 double rdMulti = 0;
125 if (pfnProgressCallback)
126 {
127 uint64_t cbFile;
128 rc = RTFileGetSize(hFile, &cbFile);
129 if (RT_FAILURE(rc))
130 {
131 RTFileClose(hFile);
132 return rc;
133 }
134 rdMulti = 100.0 / (cbFile ? cbFile : 1);
135 }
136
137 /* Allocate a reasonably large buffer, fall back on a tiny one. */
138 void *pvBufFree;
139 size_t cbBuf = _1M;
140 void *pvBuf = pvBufFree = RTMemTmpAlloc(cbBuf);
141 if (!pvBuf)
142 {
143 cbBuf = 0x1000;
144 pvBuf = alloca(cbBuf);
145 }
146
147 /* Read that file in blocks */
148 size_t cbReadTotal = 0;
149 for (;;)
150 {
151 size_t cbRead;
152 rc = RTFileRead(hFile, pvBuf, cbBuf, &cbRead);
153 if (RT_FAILURE(rc) || !cbRead)
154 break;
155 RTSha256Update(&Ctx, pvBuf, cbRead);
156 cbReadTotal += cbRead;
157
158 /* Call the progress callback if one is defined */
159 if (pfnProgressCallback)
160 {
161 rc = pfnProgressCallback((unsigned)(cbReadTotal * rdMulti), pvUser);
162 if (RT_FAILURE(rc))
163 break; /* canceled */
164 }
165 }
166 RTMemTmpFree(pvBufFree);
167 RTFileClose(hFile);
168
169 if (RT_FAILURE(rc))
170 return rc;
171
172 /* Finally calculate & format the SHA256 sum */
173 uint8_t abHash[RTSHA256_HASH_SIZE];
174 RTSha256Final(&Ctx, abHash);
175
176 char *pszDigest;
177 rc = RTStrAllocEx(&pszDigest, RTSHA256_DIGEST_LEN + 1);
178 if (RT_SUCCESS(rc))
179 {
180 rc = RTSha256ToString(abHash, pszDigest, RTSHA256_DIGEST_LEN + 1);
181 if (RT_SUCCESS(rc))
182 *ppszDigest = pszDigest;
183 else
184 RTStrFree(pszDigest);
185 }
186
187 return rc;
188}
189
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette