1/*
2 * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package sun.security.mscapi;
27
28import java.security.ProviderException;
29import java.security.SecureRandomSpi;
30
31/**
32 * Native PRNG implementation for Windows using the Microsoft Crypto API.
33 *
34 * @since 1.6
35 */
36
37public final class PRNG extends SecureRandomSpi
38    implements java.io.Serializable {
39
40    private static final long serialVersionUID = 4129268715132691532L;
41
42    /*
43     * The CryptGenRandom function fills a buffer with cryptographically random
44     * bytes.
45     */
46    private static native byte[] generateSeed(int length, byte[] seed);
47
48    /**
49     * Creates a random number generator.
50     */
51    public PRNG() {
52    }
53
54    /**
55     * Reseeds this random object. The given seed supplements, rather than
56     * replaces, the existing seed. Thus, repeated calls are guaranteed
57     * never to reduce randomness.
58     *
59     * @param seed the seed.
60     */
61    @Override
62    protected void engineSetSeed(byte[] seed) {
63        if (seed != null) {
64            generateSeed(-1, seed);
65        }
66    }
67
68    /**
69     * Generates a user-specified number of random bytes.
70     *
71     * @param bytes the array to be filled in with random bytes.
72     */
73    @Override
74    protected void engineNextBytes(byte[] bytes) {
75        if (bytes != null) {
76            if (generateSeed(0, bytes) == null) {
77                throw new ProviderException("Error generating random bytes");
78            }
79        }
80    }
81
82    /**
83     * Returns the given number of seed bytes.  This call may be used to
84     * seed other random number generators.
85     *
86     * @param numBytes the number of seed bytes to generate.
87     *
88     * @return the seed bytes.
89     */
90    @Override
91    protected byte[] engineGenerateSeed(int numBytes) {
92        byte[] seed = generateSeed(numBytes, null);
93
94        if (seed == null) {
95            throw new ProviderException("Error generating seed bytes");
96        }
97        return seed;
98    }
99}
100