1/*
2 * Copyright (c) 2000-2004,2006,2011,2013-2014 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24
25/*
26 * digestobject.h - generic virtual Digest base class
27 */
28
29#ifndef	_DIGEST_OBJECT_H_
30#define _DIGEST_OBJECT_H_
31
32#include <security_cdsa_utilities/cssmalloc.h>
33
34/* common virtual digest class */
35class DigestObject {
36public:
37	DigestObject() : mInitFlag(false), mIsDone(false) { }
38	virtual ~DigestObject() { }
39
40	/*
41	 * The remaining functions must be implemented by subclass.
42	 */
43	/* init is reusable */
44	virtual void digestInit() = 0;
45
46	/* add some data */
47	virtual void digestUpdate(
48		const void *data,
49		size_t 		len) = 0;
50
51	/* obtain digest (once only per init, update, ... cycle) */
52	virtual void digestFinal(
53		void 		*digest) = 0;  	/* RETURNED, alloc'd by caller */
54
55	/* sublass-specific copy */
56	virtual DigestObject *digestClone() const = 0;
57
58	virtual size_t digestSizeInBytes() const = 0;
59
60protected:
61	bool			mInitFlag;
62	bool			mIsDone;
63
64	bool			initFlag() 				{ return mInitFlag; }
65	void			setInitFlag(bool flag) 	{ mInitFlag = flag; }
66	bool			isDone() 				{ return mIsDone; }
67	void			setIsDone(bool done) 	{ mIsDone = done; }
68};
69
70/*
71 * NullDigest.h - nop digest for use with raw signature algorithms.
72 *				  NullDigest(someData) = someData.
73 */
74class NullDigest : public DigestObject
75{
76public:
77	NullDigest() : mInBuf(NULL), mInBufSize(0)
78	{
79	}
80
81	void digestInit()
82	{
83		/* reusable - reset */
84		if(mInBufSize) {
85			assert(mInBuf != NULL);
86			memset(mInBuf, 0, mInBufSize);
87			Allocator::standard().free(mInBuf);
88			mInBufSize = 0;
89			mInBuf = NULL;
90		}
91	}
92
93	~NullDigest()
94	{
95		digestInit();
96	}
97
98	void digestUpdate(
99		const void *data,
100		size_t 		len)
101	{
102		mInBuf = Allocator::standard().realloc(mInBuf, mInBufSize + len);
103		memmove((uint8 *)mInBuf + mInBufSize, data, len);
104		mInBufSize += len;
105	}
106
107	virtual void digestFinal(
108		void 		*digest)
109	{
110		memmove(digest, mInBuf, mInBufSize);
111	}
112
113	virtual DigestObject *digestClone() const
114	{
115		NullDigest *cloned = new NullDigest;
116		cloned->digestUpdate(mInBuf, mInBufSize);
117		return cloned;
118	}
119
120	/* unique to NullDigest - just obtain current data ptr, no copy */
121	virtual const void *digestPtr() { return mInBuf; }
122
123	size_t digestSizeInBytes() const
124	{
125		return mInBufSize;
126	}
127
128private:
129	void		*mInBuf;
130	size_t		mInBufSize;
131};
132
133#endif	/* _DIGEST_OBJECT_H_ */
134